//===-- 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 {};

  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), ConstString("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]);
      ConstString const_sect_name(sect_name);
      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.
          const_sect_name, // 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; }
