//===-- ObjectFilePECOFF.cpp ------------------------------------*- C++ -*-===//
//
// 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 "WindowsMiniDump.h"

#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Symbol/ObjectFile.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/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/Error.h"
#include "llvm/Support/MemoryBuffer.h"

#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;

struct CVInfoPdb70 {
  // 16-byte GUID
  struct _Guid {
    llvm::support::ulittle32_t Data1;
    llvm::support::ulittle16_t Data2;
    llvm::support::ulittle16_t Data3;
    uint8_t Data4[8];
  } Guid;

  llvm::support::ulittle32_t Age;
};

static UUID GetCoffUUID(llvm::object::COFFObjectFile *coff_obj) {
  if (!coff_obj)
    return UUID();

  const llvm::codeview::DebugInfo *pdb_info = nullptr;
  llvm::StringRef pdb_file;

  // This part is similar with what has done in minidump parser.
  if (!coff_obj->getDebugPDBInfo(pdb_info, pdb_file) && pdb_info) {
    if (pdb_info->PDB70.CVSignature == llvm::OMF::Signature::PDB70) {
      using llvm::support::endian::read16be;
      using llvm::support::endian::read32be;

      const uint8_t *sig = pdb_info->PDB70.Signature;
      struct CVInfoPdb70 info;
      info.Guid.Data1 = read32be(sig);
      sig += 4;
      info.Guid.Data2 = read16be(sig);
      sig += 2;
      info.Guid.Data3 = read16be(sig);
      sig += 2;
      memcpy(info.Guid.Data4, sig, 8);

      // Return 20-byte UUID if the Age is not zero
      if (pdb_info->PDB70.Age) {
        info.Age = read32be(&pdb_info->PDB70.Age);
        return UUID::fromOptionalData(&info, sizeof(info));
      }
      // Otherwise return 16-byte GUID
      return UUID::fromOptionalData(&info.Guid, sizeof(info.Guid));
    }
  }

  return UUID();
}

char ObjectFilePECOFF::ID;

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

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

lldb_private::ConstString ObjectFilePECOFF::GetPluginNameStatic() {
  static ConstString g_name("pe-coff");
  return g_name;
}

const char *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,
                                             DataBufferSP &data_sp,
                                             lldb::offset_t data_offset,
                                             const lldb_private::FileSpec *file,
                                             lldb::offset_t file_offset,
                                             lldb::offset_t length) {
  if (!data_sp) {
    data_sp = MapFileData(file, length, file_offset);
    if (!data_sp)
      return nullptr;
    data_offset = 0;
  }

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

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

  auto objfile_up = llvm::make_unique<ObjectFilePECOFF>(
      module_sp, data_sp, data_offset, file, 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::DataBufferSP &data_sp,
    const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
  if (!data_sp || !ObjectFilePECOFF::MagicBytesMatch(data_sp))
    return nullptr;
  auto objfile_up = llvm::make_unique<ObjectFilePECOFF>(
      module_sp, data_sp, process_sp, header_addr);
  if (objfile_up.get() && objfile_up->ParseHeader()) {
    return objfile_up.release();
  }
  return nullptr;
}

size_t ObjectFilePECOFF::GetModuleSpecifications(
    const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
    lldb::offset_t data_offset, lldb::offset_t file_offset,
    lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
  const size_t initial_count = specs.GetSize();
  if (!data_sp || !ObjectFilePECOFF::MagicBytesMatch(data_sp))
    return initial_count;

  auto binary = llvm::object::createBinary(file.GetPath());
  if (!binary)
    return initial_count;

  if (!binary->getBinary()->isCOFF() &&
      !binary->getBinary()->isCOFFImportFile())
    return initial_count;

  auto COFFObj =
    llvm::cast<llvm::object::COFFObjectFile>(binary->getBinary());

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

  switch (COFFObj->getMachine()) {
  case MachineAmd64:
    spec.SetTriple("x86_64-pc-windows");
    specs.Append(module_spec);
    break;
  case MachineX86:
    spec.SetTriple("i386-pc-windows");
    specs.Append(module_spec);
    spec.SetTriple("i686-pc-windows");
    specs.Append(module_spec);
    break;
  case MachineArmNt:
    spec.SetTriple("arm-pc-windows");
    specs.Append(module_spec);
    break;
  default:
    break;
  }

  return specs.GetSize() - initial_count;
}

bool ObjectFilePECOFF::SaveCore(const lldb::ProcessSP &process_sp,
                                const lldb_private::FileSpec &outfile,
                                lldb_private::Status &error) {
  return SaveMiniDump(process_sp, outfile, error);
}

bool ObjectFilePECOFF::MagicBytesMatch(DataBufferSP &data_sp) {
  DataExtractor data(data_sp, eByteOrderLittle, 4);
  lldb::offset_t offset = 0;
  uint16_t magic = data.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;
  }
  return lldb::eSymbolTypeInvalid;
}

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

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));

  auto binary = llvm::object::createBinary(m_file.GetPath());
  if (!binary) {
    LLDB_LOGF(log,
              "ObjectFilePECOFF::CreateBinary() - failed to create binary "
              "for file (%s): %s",
              m_file ? m_file.GetPath().c_str() : "<NULL>",
              errorToErrorCode(binary.takeError()).message().c_str());
    return false;
  }

  // Make sure we only handle COFF format.
  if (!binary->getBinary()->isCOFF() &&
      !binary->getBinary()->isCOFFImportFile())
    return false;

  m_owningbin = OWNBINType(std::move(*binary));
  LLDB_LOGF(log,
            "%p ObjectFilePECOFF::CreateBinary() module = %p (%s), file = "
            "%s, binary = %p (Bin = %p)",
            static_cast<void *>(this), static_cast<void *>(GetModule().get()),
            GetModule()->GetSpecificationDescription().c_str(),
            m_file ? m_file.GetPath().c_str() : "<NULL>",
            static_cast<void *>(m_owningbin.getPointer()),
            static_cast<void *>(m_owningbin->getBinary()));
  return true;
}

ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
                                   DataBufferSP &data_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, data_sp, data_offset),
      m_dos_header(), m_coff_header(), m_sect_headers(),
      m_entry_point_address(), m_deps_filespec(), m_owningbin() {
  ::memset(&m_dos_header, 0, sizeof(m_dos_header));
  ::memset(&m_coff_header, 0, sizeof(m_coff_header));
}

ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp,
                                   DataBufferSP &header_data_sp,
                                   const lldb::ProcessSP &process_sp,
                                   addr_t header_addr)
    : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
      m_dos_header(), m_coff_header(), m_sect_headers(),
      m_entry_point_address(), m_deps_filespec(), m_owningbin() {
  ::memset(&m_dos_header, 0, sizeof(m_dos_header));
  ::memset(&m_coff_header, 0, sizeof(m_coff_header));
}

ObjectFilePECOFF::~ObjectFilePECOFF() {}

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.SetByteOrder(eByteOrderLittle);
    lldb::offset_t offset = 0;

    if (ParseDOSHeader(m_data, m_dos_header)) {
      offset = m_dos_header.e_lfanew;
      uint32_t pe_signature = m_data.GetU32(&offset);
      if (pe_signature != IMAGE_NT_SIGNATURE)
        return false;
      if (ParseCOFFHeader(m_data, &offset, m_coff_header)) {
        if (m_coff_header.hdrsize > 0)
          ParseCOFFOptionalHeader(&offset);
        ParseSectionHeaders(offset);
      }
      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.GetSectionLoadList().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.GetU16(offset_ptr);
    m_coff_header_opt.major_linker_version = m_data.GetU8(offset_ptr);
    m_coff_header_opt.minor_linker_version = m_data.GetU8(offset_ptr);
    m_coff_header_opt.code_size = m_data.GetU32(offset_ptr);
    m_coff_header_opt.data_size = m_data.GetU32(offset_ptr);
    m_coff_header_opt.bss_size = m_data.GetU32(offset_ptr);
    m_coff_header_opt.entry = m_data.GetU32(offset_ptr);
    m_coff_header_opt.code_offset = m_data.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.GetU32(offset_ptr);
      } else
        m_coff_header_opt.data_offset = 0;

      if (*offset_ptr < end_offset) {
        m_coff_header_opt.image_base =
            m_data.GetMaxU64(offset_ptr, addr_byte_size);
        m_coff_header_opt.sect_alignment = m_data.GetU32(offset_ptr);
        m_coff_header_opt.file_alignment = m_data.GetU32(offset_ptr);
        m_coff_header_opt.major_os_system_version = m_data.GetU16(offset_ptr);
        m_coff_header_opt.minor_os_system_version = m_data.GetU16(offset_ptr);
        m_coff_header_opt.major_image_version = m_data.GetU16(offset_ptr);
        m_coff_header_opt.minor_image_version = m_data.GetU16(offset_ptr);
        m_coff_header_opt.major_subsystem_version = m_data.GetU16(offset_ptr);
        m_coff_header_opt.minor_subsystem_version = m_data.GetU16(offset_ptr);
        m_coff_header_opt.reserved1 = m_data.GetU32(offset_ptr);
        m_coff_header_opt.image_size = m_data.GetU32(offset_ptr);
        m_coff_header_opt.header_size = m_data.GetU32(offset_ptr);
        m_coff_header_opt.checksum = m_data.GetU32(offset_ptr);
        m_coff_header_opt.subsystem = m_data.GetU16(offset_ptr);
        m_coff_header_opt.dll_flags = m_data.GetU16(offset_ptr);
        m_coff_header_opt.stack_reserve_size =
            m_data.GetMaxU64(offset_ptr, addr_byte_size);
        m_coff_header_opt.stack_commit_size =
            m_data.GetMaxU64(offset_ptr, addr_byte_size);
        m_coff_header_opt.heap_reserve_size =
            m_data.GetMaxU64(offset_ptr, addr_byte_size);
        m_coff_header_opt.heap_commit_size =
            m_data.GetMaxU64(offset_ptr, addr_byte_size);
        m_coff_header_opt.loader_flags = m_data.GetU32(offset_ptr);
        uint32_t num_data_dir_entries = m_data.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.GetU32(offset_ptr);
          m_coff_header_opt.data_dirs[i].vmsize = m_data.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;
}

DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) {
  if (m_file) {
    // A bit of a hack, but we intend to write to this buffer, so we can't
    // mmap it.
    auto buffer_sp = MapFileData(m_file, size, offset);
    return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize());
  }
  ProcessSP process_sp(m_process_wp.lock());
  DataExtractor data;
  if (process_sp) {
    auto data_up = llvm::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;
}

// 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, llvm::array_lengthof(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.GetCStr(&string_file_offset))
      return name;
    return "";
  }
  return hdr_name;
}

// GetNListSymtab
Symtab *ObjectFilePECOFF::GetSymtab() {
  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
    if (m_symtab_up == nullptr) {
      SectionList *sect_list = GetSectionList();
      m_symtab_up.reset(new Symtab(this));
      std::lock_guard<std::recursive_mutex> guard(m_symtab_up->GetMutex());

      const uint32_t num_syms = m_coff_header.nsyms;

      if (m_file && num_syms > 0 && m_coff_header.symoff > 0) {
        const uint32_t symbol_size = 18;
        const size_t symbol_data_size = num_syms * symbol_size;
        // Include the 4-byte string table size at the end of the symbols
        DataExtractor symtab_data =
            ReadImageData(m_coff_header.symoff, symbol_data_size + 4);
        lldb::offset_t offset = symbol_data_size;
        const uint32_t strtab_size = symtab_data.GetU32(&offset);
        if (strtab_size > 0) {
          DataExtractor strtab_data = ReadImageData(
              m_coff_header.symoff + symbol_data_size, strtab_size);

          // First 4 bytes should be zeroed after strtab_size has been read,
          // because it is used as offset 0 to encode a NULL string.
          uint32_t *strtab_data_start = const_cast<uint32_t *>(
              reinterpret_cast<const uint32_t *>(strtab_data.GetDataStart()));
          strtab_data_start[0] = 0;

          offset = 0;
          std::string symbol_name;
          Symbol *symbols = m_symtab_up->Resize(num_syms);
          for (uint32_t i = 0; i < num_syms; ++i) {
            coff_symbol_t symbol;
            const uint32_t symbol_offset = offset;
            const char *symbol_name_cstr = nullptr;
            // If the first 4 bytes of the symbol string are zero, then they
            // are followed by a 4-byte string table offset. Else these
            // 8 bytes contain the symbol name
            if (symtab_data.GetU32(&offset) == 0) {
              // Long string that doesn't fit into the symbol table name, so
              // now we must read the 4 byte string table offset
              uint32_t strtab_offset = symtab_data.GetU32(&offset);
              symbol_name_cstr = strtab_data.PeekCStr(strtab_offset);
              symbol_name.assign(symbol_name_cstr);
            } else {
              // Short string that fits into the symbol table name which is 8
              // bytes
              offset += sizeof(symbol.name) - 4; // Skip remaining
              symbol_name_cstr = symtab_data.PeekCStr(symbol_offset);
              if (symbol_name_cstr == nullptr)
                break;
              symbol_name.assign(symbol_name_cstr, sizeof(symbol.name));
            }
            symbol.value = symtab_data.GetU32(&offset);
            symbol.sect = symtab_data.GetU16(&offset);
            symbol.type = symtab_data.GetU16(&offset);
            symbol.storage = symtab_data.GetU8(&offset);
            symbol.naux = symtab_data.GetU8(&offset);
            symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
            if ((int16_t)symbol.sect >= 1) {
              Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect - 1),
                                  symbol.value);
              symbols[i].GetAddressRef() = symbol_addr;
              symbols[i].SetType(MapSymbolType(symbol.type));
            }

            if (symbol.naux > 0) {
              i += symbol.naux;
              offset += symbol_size;
            }
          }
        }
      }

      // Read export header
      if (coff_data_dir_export_table < m_coff_header_opt.data_dirs.size() &&
          m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmsize > 0 &&
          m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr > 0) {
        export_directory_entry export_table;
        uint32_t data_start =
            m_coff_header_opt.data_dirs[coff_data_dir_export_table].vmaddr;

        uint32_t address_rva = data_start;
        if (m_file) {
          Address address(m_coff_header_opt.image_base + data_start, sect_list);
          address_rva =
              address.GetSection()->GetFileOffset() + address.GetOffset();
        }
        DataExtractor symtab_data =
            ReadImageData(address_rva, m_coff_header_opt.data_dirs[0].vmsize);
        lldb::offset_t offset = 0;

        // Read export_table header
        export_table.characteristics = symtab_data.GetU32(&offset);
        export_table.time_date_stamp = symtab_data.GetU32(&offset);
        export_table.major_version = symtab_data.GetU16(&offset);
        export_table.minor_version = symtab_data.GetU16(&offset);
        export_table.name = symtab_data.GetU32(&offset);
        export_table.base = symtab_data.GetU32(&offset);
        export_table.number_of_functions = symtab_data.GetU32(&offset);
        export_table.number_of_names = symtab_data.GetU32(&offset);
        export_table.address_of_functions = symtab_data.GetU32(&offset);
        export_table.address_of_names = symtab_data.GetU32(&offset);
        export_table.address_of_name_ordinals = symtab_data.GetU32(&offset);

        bool has_ordinal = export_table.address_of_name_ordinals != 0;

        lldb::offset_t name_offset = export_table.address_of_names - data_start;
        lldb::offset_t name_ordinal_offset =
            export_table.address_of_name_ordinals - data_start;

        Symbol *symbols = m_symtab_up->Resize(export_table.number_of_names);

        std::string symbol_name;

        // Read each export table entry
        for (size_t i = 0; i < export_table.number_of_names; ++i) {
          uint32_t name_ordinal =
              has_ordinal ? symtab_data.GetU16(&name_ordinal_offset) : i;
          uint32_t name_address = symtab_data.GetU32(&name_offset);

          const char *symbol_name_cstr =
              symtab_data.PeekCStr(name_address - data_start);
          symbol_name.assign(symbol_name_cstr);

          lldb::offset_t function_offset = export_table.address_of_functions -
                                           data_start +
                                           sizeof(uint32_t) * name_ordinal;
          uint32_t function_rva = symtab_data.GetU32(&function_offset);

          Address symbol_addr(m_coff_header_opt.image_base + function_rva,
                              sect_list);
          symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
          symbols[i].GetAddressRef() = symbol_addr;
          symbols[i].SetType(lldb::eSymbolTypeCode);
          symbols[i].SetDebug(true);
        }
      }
      m_symtab_up->CalculateSymbolSizes();
    }
  }
  return m_symtab_up.get();
}

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

void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) {
  if (m_sections_up)
    return;
  m_sections_up.reset(new SectionList());

  ModuleSP module_sp(GetModule());
  if (module_sp) {
    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());

    SectionSP image_sp = std::make_shared<Section>(
        module_sp, this, ~user_id_t(0), ConstString(), eSectionTypeContainer,
        m_coff_header_opt.image_base, m_coff_header_opt.image_size,
        /*file_offset*/ 0, /*file_size*/ 0, m_coff_header_opt.sect_alignment,
        /*flags*/ 0);
    m_sections_up->AddSection(image_sp);
    unified_section_list.AddSection(image_sp);

    const uint32_t nsects = m_sect_headers.size();
    ModuleSP module_sp(GetModule());
    for (uint32_t idx = 0; idx < nsects; ++idx) {
      ConstString const_sect_name(GetSectionName(m_sect_headers[idx]));
      static ConstString g_code_sect_name(".code");
      static ConstString g_CODE_sect_name("CODE");
      static ConstString g_data_sect_name(".data");
      static ConstString g_DATA_sect_name("DATA");
      static ConstString g_bss_sect_name(".bss");
      static ConstString g_BSS_sect_name("BSS");
      static ConstString g_debug_sect_name(".debug");
      static ConstString g_reloc_sect_name(".reloc");
      static ConstString g_stab_sect_name(".stab");
      static ConstString g_stabstr_sect_name(".stabstr");
      static ConstString g_sect_name_dwarf_debug_abbrev(".debug_abbrev");
      static ConstString g_sect_name_dwarf_debug_aranges(".debug_aranges");
      static ConstString g_sect_name_dwarf_debug_frame(".debug_frame");
      static ConstString g_sect_name_dwarf_debug_info(".debug_info");
      static ConstString g_sect_name_dwarf_debug_line(".debug_line");
      static ConstString g_sect_name_dwarf_debug_loc(".debug_loc");
      static ConstString g_sect_name_dwarf_debug_loclists(".debug_loclists");
      static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo");
      static ConstString g_sect_name_dwarf_debug_names(".debug_names");
      static ConstString g_sect_name_dwarf_debug_pubnames(".debug_pubnames");
      static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes");
      static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges");
      static ConstString g_sect_name_dwarf_debug_str(".debug_str");
      static ConstString g_sect_name_dwarf_debug_types(".debug_types");
      static ConstString g_sect_name_eh_frame(".eh_frame");
      static ConstString g_sect_name_go_symtab(".gosymtab");
      SectionType section_type = eSectionTypeOther;
      if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE &&
          ((const_sect_name == g_code_sect_name) ||
           (const_sect_name == g_CODE_sect_name))) {
        section_type = eSectionTypeCode;
      } else if (m_sect_headers[idx].flags &
                     llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA &&
                 ((const_sect_name == g_data_sect_name) ||
                  (const_sect_name == g_DATA_sect_name))) {
        if (m_sect_headers[idx].size == 0 && m_sect_headers[idx].offset == 0)
          section_type = eSectionTypeZeroFill;
        else
          section_type = eSectionTypeData;
      } else if (m_sect_headers[idx].flags &
                     llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA &&
                 ((const_sect_name == g_bss_sect_name) ||
                  (const_sect_name == g_BSS_sect_name))) {
        if (m_sect_headers[idx].size == 0)
          section_type = eSectionTypeZeroFill;
        else
          section_type = eSectionTypeData;
      } else if (const_sect_name == g_debug_sect_name) {
        section_type = eSectionTypeDebug;
      } else if (const_sect_name == g_stabstr_sect_name) {
        section_type = eSectionTypeDataCString;
      } else if (const_sect_name == g_reloc_sect_name) {
        section_type = eSectionTypeOther;
      } else if (const_sect_name == g_sect_name_dwarf_debug_abbrev)
        section_type = eSectionTypeDWARFDebugAbbrev;
      else if (const_sect_name == g_sect_name_dwarf_debug_aranges)
        section_type = eSectionTypeDWARFDebugAranges;
      else if (const_sect_name == g_sect_name_dwarf_debug_frame)
        section_type = eSectionTypeDWARFDebugFrame;
      else if (const_sect_name == g_sect_name_dwarf_debug_info)
        section_type = eSectionTypeDWARFDebugInfo;
      else if (const_sect_name == g_sect_name_dwarf_debug_line)
        section_type = eSectionTypeDWARFDebugLine;
      else if (const_sect_name == g_sect_name_dwarf_debug_loc)
        section_type = eSectionTypeDWARFDebugLoc;
      else if (const_sect_name == g_sect_name_dwarf_debug_loclists)
        section_type = eSectionTypeDWARFDebugLocLists;
      else if (const_sect_name == g_sect_name_dwarf_debug_macinfo)
        section_type = eSectionTypeDWARFDebugMacInfo;
      else if (const_sect_name == g_sect_name_dwarf_debug_names)
        section_type = eSectionTypeDWARFDebugNames;
      else if (const_sect_name == g_sect_name_dwarf_debug_pubnames)
        section_type = eSectionTypeDWARFDebugPubNames;
      else if (const_sect_name == g_sect_name_dwarf_debug_pubtypes)
        section_type = eSectionTypeDWARFDebugPubTypes;
      else if (const_sect_name == g_sect_name_dwarf_debug_ranges)
        section_type = eSectionTypeDWARFDebugRanges;
      else if (const_sect_name == g_sect_name_dwarf_debug_str)
        section_type = eSectionTypeDWARFDebugStr;
      else if (const_sect_name == g_sect_name_dwarf_debug_types)
        section_type = eSectionTypeDWARFDebugTypes;
      else if (const_sect_name == g_sect_name_eh_frame)
        section_type = eSectionTypeEHFrame;
      else if (const_sect_name == g_sect_name_go_symtab)
        section_type = eSectionTypeGoSymtab;
      else if (m_sect_headers[idx].flags & llvm::COFF::IMAGE_SCN_CNT_CODE) {
        section_type = eSectionTypeCode;
      } else if (m_sect_headers[idx].flags &
                 llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) {
        section_type = eSectionTypeData;
      } else if (m_sect_headers[idx].flags &
                 llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
        if (m_sect_headers[idx].size == 0)
          section_type = eSectionTypeZeroFill;
        else
          section_type = eSectionTypeData;
      }

      SectionSP section_sp(new Section(
          image_sp,        // Parent 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_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

      image_sp->GetChildren().AddSection(std::move(section_sp));
    }
  }
}

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

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

  auto COFFObj =
    llvm::cast<llvm::object::COFFObjectFile>(m_owningbin->getBinary());

  m_uuid = GetCoffUUID(COFFObj);
  return m_uuid;
}

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(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
  LLDB_LOGF(log,
            "%p ObjectFilePECOFF::ParseDependentModules() module = %p "
            "(%s), binary = %p (Bin = %p)",
            static_cast<void *>(this), static_cast<void *>(module_sp.get()),
            module_sp->GetSpecificationDescription().c_str(),
            static_cast<void *>(m_owningbin.getPointer()),
            static_cast<void *>(m_owningbin->getBinary()));

  auto COFFObj =
      llvm::dyn_cast<llvm::object::COFFObjectFile>(m_owningbin->getBinary());
  if (!COFFObj)
    return 0;

  m_deps_filespec = FileSpecList();

  for (const auto &entry : COFFObj->import_directories()) {
    llvm::StringRef dll_name;
    auto ec = entry.getName(dll_name);
    // Report a bogus entry.
    if (ec != std::error_code()) {
      LLDB_LOGF(log,
                "ObjectFilePECOFF::ParseDependentModules() - failed to get "
                "import directory entry name: %s",
                ec.message().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.GetDirectory().SetString(m_file.GetDirectory().GetCString());

    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, 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 = 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->Printf("  %s\n", spec.GetFilename().GetCString());
    }
  }
}

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:
    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; }

// PluginInterface protocol
ConstString ObjectFilePECOFF::GetPluginName() { return GetPluginNameStatic(); }

uint32_t ObjectFilePECOFF::GetPluginVersion() { return 1; }
