//===-- ObjectFilePECOFF.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "ObjectFilePECOFF.h"
#include "PECallFrameInfo.h"
#include "WindowsMiniDump.h"

#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SaveCoreOptions.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/FileSpecList.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
#include "lldb/Utility/UUID.h"

#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Support/CRC.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/TargetParser/Host.h"
#include <optional>

#define IMAGE_DOS_SIGNATURE 0x5A4D    // MZ
#define IMAGE_NT_SIGNATURE 0x00004550 // PE00
#define OPT_HEADER_MAGIC_PE32 0x010b
#define OPT_HEADER_MAGIC_PE32_PLUS 0x020b

using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(ObjectFilePECOFF)

namespace {

static constexpr OptionEnumValueElement g_abi_enums[] = {
    {
        llvm::Triple::UnknownEnvironment,
        "default",
        "Use default target (if it is Windows) or MSVC",
    },
    {
        llvm::Triple::MSVC,
        "msvc",
        "MSVC ABI",
    },
    {
        llvm::Triple::GNU,
        "gnu",
        "MinGW / Itanium ABI",
    },
};

#define LLDB_PROPERTIES_objectfilepecoff
#include "ObjectFilePECOFFProperties.inc"

enum {
#define LLDB_PROPERTIES_objectfilepecoff
#include "ObjectFilePECOFFPropertiesEnum.inc"
};

class PluginProperties : public Properties {
public:
  static llvm::StringRef GetSettingName() {
    return ObjectFilePECOFF::GetPluginNameStatic();
  }

  PluginProperties() {
    m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
    m_collection_sp->Initialize(g_objectfilepecoff_properties_def);
  }

  llvm::Triple::EnvironmentType ABI() const {
    return GetPropertyAtIndexAs<llvm::Triple::EnvironmentType>(
        ePropertyABI, llvm::Triple::UnknownEnvironment);
  }

  OptionValueDictionary *ModuleABIMap() const {
    return m_collection_sp->GetPropertyAtIndexAsOptionValueDictionary(
        ePropertyModuleABIMap);
  }
};

} // namespace

static PluginProperties &GetGlobalPluginProperties() {
  static PluginProperties g_settings;
  return g_settings;
}

static bool GetDebugLinkContents(const llvm::object::COFFObjectFile &coff_obj,
                                 std::string &gnu_debuglink_file,
                                 uint32_t &gnu_debuglink_crc) {
  static constexpr llvm::StringLiteral g_sect_name_gnu_debuglink(
      ".gnu_debuglink");
  for (const auto &section : coff_obj.sections()) {
    auto name = section.getName();
    if (!name) {
      llvm::consumeError(name.takeError());
      continue;
    }
    if (*name == g_sect_name_gnu_debuglink) {
      auto content = section.getContents();
      if (!content) {
        llvm::consumeError(content.takeError());
        return false;
      }
      DataExtractor data(
          content->data(), content->size(),
          coff_obj.isLittleEndian() ? eByteOrderLittle : eByteOrderBig, 4);
      lldb::offset_t gnu_debuglink_offset = 0;
      gnu_debuglink_file = data.GetCStr(&gnu_debuglink_offset);
      // Align to the next 4-byte offset
      gnu_debuglink_offset = llvm::alignTo(gnu_debuglink_offset, 4);
      data.GetU32(&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
      return true;
    }
  }
  return false;
}

static UUID GetCoffUUID(llvm::object::COFFObjectFile &coff_obj) {
  const llvm::codeview::DebugInfo *pdb_info = nullptr;
  llvm::StringRef pdb_file;

  // First, prefer to use the PDB build id. LLD generates this even for mingw
  // targets without PDB output, and it does not get stripped either.
  if (!coff_obj.getDebugPDBInfo(pdb_info, pdb_file) && pdb_info) {
    if (pdb_info->PDB70.CVSignature == llvm::OMF::Signature::PDB70) {
      UUID::CvRecordPdb70 info;
      memcpy(&info.Uuid, pdb_info->PDB70.Signature, sizeof(info.Uuid));
      info.Age = pdb_info->PDB70.Age;
      return UUID(info);
    }
  }

  std::string gnu_debuglink_file;
  uint32_t gnu_debuglink_crc;

  // The GNU linker normally does not write a PDB build id (unless requested
  // with the --build-id option), so we should fall back to using the crc
  // from .gnu_debuglink if it exists, just like how ObjectFileELF does it.
  if (!GetDebugLinkContents(coff_obj, gnu_debuglink_file, gnu_debuglink_crc)) {
    // If there is no .gnu_debuglink section, then this may be an object
    // containing DWARF debug info for .gnu_debuglink, so calculate the crc of
    // the object itself.
    auto raw_data = coff_obj.getData();
    LLDB_SCOPED_TIMERF(
        "Calculating module crc32 %s with size %" PRIu64 " KiB",
        FileSpec(coff_obj.getFileName()).GetFilename().str().c_str(),
        static_cast<lldb::offset_t>(raw_data.size()) / 1024);
    gnu_debuglink_crc = llvm::crc32(0, llvm::arrayRefFromStringRef(raw_data));
  }
  // Use 4 bytes of crc from the .gnu_debuglink section.
  llvm::support::ulittle32_t data(gnu_debuglink_crc);
  return UUID(&data, sizeof(data));
}

char ObjectFilePECOFF::ID;

void ObjectFilePECOFF::Initialize() {
  PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                GetPluginDescriptionStatic(), CreateInstance,
                                CreateMemoryInstance, GetModuleSpecifications,
                                SaveCore, DebuggerInitialize);
}

void ObjectFilePECOFF::DebuggerInitialize(Debugger &debugger) {
  if (!PluginManager::GetSettingForObjectFilePlugin(
          debugger, PluginProperties::GetSettingName())) {
    const bool is_global_setting = true;
    PluginManager::CreateSettingForObjectFilePlugin(
        debugger, GetGlobalPluginProperties().GetValueProperties(),
        "Properties for the PE/COFF object-file plug-in.", is_global_setting);
  }
}

void ObjectFilePECOFF::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

llvm::StringRef ObjectFilePECOFF::GetPluginDescriptionStatic() {
  return "Portable Executable and Common Object File Format object file reader "
         "(32 and 64 bit)";
}

ObjectFile *ObjectFilePECOFF::CreateInstance(
    const lldb::ModuleSP &module_sp, DataExtractorSP extractor_sp,
    lldb::offset_t data_offset, const lldb_private::FileSpec *file_p,
    lldb::offset_t file_offset, lldb::offset_t length) {
  FileSpec file = file_p ? *file_p : FileSpec();
  if (!extractor_sp || !extractor_sp->HasData()) {
    DataBufferSP data_sp = MapFileData(file, length, file_offset);
    if (!data_sp)
      return nullptr;
    data_offset = 0;
    extractor_sp = std::make_shared<DataExtractor>(data_sp);
  }

  if (!ObjectFilePECOFF::MagicBytesMatch(extractor_sp))
    return nullptr;

  // Update the data to contain the entire file if it doesn't already
  if (extractor_sp->GetByteSize() < length) {
    DataBufferSP data_sp = MapFileData(file, length, file_offset);
    if (!data_sp)
      return nullptr;
    extractor_sp = std::make_shared<DataExtractor>(data_sp);
  }

  auto objfile_up = std::make_unique<ObjectFilePECOFF>(
      module_sp, extractor_sp, data_offset, file_p, file_offset, length);
  if (!objfile_up || !objfile_up->ParseHeader())
    return nullptr;

  // Cache coff binary.
  if (!objfile_up->CreateBinary())
    return nullptr;
  return objfile_up.release();
}

ObjectFile *ObjectFilePECOFF::CreateMemoryInstance(
    const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
    const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
  if (!data_sp)
    return nullptr;
  DataExtractorSP extractor_sp =
      std::make_shared<DataExtractor>(data_sp, eByteOrderLittle, 4);
  if (!ObjectFilePECOFF::MagicBytesMatch(extractor_sp))
    return nullptr;
  auto objfile_up = std::make_unique<ObjectFilePECOFF>(
      module_sp, data_sp, process_sp, header_addr);
  if (objfile_up.get() && objfile_up->ParseHeader()) {
    return objfile_up.release();
  }
  return nullptr;
}

ModuleSpecList ObjectFilePECOFF::GetModuleSpecifications(
    const lldb_private::FileSpec &file, lldb::DataExtractorSP &extractor_sp,
    lldb::offset_t file_offset, lldb::offset_t length) {
  if (!extractor_sp || !extractor_sp->HasData() ||
      !ObjectFilePECOFF::MagicBytesMatch(extractor_sp))
    return {};

  Log *log = GetLog(LLDBLog::Object);

  if (extractor_sp->GetByteSize() < length)
    if (DataBufferSP full_sp = MapFileData(file, -1, file_offset))
      extractor_sp->SetData(std::move(full_sp));
  auto binary = llvm::object::createBinary(llvm::MemoryBufferRef(
      toStringRef(extractor_sp->GetSharedDataBuffer()->GetData()),
      file.GetFilename()));

  if (!binary) {
    LLDB_LOG_ERROR(log, binary.takeError(),
                   "Failed to create binary for file ({1}): {0}", file);
    return {};
  }

  auto *COFFObj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary->get());
  if (!COFFObj)
    return {};

  ModuleSpec module_spec(file);
  ArchSpec &spec = module_spec.GetArchitecture();
  lldb_private::UUID &uuid = module_spec.GetUUID();
  if (!uuid.IsValid())
    uuid = GetCoffUUID(*COFFObj);

  static llvm::Triple::EnvironmentType default_env = [] {
    auto def_target = llvm::Triple(
        llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple()));
    if (def_target.getOS() == llvm::Triple::Win32 &&
        def_target.getEnvironment() != llvm::Triple::UnknownEnvironment)
      return def_target.getEnvironment();
    return llvm::Triple::MSVC;
  }();

  // Check for a module-specific override.
  OptionValueSP module_env_option;
  const auto *map = GetGlobalPluginProperties().ModuleABIMap();
  if (map->GetNumValues() > 0) {
    // Step 1: Try with the exact file name.
    auto name = file.GetFilename();
    module_env_option = map->GetValueForKey(name);
    if (!module_env_option) {
      // Step 2: Try with the file name in lowercase.
      auto name_lower = name.lower();
      module_env_option = map->GetValueForKey(llvm::StringRef(name_lower));
    }
    if (!module_env_option) {
      // Step 3: Try with the file name with ".debug" suffix stripped.
      auto name_stripped = name;
      if (name_stripped.consume_back_insensitive(".debug")) {
        module_env_option = map->GetValueForKey(name_stripped);
        if (!module_env_option) {
          // Step 4: Try with the file name in lowercase with ".debug" suffix
          // stripped.
          auto name_lower = name_stripped.lower();
          module_env_option = map->GetValueForKey(llvm::StringRef(name_lower));
        }
      }
    }
  }
  llvm::Triple::EnvironmentType env;
  if (module_env_option)
    env =
        module_env_option->GetValueAs<llvm::Triple::EnvironmentType>().value_or(
            static_cast<llvm::Triple::EnvironmentType>(0));
  else
    env = GetGlobalPluginProperties().ABI();

  if (env == llvm::Triple::UnknownEnvironment)
    env = default_env;

  ModuleSpecList specs;
  switch (COFFObj->getMachine()) {
  case MachineAmd64:
    spec.SetTriple("x86_64-pc-windows");
    spec.GetTriple().setEnvironment(env);
    specs.Append(module_spec);
    break;
  case MachineX86:
    spec.SetTriple("i386-pc-windows");
    spec.GetTriple().setEnvironment(env);
    specs.Append(module_spec);
    break;
  case MachineArmNt:
    spec.SetTriple("armv7-pc-windows");
    spec.GetTriple().setEnvironment(env);
    specs.Append(module_spec);
    break;
  case MachineArm64:
  case MachineArm64X:
    spec.SetTriple("aarch64-pc-windows");
    spec.GetTriple().setEnvironment(env);
    specs.Append(module_spec);
    break;
  default:
    break;
  }

  return specs;
}

bool ObjectFilePECOFF::SaveCore(const lldb::ProcessSP &process_sp,
                                lldb_private::SaveCoreOptions &options,
                                lldb_private::Status &error) {
  // Outfile and process_sp are validated by PluginManager::SaveCore
  assert(options.GetOutputFile().has_value());
  assert(process_sp);
  return SaveMiniDump(process_sp, options, error);
}

bool ObjectFilePECOFF::MagicBytesMatch(DataExtractorSP extractor_sp) {
  lldb::offset_t offset = 0;
  uint16_t magic = extractor_sp->GetU16(&offset);
  return magic == IMAGE_DOS_SIGNATURE;
}

lldb::SymbolType ObjectFilePECOFF::MapSymbolType(uint16_t coff_symbol_type) {
  // TODO:  We need to complete this mapping of COFF symbol types to LLDB ones.
  // For now, here's a hack to make sure our function have types.
  const auto complex_type =
      coff_symbol_type >> llvm::COFF::SCT_COMPLEX_TYPE_SHIFT;
  if (complex_type == llvm::COFF::IMAGE_SYM_DTYPE_FUNCTION) {
    return lldb::eSymbolTypeCode;
  }
  const auto base_type = coff_symbol_type & 0xff;
  if (base_type == llvm::COFF::IMAGE_SYM_TYPE_NULL &&
      complex_type == llvm::COFF::IMAGE_SYM_DTYPE_NULL) {
    // Unknown type. LLD and GNU ld uses this for variables on MinGW, so
    // consider these symbols to be data to enable printing.
    return lldb::eSymbolTypeData;
  }
  return lldb::eSymbolTypeInvalid;
}

bool ObjectFilePECOFF::CreateBinary() {
  if (m_binary)
    return true;

  Log *log = GetLog(LLDBLog::Object);

  auto binary = llvm::object::createBinary(llvm::MemoryBufferRef(
      toStringRef(m_data_nsp->GetData()), m_file.GetFilename()));
  if (!binary) {
    LLDB_LOG_ERROR(log, binary.takeError(),
                   "Failed to create binary for file ({1}): {0}", m_file);
    return false;
  }

  // Make sure we only handle COFF format.
  m_binary =
      llvm::unique_dyn_cast<llvm::object::COFFObjectFile>(std::move(*binary));
  if (!m_binary)
    return false;

  LLDB_LOG(log, "this = {0}, module = {1} ({2}), file = {3}, binary = {4}",
           this, GetModule().get(), GetModule()->GetSpecificationDescription(),
           m_file.GetPath(), m_binary.get());
  return true;
}

ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
                                   DataExtractorSP extractor_sp,
                                   lldb::offset_t data_offset,
                                   const FileSpec *file,
                                   lldb::offset_t file_offset,
                                   lldb::offset_t length)
    : ObjectFile(module_sp, file, file_offset, length, extractor_sp,
                 data_offset),
      m_dos_header(), m_coff_header(), m_coff_header_opt(), m_sect_headers(),
      m_image_base(LLDB_INVALID_ADDRESS), m_entry_point_address(),
      m_deps_filespec() {}

ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
                                   WritableDataBufferSP header_data_sp,
                                   const lldb::ProcessSP &process_sp,
                                   addr_t header_addr)
    : ObjectFile(module_sp, process_sp, header_addr,
                 std::make_shared<DataExtractor>(header_data_sp)),
      m_dos_header(), m_coff_header(), m_coff_header_opt(), m_sect_headers(),
      m_image_base(LLDB_INVALID_ADDRESS), m_entry_point_address(),
      m_deps_filespec() {}

ObjectFilePECOFF::~ObjectFilePECOFF() = default;

bool ObjectFilePECOFF::ParseHeader() {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    m_sect_headers.clear();
    m_data_nsp->SetByteOrder(eByteOrderLittle);
    lldb::offset_t offset = 0;

    if (ParseDOSHeader(*m_data_nsp, m_dos_header)) {
      offset = m_dos_header.e_lfanew;
      uint32_t pe_signature = m_data_nsp->GetU32(&offset);
      if (pe_signature != IMAGE_NT_SIGNATURE)
        return false;
      if (ParseCOFFHeader(*m_data_nsp, &offset, m_coff_header)) {
        if (m_coff_header.hdrsize > 0)
          ParseCOFFOptionalHeader(&offset);
        ParseSectionHeaders(offset);
      }
      m_data_nsp->SetAddressByteSize(GetAddressByteSize());
      return true;
    }
  }
  return false;
}

bool ObjectFilePECOFF::SetLoadAddress(Target &target, addr_t value,
                                      bool value_is_offset) {
  bool changed = false;
  ModuleSP module_sp = GetModule();
  if (module_sp) {
    size_t num_loaded_sections = 0;
    SectionList *section_list = GetSectionList();
    if (section_list) {
      if (!value_is_offset) {
        value -= m_image_base;
      }

      const size_t num_sections = section_list->GetSize();
      size_t sect_idx = 0;

      for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
        // Iterate through the object file sections to find all of the sections
        // that have SHF_ALLOC in their flag bits.
        SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
        if (section_sp && !section_sp->IsThreadSpecific()) {
          if (target.SetSectionLoadAddress(
                  section_sp, section_sp->GetFileAddress() + value))
            ++num_loaded_sections;
        }
      }
      changed = num_loaded_sections > 0;
    }
  }
  return changed;
}

ByteOrder ObjectFilePECOFF::GetByteOrder() const { return eByteOrderLittle; }

bool ObjectFilePECOFF::IsExecutable() const {
  return (m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0;
}

uint32_t ObjectFilePECOFF::GetAddressByteSize() const {
  if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32_PLUS)
    return 8;
  else if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32)
    return 4;
  return 4;
}

// NeedsEndianSwap
//
// Return true if an endian swap needs to occur when extracting data from this
// file.
bool ObjectFilePECOFF::NeedsEndianSwap() const {
#if defined(__LITTLE_ENDIAN__)
  return false;
#else
  return true;
#endif
}
// ParseDOSHeader
bool ObjectFilePECOFF::ParseDOSHeader(DataExtractor &data,
                                      dos_header_t &dos_header) {
  bool success = false;
  lldb::offset_t offset = 0;
  success = data.ValidOffsetForDataOfSize(0, sizeof(dos_header));

  if (success) {
    dos_header.e_magic = data.GetU16(&offset); // Magic number
    success = dos_header.e_magic == IMAGE_DOS_SIGNATURE;

    if (success) {
      dos_header.e_cblp = data.GetU16(&offset); // Bytes on last page of file
      dos_header.e_cp = data.GetU16(&offset);   // Pages in file
      dos_header.e_crlc = data.GetU16(&offset); // Relocations
      dos_header.e_cparhdr =
          data.GetU16(&offset); // Size of header in paragraphs
      dos_header.e_minalloc =
          data.GetU16(&offset); // Minimum extra paragraphs needed
      dos_header.e_maxalloc =
          data.GetU16(&offset);               // Maximum extra paragraphs needed
      dos_header.e_ss = data.GetU16(&offset); // Initial (relative) SS value
      dos_header.e_sp = data.GetU16(&offset); // Initial SP value
      dos_header.e_csum = data.GetU16(&offset); // Checksum
      dos_header.e_ip = data.GetU16(&offset);   // Initial IP value
      dos_header.e_cs = data.GetU16(&offset);   // Initial (relative) CS value
      dos_header.e_lfarlc =
          data.GetU16(&offset); // File address of relocation table
      dos_header.e_ovno = data.GetU16(&offset); // Overlay number

      dos_header.e_res[0] = data.GetU16(&offset); // Reserved words
      dos_header.e_res[1] = data.GetU16(&offset); // Reserved words
      dos_header.e_res[2] = data.GetU16(&offset); // Reserved words
      dos_header.e_res[3] = data.GetU16(&offset); // Reserved words

      dos_header.e_oemid =
          data.GetU16(&offset); // OEM identifier (for e_oeminfo)
      dos_header.e_oeminfo =
          data.GetU16(&offset); // OEM information; e_oemid specific
      dos_header.e_res2[0] = data.GetU16(&offset); // Reserved words
      dos_header.e_res2[1] = data.GetU16(&offset); // Reserved words
      dos_header.e_res2[2] = data.GetU16(&offset); // Reserved words
      dos_header.e_res2[3] = data.GetU16(&offset); // Reserved words
      dos_header.e_res2[4] = data.GetU16(&offset); // Reserved words
      dos_header.e_res2[5] = data.GetU16(&offset); // Reserved words
      dos_header.e_res2[6] = data.GetU16(&offset); // Reserved words
      dos_header.e_res2[7] = data.GetU16(&offset); // Reserved words
      dos_header.e_res2[8] = data.GetU16(&offset); // Reserved words
      dos_header.e_res2[9] = data.GetU16(&offset); // Reserved words

      dos_header.e_lfanew =
          data.GetU32(&offset); // File address of new exe header
    }
  }
  if (!success)
    memset(&dos_header, 0, sizeof(dos_header));
  return success;
}

// ParserCOFFHeader
bool ObjectFilePECOFF::ParseCOFFHeader(DataExtractor &data,
                                       lldb::offset_t *offset_ptr,
                                       coff_header_t &coff_header) {
  bool success =
      data.ValidOffsetForDataOfSize(*offset_ptr, sizeof(coff_header));
  if (success) {
    coff_header.machine = data.GetU16(offset_ptr);
    coff_header.nsects = data.GetU16(offset_ptr);
    coff_header.modtime = data.GetU32(offset_ptr);
    coff_header.symoff = data.GetU32(offset_ptr);
    coff_header.nsyms = data.GetU32(offset_ptr);
    coff_header.hdrsize = data.GetU16(offset_ptr);
    coff_header.flags = data.GetU16(offset_ptr);
  }
  if (!success)
    memset(&coff_header, 0, sizeof(coff_header));
  return success;
}

bool ObjectFilePECOFF::ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr) {
  bool success = false;
  const lldb::offset_t end_offset = *offset_ptr + m_coff_header.hdrsize;
  if (*offset_ptr < end_offset) {
    success = true;
    m_coff_header_opt.magic = m_data_nsp->GetU16(offset_ptr);
    m_coff_header_opt.major_linker_version = m_data_nsp->GetU8(offset_ptr);
    m_coff_header_opt.minor_linker_version = m_data_nsp->GetU8(offset_ptr);
    m_coff_header_opt.code_size = m_data_nsp->GetU32(offset_ptr);
    m_coff_header_opt.data_size = m_data_nsp->GetU32(offset_ptr);
    m_coff_header_opt.bss_size = m_data_nsp->GetU32(offset_ptr);
    m_coff_header_opt.entry = m_data_nsp->GetU32(offset_ptr);
    m_coff_header_opt.code_offset = m_data_nsp->GetU32(offset_ptr);

    const uint32_t addr_byte_size = GetAddressByteSize();

    if (*offset_ptr < end_offset) {
      if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32) {
        // PE32 only
        m_coff_header_opt.data_offset = m_data_nsp->GetU32(offset_ptr);
      } else
        m_coff_header_opt.data_offset = 0;

      if (*offset_ptr < end_offset) {
        m_coff_header_opt.image_base =
            m_data_nsp->GetMaxU64(offset_ptr, addr_byte_size);
        m_coff_header_opt.sect_alignment = m_data_nsp->GetU32(offset_ptr);
        m_coff_header_opt.file_alignment = m_data_nsp->GetU32(offset_ptr);
        m_coff_header_opt.major_os_system_version =
            m_data_nsp->GetU16(offset_ptr);
        m_coff_header_opt.minor_os_system_version =
            m_data_nsp->GetU16(offset_ptr);
        m_coff_header_opt.major_image_version = m_data_nsp->GetU16(offset_ptr);
        m_coff_header_opt.minor_image_version = m_data_nsp->GetU16(offset_ptr);
        m_coff_header_opt.major_subsystem_version =
            m_data_nsp->GetU16(offset_ptr);
        m_coff_header_opt.minor_subsystem_version =
            m_data_nsp->GetU16(offset_ptr);
        m_coff_header_opt.reserved1 = m_data_nsp->GetU32(offset_ptr);
        m_coff_header_opt.image_size = m_data_nsp->GetU32(offset_ptr);
        m_coff_header_opt.header_size = m_data_nsp->GetU32(offset_ptr);
        m_coff_header_opt.checksum = m_data_nsp->GetU32(offset_ptr);
        m_coff_header_opt.subsystem = m_data_nsp->GetU16(offset_ptr);
        m_coff_header_opt.dll_flags = m_data_nsp->GetU16(offset_ptr);
        m_coff_header_opt.stack_reserve_size =
            m_data_nsp->GetMaxU64(offset_ptr, addr_byte_size);
        m_coff_header_opt.stack_commit_size =
            m_data_nsp->GetMaxU64(offset_ptr, addr_byte_size);
        m_coff_header_opt.heap_reserve_size =
            m_data_nsp->GetMaxU64(offset_ptr, addr_byte_size);
        m_coff_header_opt.heap_commit_size =
            m_data_nsp->GetMaxU64(offset_ptr, addr_byte_size);
        m_coff_header_opt.loader_flags = m_data_nsp->GetU32(offset_ptr);
        uint32_t num_data_dir_entries = m_data_nsp->GetU32(offset_ptr);
        m_coff_header_opt.data_dirs.clear();
        m_coff_header_opt.data_dirs.resize(num_data_dir_entries);
        uint32_t i;
        for (i = 0; i < num_data_dir_entries; i++) {
          m_coff_header_opt.data_dirs[i].vmaddr =
              m_data_nsp->GetU32(offset_ptr);
          m_coff_header_opt.data_dirs[i].vmsize =
              m_data_nsp->GetU32(offset_ptr);
        }

        m_image_base = m_coff_header_opt.image_base;
      }
    }
  }
  // Make sure we are on track for section data which follows
  *offset_ptr = end_offset;
  return success;
}

uint32_t ObjectFilePECOFF::GetRVA(const Address &addr) const {
  return addr.GetFileAddress() - m_image_base;
}

Address ObjectFilePECOFF::GetAddress(uint32_t rva) {
  SectionList *sect_list = GetSectionList();
  if (!sect_list)
    return Address(GetFileAddress(rva));

  return Address(GetFileAddress(rva), sect_list);
}

lldb::addr_t ObjectFilePECOFF::GetFileAddress(uint32_t rva) const {
  return m_image_base + rva;
}

DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) {
  if (!size)
    return {};

  if (m_data_nsp->ValidOffsetForDataOfSize(offset, size))
    return DataExtractor(*m_data_nsp, offset, size);

  ProcessSP process_sp(m_process_wp.lock());
  DataExtractor data;
  if (process_sp) {
    auto data_up = std::make_unique<DataBufferHeap>(size, 0);
    Status readmem_error;
    size_t bytes_read =
        process_sp->ReadMemory(m_image_base + offset, data_up->GetBytes(),
                               data_up->GetByteSize(), readmem_error);
    if (bytes_read == size) {
      DataBufferSP buffer_sp(data_up.release());
      data.SetData(buffer_sp, 0, buffer_sp->GetByteSize());
    }
  }
  return data;
}

DataExtractor ObjectFilePECOFF::ReadImageDataByRVA(uint32_t rva, size_t size) {
  Address addr = GetAddress(rva);
  SectionSP sect = addr.GetSection();
  if (!sect)
    return {};
  rva = sect->GetFileOffset() + addr.GetOffset();

  return ReadImageData(rva, size);
}

// ParseSectionHeaders
bool ObjectFilePECOFF::ParseSectionHeaders(
    uint32_t section_header_data_offset) {
  const uint32_t nsects = m_coff_header.nsects;
  m_sect_headers.clear();

  if (nsects > 0) {
    const size_t section_header_byte_size = nsects * sizeof(section_header_t);
    DataExtractor section_header_data =
        ReadImageData(section_header_data_offset, section_header_byte_size);

    lldb::offset_t offset = 0;
    if (section_header_data.ValidOffsetForDataOfSize(
            offset, section_header_byte_size)) {
      m_sect_headers.resize(nsects);

      for (uint32_t idx = 0; idx < nsects; ++idx) {
        const void *name_data = section_header_data.GetData(&offset, 8);
        if (name_data) {
          memcpy(m_sect_headers[idx].name, name_data, 8);
          m_sect_headers[idx].vmsize = section_header_data.GetU32(&offset);
          m_sect_headers[idx].vmaddr = section_header_data.GetU32(&offset);
          m_sect_headers[idx].size = section_header_data.GetU32(&offset);
          m_sect_headers[idx].offset = section_header_data.GetU32(&offset);
          m_sect_headers[idx].reloff = section_header_data.GetU32(&offset);
          m_sect_headers[idx].lineoff = section_header_data.GetU32(&offset);
          m_sect_headers[idx].nreloc = section_header_data.GetU16(&offset);
          m_sect_headers[idx].nline = section_header_data.GetU16(&offset);
          m_sect_headers[idx].flags = section_header_data.GetU32(&offset);
        }
      }
    }
  }

  return !m_sect_headers.empty();
}

llvm::StringRef ObjectFilePECOFF::GetSectionName(const section_header_t &sect) {
  llvm::StringRef hdr_name(sect.name, std::size(sect.name));
  hdr_name = hdr_name.split('\0').first;
  if (hdr_name.consume_front("/")) {
    lldb::offset_t stroff;
    if (!to_integer(hdr_name, stroff, 10))
      return "";
    lldb::offset_t string_file_offset =
        m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff;
    if (const char *name = m_data_nsp->GetCStr(&string_file_offset))
      return name;
    return "";
  }
  return hdr_name;
}

void ObjectFilePECOFF::ParseSymtab(Symtab &symtab) {
  SectionList *sect_list = GetSectionList();
  rva_symbol_list_t sorted_exports = AppendFromExportTable(sect_list, symtab);
  AppendFromCOFFSymbolTable(sect_list, symtab, sorted_exports);
}

static bool RVASymbolListCompareRVA(const std::pair<uint32_t, uint32_t> &a,
                                    const std::pair<uint32_t, uint32_t> &b) {
  return a.first < b.first;
}

void ObjectFilePECOFF::AppendFromCOFFSymbolTable(
    SectionList *sect_list, Symtab &symtab,
    const ObjectFilePECOFF::rva_symbol_list_t &sorted_exports) {
  const uint32_t num_syms = m_binary->getNumberOfSymbols();
  if (num_syms == 0)
    return;
  // Check that this is not a bigobj; we do not support bigobj.
  if (m_binary->getSymbolTableEntrySize() !=
      sizeof(llvm::object::coff_symbol16))
    return;

  Log *log = GetLog(LLDBLog::Object);
  symtab.Reserve(symtab.GetNumSymbols() + num_syms);
  for (const auto &sym_ref : m_binary->symbols()) {
    const auto coff_sym_ref = m_binary->getCOFFSymbol(sym_ref);
    auto name_or_error = sym_ref.getName();
    if (!name_or_error) {
      LLDB_LOG_ERROR(log, name_or_error.takeError(),
                     "ObjectFilePECOFF::AppendFromCOFFSymbolTable - failed to "
                     "get symbol table entry name: {0}");
      continue;
    }
    const llvm::StringRef sym_name = *name_or_error;
    Symbol symbol;
    symbol.GetMangled().SetValue(ConstString(sym_name));
    int16_t section_number =
        static_cast<int16_t>(coff_sym_ref.getSectionNumber());
    if (section_number >= 1) {
      symbol.GetAddressRef() = Address(
          sect_list->FindSectionByID(section_number), coff_sym_ref.getValue());
      const auto symbol_type = MapSymbolType(coff_sym_ref.getType());
      symbol.SetType(symbol_type);

      // Check for duplicate of exported symbols:
      const uint32_t symbol_rva = symbol.GetAddressRef().GetFileAddress() -
                                  m_coff_header_opt.image_base;
      const auto &first_match = std::lower_bound(
          sorted_exports.begin(), sorted_exports.end(),
          std::make_pair(symbol_rva, 0), RVASymbolListCompareRVA);
      for (auto it = first_match;
           it != sorted_exports.end() && it->first == symbol_rva; ++it) {
        Symbol *exported = symtab.SymbolAtIndex(it->second);
        if (symbol_type != lldb::eSymbolTypeInvalid)
          exported->SetType(symbol_type);
        if (exported->GetMangled() == symbol.GetMangled()) {
          symbol.SetExternal(true);
          // We don't want the symbol to be duplicated (e.g. when running
          // `disas -n func`), but we also don't want to erase this entry (to
          // preserve the original symbol order), so we mark it as additional.
          symbol.SetType(lldb::eSymbolTypeAdditional);
        } else {
          // It is possible for a symbol to be exported in a different name
          // from its original. In this case keep both entries so lookup using
          // either names will work. If this symbol has an invalid type, replace
          // it with the type from the export symbol.
          if (symbol.GetType() == lldb::eSymbolTypeInvalid)
            symbol.SetType(exported->GetType());
        }
      }
    } else if (section_number == llvm::COFF::IMAGE_SYM_ABSOLUTE) {
      symbol.GetAddressRef() = Address(coff_sym_ref.getValue());
      symbol.SetType(lldb::eSymbolTypeAbsolute);
    }
    symtab.AddSymbol(symbol);
  }
}

ObjectFilePECOFF::rva_symbol_list_t
ObjectFilePECOFF::AppendFromExportTable(SectionList *sect_list,
                                        Symtab &symtab) {
  const auto *export_table = m_binary->getExportTable();
  if (!export_table)
    return {};
  const uint32_t num_syms = export_table->AddressTableEntries;
  if (num_syms == 0)
    return {};

  Log *log = GetLog(LLDBLog::Object);
  rva_symbol_list_t export_list;
  symtab.Reserve(symtab.GetNumSymbols() + num_syms);
  // Read each export table entry, ordered by ordinal instead of by name.
  for (const auto &entry : m_binary->export_directories()) {
    llvm::StringRef sym_name;
    if (auto err = entry.getSymbolName(sym_name)) {
      LLDB_LOG_ERROR(log, std::move(err),
                     "ObjectFilePECOFF::AppendFromExportTable - failed to get "
                     "export table entry name: {0}");
      continue;
    }
    Symbol symbol;
    // Note: symbol name may be empty if it is only exported by ordinal.
    symbol.GetMangled().SetValue(ConstString(sym_name));

    uint32_t ordinal;
    llvm::cantFail(entry.getOrdinal(ordinal));
    symbol.SetID(ordinal);

    bool is_forwarder;
    llvm::cantFail(entry.isForwarder(is_forwarder));
    if (is_forwarder) {
      // Forwarder exports are redirected by the loader transparently, but keep
      // it in symtab and make a note using the symbol name.
      llvm::StringRef forwarder_name;
      if (auto err = entry.getForwardTo(forwarder_name)) {
        LLDB_LOG_ERROR(log, std::move(err),
                       "ObjectFilePECOFF::AppendFromExportTable - failed to "
                       "get forwarder name of forwarder export '{1}': {0}",
                       sym_name);
        continue;
      }
      llvm::SmallString<256> new_name = {symbol.GetDisplayName().GetStringRef(),
                                         " (forwarded to ", forwarder_name,
                                         ")"};
      symbol.GetMangled().SetDemangledName(ConstString(new_name.str()));
      symbol.SetDemangledNameIsSynthesized(true);
    }

    uint32_t function_rva;
    if (auto err = entry.getExportRVA(function_rva)) {
      LLDB_LOG_ERROR(log, std::move(err),
                     "ObjectFilePECOFF::AppendFromExportTable - failed to get "
                     "address of export entry '{1}': {0}",
                     sym_name);
      continue;
    }
    // Skip the symbol if it doesn't look valid.
    if (function_rva == 0 && sym_name.empty())
      continue;
    symbol.GetAddressRef() =
        Address(m_coff_header_opt.image_base + function_rva, sect_list);

    // An exported symbol may be either code or data. Guess by checking whether
    // the section containing the symbol is executable.
    symbol.SetType(lldb::eSymbolTypeData);
    if (!is_forwarder)
      if (auto section_sp = symbol.GetAddressRef().GetSection())
        if (section_sp->GetPermissions() & ePermissionsExecutable)
          symbol.SetType(lldb::eSymbolTypeCode);
    symbol.SetExternal(true);
    uint32_t idx = symtab.AddSymbol(symbol);
    export_list.push_back(std::make_pair(function_rva, idx));
  }
  llvm::stable_sort(export_list, RVASymbolListCompareRVA);
  return export_list;
}

std::unique_ptr<CallFrameInfo> ObjectFilePECOFF::CreateCallFrameInfo() {
  if (llvm::COFF::EXCEPTION_TABLE >= m_coff_header_opt.data_dirs.size())
    return {};

  data_directory data_dir_exception =
      m_coff_header_opt.data_dirs[llvm::COFF::EXCEPTION_TABLE];
  if (!data_dir_exception.vmaddr)
    return {};

  // TODO: decode ARM64 .pdata/.xdata so optimized frameless code unwinds.
  if (m_coff_header.machine != llvm::COFF::IMAGE_FILE_MACHINE_AMD64)
    return {};

  return std::make_unique<PECallFrameInfo>(*this, data_dir_exception.vmaddr,
                                           data_dir_exception.vmsize);
}

bool ObjectFilePECOFF::IsStripped() {
  // TODO: determine this for COFF
  return false;
}

SectionType ObjectFilePECOFF::GetSectionType(llvm::StringRef sect_name,
                                             const section_header_t &sect) {
  static constexpr llvm::StringLiteral g_code_sect_name(".code");
  static constexpr llvm::StringLiteral g_CODE_sect_name("CODE");
  static constexpr llvm::StringLiteral g_data_sect_name(".data");
  static constexpr llvm::StringLiteral g_DATA_sect_name("DATA");
  static constexpr llvm::StringLiteral g_bss_sect_name(".bss");
  static constexpr llvm::StringLiteral g_BSS_sect_name("BSS");

  if (sect.flags & llvm::COFF::IMAGE_SCN_CNT_CODE &&
      ((sect_name == g_code_sect_name) || (sect_name == g_CODE_sect_name))) {
    return eSectionTypeCode;
  }
  if (sect.flags & llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA &&
      ((sect_name == g_data_sect_name) || (sect_name == g_DATA_sect_name))) {
    if (sect.size == 0 && sect.offset == 0)
      return eSectionTypeZeroFill;
    else
      return eSectionTypeData;
  }
  if (sect.flags & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA &&
      ((sect_name == g_bss_sect_name) || (sect_name == g_BSS_sect_name))) {
    if (sect.size == 0)
      return eSectionTypeZeroFill;
    else
      return eSectionTypeData;
  }

  if (sect_name.consume_front(".debug_"))
    return GetDWARFSectionTypeFromName(sect_name);

  SectionType section_type =
      llvm::StringSwitch<SectionType>(sect_name)
          // PE/COFF image-file section names are limited to 8 characters,
          // so the linker truncates the longer source names. Match both.
          .Cases({".eh_frame", ".eh_fram"}, eSectionTypeEHFrame)
          .Cases({".gosymtab", ".gosymta"}, eSectionTypeGoSymtab)
          .Cases({".lldbsummaries", ".lldbsum"},
                 lldb::eSectionTypeLLDBTypeSummaries)
          .Cases({".lldbformatters", ".lldbfor"},
                 lldb::eSectionTypeLLDBFormatters)
          .Case(".debug", eSectionTypeDebug)
          .Case(".stabstr", eSectionTypeDataCString)
          .Case(".reloc", eSectionTypeOther)
          .Case("swiftast", eSectionTypeSwiftModules)
          .Default(eSectionTypeInvalid);
  if (section_type != eSectionTypeInvalid)
    return section_type;

  if (sect.flags & llvm::COFF::IMAGE_SCN_CNT_CODE)
    return eSectionTypeCode;
  if (sect.flags & llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
    return eSectionTypeData;
  if (sect.flags & llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
    if (sect.size == 0)
      return eSectionTypeZeroFill;
    else
      return eSectionTypeData;
  }
  return eSectionTypeOther;
}

size_t ObjectFilePECOFF::GetSectionDataSize(Section *section) {
  // For executables, SizeOfRawData (getFileSize()) is aligned by
  // FileAlignment and the actual section size is in VirtualSize
  // (getByteSize()). See the comment on
  // llvm::object::COFFObjectFile::getSectionSize().
  if (m_binary->getPE32Header() || m_binary->getPE32PlusHeader())
    return std::min(section->GetByteSize(), section->GetFileSize());
  return section->GetFileSize();
}

void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) {
  if (m_sections_up)
    return;
  m_sections_up = std::make_unique<SectionList>();
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());

    SectionSP header_sp = std::make_shared<Section>(
        module_sp, this, ~user_id_t(0), "PECOFF header", eSectionTypeOther,
        m_coff_header_opt.image_base, m_coff_header_opt.header_size,
        /*file_offset*/ 0, m_coff_header_opt.header_size,
        m_coff_header_opt.sect_alignment,
        /*flags*/ 0);
    header_sp->SetPermissions(ePermissionsReadable);
    m_sections_up->AddSection(header_sp);
    unified_section_list.AddSection(header_sp);

    const uint32_t nsects = m_sect_headers.size();
    for (uint32_t idx = 0; idx < nsects; ++idx) {
      llvm::StringRef sect_name = GetSectionName(m_sect_headers[idx]);
      SectionType section_type = GetSectionType(sect_name, m_sect_headers[idx]);

      SectionSP section_sp = std::make_shared<Section>(
          module_sp,       // Module to which this section belongs
          this,            // Object file to which this section belongs
          idx + 1,         // Section ID is the 1 based section index.
          sect_name.str(), // Name of this section
          section_type,
          m_coff_header_opt.image_base +
              m_sect_headers[idx].vmaddr, // File VM address == addresses as
                                          // they are found in the object file
          m_sect_headers[idx].vmsize,     // VM size in bytes of this section
          m_sect_headers[idx]
              .offset, // Offset to the data for this section in the file
          m_sect_headers[idx]
              .size, // Size in bytes of this section as found in the file
          m_coff_header_opt.sect_alignment, // Section alignment
          m_sect_headers[idx].flags);       // Flags for this section

      uint32_t permissions = 0;
      if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_MEM_EXECUTE)
        permissions |= ePermissionsExecutable;
      if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_MEM_READ)
        permissions |= ePermissionsReadable;
      if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_MEM_WRITE)
        permissions |= ePermissionsWritable;
      section_sp->SetPermissions(permissions);

      m_sections_up->AddSection(section_sp);
      unified_section_list.AddSection(section_sp);
    }
  }
}

UUID ObjectFilePECOFF::GetUUID() {
  if (m_uuid.IsValid())
    return m_uuid;

  if (!CreateBinary())
    return UUID();

  m_uuid = GetCoffUUID(*m_binary);
  return m_uuid;
}

std::optional<FileSpec> ObjectFilePECOFF::GetDebugLink() {
  std::string gnu_debuglink_file;
  uint32_t gnu_debuglink_crc;
  if (GetDebugLinkContents(*m_binary, gnu_debuglink_file, gnu_debuglink_crc))
    return FileSpec(gnu_debuglink_file);
  return std::nullopt;
}

std::optional<FileSpec> ObjectFilePECOFF::GetPDBPath() {
  llvm::StringRef pdb_file;
  const llvm::codeview::DebugInfo *pdb_info = nullptr;
  if (llvm::Error Err = m_binary->getDebugPDBInfo(pdb_info, pdb_file)) {
    // DebugInfo section is corrupt.
    Log *log = GetLog(LLDBLog::Object);
    llvm::StringRef file = m_binary->getFileName();
    LLDB_LOG_ERROR(
        log, std::move(Err),
        "Failed to read Codeview record for PDB debug info file ({1}): {0}",
        file);
    return std::nullopt;
  }
  if (pdb_file.empty()) {
    // No DebugInfo section present.
    return std::nullopt;
  }
  return FileSpec(pdb_file, FileSpec::GuessPathStyle(pdb_file).value_or(
                                FileSpec::Style::native));
}

uint32_t ObjectFilePECOFF::ParseDependentModules() {
  ModuleSP module_sp(GetModule());
  if (!module_sp)
    return 0;

  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
  if (m_deps_filespec)
    return m_deps_filespec->GetSize();

  // Cache coff binary if it is not done yet.
  if (!CreateBinary())
    return 0;

  Log *log = GetLog(LLDBLog::Object);
  LLDB_LOG(log, "this = {0}, module = {1} ({2}), file = {3}, binary = {4}",
           this, GetModule().get(), GetModule()->GetSpecificationDescription(),
           m_file.GetPath(), m_binary.get());

  m_deps_filespec = FileSpecList();

  for (const auto &entry : m_binary->import_directories()) {
    llvm::StringRef dll_name;
    // Report a bogus entry.
    if (llvm::Error e = entry.getName(dll_name)) {
      LLDB_LOGF(log,
                "ObjectFilePECOFF::ParseDependentModules() - failed to get "
                "import directory entry name: %s",
                llvm::toString(std::move(e)).c_str());
      continue;
    }

    // At this moment we only have the base name of the DLL. The full path can
    // only be seen after the dynamic loading.  Our best guess is Try to get it
    // with the help of the object file's directory.
    llvm::SmallString<128> dll_fullpath;
    FileSpec dll_specs(dll_name);
    dll_specs.SetDirectory(m_file.GetDirectory());

    if (!llvm::sys::fs::real_path(dll_specs.GetPath(), dll_fullpath))
      m_deps_filespec->EmplaceBack(dll_fullpath);
    else {
      // Known DLLs or DLL not found in the object file directory.
      m_deps_filespec->EmplaceBack(dll_name);
    }
  }
  return m_deps_filespec->GetSize();
}

uint32_t ObjectFilePECOFF::GetDependentModules(FileSpecList &files) {
  auto num_modules = ParseDependentModules();
  auto original_size = files.GetSize();

  for (unsigned i = 0; i < num_modules; ++i)
    files.AppendIfUnique(m_deps_filespec->GetFileSpecAtIndex(i));

  return files.GetSize() - original_size;
}

lldb_private::Address ObjectFilePECOFF::GetEntryPointAddress() {
  if (m_entry_point_address.IsValid())
    return m_entry_point_address;

  if (!ParseHeader() || !IsExecutable())
    return m_entry_point_address;

  SectionList *section_list = GetSectionList();
  addr_t file_addr = m_coff_header_opt.entry + m_coff_header_opt.image_base;

  if (!section_list)
    m_entry_point_address.SetOffset(file_addr);
  else
    m_entry_point_address.ResolveAddressUsingFileSections(file_addr,
                                                          section_list);
  return m_entry_point_address;
}

Address ObjectFilePECOFF::GetBaseAddress() {
  return Address(GetSectionList()->GetSectionAtIndex(0), 0);
}

// Dump
//
// Dump the specifics of the runtime file container (such as any headers
// segments, sections, etc).
void ObjectFilePECOFF::Dump(Stream *s) {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    s->Printf("%p: ", static_cast<void *>(this));
    s->Indent();
    s->PutCString("ObjectFilePECOFF");

    ArchSpec header_arch = GetArchitecture();

    *s << ", file = '" << m_file
       << "', arch = " << header_arch.GetArchitectureName() << "\n";

    SectionList *sections = GetSectionList();
    if (sections)
      sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,
                     UINT32_MAX);

    if (m_symtab_up)
      m_symtab_up->Dump(s, nullptr, eSortOrderNone);

    if (m_dos_header.e_magic)
      DumpDOSHeader(s, m_dos_header);
    if (m_coff_header.machine) {
      DumpCOFFHeader(s, m_coff_header);
      if (m_coff_header.hdrsize)
        DumpOptCOFFHeader(s, m_coff_header_opt);
    }
    s->EOL();
    DumpSectionHeaders(s);
    s->EOL();

    DumpDependentModules(s);
    s->EOL();
  }
}

// DumpDOSHeader
//
// Dump the MS-DOS header to the specified output stream
void ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t &header) {
  s->PutCString("MSDOS Header\n");
  s->Printf("  e_magic    = 0x%4.4x\n", header.e_magic);
  s->Printf("  e_cblp     = 0x%4.4x\n", header.e_cblp);
  s->Printf("  e_cp       = 0x%4.4x\n", header.e_cp);
  s->Printf("  e_crlc     = 0x%4.4x\n", header.e_crlc);
  s->Printf("  e_cparhdr  = 0x%4.4x\n", header.e_cparhdr);
  s->Printf("  e_minalloc = 0x%4.4x\n", header.e_minalloc);
  s->Printf("  e_maxalloc = 0x%4.4x\n", header.e_maxalloc);
  s->Printf("  e_ss       = 0x%4.4x\n", header.e_ss);
  s->Printf("  e_sp       = 0x%4.4x\n", header.e_sp);
  s->Printf("  e_csum     = 0x%4.4x\n", header.e_csum);
  s->Printf("  e_ip       = 0x%4.4x\n", header.e_ip);
  s->Printf("  e_cs       = 0x%4.4x\n", header.e_cs);
  s->Printf("  e_lfarlc   = 0x%4.4x\n", header.e_lfarlc);
  s->Printf("  e_ovno     = 0x%4.4x\n", header.e_ovno);
  s->Printf("  e_res[4]   = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n",
            header.e_res[0], header.e_res[1], header.e_res[2], header.e_res[3]);
  s->Printf("  e_oemid    = 0x%4.4x\n", header.e_oemid);
  s->Printf("  e_oeminfo  = 0x%4.4x\n", header.e_oeminfo);
  s->Printf("  e_res2[10] = { 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, "
            "0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x, 0x%4.4x }\n",
            header.e_res2[0], header.e_res2[1], header.e_res2[2],
            header.e_res2[3], header.e_res2[4], header.e_res2[5],
            header.e_res2[6], header.e_res2[7], header.e_res2[8],
            header.e_res2[9]);
  s->Printf("  e_lfanew   = 0x%8.8x\n", header.e_lfanew);
}

// DumpCOFFHeader
//
// Dump the COFF header to the specified output stream
void ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t &header) {
  s->PutCString("COFF Header\n");
  s->Printf("  machine = 0x%4.4x\n", header.machine);
  s->Printf("  nsects  = 0x%4.4x\n", header.nsects);
  s->Printf("  modtime = 0x%8.8x\n", header.modtime);
  s->Printf("  symoff  = 0x%8.8x\n", header.symoff);
  s->Printf("  nsyms   = 0x%8.8x\n", header.nsyms);
  s->Printf("  hdrsize = 0x%4.4x\n", header.hdrsize);
}

// DumpOptCOFFHeader
//
// Dump the optional COFF header to the specified output stream
void ObjectFilePECOFF::DumpOptCOFFHeader(Stream *s,
                                         const coff_opt_header_t &header) {
  s->PutCString("Optional COFF Header\n");
  s->Printf("  magic                   = 0x%4.4x\n", header.magic);
  s->Printf("  major_linker_version    = 0x%2.2x\n",
            header.major_linker_version);
  s->Printf("  minor_linker_version    = 0x%2.2x\n",
            header.minor_linker_version);
  s->Printf("  code_size               = 0x%8.8x\n", header.code_size);
  s->Printf("  data_size               = 0x%8.8x\n", header.data_size);
  s->Printf("  bss_size                = 0x%8.8x\n", header.bss_size);
  s->Printf("  entry                   = 0x%8.8x\n", header.entry);
  s->Printf("  code_offset             = 0x%8.8x\n", header.code_offset);
  s->Printf("  data_offset             = 0x%8.8x\n", header.data_offset);
  s->Printf("  image_base              = 0x%16.16" PRIx64 "\n",
            header.image_base);
  s->Printf("  sect_alignment          = 0x%8.8x\n", header.sect_alignment);
  s->Printf("  file_alignment          = 0x%8.8x\n", header.file_alignment);
  s->Printf("  major_os_system_version = 0x%4.4x\n",
            header.major_os_system_version);
  s->Printf("  minor_os_system_version = 0x%4.4x\n",
            header.minor_os_system_version);
  s->Printf("  major_image_version     = 0x%4.4x\n",
            header.major_image_version);
  s->Printf("  minor_image_version     = 0x%4.4x\n",
            header.minor_image_version);
  s->Printf("  major_subsystem_version = 0x%4.4x\n",
            header.major_subsystem_version);
  s->Printf("  minor_subsystem_version = 0x%4.4x\n",
            header.minor_subsystem_version);
  s->Printf("  reserved1               = 0x%8.8x\n", header.reserved1);
  s->Printf("  image_size              = 0x%8.8x\n", header.image_size);
  s->Printf("  header_size             = 0x%8.8x\n", header.header_size);
  s->Printf("  checksum                = 0x%8.8x\n", header.checksum);
  s->Printf("  subsystem               = 0x%4.4x\n", header.subsystem);
  s->Printf("  dll_flags               = 0x%4.4x\n", header.dll_flags);
  s->Printf("  stack_reserve_size      = 0x%16.16" PRIx64 "\n",
            header.stack_reserve_size);
  s->Printf("  stack_commit_size       = 0x%16.16" PRIx64 "\n",
            header.stack_commit_size);
  s->Printf("  heap_reserve_size       = 0x%16.16" PRIx64 "\n",
            header.heap_reserve_size);
  s->Printf("  heap_commit_size        = 0x%16.16" PRIx64 "\n",
            header.heap_commit_size);
  s->Printf("  loader_flags            = 0x%8.8x\n", header.loader_flags);
  s->Printf("  num_data_dir_entries    = 0x%8.8x\n",
            (uint32_t)header.data_dirs.size());
  uint32_t i;
  for (i = 0; i < header.data_dirs.size(); i++) {
    s->Printf("  data_dirs[%2u] vmaddr = 0x%8.8x, vmsize = 0x%8.8x\n", i,
              header.data_dirs[i].vmaddr, header.data_dirs[i].vmsize);
  }
}
// DumpSectionHeader
//
// Dump a single ELF section header to the specified output stream
void ObjectFilePECOFF::DumpSectionHeader(Stream *s,
                                         const section_header_t &sh) {
  std::string name = std::string(GetSectionName(sh));
  s->Printf("%-16s 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x 0x%4.4x "
            "0x%4.4x 0x%8.8x\n",
            name.c_str(), sh.vmaddr, sh.vmsize, sh.offset, sh.size, sh.reloff,
            sh.lineoff, sh.nreloc, sh.nline, sh.flags);
}

// DumpSectionHeaders
//
// Dump all of the ELF section header to the specified output stream
void ObjectFilePECOFF::DumpSectionHeaders(Stream *s) {

  s->PutCString("Section Headers\n");
  s->PutCString("IDX  name             vm addr    vm size    file off   file "
                "size  reloc off  line off   nreloc nline  flags\n");
  s->PutCString("==== ---------------- ---------- ---------- ---------- "
                "---------- ---------- ---------- ------ ------ ----------\n");

  uint32_t idx = 0;
  SectionHeaderCollIter pos, end = m_sect_headers.end();

  for (pos = m_sect_headers.begin(); pos != end; ++pos, ++idx) {
    s->Printf("[%2u] ", idx);
    ObjectFilePECOFF::DumpSectionHeader(s, *pos);
  }
}

// DumpDependentModules
//
// Dump all of the dependent modules to the specified output stream
void ObjectFilePECOFF::DumpDependentModules(lldb_private::Stream *s) {
  auto num_modules = ParseDependentModules();
  if (num_modules > 0) {
    s->PutCString("Dependent Modules\n");
    for (unsigned i = 0; i < num_modules; ++i) {
      auto spec = m_deps_filespec->GetFileSpecAtIndex(i);
      s->Format("  {0}\n", spec.GetFilename());
    }
  }
}

bool ObjectFilePECOFF::IsWindowsSubsystem() {
  switch (m_coff_header_opt.subsystem) {
  case llvm::COFF::IMAGE_SUBSYSTEM_NATIVE:
  case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI:
  case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI:
  case llvm::COFF::IMAGE_SUBSYSTEM_NATIVE_WINDOWS:
  case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
  case llvm::COFF::IMAGE_SUBSYSTEM_XBOX:
  case llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION:
    return true;
  default:
    return false;
  }
}

ArchSpec ObjectFilePECOFF::GetArchitecture() {
  uint16_t machine = m_coff_header.machine;
  switch (machine) {
  default:
    break;
  case llvm::COFF::IMAGE_FILE_MACHINE_AMD64:
  case llvm::COFF::IMAGE_FILE_MACHINE_I386:
  case llvm::COFF::IMAGE_FILE_MACHINE_POWERPC:
  case llvm::COFF::IMAGE_FILE_MACHINE_POWERPCFP:
  case llvm::COFF::IMAGE_FILE_MACHINE_ARM:
  case llvm::COFF::IMAGE_FILE_MACHINE_ARMNT:
  case llvm::COFF::IMAGE_FILE_MACHINE_THUMB:
  case llvm::COFF::IMAGE_FILE_MACHINE_ARM64:
    ArchSpec arch;
    arch.SetArchitecture(eArchTypeCOFF, machine, LLDB_INVALID_CPUTYPE,
                         IsWindowsSubsystem() ? llvm::Triple::Win32
                                              : llvm::Triple::UnknownOS);
    return arch;
  }
  return ArchSpec();
}

ObjectFile::Type ObjectFilePECOFF::CalculateType() {
  if (m_coff_header.machine != 0) {
    if ((m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0)
      return eTypeExecutable;
    else
      return eTypeSharedLibrary;
  }
  return eTypeExecutable;
}

ObjectFile::Strata ObjectFilePECOFF::CalculateStrata() { return eStrataUser; }
