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_s390x.h"
22 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
23 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
24 #include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h"
25 #include "Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h"
26 #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
27 #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
28 #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
29 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
30 #include "RegisterContextPOSIXCore_arm.h"
31 #include "RegisterContextPOSIXCore_arm64.h"
32 #include "RegisterContextPOSIXCore_mips64.h"
33 #include "RegisterContextPOSIXCore_powerpc.h"
34 #include "RegisterContextPOSIXCore_s390x.h"
35 #include "RegisterContextPOSIXCore_x86_64.h"
36 
37 using namespace lldb;
38 using namespace lldb_private;
39 
40 //----------------------------------------------------------------------
41 // Construct a Thread object with given data
42 //----------------------------------------------------------------------
43 ThreadElfCore::ThreadElfCore (Process &process, const ThreadData &td) :
44     Thread(process, td.tid),
45     m_thread_name(td.name),
46     m_thread_reg_ctx_sp (),
47     m_signo(td.signo),
48     m_gpregset_data(td.gpregset),
49     m_fpregset_data(td.fpregset),
50     m_vregset_data(td.vregset)
51 {
52 }
53 
54 ThreadElfCore::~ThreadElfCore ()
55 {
56     DestroyThread();
57 }
58 
59 void
60 ThreadElfCore::RefreshStateAfterStop()
61 {
62     GetRegisterContext()->InvalidateIfNeeded (false);
63 }
64 
65 void
66 ThreadElfCore::ClearStackFrames ()
67 {
68     Unwind *unwinder = GetUnwinder ();
69     if (unwinder)
70         unwinder->Clear();
71     Thread::ClearStackFrames();
72 }
73 
74 RegisterContextSP
75 ThreadElfCore::GetRegisterContext ()
76 {
77     if (m_reg_context_sp.get() == NULL) {
78         m_reg_context_sp = CreateRegisterContextForFrame (NULL);
79     }
80     return m_reg_context_sp;
81 }
82 
83 RegisterContextSP
84 ThreadElfCore::CreateRegisterContextForFrame (StackFrame *frame)
85 {
86     RegisterContextSP reg_ctx_sp;
87     uint32_t concrete_frame_idx = 0;
88     Log *log (GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
89 
90     if (frame)
91         concrete_frame_idx = frame->GetConcreteFrameIndex ();
92 
93     if (concrete_frame_idx == 0)
94     {
95         if (m_thread_reg_ctx_sp)
96             return m_thread_reg_ctx_sp;
97 
98         ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
99         ArchSpec arch = process->GetArchitecture();
100         RegisterInfoInterface *reg_interface = NULL;
101 
102         switch (arch.GetTriple().getOS())
103         {
104             case llvm::Triple::FreeBSD:
105             {
106                 switch (arch.GetMachine())
107                 {
108                     case llvm::Triple::aarch64:
109                         reg_interface = new RegisterContextFreeBSD_arm64(arch);
110                         break;
111                     case llvm::Triple::arm:
112                         reg_interface = new RegisterContextFreeBSD_arm(arch);
113                         break;
114                     case llvm::Triple::ppc:
115                         reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
116                         break;
117                     case llvm::Triple::ppc64:
118                         reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
119                         break;
120                     case llvm::Triple::mips64:
121                         reg_interface = new RegisterContextFreeBSD_mips64(arch);
122                         break;
123                     case llvm::Triple::x86:
124                         reg_interface = new RegisterContextFreeBSD_i386(arch);
125                         break;
126                     case llvm::Triple::x86_64:
127                         reg_interface = new RegisterContextFreeBSD_x86_64(arch);
128                         break;
129                     default:
130                         break;
131                 }
132                 break;
133             }
134 
135             case llvm::Triple::Linux:
136             {
137                 switch (arch.GetMachine())
138                 {
139                     case llvm::Triple::arm:
140                         reg_interface = new RegisterContextLinux_arm(arch);
141                         break;
142                     case llvm::Triple::aarch64:
143                         reg_interface = new RegisterContextLinux_arm64(arch);
144                         break;
145                     case llvm::Triple::systemz:
146                         reg_interface = new RegisterContextLinux_s390x(arch);
147                         break;
148                     case llvm::Triple::x86:
149                         reg_interface = new RegisterContextLinux_i386(arch);
150                         break;
151                     case llvm::Triple::x86_64:
152                         reg_interface = new RegisterContextLinux_x86_64(arch);
153                         break;
154                     default:
155                         break;
156                 }
157                 break;
158             }
159 
160             default:
161                 break;
162         }
163 
164         if (!reg_interface) {
165             if (log)
166                 log->Printf ("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
167                              __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
168                 assert (false && "Architecture or OS not supported");
169         }
170 
171         switch (arch.GetMachine())
172         {
173             case llvm::Triple::aarch64:
174                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
175                 break;
176             case llvm::Triple::arm:
177                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm (*this, reg_interface, m_gpregset_data, m_fpregset_data));
178                 break;
179             case llvm::Triple::mips64:
180                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
181                 break;
182             case llvm::Triple::ppc:
183             case llvm::Triple::ppc64:
184                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc (*this, reg_interface, m_gpregset_data, m_fpregset_data, m_vregset_data));
185                 break;
186             case llvm::Triple::systemz:
187                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x (*this, reg_interface, m_gpregset_data, m_fpregset_data));
188                 break;
189             case llvm::Triple::x86:
190             case llvm::Triple::x86_64:
191                 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64 (*this, reg_interface, m_gpregset_data, m_fpregset_data));
192                 break;
193             default:
194                 break;
195         }
196 
197         reg_ctx_sp = m_thread_reg_ctx_sp;
198     }
199     else if (m_unwinder_ap.get())
200     {
201         reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
202     }
203     return reg_ctx_sp;
204 }
205 
206 bool
207 ThreadElfCore::CalculateStopInfo ()
208 {
209     ProcessSP process_sp (GetProcess());
210     if (process_sp)
211     {
212         SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, m_signo));
213         return true;
214     }
215     return false;
216 }
217 
218 //----------------------------------------------------------------
219 // Parse PRSTATUS from NOTE entry
220 //----------------------------------------------------------------
221 ELFLinuxPrStatus::ELFLinuxPrStatus()
222 {
223     memset(this, 0, sizeof(ELFLinuxPrStatus));
224 }
225 
226 Error
227 ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch)
228 {
229     Error error;
230     ByteOrder byteorder = data.GetByteOrder();
231     if (GetSize(arch) > data.GetByteSize())
232     {
233         error.SetErrorStringWithFormat("NT_PRSTATUS size should be %lu, but the remaining bytes are: %" PRIu64,
234                                        GetSize(arch), data.GetByteSize());
235         return error;
236     }
237 
238     switch(arch.GetCore())
239     {
240         case ArchSpec::eCore_s390x_generic:
241         case ArchSpec::eCore_x86_64_x86_64:
242             data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this);
243             break;
244         case ArchSpec::eCore_x86_32_i386:
245         case ArchSpec::eCore_x86_32_i486:
246         {
247             // Parsing from a 32 bit ELF core file, and populating/reusing the structure
248             // properly, because the struct is for the 64 bit version
249             offset_t offset = 0;
250             si_signo = data.GetU32(&offset);
251             si_code = data.GetU32(&offset);
252             si_errno = data.GetU32(&offset);
253 
254             pr_cursig = data.GetU16(&offset);
255             offset += 2; // pad
256 
257             pr_sigpend = data.GetU32(&offset);
258             pr_sighold = data.GetU32(&offset);
259 
260             pr_pid = data.GetU32(&offset);
261             pr_ppid = data.GetU32(&offset);
262             pr_pgrp = data.GetU32(&offset);
263             pr_sid = data.GetU32(&offset);
264 
265             pr_utime.tv_sec = data.GetU32(&offset);
266             pr_utime.tv_usec = data.GetU32(&offset);
267 
268             pr_stime.tv_sec = data.GetU32(&offset);
269             pr_stime.tv_usec = data.GetU32(&offset);
270 
271             pr_cutime.tv_sec = data.GetU32(&offset);
272             pr_cutime.tv_usec = data.GetU32(&offset);
273 
274             pr_cstime.tv_sec = data.GetU32(&offset);
275             pr_cstime.tv_usec = data.GetU32(&offset);
276 
277             break;
278         }
279         default:
280             error.SetErrorStringWithFormat("ELFLinuxPrStatus::%s Unknown architecture", __FUNCTION__);
281             break;
282     }
283 
284     return error;
285 }
286 
287 //----------------------------------------------------------------
288 // Parse PRPSINFO from NOTE entry
289 //----------------------------------------------------------------
290 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo()
291 {
292     memset(this, 0, sizeof(ELFLinuxPrPsInfo));
293 }
294 
295 Error
296 ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch)
297 {
298     Error error;
299     ByteOrder byteorder = data.GetByteOrder();
300     if (GetSize(arch) > data.GetByteSize())
301     {
302         error.SetErrorStringWithFormat("NT_PRPSINFO size should be %lu, but the remaining bytes are: %" PRIu64,
303                                        GetSize(arch), data.GetByteSize());
304         return error;
305     }
306 
307     switch(arch.GetCore())
308     {
309         case ArchSpec::eCore_s390x_generic:
310         case ArchSpec::eCore_x86_64_x86_64:
311             data.ExtractBytes(0, sizeof(ELFLinuxPrPsInfo), byteorder, this);
312             break;
313         case ArchSpec::eCore_x86_32_i386:
314         case ArchSpec::eCore_x86_32_i486:
315         {
316             // Parsing from a 32 bit ELF core file, and populating/reusing the structure
317             // properly, because the struct is for the 64 bit version
318             size_t size = 0;
319             offset_t offset = 0;
320 
321             pr_state = data.GetU8(&offset);
322             pr_sname = data.GetU8(&offset);
323             pr_zomb = data.GetU8(&offset);
324             pr_nice = data.GetU8(&offset);
325 
326             pr_flag = data.GetU32(&offset);
327             pr_uid = data.GetU16(&offset);
328             pr_gid = data.GetU16(&offset);
329 
330             pr_pid = data.GetU32(&offset);
331             pr_ppid = data.GetU32(&offset);
332             pr_pgrp = data.GetU32(&offset);
333             pr_sid = data.GetU32(&offset);
334 
335             size = 16;
336             data.ExtractBytes(offset, size, byteorder, pr_fname);
337             offset += size;
338 
339             size = 80;
340             data.ExtractBytes(offset, size, byteorder, pr_psargs);
341             offset += size;
342 
343             break;
344         }
345         default:
346             error.SetErrorStringWithFormat("ELFLinuxPrPsInfo::%s Unknown architecture", __FUNCTION__);
347             break;
348     }
349 
350     return error;
351 }
352 
353