[Lldb-commits] [PATCH 1/2] elf-core: Parse vendor-specific notes

Ed Maste emaste at freebsd.org
Fri Jul 19 13:41:31 PDT 2013


ELF notes contain a 'name' field, which specifies a vendor who defines
the format of the note.  Examples are 'GNU' and 'FreeBSD', or it may be
empty for generic notes.

Add a case for FreeBSD-specific notes, leaving GNU notes, other vendor-
specific notes, and generic notes to be handled by the existing code
for now.
---
 source/Plugins/Process/elf-core/ProcessElfCore.cpp | 86 +++++++++++++++-------
 1 file changed, 60 insertions(+), 26 deletions(-)

diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index 3e7d07d..20d47a6 100644
--- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -370,6 +370,21 @@ enum {
     NT_AUXV
 };
 
+enum {
+    NT_FREEBSD_PRSTATUS      = 1,
+    NT_FREEBSD_FPREGSET,
+    NT_FREEBSD_PRPSINFO,
+    NT_FREEBSD_THRMISC       = 7,
+    NT_FREEBSD_PROCSTAT_AUXV = 16
+};
+
+/// Align the given value to next boundary specified by the alignment bytes
+static uint32_t
+AlignToNext(uint32_t value, int alignment_bytes)
+{
+    return (value + alignment_bytes - 1) & ~(alignment_bytes - 1);
+}
+
 /// Note Structure found in ELF core dumps.
 /// This is PT_NOTE type program/segments in the core file.
 struct ELFNote
@@ -378,6 +393,8 @@ struct ELFNote
     elf::elf_word n_descsz;
     elf::elf_word n_type;
 
+    std::string n_name;
+
     ELFNote()
     {
         memset(this, 0, sizeof(ELFNote));
@@ -402,17 +419,12 @@ struct ELFNote
         if (data.GetU32(offset, &n_namesz, 3) == NULL)
             return false;
 
+        n_name = data.GetCStr(offset, AlignToNext(n_namesz, 4));
+
         return true;
     }
 };
 
-/// Align the given value to next boundary specified by the alignment bytes
-static uint32_t
-AlignToNext(uint32_t value, int alignment_bytes)
-{
-    return (value + alignment_bytes - 1) & ~(alignment_bytes - 1);
-}
-
 /// Parse Thread context from PT_NOTE segment and store it in the thread list
 /// Notes:
 /// 1) A PT_NOTE segment is composed of one or more NOTE entries.
@@ -461,32 +473,54 @@ ProcessElfCore::ParseThreadContextsFromNoteSegment(const elf::ELFProgramHeader *
         }
 
         size_t note_start, note_size;
-        note_start = offset + AlignToNext(note.n_namesz, 4);
+        note_start = offset;
         note_size = AlignToNext(note.n_descsz, 4);
 
         // Store the NOTE information in the current thread
         DataExtractor note_data (segment_data, note_start, note_size);
-        switch (note.n_type)
+        if (note.n_name == "FreeBSD")
+        {
+            switch (note.n_type)
+            {
+                case NT_FREEBSD_PRSTATUS:
+                    have_prstatus = true;
+                    thread_data->prstatus = note_data;
+                    break;
+                case NT_FREEBSD_FPREGSET:
+                    thread_data->fpregset = note_data;
+                    break;
+                case NT_FREEBSD_PRPSINFO:
+                    have_prpsinfo = true;
+                    thread_data->prpsinfo = note_data;
+                    break;
+                default:
+                    break;
+            }
+        }
+        else
         {
-            case NT_PRSTATUS:
-                have_prstatus = true;
-                thread_data->prstatus = note_data;
-                break;
-            case NT_FPREGSET:
-                thread_data->fpregset = note_data;
-                break;
-            case NT_PRPSINFO:
-                have_prpsinfo = true;
-                thread_data->prpsinfo = note_data;
-                break;
-            case NT_AUXV:
-                m_auxv = DataExtractor(note_data);
-                break;
-            default:
-                break;
+            switch (note.n_type)
+            {
+                case NT_PRSTATUS:
+                    have_prstatus = true;
+                    thread_data->prstatus = note_data;
+                    break;
+                case NT_FPREGSET:
+                    thread_data->fpregset = note_data;
+                    break;
+                case NT_PRPSINFO:
+                    have_prpsinfo = true;
+                    thread_data->prpsinfo = note_data;
+                    break;
+                case NT_AUXV:
+                    m_auxv = DataExtractor(note_data);
+                    break;
+                default:
+                    break;
+            }
         }
 
-        offset += AlignToNext(note.n_namesz, 4) + note_size;
+        offset += note_size;
     }
     // Add last entry in the note section
     if (thread_data && thread_data->prstatus.GetByteSize() > 0)
-- 
1.7.11.5




More information about the lldb-commits mailing list