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