[Lldb-commits] [lldb] r196125 - elf: Move elf note parsing to ObjectFileELF.cpp
Ed Maste
emaste at freebsd.org
Mon Dec 2 09:49:13 PST 2013
Author: emaste
Date: Mon Dec 2 11:49:13 2013
New Revision: 196125
URL: http://llvm.org/viewvc/llvm-project?rev=196125&view=rev
Log:
elf: Move elf note parsing to ObjectFileELF.cpp
Separate ELF note implementations were introduced for core files and
GNU build-id. Move the more general one from elf-core to ObjectFileELF
and use it for build-id as well.
Review: http://llvm-reviews.chandlerc.com/D1902
Modified:
lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp
Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=196125&r1=196124&r2=196125&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Mon Dec 2 11:49:13 2013
@@ -16,6 +16,7 @@
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/FileSpecList.h"
+#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
@@ -143,6 +144,44 @@ ELFRelocation::RelocSymbol64(const ELFRe
} // end anonymous namespace
+bool
+ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset)
+{
+ // Read all fields.
+ if (data.GetU32(offset, &n_namesz, 3) == NULL)
+ return false;
+
+ // The name field is required to be nul-terminated, and n_namesz
+ // includes the terminating nul in observed implementations (contrary
+ // to the ELF-64 spec). A special case is needed for cores generated
+ // by some older Linux versions, which write a note named "CORE"
+ // without a nul terminator and n_namesz = 4.
+ if (n_namesz == 4)
+ {
+ char buf[4];
+ if (data.ExtractBytes (*offset, 4, data.GetByteOrder(), buf) != 4)
+ return false;
+ if (strncmp (buf, "CORE", 4) == 0)
+ {
+ n_name = "CORE";
+ *offset += 4;
+ return true;
+ }
+ }
+
+ const char *cstr = data.GetCStr(offset, llvm::RoundUpToAlignment (n_namesz, 4));
+ if (cstr == NULL)
+ {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
+ if (log)
+ log->Printf("Failed to parse note name lacking nul terminator");
+
+ return false;
+ }
+ n_name = cstr;
+ return true;
+}
+
//------------------------------------------------------------------
// Static methods.
//------------------------------------------------------------------
@@ -685,42 +724,26 @@ ParseNoteGNUBuildID(DataExtractor &data,
{
// 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)
+ ELFNote note = ELFNote();
+ if (!note.Parse(data, &offset))
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))
+ if (note.n_name == "GNU" && (note.n_type == g_gnu_build_id) &&
+ (note.n_descsz == 16 || note.n_descsz == 20))
{
- char name[4];
- if (data.GetU8 (&offset, name, 4) == NULL)
+ uint8_t uuidbuf[20];
+ if (data.GetU8 (&offset, &uuidbuf, note.n_descsz) == 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;
- }
+ uuid.SetBytes (uuidbuf, note.n_descsz);
+ return true;
}
- offset = offset_next_note;
+ offset += llvm::RoundUpToAlignment(note.n_descsz, 4);
}
return false;
}
Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h?rev=196125&r1=196124&r2=196125&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h Mon Dec 2 11:49:13 2013
@@ -20,6 +20,34 @@
#include "ELFHeader.h"
+struct ELFNote
+{
+ elf::elf_word n_namesz;
+ elf::elf_word n_descsz;
+ elf::elf_word n_type;
+
+ std::string n_name;
+
+ ELFNote() : n_namesz(0), n_descsz(0), n_type(0)
+ {
+ }
+
+ /// Parse an ELFNote entry from the given DataExtractor starting at position
+ /// \p offset.
+ ///
+ /// @param[in] data
+ /// The DataExtractor to read from.
+ ///
+ /// @param[in,out] offset
+ /// Pointer to an offset in the data. On return the offset will be
+ /// advanced by the number of bytes read.
+ ///
+ /// @return
+ /// True if the ELFRel entry was successfully read and false otherwise.
+ bool
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
+};
+
//------------------------------------------------------------------------------
/// @class ObjectFileELF
/// @brief Generic ELF object file reader.
Modified: lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp?rev=196125&r1=196124&r2=196125&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp Mon Dec 2 11:49:13 2013
@@ -363,71 +363,6 @@ enum {
NT_FREEBSD_PROCSTAT_AUXV = 16
};
-/// Note Structure found in ELF core dumps.
-/// This is PT_NOTE type program/segments in the core file.
-struct ELFNote
-{
- elf::elf_word n_namesz;
- elf::elf_word n_descsz;
- elf::elf_word n_type;
-
- std::string n_name;
-
- ELFNote() : n_namesz(0), n_descsz(0), n_type(0)
- {
- }
-
- /// Parse an ELFNote entry from the given DataExtractor starting at position
- /// \p offset.
- ///
- /// @param[in] data
- /// The DataExtractor to read from.
- ///
- /// @param[in,out] offset
- /// Pointer to an offset in the data. On return the offset will be
- /// advanced by the number of bytes read.
- ///
- /// @return
- /// True if the ELFRel entry was successfully read and false otherwise.
- bool
- Parse(const DataExtractor &data, lldb::offset_t *offset)
- {
- // Read all fields.
- if (data.GetU32(offset, &n_namesz, 3) == NULL)
- return false;
-
- // The name field is required to be nul-terminated, and n_namesz
- // includes the terminating nul in observed implementations (contrary
- // to the ELF-64 spec). A special case is needed for cores generated
- // by some older Linux versions, which write a note named "CORE"
- // without a nul terminator and n_namesz = 4.
- if (n_namesz == 4)
- {
- char buf[4];
- if (data.ExtractBytes (*offset, 4, data.GetByteOrder(), buf) != 4)
- return false;
- if (strncmp (buf, "CORE", 4) == 0)
- {
- n_name = "CORE";
- *offset += 4;
- return true;
- }
- }
-
- const char *cstr = data.GetCStr(offset, llvm::RoundUpToAlignment(n_namesz, 4));
- if (cstr == NULL)
- {
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
- if (log)
- log->Printf("Failed to parse note name lacking nul terminator");
-
- return false;
- }
- n_name = cstr;
- return true;
- }
-};
-
// Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
static void
ParseFreeBSDPrStatus(ThreadData *thread_data, DataExtractor &data,
More information about the lldb-commits
mailing list