diff options
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp')
| -rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 82 |
1 files changed, 72 insertions, 10 deletions
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. |

