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