[Lldb-commits] [lldb] r186975 - elf-core: Improve FreeBSD support and move data extraction to parse time

Ed Maste emaste at freebsd.org
Tue Jul 23 11:30:50 PDT 2013


Author: emaste
Date: Tue Jul 23 13:30:49 2013
New Revision: 186975

URL: http://llvm.org/viewvc/llvm-project?rev=186975&view=rev
Log:
elf-core: Improve FreeBSD support and move data extraction to parse time

Extracting thread data at parse time simplifies multi-platform support.
This change adds FreeBSD thread names and auxv info.

Thanks to Samuel Jacob for review, testing, and improvements.

Modified:
    lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp
    lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h
    lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp
    lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.h

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=186975&r1=186974&r2=186975&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp Tue Jul 23 13:30:49 2013
@@ -231,8 +231,7 @@ ProcessElfCore::UpdateThreadList (Thread
     for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
     {
         const ThreadData &td = m_thread_data[tid];
-        lldb::ThreadSP thread_sp(new ThreadElfCore (*this, tid, td.prstatus,
-                                                    td.prpsinfo, td.fpregset));
+        lldb::ThreadSP thread_sp(new ThreadElfCore (*this, tid, td));
         new_thread_list.AddThread (thread_sp);
     }
     return new_thread_list.GetSize(false) > 0;
@@ -436,6 +435,13 @@ struct ELFNote
     }
 };
 
+static void
+ParseFreeBSDThrMisc(ThreadData *thread_data, DataExtractor &data)
+{
+    lldb::offset_t offset = 0;
+    thread_data->name = data.GetCStr(&offset, 20);
+}
+
 /// 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.
@@ -465,6 +471,12 @@ ProcessElfCore::ParseThreadContextsFromN
     bool have_prstatus = false;
     bool have_prpsinfo = false;
 
+    ArchSpec arch = GetArchitecture();
+    ELFPrPsInfo prpsinfo;
+    ELFPrStatus prstatus;
+    size_t header_size;
+    size_t len;
+
     // Loop through the NOTE entires in the segment
     while (offset < segment_header->p_filesz)
     {
@@ -475,7 +487,7 @@ ProcessElfCore::ParseThreadContextsFromN
         if ((note.n_type == NT_PRSTATUS && have_prstatus) ||
             (note.n_type == NT_PRPSINFO && have_prpsinfo))
         {
-            assert(thread_data->prstatus.GetByteSize() > 0);
+            assert(thread_data->gpregset.GetByteSize() > 0);
             // Add the new thread to thread list
             m_thread_data.push_back(*thread_data);
             thread_data = new ThreadData();
@@ -495,14 +507,24 @@ ProcessElfCore::ParseThreadContextsFromN
             {
                 case NT_FREEBSD_PRSTATUS:
                     have_prstatus = true;
-                    thread_data->prstatus = note_data;
+                    prstatus.Parse(note_data, arch);
+                    thread_data->signo = prstatus.pr_cursig;
+                    header_size = ELFPrStatus::GetSize(arch);
+                    len = note_data.GetByteSize() - header_size;
+                    thread_data->gpregset = DataExtractor(note_data, header_size, len);
                     break;
                 case NT_FREEBSD_FPREGSET:
                     thread_data->fpregset = note_data;
                     break;
                 case NT_FREEBSD_PRPSINFO:
                     have_prpsinfo = true;
-                    thread_data->prpsinfo = note_data;
+                    break;
+                case NT_FREEBSD_THRMISC:
+                    ParseFreeBSDThrMisc(thread_data, note_data);
+                    break;
+                case NT_FREEBSD_PROCSTAT_AUXV:
+                    // FIXME: FreeBSD sticks an int at the beginning of the note
+                    m_auxv = DataExtractor(segment_data, note_start + 4, note_size - 4);
                     break;
                 default:
                     break;
@@ -514,14 +536,19 @@ ProcessElfCore::ParseThreadContextsFromN
             {
                 case NT_PRSTATUS:
                     have_prstatus = true;
-                    thread_data->prstatus = note_data;
+                    prstatus.Parse(note_data, arch);
+                    thread_data->signo = prstatus.pr_cursig;
+                    header_size = ELFPrStatus::GetSize(arch);
+                    len = note_data.GetByteSize() - header_size;
+                    thread_data->gpregset = DataExtractor(note_data, header_size, len);
                     break;
                 case NT_FPREGSET:
                     thread_data->fpregset = note_data;
                     break;
                 case NT_PRPSINFO:
                     have_prpsinfo = true;
-                    thread_data->prpsinfo = note_data;
+                    prpsinfo.Parse(note_data, arch);
+                    thread_data->name = prpsinfo.pr_fname;
                     break;
                 case NT_AUXV:
                     m_auxv = DataExtractor(note_data);
@@ -534,7 +561,7 @@ ProcessElfCore::ParseThreadContextsFromN
         offset += note_size;
     }
     // Add last entry in the note section
-    if (thread_data && thread_data->prstatus.GetByteSize() > 0)
+    if (thread_data && thread_data->gpregset.GetByteSize() > 0)
     {
         m_thread_data.push_back(*thread_data);
     }

Modified: lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h?rev=186975&r1=186974&r2=186975&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h Tue Jul 23 13:30:49 2013
@@ -28,6 +28,8 @@
 
 #include "Plugins/ObjectFile/ELF/ELFHeader.h"
 
+struct ThreadData;
+
 class ProcessElfCore : public lldb_private::Process
 {
 public:
@@ -135,15 +137,6 @@ private:
     typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
     typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1> VMRangeToFileOffset;
 
-    // In ELF core file thread context is described mainly by 3 Note entries
-    // The following structure holds pointers to those note entries.
-    struct ThreadData
-    {
-        lldb_private::DataExtractor prstatus;
-        lldb_private::DataExtractor fpregset;
-        lldb_private::DataExtractor prpsinfo;
-    };
-
     lldb::ModuleSP m_core_module_sp;
     lldb_private::FileSpec m_core_file;
     std::string  m_dyld_plugin_name;

Modified: lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp?rev=186975&r1=186974&r2=186975&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.cpp Tue Jul 23 13:30:49 2013
@@ -23,24 +23,17 @@ using namespace lldb;
 using namespace lldb_private;
 
 //----------------------------------------------------------------------
-// Construct a Thread object with given PRSTATUS, PRPSINFO and FPREGSET
+// Construct a Thread object with given data
 //----------------------------------------------------------------------
-ThreadElfCore::ThreadElfCore (Process &process, tid_t tid, DataExtractor prstatus,
-                              DataExtractor prpsinfo, DataExtractor fpregset) :
+ThreadElfCore::ThreadElfCore (Process &process, tid_t tid,
+                              const ThreadData &td) :
     Thread(process, tid),
-    m_thread_reg_ctx_sp ()
+    m_thread_name(td.name),
+    m_thread_reg_ctx_sp (),
+    m_signo(td.signo),
+    m_gpregset_data(td.gpregset),
+    m_fpregset_data(td.fpregset)
 {
-    ProcessElfCore *pr = static_cast<ProcessElfCore *>(GetProcess().get());
-    ArchSpec arch = pr->GetArchitecture();
-
-    /* Parse the datastructures from the file */
-    m_prstatus.Parse(prstatus, arch);
-    m_prpsinfo.Parse(prpsinfo, arch);
-
-    m_prstatus_data = prstatus;
-    m_fpregset_data = fpregset;
-
-    m_thread_name = std::string(m_prpsinfo.pr_fname);
 }
 
 ThreadElfCore::~ThreadElfCore ()
@@ -89,19 +82,16 @@ ThreadElfCore::CreateRegisterContextForF
 
         ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
         ArchSpec arch = process->GetArchitecture();
-        size_t header_size = ELFPrStatus::GetSize(arch);
-        size_t len = m_prstatus_data.GetByteSize() - header_size;
-        DataExtractor gpregset_data = DataExtractor(m_prstatus_data, header_size, len);
         switch (arch.GetMachine())
         {
             case llvm::Triple::x86_64:
                 switch (arch.GetTriple().getOS())
                 {
                     case llvm::Triple::FreeBSD:
-                        m_thread_reg_ctx_sp.reset(new RegisterContextCoreFreeBSD_x86_64 (*this, gpregset_data, m_fpregset_data));
+                        m_thread_reg_ctx_sp.reset(new RegisterContextCoreFreeBSD_x86_64 (*this, m_gpregset_data, m_fpregset_data));
                         break;
                     case llvm::Triple::Linux:
-                        m_thread_reg_ctx_sp.reset(new RegisterContextCoreLinux_x86_64 (*this, gpregset_data, m_fpregset_data));
+                        m_thread_reg_ctx_sp.reset(new RegisterContextCoreLinux_x86_64 (*this, m_gpregset_data, m_fpregset_data));
                         break;
                     default:
                         if (log)
@@ -132,7 +122,7 @@ ThreadElfCore::CalculateStopInfo ()
     ProcessSP process_sp (GetProcess());
     if (process_sp)
     {
-        SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_prstatus.pr_cursig));
+        SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo));
         return true;
     }
     return false;

Modified: lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.h?rev=186975&r1=186974&r2=186975&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.h (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/ThreadElfCore.h Tue Jul 23 13:30:49 2013
@@ -125,13 +125,19 @@ struct ELFPrPsInfo
 
 };
 
+struct ThreadData
+{
+    lldb_private::DataExtractor gpregset;
+    lldb_private::DataExtractor fpregset;
+    int signo;
+    std::string name;
+};
+
 class ThreadElfCore : public lldb_private::Thread
 {
 public:
     ThreadElfCore (lldb_private::Process &process, lldb::tid_t tid,
-                   lldb_private::DataExtractor prstatus,
-                   lldb_private::DataExtractor prpsinfo,
-                   lldb_private::DataExtractor fpregset);
+                   const ThreadData &td);
 
     virtual
     ~ThreadElfCore ();
@@ -178,9 +184,9 @@ protected:
     std::string m_thread_name;
     lldb::RegisterContextSP m_thread_reg_ctx_sp;
 
-    ELFPrStatus m_prstatus;
-    ELFPrPsInfo m_prpsinfo;
-    lldb_private::DataExtractor m_prstatus_data;
+    int m_signo;
+
+    lldb_private::DataExtractor m_gpregset_data;
     lldb_private::DataExtractor m_fpregset_data;
 
     virtual bool CalculateStopInfo();





More information about the lldb-commits mailing list