Index: lit/Modules/PECOFF/dep-modules.yaml =================================================================== --- /dev/null +++ lit/Modules/PECOFF/dep-modules.yaml @@ -0,0 +1,170 @@ +# REQUIRES: system-windows +# RUN: yaml2obj < %p/export-dllfunc.yaml > %t.export-dllfunc.obj +# RUN: yaml2obj < %s > %t.obj +# +# RUN: lld-link /machine:x64 /out:%t.export-dllfunc.dll /noentry /nodefaultlib /dll %t.export-dllfunc.obj /export:DllFunc +# RUN: lld-link /out:%t.exe %t.obj %t.export-dllfunc.lib /nodefaultlib /entry:main /include:DllFunc +# +# RUN: lldb-test object-file -dep-modules %t.exe | FileCheck -check-prefix=DEPS %s + + +# DEPS: Showing 1 dependent module(s) + +# Ignore checking the directory and any tentative string in the path. +# DEPS: Name: {{.*}}dep-modules.yaml.{{.*}}export-dllfunc.dll + + +--- !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: 16 + SectionData: 4883EC48C7442444000000004889542438894C2434B904000000E80000000089442430B908000000E8000000008944242C8B4424300344242C4883C448C3 + Relocations: + - VirtualAddress: 27 + SymbolName: 'DllFunc' + Type: IMAGE_REL_AMD64_REL32 + - VirtualAddress: 41 + SymbolName: 'DllFunc' + Type: IMAGE_REL_AMD64_REL32 + - 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: '' + - Name: .xdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '0104010004820000' + - Name: .drectve + Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962 + - Name: .pdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '000000003E00000000000000' + Relocations: + - VirtualAddress: 0 + SymbolName: main + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 4 + SymbolName: main + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 8 + SymbolName: .xdata + Type: IMAGE_REL_AMD64_ADDR32NB + - Name: .llvm_addrsig + Characteristics: [ IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: '10' +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 62 + NumberOfRelocations: 2 + NumberOfLinenumbers: 0 + CheckSum: 373303044 + 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: .xdata + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 8 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 2657791889 + Number: 4 + - Name: .drectve + Value: 0 + SectionNumber: 5 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 48 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 149686238 + Number: 5 + - Name: .pdata + Value: 0 + SectionNumber: 6 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 12 + NumberOfRelocations: 3 + NumberOfLinenumbers: 0 + CheckSum: 2420588879 + Number: 6 + - Name: .llvm_addrsig + Value: 0 + SectionNumber: 7 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 1 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 498536548 + Number: 7 + - Name: '@feat.00' + Value: 0 + SectionNumber: -1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: main + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: 'DllFunc' + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... Index: lit/Modules/PECOFF/export-dllfunc.yaml =================================================================== --- /dev/null +++ lit/Modules/PECOFF/export-dllfunc.yaml @@ -0,0 +1,172 @@ +# REQUIRES: system-windows +# RUN: yaml2obj < %s > %t.obj +# +# RUN: lld-link /machine:x64 /out:%t.dll /noentry /nodefaultlib /dll %t.obj /export:DllFunc +# +# RUN: lldb-test object-file %t.dll | FileCheck -check-prefix=BASIC-CHECK %s +# RUN: lldb-test object-file -dep-modules %t.dll | FileCheck -check-prefix=DEPS %s + + +# BASIC-CHECK: Showing 3 sections +# BASIC-CHECK: Index: 0 +# BASIC-CHECK: Name: .text +# BASIC-CHECK: Type: code +# BASIC-CHECK: VM size: 22 +# BASIC-CHECK: File size: 512 +# +# BASIC-CHECK: Index: 1 +# BASIC-CHECK: Name: .rdata +# BASIC-CHECK: Type: data +# BASIC-CHECK: VM size: {{.}} +# BASIC-CHECK: File size: 512 +# +# BASIC-CHECK: Index: 2 +# BASIC-CHECK: Name: .pdata +# BASIC-CHECK: Type: data +# BASIC-CHECK: VM size: 12 +# BASIC-CHECK: File size: 512 +# +# DEPS: Showing 0 dependent module(s) + + +--- !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: 16 + SectionData: 50894C24048B4C24040FAF4C2404890C248B042459C3 + - 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: '' + - Name: .xdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '0101010001020000' + - Name: .drectve + Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ] + Alignment: 1 + SectionData: 202F44454641554C544C49423A6C6962636D742E6C6962202F44454641554C544C49423A6F6C646E616D65732E6C6962 + - Name: .pdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '000000001600000000000000' + Relocations: + - VirtualAddress: 0 + SymbolName: 'DllFunc' + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 4 + SymbolName: 'DllFunc' + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 8 + SymbolName: .xdata + Type: IMAGE_REL_AMD64_ADDR32NB + - 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: 22 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 3054557294 + 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: .xdata + Value: 0 + SectionNumber: 4 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 8 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 448359300 + Number: 4 + - Name: .drectve + Value: 0 + SectionNumber: 5 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 48 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 149686238 + Number: 5 + - Name: .pdata + Value: 0 + SectionNumber: 6 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 12 + NumberOfRelocations: 3 + NumberOfLinenumbers: 0 + CheckSum: 3134470316 + Number: 6 + - Name: .llvm_addrsig + Value: 0 + SectionNumber: 7 + 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: 7 + - Name: '@feat.00' + Value: 0 + SectionNumber: -1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: 'DllFunc' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... Index: lit/Modules/PECOFF/lit.local.cfg =================================================================== --- /dev/null +++ lit/Modules/PECOFF/lit.local.cfg @@ -0,0 +1 @@ +config.suffixes = ['.yaml', '.test'] Index: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h =================================================================== --- source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h +++ source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h @@ -13,6 +13,7 @@ #include #include "lldb/Symbol/ObjectFile.h" +#include "llvm/Object/Binary.h" class ObjectFilePECOFF : public lldb_private::ObjectFile { public: @@ -257,6 +258,8 @@ bool ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr); bool ParseSectionHeaders(uint32_t offset); + uint32_t ParseDependentModules(); + static void DumpDOSHeader(lldb_private::Stream *s, const dos_header_t &header); static void DumpCOFFHeader(lldb_private::Stream *s, @@ -265,6 +268,8 @@ const coff_opt_header_t &header); void DumpSectionHeaders(lldb_private::Stream *s); void DumpSectionHeader(lldb_private::Stream *s, const section_header_t &sh); + void DumpDependentModules(lldb_private::Stream *s); + bool GetSectionName(std::string §_name, const section_header_t §); typedef std::vector SectionHeaderColl; @@ -272,12 +277,18 @@ typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter; private: + bool CreateBinary(); + +private: dos_header_t m_dos_header; coff_header_t m_coff_header; coff_opt_header_t m_coff_header_opt; SectionHeaderColl m_sect_headers; lldb::addr_t m_image_base; lldb_private::Address m_entry_point_address; + llvm::Optional m_deps_filespec; + typedef llvm::object::OwningBinary OWNBINType; + llvm::Optional m_owningbin; }; #endif // liblldb_ObjectFilePECOFF_h_ Index: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp =================================================================== --- source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -23,11 +23,14 @@ #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" #include "lldb/Utility/UUID.h" #include "llvm/BinaryFormat/COFF.h" +#include "llvm/Object/COFFImportFile.h" +#include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ @@ -86,6 +89,10 @@ if (!objfile_ap || !objfile_ap->ParseHeader()) return nullptr; + // Cache coff binary. + if (!objfile_ap->CreateBinary()) + return nullptr; + return objfile_ap.release(); } @@ -131,9 +138,7 @@ specs.Append(ModuleSpec(file, spec)); spec.SetTriple("i686-pc-windows"); specs.Append(ModuleSpec(file, spec)); - } - else if (coff_header.machine == MachineArmNt) - { + } else if (coff_header.machine == MachineArmNt) { spec.SetTriple("arm-pc-windows"); specs.Append(ModuleSpec(file, spec)); } @@ -168,6 +173,40 @@ return lldb::eSymbolTypeInvalid; } +bool ObjectFilePECOFF::CreateBinary() { + if (m_owningbin) + return true; + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + + auto binary = llvm::object::createBinary(m_file.GetPath()); + if (!binary) { + if (log) + log->Printf("ObjectFilePECOFF::CreateBinary() - failed to create binary " + "for file (%s): %s", + m_file ? m_file.GetPath().c_str() : "", + errorToErrorCode(binary.takeError()).message().c_str()); + return false; + } + + // Make sure we only handle COFF format. + if (!binary->getBinary()->isCOFF() && + !binary->getBinary()->isCOFFImportFile()) + return false; + + m_owningbin = OWNBINType(std::move(*binary)); + if (log) + log->Printf("%p ObjectFilePECOFF::CreateBinary() module = %p (%s), file = " + "%s, binary = %p (Bin = %p)", + static_cast(this), + static_cast(GetModule().get()), + GetModule()->GetSpecificationDescription().c_str(), + m_file ? m_file.GetPath().c_str() : "", + static_cast(m_owningbin.getPointer()), + static_cast(m_owningbin->getBinary())); + return true; +} + ObjectFilePECOFF::ObjectFilePECOFF(const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, lldb::offset_t data_offset, @@ -176,7 +215,7 @@ 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() { + m_entry_point_address(), m_deps_filespec(), m_owningbin() { ::memset(&m_dos_header, 0, sizeof(m_dos_header)); ::memset(&m_coff_header, 0, sizeof(m_coff_header)); ::memset(&m_coff_header_opt, 0, sizeof(m_coff_header_opt)); @@ -188,7 +227,7 @@ 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() { + m_entry_point_address(), m_deps_filespec(), m_owningbin() { ::memset(&m_dos_header, 0, sizeof(m_dos_header)); ::memset(&m_coff_header, 0, sizeof(m_coff_header)); ::memset(&m_coff_header_opt, 0, sizeof(m_coff_header_opt)); @@ -431,7 +470,7 @@ DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) { if (m_file) { - // A bit of a hack, but we intend to write to this buffer, so we can't + // A bit of a hack, but we intend to write to this buffer, so we can't // mmap it. auto buffer_sp = MapFileData(m_file, size, offset); return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize()); @@ -805,8 +844,73 @@ bool ObjectFilePECOFF::GetUUID(UUID *uuid) { return false; } +uint32_t ObjectFilePECOFF::ParseDependentModules() { + ModuleSP module_sp(GetModule()); + if (!module_sp) + return 0; + + std::lock_guard guard(module_sp->GetMutex()); + if (m_deps_filespec) + return m_deps_filespec->GetSize(); + + // Cache coff binary if it is not done yet. + if (!CreateBinary()) + return 0; + + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); + if (log) + log->Printf("%p ObjectFilePECOFF::ParseDependentModules() module = %p " + "(%s), binary = %p (Bin = %p)", + static_cast(this), static_cast(module_sp.get()), + module_sp->GetSpecificationDescription().c_str(), + static_cast(m_owningbin.getPointer()), + m_owningbin ? static_cast(m_owningbin->getBinary()) + : nullptr); + + auto COFFObj = + llvm::dyn_cast(m_owningbin->getBinary()); + if (!COFFObj) + return 0; + + m_deps_filespec = FileSpecList(); + + for (const auto &entry : COFFObj->import_directories()) { + llvm::StringRef dll_name; + auto ec = entry.getName(dll_name); + // Report a bogus entry. + if (ec != std::error_code()) { + if (log) + log->Printf("ObjectFilePECOFF::ParseDependentModules() - failed to get " + "import directory entry name: %s", + ec.message().c_str()); + continue; + } + + // At this moment we only have the base name of the DLL. The full path can + // only be seen after the dynamic loading. Our best guess is Try to get it + // with the help of the object file's directory. + llvm::SmallString dll_fullpath; + FileSpec dll_specs(dll_name); + dll_specs.GetDirectory().SetString(m_file.GetDirectory().GetCString()); + + if (!llvm::sys::fs::real_path(dll_specs.GetPath(), dll_fullpath)) + m_deps_filespec->Append(FileSpec(dll_fullpath)); + else { + // Known DLLs or DLL not found in the object file directory. + m_deps_filespec->Append(FileSpec(dll_name)); + } + } + return m_deps_filespec->GetSize(); +} + uint32_t ObjectFilePECOFF::GetDependentModules(FileSpecList &files) { - return 0; + auto num_modules = ParseDependentModules(); + auto original_size = files.GetSize(); + + for (unsigned i = 0; i < num_modules; ++i) + files.AppendIfUnique(m_deps_filespec->GetFileSpecAtIndex(i)); + + return files.GetSize() - original_size; } lldb_private::Address ObjectFilePECOFF::GetEntryPointAddress() { @@ -863,6 +967,9 @@ s->EOL(); DumpSectionHeaders(s); s->EOL(); + + DumpDependentModules(s); + s->EOL(); } } @@ -1010,6 +1117,22 @@ } } +//---------------------------------------------------------------------- +// DumpDependentModules +// +// Dump all of the dependent modules to the specified output stream +//---------------------------------------------------------------------- +void ObjectFilePECOFF::DumpDependentModules(lldb_private::Stream *s) { + auto num_modules = ParseDependentModules(); + if (num_modules > 0) { + s->PutCString("Dependent Modules\n"); + for (unsigned i = 0; i < num_modules; ++i) { + auto spec = m_deps_filespec->GetFileSpecAtIndex(i); + s->Printf(" %s\n", spec.GetFilename().GetCString()); + } + } +} + bool ObjectFilePECOFF::IsWindowsSubsystem() { switch (m_coff_header_opt.subsystem) { case llvm::COFF::IMAGE_SUBSYSTEM_NATIVE: Index: tools/lldb-test/lldb-test.cpp =================================================================== --- tools/lldb-test/lldb-test.cpp +++ tools/lldb-test/lldb-test.cpp @@ -90,6 +90,9 @@ cl::opt SectionContents("contents", cl::desc("Dump each section's contents"), cl::sub(ObjectFileSubcommand)); +cl::opt SectionDependentModules("dep-modules", + cl::desc("Dump each dependent module"), + cl::sub(ObjectFileSubcommand)); cl::list InputFilenames(cl::Positional, cl::desc(""), cl::OneOrMore, cl::sub(ObjectFileSubcommand)); @@ -612,8 +615,7 @@ if (DumpAST) { if (Find != FindType::None) - return make_string_error( - "Cannot both search and dump AST."); + return make_string_error("Cannot both search and dump AST."); if (Regex || !Context.empty() || !Name.empty() || !File.empty() || Line != 0) return make_string_error( @@ -758,6 +760,20 @@ } Printer.NewLine(); } + + if (opts::object::SectionDependentModules) { + // A non-empty section list ensures a valid object file. + auto Obj = ModulePtr->GetObjectFile(); + FileSpecList Files; + auto Count = Obj->GetDependentModules(Files); + Printer.formatLine("Showing {0} dependent module(s)", Count); + for (size_t I = 0; I < Files.GetSize(); ++I) { + AutoIndent Indent(Printer, 2); + Printer.formatLine("Name: {0}", + Files.GetFileSpecAtIndex(I).GetCString()); + } + Printer.NewLine(); + } } return HadErrors; } @@ -832,8 +848,8 @@ ++Probe; } - // Insert the new allocation into the interval map. Use unique allocation IDs - // to inhibit interval coalescing. + // Insert the new allocation into the interval map. Use unique allocation + // IDs to inhibit interval coalescing. static unsigned AllocationID = 0; if (Size) State.Allocations.insert(Addr, EndOfRegion, AllocationID++);