summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/ObjectFile/ELF
diff options
context:
space:
mode:
authorMichael Sartain <mikesart@valvesoftware.com>2013-05-23 20:57:03 +0000
committerMichael Sartain <mikesart@valvesoftware.com>2013-05-23 20:57:03 +0000
commitc836ae7d365fea52f558aaee1a7dbf45f6bb1e77 (patch)
treeaf98018aaa075ba60d0dc8e78eebbf9691c9502c /lldb/source/Plugins/ObjectFile/ELF
parentc3ce7f27403c5b404fe854e5c9063fd6a47ce261 (diff)
downloadbcm5719-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.h4
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp82
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h4
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, &notehdr, 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;
OpenPOWER on IntegriCloud