Index: lit/Modules/PECOFF/export-dllfunc.yaml =================================================================== --- lit/Modules/PECOFF/export-dllfunc.yaml +++ lit/Modules/PECOFF/export-dllfunc.yaml @@ -1,11 +1,15 @@ # REQUIRES: system-windows # RUN: yaml2obj < %s > %t.obj # -# RUN: lld-link /machine:x64 /out:%t.dll /noentry /nodefaultlib /dll %t.obj /export:DllFunc +# RUN: lld-link /machine:x64 /out:%t.dll /noentry /nodefaultlib /debug /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: Plugin name: pe-coff + +# timestamp and build id of debug info in the coff header varies. So does its UUID. +# BASIC-CHECK-DAG: UUID: {{[0-9A-F]{7,}[0-9A-F]}}-{{.*}} # BASIC-CHECK: Showing 3 subsections # BASIC-CHECK: Index: 0 Index: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h =================================================================== --- source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h +++ source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h @@ -286,6 +286,8 @@ llvm::Optional m_deps_filespec; typedef llvm::object::OwningBinary OWNBINType; llvm::Optional m_owningbin; + + lldb_private::UUID m_uuid; }; #endif // liblldb_ObjectFilePECOFF_h_ Index: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp =================================================================== --- source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -40,6 +40,31 @@ using namespace lldb; using namespace lldb_private; +namespace { +UUID GetCoffUUID(const FileSpec &file_spec) { + auto binary = llvm::object::createBinary(file_spec.GetPath()); + if (!binary) + return UUID(); + if (!binary->getBinary()->isCOFF() && + !binary->getBinary()->isCOFFImportFile()) + return UUID(); + + auto COFFObj = + llvm::dyn_cast(binary->getBinary()); + if (!COFFObj) + return UUID(); + + // Return PDB's GUID if any. + const llvm::codeview::DebugInfo *pdb_info = nullptr; + llvm::StringRef pdb_file; + if (!COFFObj->getDebugPDBInfo(pdb_info, pdb_file) && pdb_info) + return UUID::fromOptionalData(pdb_info->PDB70.Signature); + + return UUID(); +} + +} // namespace + void ObjectFilePECOFF::Initialize() { PluginManager::RegisterPlugin( GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, @@ -128,18 +153,24 @@ if (pe_signature != IMAGE_NT_SIGNATURE) return false; if (ParseCOFFHeader(data, &offset, coff_header)) { - ArchSpec spec; + ModuleSpec module_spec(file); + ArchSpec &spec = module_spec.GetArchitecture(); + + lldb_private::UUID &uuid = module_spec.GetUUID(); + if (!uuid.IsValid()) + uuid = GetCoffUUID(file); + if (coff_header.machine == MachineAmd64) { spec.SetTriple("x86_64-pc-windows"); - specs.Append(ModuleSpec(file, spec)); + specs.Append(module_spec); } else if (coff_header.machine == MachineX86) { spec.SetTriple("i386-pc-windows"); - specs.Append(ModuleSpec(file, spec)); + specs.Append(module_spec); spec.SetTriple("i686-pc-windows"); - specs.Append(ModuleSpec(file, spec)); + specs.Append(module_spec); } else if (coff_header.machine == MachineArmNt) { spec.SetTriple("arm-pc-windows"); - specs.Append(ModuleSpec(file, spec)); + specs.Append(module_spec); } } } @@ -828,7 +859,13 @@ } } -UUID ObjectFilePECOFF::GetUUID() { return UUID(); } +UUID ObjectFilePECOFF::GetUUID() { + if (m_uuid.IsValid()) + return m_uuid; + + m_uuid = GetCoffUUID(GetFileSpec()); + return m_uuid; +} uint32_t ObjectFilePECOFF::ParseDependentModules() { ModuleSP module_sp(GetModule()); @@ -850,8 +887,7 @@ 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); + static_cast(m_owningbin->getBinary())); auto COFFObj = llvm::dyn_cast(m_owningbin->getBinary()); @@ -912,7 +948,8 @@ if (!section_list) m_entry_point_address.SetOffset(file_addr); else - m_entry_point_address.ResolveAddressUsingFileSections(file_addr, section_list); + m_entry_point_address.ResolveAddressUsingFileSections(file_addr, + section_list); return m_entry_point_address; }