ThreadElfCore.cpp revision 26345cbada66df8e698111cdf8d1689ccefe8331
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 "RegisterContextCoreLinux_x86_64.h"
20
21using namespace lldb;
22using namespace lldb_private;
23
24//----------------------------------------------------------------------
25// Construct a Thread object with given PRSTATUS, PRPSINFO and FPREGSET
26//----------------------------------------------------------------------
27ThreadElfCore::ThreadElfCore (Process &process, tid_t tid, DataExtractor prstatus,
28                              DataExtractor prpsinfo, DataExtractor fpregset) :
29    Thread(process, tid),
30    m_thread_reg_ctx_sp ()
31{
32    ProcessElfCore *pr = static_cast<ProcessElfCore *>(GetProcess().get());
33    ArchSpec arch = pr->GetArchitecture();
34
35    /* Parse the datastructures from the file */
36    m_prstatus.Parse(prstatus, arch);
37    m_prpsinfo.Parse(prpsinfo, arch);
38
39    m_prstatus_data = prstatus;
40    m_fpregset_data = fpregset;
41
42    m_thread_name = std::string(m_prpsinfo.pr_fname);
43}
44
45ThreadElfCore::~ThreadElfCore ()
46{
47    DestroyThread();
48}
49
50void
51ThreadElfCore::RefreshStateAfterStop()
52{
53    GetRegisterContext()->InvalidateIfNeeded (false);
54}
55
56void
57ThreadElfCore::ClearStackFrames ()
58{
59    Unwind *unwinder = GetUnwinder ();
60    if (unwinder)
61        unwinder->Clear();
62    Thread::ClearStackFrames();
63}
64
65RegisterContextSP
66ThreadElfCore::GetRegisterContext ()
67{
68    if (m_reg_context_sp.get() == NULL) {
69        m_reg_context_sp = CreateRegisterContextForFrame (NULL);
70    }
71    return m_reg_context_sp;
72}
73
74RegisterContextSP
75ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
76{
77    RegisterContextSP reg_ctx_sp;
78    uint32_t concrete_frame_idx = 0;
79    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
80
81    if (frame)
82        concrete_frame_idx = frame->GetConcreteFrameIndex ();
83
84    if (concrete_frame_idx == 0)
85    {
86        if (m_thread_reg_ctx_sp)
87            return m_thread_reg_ctx_sp;
88
89        ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
90        ArchSpec arch = process->GetArchitecture();
91        size_t header_size = ELFPrStatus::GetSize(arch);
92        size_t len = m_prstatus_data.GetByteSize() - header_size;
93        DataExtractor gpregset_data = DataExtractor(m_prstatus_data, header_size, len);
94        switch (arch.GetMachine())
95        {
96            case llvm::Triple::x86_64:
97                m_thread_reg_ctx_sp.reset(new RegisterContextCoreLinux_x86_64 (*this, gpregset_data, m_fpregset_data));
98                break;
99            default:
100                if (log)
101                    log->Printf ("elf-core::%s:: Architecture(%d) not supported",
102                                 __FUNCTION__, arch.GetMachine());
103        }
104        reg_ctx_sp = m_thread_reg_ctx_sp;
105    }
106    else if (m_unwinder_ap.get())
107    {
108        reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
109    }
110    return reg_ctx_sp;
111}
112
113bool
114ThreadElfCore::CalculateStopInfo ()
115{
116    ProcessSP process_sp (GetProcess());
117    if (process_sp)
118    {
119        SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_prstatus.pr_cursig));
120        return true;
121    }
122    return false;
123}
124
125//----------------------------------------------------------------
126// Parse PRSTATUS from NOTE entry
127//----------------------------------------------------------------
128ELFPrStatus::ELFPrStatus()
129{
130    memset(this, 0, sizeof(ELFPrStatus));
131}
132
133bool
134ELFPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
135{
136    ByteOrder byteorder = data.GetByteOrder();
137    size_t len;
138    switch(arch.GetCore())
139    {
140        case ArchSpec::eCore_x86_64_x86_64:
141            len = data.ExtractBytes(0, ELFPRSTATUS64_SIZE, byteorder, this);
142            return len == ELFPRSTATUS64_SIZE;
143        default:
144            return false;
145    }
146}
147
148//----------------------------------------------------------------
149// Parse PRPSINFO from NOTE entry
150//----------------------------------------------------------------
151ELFPrPsInfo::ELFPrPsInfo()
152{
153    memset(this, 0, sizeof(ELFPrPsInfo));
154}
155
156bool
157ELFPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
158{
159    ByteOrder byteorder = data.GetByteOrder();
160    size_t len;
161    switch(arch.GetCore())
162    {
163        case ArchSpec::eCore_x86_64_x86_64:
164            len = data.ExtractBytes(0, ELFPRPSINFO64_SIZE, byteorder, this);
165            return len == ELFPRPSINFO64_SIZE;
166        default:
167            return false;
168    }
169}
170
171