forked from OSchip/llvm-project
[PECOFF] Implementation of ObjectFilePECOFF:: GetUUID()
Summary: Provide an implementation of GetUUID() for remote debugging scenarios. Return a PDB's GUID (or PDB70's Signature) as the UUID. Reviewers: amccarth, labath Reviewed By: labath Subscribers: amccarth, clayborg, Hui, labath, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D56229 llvm-svn: 359528
This commit is contained in:
parent
d1e87d41cb
commit
b8d03935e9
|
@ -1,11 +1,15 @@
|
|||
# REQUIRES: lld
|
||||
# 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
|
||||
|
||||
# UUID should not be empty if the module is built with debug info.
|
||||
# BASIC-CHECK-DAG: UUID: {{[0-9A-F]{7,}[0-9A-F]}}-{{.*}}
|
||||
|
||||
# BASIC-CHECK: Showing 3 subsections
|
||||
# BASIC-CHECK: Index: 0
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
# REQUIRES: lld
|
||||
# RUN: yaml2obj %s > %t.obj
|
||||
# RUN: lldb-test object-file %t.obj | FileCheck %s
|
||||
|
||||
# CHECK-DAG: UUID: 14B292E0-D81A-B4F1-4C4C-44205044422E-00000001
|
||||
|
||||
--- !COFF
|
||||
OptionalHeader:
|
||||
AddressOfEntryPoint: 0
|
||||
ImageBase: 2147483648
|
||||
SectionAlignment: 4096
|
||||
FileAlignment: 512
|
||||
MajorOperatingSystemVersion: 6
|
||||
MinorOperatingSystemVersion: 0
|
||||
MajorImageVersion: 0
|
||||
MinorImageVersion: 0
|
||||
MajorSubsystemVersion: 6
|
||||
MinorSubsystemVersion: 0
|
||||
Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI
|
||||
DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT ]
|
||||
SizeOfStackReserve: 1048576
|
||||
SizeOfStackCommit: 4096
|
||||
SizeOfHeapReserve: 1048576
|
||||
SizeOfHeapCommit: 4096
|
||||
ExportTable:
|
||||
RelativeVirtualAddress: 8327
|
||||
Size: 90
|
||||
ImportTable:
|
||||
RelativeVirtualAddress: 0
|
||||
Size: 0
|
||||
ResourceTable:
|
||||
RelativeVirtualAddress: 0
|
||||
Size: 0
|
||||
ExceptionTable:
|
||||
RelativeVirtualAddress: 12288
|
||||
Size: 12
|
||||
CertificateTable:
|
||||
RelativeVirtualAddress: 0
|
||||
Size: 0
|
||||
BaseRelocationTable:
|
||||
RelativeVirtualAddress: 0
|
||||
Size: 0
|
||||
Debug:
|
||||
RelativeVirtualAddress: 8192
|
||||
Size: 28
|
||||
Architecture:
|
||||
RelativeVirtualAddress: 0
|
||||
Size: 0
|
||||
GlobalPtr:
|
||||
RelativeVirtualAddress: 0
|
||||
Size: 0
|
||||
TlsTable:
|
||||
RelativeVirtualAddress: 0
|
||||
Size: 0
|
||||
LoadConfigTable:
|
||||
RelativeVirtualAddress: 0
|
||||
Size: 0
|
||||
BoundImport:
|
||||
RelativeVirtualAddress: 0
|
||||
Size: 0
|
||||
IAT:
|
||||
RelativeVirtualAddress: 0
|
||||
Size: 0
|
||||
DelayImportDescriptor:
|
||||
RelativeVirtualAddress: 0
|
||||
Size: 0
|
||||
ClrRuntimeHeader:
|
||||
RelativeVirtualAddress: 0
|
||||
Size: 0
|
||||
header:
|
||||
Machine: IMAGE_FILE_MACHINE_AMD64
|
||||
Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE, IMAGE_FILE_DLL ]
|
||||
sections:
|
||||
- Name: .text
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
VirtualAddress: 4096
|
||||
VirtualSize: 22
|
||||
SectionData: 50894C24048B4C24040FAF4C2404890C248B042459C3
|
||||
- Name: .rdata
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
|
||||
VirtualAddress: 8192
|
||||
VirtualSize: 236
|
||||
SectionData: 00000000A565B65C00000000020000006B0000001C2000001C06000052534453E092B2141AD8F1B44C4C44205044422E01000000443A5C757073747265616D5C6275696C645C746F6F6C735C6C6C64625C6C69745C4D6F64756C65735C5045434F46465C4F75747075745C6578706F72742D646C6C66756E632E79616D6C2E746D702E70646200000000000000000000000000AF200000000000000200000001000000CB200000D3200000D72000006578706F72742D646C6C66756E632E79616D6C2E746D702E646C6C000000000000100000D92000000100446C6C46756E63000000000101010001020000
|
||||
- Name: .pdata
|
||||
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
|
||||
VirtualAddress: 12288
|
||||
VirtualSize: 12
|
||||
SectionData: '0010000016100000E4200000'
|
||||
symbols: []
|
||||
...
|
|
@ -40,6 +40,54 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
struct CVInfoPdb70 {
|
||||
// 16-byte GUID
|
||||
struct _Guid {
|
||||
llvm::support::ulittle32_t Data1;
|
||||
llvm::support::ulittle16_t Data2;
|
||||
llvm::support::ulittle16_t Data3;
|
||||
uint8_t Data4[8];
|
||||
} Guid;
|
||||
|
||||
llvm::support::ulittle32_t Age;
|
||||
};
|
||||
|
||||
static UUID GetCoffUUID(llvm::object::COFFObjectFile *coff_obj) {
|
||||
if (!coff_obj)
|
||||
return UUID();
|
||||
|
||||
const llvm::codeview::DebugInfo *pdb_info = nullptr;
|
||||
llvm::StringRef pdb_file;
|
||||
|
||||
// This part is similar with what has done in minidump parser.
|
||||
if (!coff_obj->getDebugPDBInfo(pdb_info, pdb_file) && pdb_info) {
|
||||
if (pdb_info->PDB70.CVSignature == llvm::OMF::Signature::PDB70) {
|
||||
using llvm::support::endian::read16be;
|
||||
using llvm::support::endian::read32be;
|
||||
|
||||
const uint8_t *sig = pdb_info->PDB70.Signature;
|
||||
struct CVInfoPdb70 info;
|
||||
info.Guid.Data1 = read32be(sig);
|
||||
sig += 4;
|
||||
info.Guid.Data2 = read16be(sig);
|
||||
sig += 2;
|
||||
info.Guid.Data3 = read16be(sig);
|
||||
sig += 2;
|
||||
memcpy(info.Guid.Data4, sig, 8);
|
||||
|
||||
// Return 20-byte UUID if the Age is not zero
|
||||
if (pdb_info->PDB70.Age) {
|
||||
info.Age = read32be(&pdb_info->PDB70.Age);
|
||||
return UUID::fromOptionalData(&info, sizeof(info));
|
||||
}
|
||||
// Otherwise return 16-byte GUID
|
||||
return UUID::fromOptionalData(&info.Guid, sizeof(info.Guid));
|
||||
}
|
||||
}
|
||||
|
||||
return UUID();
|
||||
}
|
||||
|
||||
void ObjectFilePECOFF::Initialize() {
|
||||
PluginManager::RegisterPlugin(
|
||||
GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
|
||||
|
@ -113,36 +161,43 @@ size_t ObjectFilePECOFF::GetModuleSpecifications(
|
|||
lldb::offset_t data_offset, lldb::offset_t file_offset,
|
||||
lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
|
||||
const size_t initial_count = specs.GetSize();
|
||||
if (!data_sp || !ObjectFilePECOFF::MagicBytesMatch(data_sp))
|
||||
return initial_count;
|
||||
|
||||
if (ObjectFilePECOFF::MagicBytesMatch(data_sp)) {
|
||||
DataExtractor data;
|
||||
data.SetData(data_sp, data_offset, length);
|
||||
data.SetByteOrder(eByteOrderLittle);
|
||||
auto binary = llvm::object::createBinary(file.GetPath());
|
||||
if (!binary)
|
||||
return initial_count;
|
||||
|
||||
dos_header_t dos_header;
|
||||
coff_header_t coff_header;
|
||||
if (!binary->getBinary()->isCOFF() &&
|
||||
!binary->getBinary()->isCOFFImportFile())
|
||||
return initial_count;
|
||||
|
||||
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));
|
||||
} else if (coff_header.machine == MachineArmNt) {
|
||||
spec.SetTriple("arm-pc-windows");
|
||||
specs.Append(ModuleSpec(file, spec));
|
||||
}
|
||||
}
|
||||
}
|
||||
auto COFFObj =
|
||||
llvm::cast<llvm::object::COFFObjectFile>(binary->getBinary());
|
||||
|
||||
ModuleSpec module_spec(file);
|
||||
ArchSpec &spec = module_spec.GetArchitecture();
|
||||
lldb_private::UUID &uuid = module_spec.GetUUID();
|
||||
if (!uuid.IsValid())
|
||||
uuid = GetCoffUUID(COFFObj);
|
||||
|
||||
switch (COFFObj->getMachine()) {
|
||||
case MachineAmd64:
|
||||
spec.SetTriple("x86_64-pc-windows");
|
||||
specs.Append(module_spec);
|
||||
break;
|
||||
case MachineX86:
|
||||
spec.SetTriple("i386-pc-windows");
|
||||
specs.Append(module_spec);
|
||||
spec.SetTriple("i686-pc-windows");
|
||||
specs.Append(module_spec);
|
||||
break;
|
||||
case MachineArmNt:
|
||||
spec.SetTriple("arm-pc-windows");
|
||||
specs.Append(module_spec);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return specs.GetSize() - initial_count;
|
||||
|
@ -828,7 +883,19 @@ void ObjectFilePECOFF::CreateSections(SectionList &unified_section_list) {
|
|||
}
|
||||
}
|
||||
|
||||
UUID ObjectFilePECOFF::GetUUID() { return UUID(); }
|
||||
UUID ObjectFilePECOFF::GetUUID() {
|
||||
if (m_uuid.IsValid())
|
||||
return m_uuid;
|
||||
|
||||
if (!CreateBinary())
|
||||
return UUID();
|
||||
|
||||
auto COFFObj =
|
||||
llvm::cast<llvm::object::COFFObjectFile>(m_owningbin->getBinary());
|
||||
|
||||
m_uuid = GetCoffUUID(COFFObj);
|
||||
return m_uuid;
|
||||
}
|
||||
|
||||
uint32_t ObjectFilePECOFF::ParseDependentModules() {
|
||||
ModuleSP module_sp(GetModule());
|
||||
|
@ -850,8 +917,7 @@ uint32_t ObjectFilePECOFF::ParseDependentModules() {
|
|||
static_cast<void *>(this), static_cast<void *>(module_sp.get()),
|
||||
module_sp->GetSpecificationDescription().c_str(),
|
||||
static_cast<void *>(m_owningbin.getPointer()),
|
||||
m_owningbin ? static_cast<void *>(m_owningbin->getBinary())
|
||||
: nullptr);
|
||||
static_cast<void *>(m_owningbin->getBinary()));
|
||||
|
||||
auto COFFObj =
|
||||
llvm::dyn_cast<llvm::object::COFFObjectFile>(m_owningbin->getBinary());
|
||||
|
@ -912,7 +978,8 @@ lldb_private::Address ObjectFilePECOFF::GetEntryPointAddress() {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -286,6 +286,7 @@ private:
|
|||
llvm::Optional<lldb_private::FileSpecList> m_deps_filespec;
|
||||
typedef llvm::object::OwningBinary<llvm::object::Binary> OWNBINType;
|
||||
llvm::Optional<OWNBINType> m_owningbin;
|
||||
lldb_private::UUID m_uuid;
|
||||
};
|
||||
|
||||
#endif // liblldb_ObjectFilePECOFF_h_
|
||||
|
|
Loading…
Reference in New Issue