diff options
author | Michael Sartain <mikesart@valvesoftware.com> | 2013-05-23 20:57:03 +0000 |
---|---|---|
committer | Michael Sartain <mikesart@valvesoftware.com> | 2013-05-23 20:57:03 +0000 |
commit | c836ae7d365fea52f558aaee1a7dbf45f6bb1e77 (patch) | |
tree | af98018aaa075ba60d0dc8e78eebbf9691c9502c /lldb/source/Plugins/ObjectFile/ELF | |
parent | c3ce7f27403c5b404fe854e5c9063fd6a47ce261 (diff) | |
download | bcm5719-llvm-c836ae7d365fea52f558aaee1a7dbf45f6bb1e77.tar.gz bcm5719-llvm-c836ae7d365fea52f558aaee1a7dbf45f6bb1e77.zip |
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
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF')
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h | 4 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 82 | ||||
-rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 4 |
3 files changed, 78 insertions, 12 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h index 11ab1dcef44..aa2c16b6168 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h @@ -107,7 +107,7 @@ struct ELFHeader GetRelocationJumpSlotType() const; //-------------------------------------------------------------------------- - /// Parse an ELFSectionHeader entry starting at position \p offset and + /// Parse an ELFHeader entry starting at position \p offset and /// update the data extractor with the address size and byte order /// attributes as defined by the header. /// @@ -120,7 +120,7 @@ struct ELFHeader /// advanced by the number of bytes read. /// /// @return - /// True if the ELFSectionHeader was successfully read and false + /// True if the ELFHeader was successfully read and false /// otherwise. bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset); diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 31f1f28d05b..d665e586de2 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -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. diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index 6efd98123ad..f1fea3c666d 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -16,6 +16,7 @@ #include "lldb/lldb-private.h" #include "lldb/Host/FileSpec.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Core/UUID.h" #include "ELFHeader.h" @@ -154,6 +155,9 @@ private: /// ELF file header. elf::ELFHeader m_header; + /// ELF build ID + lldb_private::UUID m_uuid; + /// Collection of program headers. ProgramHeaderColl m_program_headers; |