mirror of
https://github.com/intel/llvm.git
synced 2026-01-18 07:57:36 +08:00
ObjectFileELF::GetModuleSpecifications on Linux should work now.
Which means "platform process list" should work and list the architecture. We are now parsing the elf build-id if it exists, which should allow us to load stripped symbols (looking at that next). llvm-svn: 182610
This commit is contained in:
@@ -243,11 +243,8 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
|
||||
lldb::offset_t length,
|
||||
lldb_private::ModuleSpecList &specs)
|
||||
{
|
||||
// FIXME: mikesart@valvesoftware.com
|
||||
// Implementing this function has broken several tests. Specifically this one:
|
||||
// Python dotest.py --executable <path-to-lldb> -p TestCallStdStringFunction.py
|
||||
const size_t initial_count = specs.GetSize();
|
||||
#if 0
|
||||
|
||||
if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
|
||||
{
|
||||
DataExtractor data;
|
||||
@@ -264,15 +261,20 @@ ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,
|
||||
LLDB_INVALID_CPUTYPE);
|
||||
if (spec.GetArchitecture().IsValid())
|
||||
{
|
||||
// ObjectFileMachO adds the UUID here also, but that isn't in the elf header
|
||||
// so we'd have to read the entire file in and calculate the md5sum.
|
||||
// That'd be bad for this routine...
|
||||
// We could parse the ABI tag information (in .note, .notes, or .note.ABI-tag) to get the
|
||||
// machine information. However, we'd have to read a good bit of the rest of the file,
|
||||
// and this info isn't guaranteed to exist or be correct. More details here:
|
||||
// http://refspecs.linuxfoundation.org/LSB_1.2.0/gLSB/noteabitag.html
|
||||
// Instead of passing potentially incorrect information down the pipeline, grab
|
||||
// the host information and use it.
|
||||
spec.GetArchitecture().GetTriple().setOSName (Host::GetOSString().GetCString());
|
||||
spec.GetArchitecture().GetTriple().setVendorName(Host::GetVendorString().GetCString());
|
||||
specs.Append(spec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return specs.GetSize() - initial_count;
|
||||
}
|
||||
|
||||
@@ -360,7 +362,12 @@ ObjectFileELF::ParseHeader()
|
||||
bool
|
||||
ObjectFileELF::GetUUID(lldb_private::UUID* uuid)
|
||||
{
|
||||
// FIXME: Return MD5 sum here. See comment in ObjectFile.h.
|
||||
if (m_uuid.IsValid())
|
||||
{
|
||||
*uuid = m_uuid;
|
||||
return true;
|
||||
}
|
||||
// FIXME: Return MD5 sum here. See comment in ObjectFile.h.
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -661,6 +668,51 @@ ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
ParseNoteGNUBuildID(DataExtractor& data, lldb_private::UUID& uuid)
|
||||
{
|
||||
// Try to parse the note section (ie .note.gnu.build-id|.notes|.note|...) and get the build id.
|
||||
// BuildID documentation: https://fedoraproject.org/wiki/Releases/FeatureBuildId
|
||||
struct
|
||||
{
|
||||
uint32_t name_len; // Length of note name
|
||||
uint32_t desc_len; // Length of note descriptor
|
||||
uint32_t type; // Type of note (1 is ABI_TAG, 3 is BUILD_ID)
|
||||
} notehdr;
|
||||
lldb::offset_t offset = 0;
|
||||
static const uint32_t g_gnu_build_id = 3; // NT_GNU_BUILD_ID from elf.h
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (data.GetU32 (&offset, ¬ehdr, 3) == NULL)
|
||||
return false;
|
||||
|
||||
notehdr.name_len = llvm::RoundUpToAlignment (notehdr.name_len, 4);
|
||||
notehdr.desc_len = llvm::RoundUpToAlignment (notehdr.desc_len, 4);
|
||||
|
||||
lldb::offset_t offset_next_note = offset + notehdr.name_len + notehdr.desc_len;
|
||||
|
||||
// 16 bytes is UUID|MD5, 20 bytes is SHA1
|
||||
if ((notehdr.type == g_gnu_build_id) && (notehdr.name_len == 4) &&
|
||||
(notehdr.desc_len == 16 || notehdr.desc_len == 20))
|
||||
{
|
||||
char name[4];
|
||||
if (data.GetU8 (&offset, name, 4) == NULL)
|
||||
return false;
|
||||
if (!strcmp(name, "GNU"))
|
||||
{
|
||||
uint8_t uuidbuf[20];
|
||||
if (data.GetU8 (&offset, &uuidbuf, notehdr.desc_len) == NULL)
|
||||
return false;
|
||||
uuid.SetBytes (uuidbuf, notehdr.desc_len);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
offset = offset_next_note;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SectionList *
|
||||
ObjectFileELF::GetSectionList()
|
||||
{
|
||||
@@ -727,7 +779,17 @@ ObjectFileELF::GetSectionList()
|
||||
else if (name == g_sect_name_dwarf_debug_ranges) sect_type = eSectionTypeDWARFDebugRanges;
|
||||
else if (name == g_sect_name_dwarf_debug_str) sect_type = eSectionTypeDWARFDebugStr;
|
||||
else if (name == g_sect_name_eh_frame) sect_type = eSectionTypeEHFrame;
|
||||
|
||||
else if (header.sh_type == SHT_NOTE)
|
||||
{
|
||||
if (!m_uuid.IsValid())
|
||||
{
|
||||
DataExtractor data;
|
||||
if (vm_size && (GetData (header.sh_offset, vm_size, data) == vm_size))
|
||||
{
|
||||
ParseNoteGNUBuildID (data, m_uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SectionSP section_sp(new Section(
|
||||
GetModule(), // Module to which this section belongs.
|
||||
|
||||
Reference in New Issue
Block a user