diff options
Diffstat (limited to 'source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp')
-rw-r--r-- | source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp | 1748 |
1 files changed, 847 insertions, 901 deletions
diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index 5f5a0ab07ad6..f0647e02158b 100644 --- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -14,7 +14,7 @@ #include "lldb/Core/ArchSpec.h" #include "lldb/Core/DataBuffer.h" -#include "lldb/Host/FileSpec.h" +#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/FileSpecList.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" @@ -24,858 +24,818 @@ #include "lldb/Core/StreamString.h" #include "lldb/Core/Timer.h" #include "lldb/Core/UUID.h" +#include "lldb/Host/FileSpec.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.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 +#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; -void -ObjectFilePECOFF::Initialize() -{ - PluginManager::RegisterPlugin (GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance, - CreateMemoryInstance, - GetModuleSpecifications, - SaveCore); +void ObjectFilePECOFF::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, + CreateMemoryInstance, GetModuleSpecifications, SaveCore); } -void -ObjectFilePECOFF::Terminate() -{ - PluginManager::UnregisterPlugin (CreateInstance); +void ObjectFilePECOFF::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); } +lldb_private::ConstString ObjectFilePECOFF::GetPluginNameStatic() { + static ConstString g_name("pe-coff"); + return g_name; +} -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)"; } -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 = file->MemoryMapFileContentsIfLocal(file_offset, length); + data_offset = 0; + } + + if (ObjectFilePECOFF::MagicBytesMatch(data_sp)) { + // Update the data to contain the entire file if it doesn't already + if (data_sp->GetByteSize() < length) + data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length); + std::unique_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF( + module_sp, data_sp, data_offset, file, file_offset, length)); + if (objfile_ap.get() && objfile_ap->ParseHeader()) + return objfile_ap.release(); + } + return NULL; } +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_ap = llvm::make_unique<ObjectFilePECOFF>( + module_sp, data_sp, process_sp, header_addr); + if (objfile_ap.get() && objfile_ap->ParseHeader()) { + return objfile_ap.release(); + } + return nullptr; +} -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 = file->MemoryMapFileContentsIfLocal(file_offset, length); - data_offset = 0; - } +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 (ObjectFilePECOFF::MagicBytesMatch(data_sp)) - { - // Update the data to contain the entire file if it doesn't already - if (data_sp->GetByteSize() < length) - data_sp = file->MemoryMapFileContentsIfLocal(file_offset, length); - std::unique_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF (module_sp, data_sp, data_offset, file, file_offset, length)); - if (objfile_ap.get() && objfile_ap->ParseHeader()) - return objfile_ap.release(); - } - return NULL; -} + if (ObjectFilePECOFF::MagicBytesMatch(data_sp)) { + DataExtractor data; + data.SetData(data_sp, data_offset, length); + data.SetByteOrder(eByteOrderLittle); -ObjectFile * -ObjectFilePECOFF::CreateMemoryInstance (const lldb::ModuleSP &module_sp, - lldb::DataBufferSP& data_sp, - const lldb::ProcessSP &process_sp, - lldb::addr_t header_addr) -{ - return NULL; -} + dos_header_t dos_header; + coff_header_t coff_header; -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 (ObjectFilePECOFF::MagicBytesMatch(data_sp)) - { - DataExtractor data; - data.SetData(data_sp, data_offset, length); - data.SetByteOrder(eByteOrderLittle); - - dos_header_t dos_header; - coff_header_t coff_header; - - if (ParseDOSHeader(data, dos_header)) - { - lldb::offset_t offset = dos_header.e_lfanew; - uint32_t pe_signature = data.GetU32(&offset); - if (pe_signature != IMAGE_NT_SIGNATURE) - return false; - if (ParseCOFFHeader(data, &offset, coff_header)) - { - ArchSpec spec; - if (coff_header.machine == MachineAmd64) - { - spec.SetTriple("x86_64-pc-windows"); - specs.Append(ModuleSpec(file, spec)); - } - else if (coff_header.machine == MachineX86) - { - spec.SetTriple("i386-pc-windows"); - specs.Append(ModuleSpec(file, spec)); - spec.SetTriple("i686-pc-windows"); - specs.Append(ModuleSpec(file, spec)); - } - } + if (ParseDOSHeader(data, dos_header)) { + lldb::offset_t offset = dos_header.e_lfanew; + uint32_t pe_signature = data.GetU32(&offset); + if (pe_signature != IMAGE_NT_SIGNATURE) + return false; + if (ParseCOFFHeader(data, &offset, coff_header)) { + ArchSpec spec; + if (coff_header.machine == MachineAmd64) { + spec.SetTriple("x86_64-pc-windows"); + specs.Append(ModuleSpec(file, spec)); + } else if (coff_header.machine == MachineX86) { + spec.SetTriple("i386-pc-windows"); + specs.Append(ModuleSpec(file, spec)); + spec.SetTriple("i686-pc-windows"); + specs.Append(ModuleSpec(file, spec)); } + } } + } - return specs.GetSize() - initial_count; + return specs.GetSize() - initial_count; } -bool -ObjectFilePECOFF::SaveCore(const lldb::ProcessSP &process_sp, - const lldb_private::FileSpec &outfile, - lldb_private::Error &error) -{ - return SaveMiniDump(process_sp, outfile, error); +bool ObjectFilePECOFF::SaveCore(const lldb::ProcessSP &process_sp, + const lldb_private::FileSpec &outfile, + lldb_private::Error &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; +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; +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; } -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_coff_header_opt (), - m_sect_headers (), - m_entry_point_address () -{ - ::memset (&m_dos_header, 0, sizeof(m_dos_header)); - ::memset (&m_coff_header, 0, sizeof(m_coff_header)); - ::memset (&m_coff_header_opt, 0, sizeof(m_coff_header_opt)); +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_coff_header_opt(), m_sect_headers(), + m_entry_point_address() { + ::memset(&m_dos_header, 0, sizeof(m_dos_header)); + ::memset(&m_coff_header, 0, sizeof(m_coff_header)); + ::memset(&m_coff_header_opt, 0, sizeof(m_coff_header_opt)); } - -ObjectFilePECOFF::~ObjectFilePECOFF() -{ +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_coff_header_opt(), m_sect_headers(), + m_entry_point_address() { + ::memset(&m_dos_header, 0, sizeof(m_dos_header)); + ::memset(&m_coff_header, 0, sizeof(m_coff_header)); + ::memset(&m_coff_header_opt, 0, sizeof(m_coff_header_opt)); } +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; - } +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; + } + 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; +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; + } + return changed; } +ByteOrder ObjectFilePECOFF::GetByteOrder() const { return eByteOrderLittle; } -ByteOrder -ObjectFilePECOFF::GetByteOrder () const -{ - return eByteOrderLittle; -} - -bool -ObjectFilePECOFF::IsExecutable() const -{ - return (m_coff_header.flags & llvm::COFF::IMAGE_FILE_DLL) == 0; +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; +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 +// Return true if an endian swap needs to occur when extracting data // from this file. //---------------------------------------------------------------------- -bool -ObjectFilePECOFF::NeedsEndianSwap() const -{ +bool ObjectFilePECOFF::NeedsEndianSwap() const { #if defined(__LITTLE_ENDIAN__) - return false; + return false; #else - return true; + 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 - } +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; + } + 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::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_file_offset = m_coff_header_opt.image_base; - m_image_base = m_coff_header_opt.image_base; - } +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_file_offset = m_coff_header_opt.image_base; + 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; + } + // 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) { + DataBufferSP buffer_sp(m_file.ReadFileContents(offset, size)); + return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize()); + } + ProcessSP process_sp(m_process_wp.lock()); + DataExtractor data; + if (process_sp) { + auto data_ap = llvm::make_unique<DataBufferHeap>(size, 0); + Error readmem_error; + size_t bytes_read = + process_sp->ReadMemory(m_image_base + offset, data_ap->GetBytes(), + data_ap->GetByteSize(), readmem_error); + if (bytes_read == size) { + DataBufferSP buffer_sp(data_ap.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 uint32_t addr_byte_size = GetAddressByteSize (); - const size_t section_header_byte_size = nsects * sizeof(section_header_t); - DataBufferSP section_header_data_sp(m_file.ReadFileContents (section_header_data_offset, section_header_byte_size)); - DataExtractor section_header_data (section_header_data_sp, GetByteOrder(), addr_byte_size); +bool ObjectFilePECOFF::ParseSectionHeaders( + uint32_t section_header_data_offset) { + const uint32_t nsects = m_coff_header.nsects; + m_sect_headers.clear(); - 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); - } - } + 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() == false; + } + + return m_sect_headers.empty() == false; } -bool -ObjectFilePECOFF::GetSectionName(std::string& sect_name, const section_header_t& sect) -{ - if (sect.name[0] == '/') - { - lldb::offset_t stroff = strtoul(§.name[1], NULL, 10); - lldb::offset_t string_file_offset = m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff; - const char *name = m_data.GetCStr (&string_file_offset); - if (name) - { - sect_name = name; - return true; - } - - return false; +bool ObjectFilePECOFF::GetSectionName(std::string §_name, + const section_header_t §) { + if (sect.name[0] == '/') { + lldb::offset_t stroff = strtoul(§.name[1], NULL, 10); + lldb::offset_t string_file_offset = + m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff; + const char *name = m_data.GetCStr(&string_file_offset); + if (name) { + sect_name = name; + return true; } - sect_name = sect.name; - return true; -} + + return false; + } + sect_name = sect.name; + return true; +} //---------------------------------------------------------------------- // GetNListSymtab //---------------------------------------------------------------------- -Symtab * -ObjectFilePECOFF::GetSymtab() -{ - ModuleSP module_sp(GetModule()); - if (module_sp) - { - std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - if (m_symtab_ap.get() == NULL) - { - SectionList *sect_list = GetSectionList(); - m_symtab_ap.reset(new Symtab(this)); - std::lock_guard<std::recursive_mutex> guard(m_symtab_ap->GetMutex()); - - const uint32_t num_syms = m_coff_header.nsyms; - - if (num_syms > 0 && m_coff_header.symoff > 0) - { - const uint32_t symbol_size = 18; - const uint32_t addr_byte_size = GetAddressByteSize (); - const size_t symbol_data_size = num_syms * symbol_size; - // Include the 4-byte string table size at the end of the symbols - DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff, symbol_data_size + 4)); - DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), addr_byte_size); - lldb::offset_t offset = symbol_data_size; - const uint32_t strtab_size = symtab_data.GetU32 (&offset); - DataBufferSP strtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff + symbol_data_size, strtab_size)); - DataExtractor strtab_data (strtab_data_sp, GetByteOrder(), addr_byte_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 = (uint32_t*)strtab_data_sp->GetBytes(); - strtab_data_start[0] = 0; - - offset = 0; - std::string symbol_name; - Symbol *symbols = m_symtab_ap->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 = NULL; - // 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 == NULL) - 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; - } - } - +Symtab *ObjectFilePECOFF::GetSymtab() { + ModuleSP module_sp(GetModule()); + if (module_sp) { + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); + if (m_symtab_ap.get() == NULL) { + SectionList *sect_list = GetSectionList(); + m_symtab_ap.reset(new Symtab(this)); + std::lock_guard<std::recursive_mutex> guard(m_symtab_ap->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 = (uint32_t *)strtab_data.GetDataStart(); + strtab_data_start[0] = 0; + + offset = 0; + std::string symbol_name; + Symbol *symbols = m_symtab_ap->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 = NULL; + // 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 == NULL) + 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)); } - // 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; - Address address(m_coff_header_opt.image_base + data_start, sect_list); - DataBufferSP symtab_data_sp(m_file.ReadFileContents(address.GetSection()->GetFileOffset() + address.GetOffset(), m_coff_header_opt.data_dirs[0].vmsize)); - DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), GetAddressByteSize()); - 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_ap->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); - } + if (symbol.naux > 0) { + i += symbol.naux; + offset += symbol_size; } - m_symtab_ap->CalculateSymbolSizes(); + } } - } - return m_symtab_ap.get(); + } + + // 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_ap->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_ap->CalculateSymbolSizes(); + } + } + return m_symtab_ap.get(); } -bool -ObjectFilePECOFF::IsStripped () -{ - // TODO: determine this for COFF - return false; +bool ObjectFilePECOFF::IsStripped() { + // TODO: determine this for COFF + return false; } +void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) { + if (!m_sections_ap.get()) { + m_sections_ap.reset(new SectionList()); - -void -ObjectFilePECOFF::CreateSections (SectionList &unified_section_list) -{ - if (!m_sections_ap.get()) - { - m_sections_ap.reset(new SectionList()); - - ModuleSP module_sp(GetModule()); - if (module_sp) - { - std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); - const uint32_t nsects = m_sect_headers.size(); - ModuleSP module_sp (GetModule()); - for (uint32_t idx = 0; idx<nsects; ++idx) - { - std::string sect_name; - GetSectionName (sect_name, m_sect_headers[idx]); - ConstString const_sect_name (sect_name.c_str()); - 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_macinfo (".debug_macinfo"); - 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_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))) - { - 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_macinfo) section_type = eSectionTypeDWARFDebugMacInfo; - 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_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; - } - - // Use a segment ID of the segment index shifted left by 8 so they - // never conflict with any of the sections. - SectionSP section_sp (new 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 segment index shifted right by 8 bits as not to collide with any of the 256 section IDs that are possible - const_sect_name, // Name of this section - section_type, // This section is a container of other sections. - 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 - - //section_sp->SetIsEncrypted (segment_is_encrypted); - - unified_section_list.AddSection(section_sp); - m_sections_ap->AddSection (section_sp); - } + ModuleSP module_sp(GetModule()); + if (module_sp) { + std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); + const uint32_t nsects = m_sect_headers.size(); + ModuleSP module_sp(GetModule()); + for (uint32_t idx = 0; idx < nsects; ++idx) { + std::string sect_name; + GetSectionName(sect_name, m_sect_headers[idx]); + ConstString const_sect_name(sect_name.c_str()); + 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_macinfo(".debug_macinfo"); + 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_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))) { + 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_macinfo) + section_type = eSectionTypeDWARFDebugMacInfo; + 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_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; } + + // Use a segment ID of the segment index shifted left by 8 so they + // never conflict with any of the sections. + SectionSP section_sp(new 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 segment index shifted right by + // 8 bits as not to collide with any of the 256 section IDs + // that are possible + const_sect_name, // Name of this section + section_type, // This section is a container of other sections. + 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 + + // section_sp->SetIsEncrypted (segment_is_encrypted); + + unified_section_list.AddSection(section_sp); + m_sections_ap->AddSection(section_sp); + } } + } } -bool -ObjectFilePECOFF::GetUUID (UUID* uuid) -{ - return false; -} +bool ObjectFilePECOFF::GetUUID(UUID *uuid) { return false; } -uint32_t -ObjectFilePECOFF::GetDependentModules (FileSpecList& files) -{ - return 0; +uint32_t ObjectFilePECOFF::GetDependentModules(FileSpecList &files) { + return 0; } -lldb_private::Address -ObjectFilePECOFF::GetEntryPointAddress () -{ - if (m_entry_point_address.IsValid()) - return m_entry_point_address; +lldb_private::Address ObjectFilePECOFF::GetEntryPointAddress() { + if (m_entry_point_address.IsValid()) + return m_entry_point_address; - if (!ParseHeader() || !IsExecutable()) - return m_entry_point_address; + if (!ParseHeader() || !IsExecutable()) + return m_entry_point_address; - SectionList *section_list = GetSectionList(); - addr_t offset = m_coff_header_opt.entry; + SectionList *section_list = GetSectionList(); + addr_t offset = m_coff_header_opt.entry; - if (!section_list) - m_entry_point_address.SetOffset(offset); - else - m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list); - return m_entry_point_address; + if (!section_list) + m_entry_point_address.SetOffset(offset); + else + m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list); + return m_entry_point_address; } - //---------------------------------------------------------------------- // 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 (header_arch); - - *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; - - SectionList *sections = GetSectionList(); - if (sections) - sections->Dump(s, NULL, true, UINT32_MAX); - - if (m_symtab_ap.get()) - m_symtab_ap->Dump(s, NULL, 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(); +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(header_arch); + + *s << ", file = '" << m_file + << "', arch = " << header_arch.GetArchitectureName() << "\n"; + + SectionList *sections = GetSectionList(); + if (sections) + sections->Dump(s, NULL, true, UINT32_MAX); + + if (m_symtab_ap.get()) + m_symtab_ap->Dump(s, NULL, 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(); + } } //---------------------------------------------------------------------- @@ -883,43 +843,33 @@ ObjectFilePECOFF::Dump(Stream *s) // // 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); +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); } //---------------------------------------------------------------------- @@ -927,16 +877,14 @@ ObjectFilePECOFF::DumpDOSHeader(Stream *s, const dos_header_t& header) // // 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); +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); } //---------------------------------------------------------------------- @@ -944,147 +892,145 @@ ObjectFilePECOFF::DumpCOFFHeader(Stream *s, const coff_header_t& header) // // 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); - } +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(name, 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); +void ObjectFilePECOFF::DumpSectionHeader(Stream *s, + const section_header_t &sh) { + std::string name; + GetSectionName(name, 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); - } +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); + } } -bool -ObjectFilePECOFF::GetArchitecture (ArchSpec &arch) -{ - uint16_t machine = m_coff_header.machine; - switch (machine) - { - 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: - arch.SetArchitecture (eArchTypeCOFF, machine, LLDB_INVALID_CPUTYPE); - return true; - default: - break; - } +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; + } } -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; +bool ObjectFilePECOFF::GetArchitecture(ArchSpec &arch) { + uint16_t machine = m_coff_header.machine; + switch (machine) { + 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: + arch.SetArchitecture(eArchTypeCOFF, machine, LLDB_INVALID_CPUTYPE, + IsWindowsSubsystem() ? llvm::Triple::Win32 + : llvm::Triple::UnknownOS); + return true; + default: + break; + } + return false; } -ObjectFile::Strata -ObjectFilePECOFF::CalculateStrata() -{ - return eStrataUser; +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; -} +ConstString ObjectFilePECOFF::GetPluginName() { return GetPluginNameStatic(); } +uint32_t ObjectFilePECOFF::GetPluginVersion() { return 1; } |