diff --git a/lldb/source/Plugins/ObjectFile/CMakeLists.txt b/lldb/source/Plugins/ObjectFile/CMakeLists.txt --- a/lldb/source/Plugins/ObjectFile/CMakeLists.txt +++ b/lldb/source/Plugins/ObjectFile/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(Breakpad) +add_subdirectory(COFF) add_subdirectory(ELF) add_subdirectory(JSON) add_subdirectory(Mach-O) diff --git a/lldb/source/Plugins/ObjectFile/COFF/CMakeLists.txt b/lldb/source/Plugins/ObjectFile/COFF/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/lldb/source/Plugins/ObjectFile/COFF/CMakeLists.txt @@ -0,0 +1,13 @@ +add_lldb_library(lldbPluginObjectFileCOFF PLUGIN + ObjectFileCOFF.cpp + + LINK_LIBS + lldbCore + lldbHost + lldbSymbol + lldbTarget + + LINK_COMPONENTS + BinaryFormat + Object + Support) diff --git a/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.h b/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.h new file mode 100644 --- /dev/null +++ b/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.h @@ -0,0 +1,116 @@ +//===-- ObjectFileCOFF.h -------------------------------------- -*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_COFF_OBJECTFILECOFF_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_COFF_OBJECTFILECOFF_H + +#include "lldb/Symbol/ObjectFile.h" + +#include "llvm/Object/COFF.h" + +/// \class ObjectFileELF +/// Generic COFF object file reader. +/// +/// This class provides a generic COFF reader plugin implementing the ObjectFile +/// protocol. Assumes that the COFF object format is a Microsoft style COFF +/// rather than the full generality afforded by it. +class ObjectFileCOFF : public lldb_private::ObjectFile { + std::unique_ptr m_object; + lldb_private::UUID m_uuid; + + ObjectFileCOFF(std::unique_ptr object, + const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, + lldb::offset_t data_offset, const lldb_private::FileSpec *file, + lldb::offset_t file_offset, lldb::offset_t length) + : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset), + m_object(std::move(object)) {} + +public: + ~ObjectFileCOFF() override; + + static void Initialize(); + static void Terminate(); + + static llvm::StringRef GetPluginNameStatic() { return "COFF"; } + static llvm::StringRef GetPluginDescriptionStatic() { + return "COFF Object File Reader"; + } + + static lldb_private::ObjectFile * + CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, + lldb::offset_t data_offset, const lldb_private::FileSpec *file, + lldb::offset_t file_offset, lldb::offset_t length); + + static lldb_private::ObjectFile * + CreateMemoryInstance(const lldb::ModuleSP &module_sp, + lldb::WritableDataBufferSP data_sp, + const lldb::ProcessSP &process_sp, lldb::addr_t header); + + static size_t 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); + + // LLVM RTTI support + static char ID; + bool isA(const void *ClassID) const override { + return ClassID == &ID || ObjectFile::isA(ClassID); + } + static bool classof(const ObjectFile *obj) { return obj->isA(&ID); } + + // PluginInterface protocol + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + + // ObjectFile protocol + void Dump(lldb_private::Stream *stream) override; + + uint32_t GetAddressByteSize() const override; + + uint32_t GetDependentModules(lldb_private::FileSpecList &specs) override { + return 0; + } + + bool IsExecutable() const override { + // COFF is an object file format only, it cannot host an executable. + return false; + } + + lldb_private::ArchSpec GetArchitecture() override; + + void CreateSections(lldb_private::SectionList &) override; + + void ParseSymtab(lldb_private::Symtab &) override; + + bool IsStripped() override { + // FIXME see if there is a good way to identify a /Z7 v /Zi or /ZI build. + return false; + } + + lldb_private::UUID GetUUID() override { return m_uuid; } + + lldb::ByteOrder GetByteOrder() const override { + // Microsoft always uses little endian. + return lldb::ByteOrder::eByteOrderLittle; + } + + bool ParseHeader() override; + + lldb_private::ObjectFile::Type CalculateType() override { + // COFF is an object file format only, it cannot host an executable. + return lldb_private::ObjectFile::eTypeObjectFile; + } + + lldb_private::ObjectFile::Strata CalculateStrata() override { + // FIXME the object file may correspond to a kernel image. + return lldb_private::ObjectFile::eStrataUser; + } +}; + +#endif diff --git a/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp b/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp new file mode 100644 --- /dev/null +++ b/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp @@ -0,0 +1,311 @@ +//===-- ObjectFileCOFF.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ObjectFileCOFF.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Utility/LLDBLog.h" + +#include "llvm/Support/Error.h" +#include "llvm/Support/FormatAdapters.h" + +using namespace lldb; +using namespace lldb_private; + +using namespace llvm; +using namespace llvm::object; + +static bool IsCOFFObjectFile(const DataBufferSP &data) { + return identify_magic(toStringRef(data->GetData())) == + file_magic::coff_object; +} + +LLDB_PLUGIN_DEFINE(ObjectFileCOFF) + +char ObjectFileCOFF::ID; + +ObjectFileCOFF::~ObjectFileCOFF() = default; + +void ObjectFileCOFF::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + CreateMemoryInstance, GetModuleSpecifications); +} + +void ObjectFileCOFF::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ObjectFile * +ObjectFileCOFF::CreateInstance(const ModuleSP &module_sp, DataBufferSP data_sp, + offset_t data_offset, const FileSpec *file, + offset_t file_offset, offset_t length) { + Log *log = GetLog(LLDBLog::Object); + + if (!data_sp) { + data_sp = MapFileData(*file, length, file_offset); + if (!data_sp) { + LLDB_LOG(log, + "Failed to create ObjectFileCOFF instance: cannot read file {0}", + file->GetPath()); + return nullptr; + } + data_offset = 0; + } + + assert(data_sp && "must have mapped file at this point"); + + if (!IsCOFFObjectFile(data_sp)) + return nullptr; + + if (data_sp->GetByteSize() < length) { + data_sp = MapFileData(*file, length, file_offset); + if (!data_sp) { + LLDB_LOG(log, + "Failed to create ObjectFileCOFF instance: cannot read file {0}", + file->GetPath()); + return nullptr; + } + data_offset = 0; + } + + + MemoryBufferRef buffer{toStringRef(data_sp->GetData()), + file->GetFilename().GetStringRef()}; + + Expected> binary = createBinary(buffer); + if (!binary) { + LLDB_LOG_ERROR(log, binary.takeError(), + "Failed to create binary for file ({1}): {0}", + file->GetPath()); + return nullptr; + } + + LLDB_LOG(log, "ObjectFileCOFF::ObjectFileCOFF module = {1} ({2}), file = {3}", + module_sp.get(), module_sp->GetSpecificationDescription(), + file->GetPath()); + + return new ObjectFileCOFF(unique_dyn_cast(std::move(*binary)), + module_sp, data_sp, data_offset, file, file_offset, + length); +} + +lldb_private::ObjectFile *ObjectFileCOFF::CreateMemoryInstance( + const ModuleSP &module_sp, WritableDataBufferSP data_sp, + const ProcessSP &process_sp, addr_t header) { + // FIXME: do we need to worry about construction from a memory region? + return nullptr; +} + +size_t ObjectFileCOFF::GetModuleSpecifications( + const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset, + offset_t file_offset, offset_t length, ModuleSpecList &specs) { + if (!IsCOFFObjectFile(data_sp)) + return 0; + + MemoryBufferRef buffer{toStringRef(data_sp->GetData()), + file.GetFilename().GetStringRef()}; + Expected> binary = createBinary(buffer); + if (!binary) { + Log *log = GetLog(LLDBLog::Object); + LLDB_LOG_ERROR(log, binary.takeError(), + "Failed to create binary for file ({1}): {0}", + file.GetFilename()); + return 0; + } + + std::unique_ptr object = + unique_dyn_cast(std::move(*binary)); + switch (static_cast(object->getMachine())) { + case COFF::IMAGE_FILE_MACHINE_I386: + specs.Append(ModuleSpec(file, ArchSpec("i686-unknown-windows-msvc"))); + return 1; + case COFF::IMAGE_FILE_MACHINE_AMD64: + specs.Append(ModuleSpec(file, ArchSpec("x86_64-unknown-windows-msvc"))); + return 1; + case COFF::IMAGE_FILE_MACHINE_ARMNT: + specs.Append(ModuleSpec(file, ArchSpec("armv7-unknown-windows-msvc"))); + return 1; + case COFF::IMAGE_FILE_MACHINE_ARM64: + specs.Append(ModuleSpec(file, ArchSpec("aarch64-unknown-windows-msvc"))); + return 1; + default: + return 0; + } +} + +void ObjectFileCOFF::Dump(Stream *stream) { + ModuleSP module(GetModule()); + if (!module) + return; + + std::lock_guard guard(module->GetMutex()); + + stream->Printf("%p: ", static_cast(this)); + stream->Indent(); + stream->PutCString("ObjectFileCOFF"); + *stream << ", file = '" << m_file + << "', arch = " << GetArchitecture().GetArchitectureName() << '\n'; + + if (SectionList *sections = GetSectionList()) + sections->Dump(stream->AsRawOstream(), stream->GetIndentLevel(), nullptr, + true, std::numeric_limits::max()); +} + +uint32_t ObjectFileCOFF::GetAddressByteSize() const { + return const_cast(this)->GetArchitecture().GetAddressByteSize(); +} + +ArchSpec ObjectFileCOFF::GetArchitecture() { + switch (static_cast(m_object->getMachine())) { + case COFF::IMAGE_FILE_MACHINE_I386: + return ArchSpec("i686-unknown-windows-msvc"); + case COFF::IMAGE_FILE_MACHINE_AMD64: + return ArchSpec("x86_64-unknown-windows-msvc"); + case COFF::IMAGE_FILE_MACHINE_ARMNT: + return ArchSpec("armv7-unknown-windows-msvc"); + case COFF::IMAGE_FILE_MACHINE_ARM64: + return ArchSpec("aarch64-unknown-windows-msvc"); + default: + return ArchSpec(); + } +} + +void ObjectFileCOFF::CreateSections(lldb_private::SectionList §ions) { + if (m_sections_up) + return; + + m_sections_up = std::make_unique(); + ModuleSP module(GetModule()); + if (!module) + return; + + std::lock_guard guard(module->GetMutex()); + + auto SectionType = [](StringRef Name, + const coff_section *Section) -> lldb::SectionType { + lldb::SectionType type = + StringSwitch(Name) + // DWARF Debug Sections + .Case(".debug_abbrev", eSectionTypeDWARFDebugAbbrev) + .Case(".debug_info", eSectionTypeDWARFDebugInfo) + .Case(".debug_line", eSectionTypeDWARFDebugLine) + .Case(".debug_pubnames", eSectionTypeDWARFDebugPubNames) + .Case(".debug_pubtypes", eSectionTypeDWARFDebugPubTypes) + .Case(".debug_str", eSectionTypeDWARFDebugStr) + // CodeView Debug Sections: .debug$S, .debug$T + .StartsWith(".debug$", eSectionTypeDebug) + .Case("clangast", eSectionTypeOther) + .Default(eSectionTypeInvalid); + if (type != eSectionTypeInvalid) + return type; + + if (Section->Characteristics & COFF::IMAGE_SCN_CNT_CODE) + return eSectionTypeCode; + if (Section->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) + return eSectionTypeData; + if (Section->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) + return Section->SizeOfRawData ? eSectionTypeData : eSectionTypeZeroFill; + return eSectionTypeOther; + }; + auto Permissions = [](const object::coff_section *Section) -> uint32_t { + uint32_t permissions = 0; + if (Section->Characteristics & COFF::IMAGE_SCN_MEM_EXECUTE) + permissions |= lldb::ePermissionsExecutable; + if (Section->Characteristics & COFF::IMAGE_SCN_MEM_READ) + permissions |= lldb::ePermissionsReadable; + if (Section->Characteristics & COFF::IMAGE_SCN_MEM_WRITE) + permissions |= lldb::ePermissionsWritable; + return permissions; + }; + + for (const auto &SecRef : m_object->sections()) { + const auto COFFSection = m_object->getCOFFSection(SecRef); + + llvm::Expected Name = SecRef.getName(); + StringRef SectionName = Name ? *Name : COFFSection->Name; + if (!Name) + consumeError(Name.takeError()); + + SectionSP section = + std::make_unique
(module, this, + static_cast(SecRef.getIndex()), + ConstString(SectionName), + SectionType(SectionName, COFFSection), + COFFSection->VirtualAddress, + COFFSection->VirtualSize, + COFFSection->PointerToRawData, + COFFSection->SizeOfRawData, + COFFSection->getAlignment(), + 0); + section->SetPermissions(Permissions(COFFSection)); + + m_sections_up->AddSection(section); + sections.AddSection(section); + } +} + +void ObjectFileCOFF::ParseSymtab(lldb_private::Symtab &symtab) { + Log *log = GetLog(LLDBLog::Object); + + SectionList *sections = GetSectionList(); + symtab.Reserve(symtab.GetNumSymbols() + m_object->getNumberOfSymbols()); + + auto SymbolType = [](const COFFSymbolRef &Symbol) -> lldb::SymbolType { + if (Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) + return eSymbolTypeCode; + if (Symbol.getBaseType() == COFF::IMAGE_SYM_TYPE_NULL && + Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_NULL) + return eSymbolTypeData; + return eSymbolTypeInvalid; + }; + + for (const auto &SymRef : m_object->symbols()) { + const auto COFFSymRef = m_object->getCOFFSymbol(SymRef); + + Expected NameOrErr = SymRef.getName(); + if (auto error = NameOrErr.takeError()) { + LLDB_LOG(log, "ObjectFileCOFF: failed to get symbol name: {0}", + llvm::fmt_consume(std::move(error))); + continue; + } + + Symbol symbol; + symbol.GetMangled().SetValue(ConstString(*NameOrErr)); + + int16_t SecIdx = static_cast(COFFSymRef.getSectionNumber()); + if (SecIdx == COFF::IMAGE_SYM_ABSOLUTE) { + symbol.GetAddressRef() = Address{COFFSymRef.getValue()}; + symbol.SetType(eSymbolTypeAbsolute); + } else if (SecIdx >= 1) { + symbol.GetAddressRef() = Address(sections->GetSectionAtIndex(SecIdx - 1), + COFFSymRef.getValue()); + symbol.SetType(SymbolType(COFFSymRef)); + } + + symtab.AddSymbol(symbol); + } + + LLDB_LOG(log, "ObjectFileCOFF::ParseSymtab processed {0} symbols", + m_object->getNumberOfSymbols()); +} + +bool ObjectFileCOFF::ParseHeader() { + ModuleSP module(GetModule()); + if (!module) + return false; + + std::lock_guard guard(module->GetMutex()); + + m_data.SetByteOrder(eByteOrderLittle); + m_data.SetAddressByteSize(GetAddressByteSize()); + + return true; +} diff --git a/lldb/test/Shell/ObjectFile/COFF/basic.yaml b/lldb/test/Shell/ObjectFile/COFF/basic.yaml new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/ObjectFile/COFF/basic.yaml @@ -0,0 +1,234 @@ +# RUN: yaml2obj %s -o %t +# RUN: lldb-test object-file %t | FileCheck %s + +# CHECK: Plugin name: COFF +# CHECK: Architecture: x86_64-unknown-windows-msvc + +# CHECK: Executable: false +# CHECK: Stripped: false +# CHECK: Type: object file +# CHECK: Strata: user + +# CHECK: Name: .text +# CHECK: Type: code + +# CHECK: Name: .data +# CHECK: Type: data + +# CHECK: Name: .bss +# CHECK: Type: zero-fill + +# CHECK: Name: .rdata +# CHECK: Type: data + +# CHECK: Name: .debug_abbrev +# CHECK: Type: dwarf-abbrev + +# CHECK: Name: .debug_info +# CHECK: Type: dwarf-info + +# CHECK: Name: .debug_str +# CHECK: Type: dwarf-str + +# CHECK: Name: .debug_line +# CHECK: Type: dwarf-line + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '' + - Name: .data + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: '' + - Name: .bss + Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: '' + SizeOfRawData: 0 + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 1 + SectionData: 31343A34313A303700 + - Name: .debug_abbrev + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + SectionData: 011101250E1305030E10171B0E0000023400030E49133F193A0B3B0B02180000030101491300000421004913370B000005260049130000062400030E3E0B0B0B0000072400030E0B0B3E0B000000 + - Name: .debug_info + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + SectionData: 4F0000000400000000000801000000000C00320000000000000034000000023F00000033000000010109030000000000000000033F000000044B0000000900054400000006490000000601074E000000080700 + Relocations: + - VirtualAddress: 6 + SymbolName: .debug_abbrev + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 12 + SymbolName: .debug_str + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 18 + SymbolName: .debug_str + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 22 + SymbolName: .debug_line + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 26 + SymbolName: .debug_str + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 31 + SymbolName: .debug_str + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 43 + SymbolName: timestamp + Type: IMAGE_REL_AMD64_ADDR64 + - VirtualAddress: 69 + SymbolName: .debug_str + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 76 + SymbolName: .debug_str + Type: IMAGE_REL_AMD64_SECREL + - Name: .debug_str + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + SectionData: 4170706C6520636C616E672076657273696F6E2031342E302E332028636C616E672D313430332E302E32322E31342E3129002D002F7661722F656D7074790074696D657374616D700063686172005F5F41525241595F53495A455F545950455F5F00 + - Name: .debug_line + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + SectionData: 2500000004001F000000010101FB0E0D000101010100000001000001003C737464696E3E0000000000 + - Name: .llvm_addrsig + Characteristics: [ IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: '' +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 1 + - Name: .data + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 2 + - Name: .bss + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 3 + - Name: .rdata + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 9 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 479132390 + Number: 4 + - Name: .debug_abbrev + Value: 0 + SectionNumber: 5 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 78 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 937319867 + Number: 5 + - Name: .debug_info + Value: 0 + SectionNumber: 6 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 83 + NumberOfRelocations: 9 + NumberOfLinenumbers: 0 + CheckSum: 1429914004 + Number: 6 + - Name: .debug_str + Value: 0 + SectionNumber: 7 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 98 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 580727506 + Number: 7 + - Name: .debug_line + Value: 0 + SectionNumber: 8 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 41 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 2878960311 + Number: 8 + - Name: .llvm_addrsig + Value: 0 + SectionNumber: 9 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 9 + - Name: '@feat.00' + Value: 0 + SectionNumber: -1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: timestamp + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: .file + Value: 0 + SectionNumber: -2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_FILE + File: '-' +...