ThreadElfCore.cpp revision 288943
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/Core/Log.h"
12#include "lldb/Target/RegisterContext.h"
13#include "lldb/Target/StopInfo.h"
14#include "lldb/Target/Target.h"
15#include "lldb/Target/Unwind.h"
16
17#include "ThreadElfCore.h"
18#include "ProcessElfCore.h"
19#include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
20#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
21#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
22#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h"
23#include "Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h"
24#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
25#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
26#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
27#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
28#include "RegisterContextPOSIXCore_arm.h"
29#include "RegisterContextPOSIXCore_arm64.h"
30#include "RegisterContextPOSIXCore_mips64.h"
31#include "RegisterContextPOSIXCore_powerpc.h"
32#include "RegisterContextPOSIXCore_x86_64.h"
33
34using namespace lldb;
35using namespace lldb_private;
36
37//----------------------------------------------------------------------
38// Construct a Thread object with given data
39//----------------------------------------------------------------------
40ThreadElfCore::ThreadElfCore (Process &process, tid_t tid,
41                              const ThreadData &td) :
42    Thread(process, tid),
43    m_thread_name(td.name),
44    m_thread_reg_ctx_sp (),
45    m_signo(td.signo),
46    m_gpregset_data(td.gpregset),
47    m_fpregset_data(td.fpregset),
48    m_vregset_data(td.vregset)
49{
50}
51
52ThreadElfCore::~ThreadElfCore ()
53{
54    DestroyThread();
55}
56
57void
58ThreadElfCore::RefreshStateAfterStop()
59{
60    GetRegisterContext()->InvalidateIfNeeded (false);
61}
62
63void
64ThreadElfCore::ClearStackFrames ()
65{
66    Unwind *unwinder = GetUnwinder ();
67    if (unwinder)
68        unwinder->Clear();
69    Thread::ClearStackFrames();
70}
71
72RegisterContextSP
73ThreadElfCore::GetRegisterContext ()
74{
75    if (m_reg_context_sp.get() == NULL) {
76        m_reg_context_sp = CreateRegisterContextForFrame (NULL);
77    }
78    return m_reg_context_sp;
79}
80
81RegisterContextSP
82ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
83{
84    RegisterContextSP reg_ctx_sp;
85    uint32_t concrete_frame_idx = 0;
86    Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
87
88    if (frame)
89        concrete_frame_idx = frame->GetConcreteFrameIndex ();
90
91    if (concrete_frame_idx == 0)
92    {
93        if (m_thread_reg_ctx_sp)
94            return m_thread_reg_ctx_sp;
95
96        ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
97        ArchSpec arch = process->GetArchitecture();
98        RegisterInfoInterface *reg_interface = NULL;
99
100        switch (arch.GetTriple().getOS())
101        {
102            case llvm::Triple::FreeBSD:
103            {
104                switch (arch.GetMachine())
105                {
106                    case llvm::Triple::aarch64:
107                        reg_interface = new RegisterContextFreeBSD_arm64(arch);
108                        break;
109                    case llvm::Triple::arm:
110                        reg_interface = new RegisterContextFreeBSD_arm(arch);
111                        break;
112                    case llvm::Triple::ppc:
113                        reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
114                        break;
115                    case llvm::Triple::ppc64:
116                        reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
117                        break;
118                    case llvm::Triple::mips64:
119                        reg_interface = new RegisterContextFreeBSD_mips64(arch);
120                        break;
121                    case llvm::Triple::x86:
122                        reg_interface = new RegisterContextFreeBSD_i386(arch);
123                        break;
124                    case llvm::Triple::x86_64:
125                        reg_interface = new RegisterContextFreeBSD_x86_64(arch);
126                        break;
127                    default:
128                        break;
129                }
130                break;
131            }
132
133            case llvm::Triple::Linux:
134            {
135                switch (arch.GetMachine())
136                {
137                    case llvm::Triple::arm:
138                        reg_interface = new RegisterContextLinux_arm(arch);
139                        break;
140                    case llvm::Triple::aarch64:
141                        reg_interface = new RegisterContextLinux_arm64(arch);
142                        break;
143                    case llvm::Triple::x86_64:
144                        reg_interface = new RegisterContextLinux_x86_64(arch);
145                        break;
146                    default:
147                        break;
148                }
149                break;
150            }
151
152            default:
153                break;
154        }
155
156        if (!reg_interface) {
157            if (log)
158                log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
159                             __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
160                assert (false && "Architecture or OS not supported");
161        }
162
163        switch (arch.GetMachine())
164        {
165            case llvm::Triple::aarch64:
166                m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
167                break;
168            case llvm::Triple::arm:
169                m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm (*this, reg_interface, m_gpregset_data, m_fpregset_data));
170                break;
171            case llvm::Triple::mips64:
172                m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
173                break;
174            case llvm::Triple::ppc:
175            case llvm::Triple::ppc64:
176                m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data));
177                break;
178            case llvm::Triple::x86:
179            case llvm::Triple::x86_64:
180                m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
181                break;
182            default:
183                break;
184        }
185
186        reg_ctx_sp = m_thread_reg_ctx_sp;
187    }
188    else if (m_unwinder_ap.get())
189    {
190        reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
191    }
192    return reg_ctx_sp;
193}
194
195bool
196ThreadElfCore::CalculateStopInfo ()
197{
198    ProcessSP process_sp (GetProcess());
199    if (process_sp)
200    {
201        SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo));
202        return true;
203    }
204    return false;
205}
206
207//----------------------------------------------------------------
208// Parse PRSTATUS from NOTE entry
209//----------------------------------------------------------------
210ELFLinuxPrStatus::ELFLinuxPrStatus()
211{
212    memset(this, 0, sizeof(ELFLinuxPrStatus));
213}
214
215bool
216ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
217{
218    ByteOrder byteorder = data.GetByteOrder();
219    size_t len;
220    switch(arch.GetCore())
221    {
222        case ArchSpec::eCore_x86_64_x86_64:
223            len = data.ExtractBytes(0, ELFLINUXPRSTATUS64_SIZE, byteorder, this);
224            return len == ELFLINUXPRSTATUS64_SIZE;
225        default:
226            return false;
227    }
228}
229
230//----------------------------------------------------------------
231// Parse PRPSINFO from NOTE entry
232//----------------------------------------------------------------
233ELFLinuxPrPsInfo::ELFLinuxPrPsInfo()
234{
235    memset(this, 0, sizeof(ELFLinuxPrPsInfo));
236}
237
238bool
239ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
240{
241    ByteOrder byteorder = data.GetByteOrder();
242    size_t len;
243    switch(arch.GetCore())
244    {
245        case ArchSpec::eCore_x86_64_x86_64:
246            len = data.ExtractBytes(0, ELFLINUXPRPSINFO64_SIZE, byteorder, this);
247            return len == ELFLINUXPRPSINFO64_SIZE;
248        default:
249            return false;
250    }
251}
252
253