[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, &notehdr, 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