Home | History | Annotate | Download | only in elf-core
      1 //===-- ThreadElfCore.cpp --------------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "lldb/Core/DataExtractor.h"
     11 #include "lldb/Target/RegisterContext.h"
     12 #include "lldb/Target/StopInfo.h"
     13 #include "lldb/Target/Target.h"
     14 #include "lldb/Target/Unwind.h"
     15 #include "ProcessPOSIXLog.h"
     16 
     17 #include "ThreadElfCore.h"
     18 #include "ProcessElfCore.h"
     19 #include "RegisterContextCoreFreeBSD_x86_64.h"
     20 #include "RegisterContextCoreLinux_x86_64.h"
     21 
     22 using namespace lldb;
     23 using namespace lldb_private;
     24 
     25 //----------------------------------------------------------------------
     26 // Construct a Thread object with given data
     27 //----------------------------------------------------------------------
     28 ThreadElfCore::ThreadElfCore (Process &process, tid_t tid,
     29                               const ThreadData &td) :
     30     Thread(process, tid),
     31     m_thread_name(td.name),
     32     m_thread_reg_ctx_sp (),
     33     m_signo(td.signo),
     34     m_gpregset_data(td.gpregset),
     35     m_fpregset_data(td.fpregset)
     36 {
     37 }
     38 
     39 ThreadElfCore::~ThreadElfCore ()
     40 {
     41     DestroyThread();
     42 }
     43 
     44 void
     45 ThreadElfCore::RefreshStateAfterStop()
     46 {
     47     GetRegisterContext()->InvalidateIfNeeded (false);
     48 }
     49 
     50 void
     51 ThreadElfCore::ClearStackFrames ()
     52 {
     53     Unwind *unwinder = GetUnwinder ();
     54     if (unwinder)
     55         unwinder->Clear();
     56     Thread::ClearStackFrames();
     57 }
     58 
     59 RegisterContextSP
     60 ThreadElfCore::GetRegisterContext ()
     61 {
     62     if (m_reg_context_sp.get() == NULL) {
     63         m_reg_context_sp = CreateRegisterContextForFrame (NULL);
     64     }
     65     return m_reg_context_sp;
     66 }
     67 
     68 RegisterContextSP
     69 ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
     70 {
     71     RegisterContextSP reg_ctx_sp;
     72     uint32_t concrete_frame_idx = 0;
     73     Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
     74 
     75     if (frame)
     76         concrete_frame_idx = frame->GetConcreteFrameIndex ();
     77 
     78     if (concrete_frame_idx == 0)
     79     {
     80         if (m_thread_reg_ctx_sp)
     81             return m_thread_reg_ctx_sp;
     82 
     83         ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
     84         ArchSpec arch = process->GetArchitecture();
     85         switch (arch.GetMachine())
     86         {
     87             case llvm::Triple::x86_64:
     88                 switch (arch.GetTriple().getOS())
     89                 {
     90                     case llvm::Triple::FreeBSD:
     91                         m_thread_reg_ctx_sp.reset(new RegisterContextCoreFreeBSD_x86_64 (*this, m_gpregset_data, m_fpregset_data));
     92                         break;
     93                     case llvm::Triple::Linux:
     94                         m_thread_reg_ctx_sp.reset(new RegisterContextCoreLinux_x86_64 (*this, m_gpregset_data, m_fpregset_data));
     95                         break;
     96                     default:
     97                         if (log)
     98                             log->Printf ("elf-core::%s:: OS(%d) not supported",
     99                                          __FUNCTION__, arch.GetTriple().getOS());
    100                         assert (false && "OS not supported");
    101                         break;
    102                 }
    103                 break;
    104             default:
    105                 if (log)
    106                     log->Printf ("elf-core::%s:: Architecture(%d) not supported",
    107                                  __FUNCTION__, arch.GetMachine());
    108                 assert (false && "Architecture not supported");
    109         }
    110         reg_ctx_sp = m_thread_reg_ctx_sp;
    111     }
    112     else if (m_unwinder_ap.get())
    113     {
    114         reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
    115     }
    116     return reg_ctx_sp;
    117 }
    118 
    119 bool
    120 ThreadElfCore::CalculateStopInfo ()
    121 {
    122     ProcessSP process_sp (GetProcess());
    123     if (process_sp)
    124     {
    125         SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo));
    126         return true;
    127     }
    128     return false;
    129 }
    130 
    131 //----------------------------------------------------------------
    132 // Parse PRSTATUS from NOTE entry
    133 //----------------------------------------------------------------
    134 ELFLinuxPrStatus::ELFLinuxPrStatus()
    135 {
    136     memset(this, 0, sizeof(ELFLinuxPrStatus));
    137 }
    138 
    139 bool
    140 ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
    141 {
    142     ByteOrder byteorder = data.GetByteOrder();
    143     size_t len;
    144     switch(arch.GetCore())
    145     {
    146         case ArchSpec::eCore_x86_64_x86_64:
    147             len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this);
    148             return len == ELFLINUXPRSTATUS64_SIZE;
    149         default:
    150             return false;
    151     }
    152 }
    153 
    154 //----------------------------------------------------------------
    155 // Parse PRPSINFO from NOTE entry
    156 //----------------------------------------------------------------
    157 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo()
    158 {
    159     memset(this, 0, sizeof(ELFLinuxPrPsInfo));
    160 }
    161 
    162 bool
    163 ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
    164 {
    165     ByteOrder byteorder = data.GetByteOrder();
    166     size_t len;
    167     switch(arch.GetCore())
    168     {
    169         case ArchSpec::eCore_x86_64_x86_64:
    170             len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this);
    171             return len == ELFLINUXPRPSINFO64_SIZE;
    172         default:
    173             return false;
    174     }
    175 }
    176 
    177