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/Target/RegisterContext.h"
11 #include "lldb/Target/StopInfo.h"
12 #include "lldb/Target/Target.h"
13 #include "lldb/Target/Unwind.h"
14 #include "lldb/Utility/DataExtractor.h"
15 #include "lldb/Utility/Log.h"
16 
17 #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
18 #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
19 #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
20 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
21 #include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
22 #include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
23 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
24 #include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
25 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
26 #include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h"
27 #include "Plugins/Process/Utility/RegisterContextOpenBSD_i386.h"
28 #include "Plugins/Process/Utility/RegisterContextOpenBSD_x86_64.h"
29 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
30 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
31 #include "ProcessElfCore.h"
32 #include "RegisterContextPOSIXCore_arm.h"
33 #include "RegisterContextPOSIXCore_arm64.h"
34 #include "RegisterContextPOSIXCore_mips64.h"
35 #include "RegisterContextPOSIXCore_powerpc.h"
36 #include "RegisterContextPOSIXCore_s390x.h"
37 #include "RegisterContextPOSIXCore_x86_64.h"
38 #include "ThreadElfCore.h"
39 
40 using namespace lldb;
41 using namespace lldb_private;
42 
43 //----------------------------------------------------------------------
44 // Construct a Thread object with given data
45 //----------------------------------------------------------------------
46 ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td)
47     : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
48       m_signo(td.signo), m_gpregset_data(td.gpregset),
49       m_fpregset_data(td.fpregset), m_vregset_data(td.vregset) {}
50 
51 ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
52 
53 void ThreadElfCore::RefreshStateAfterStop() {
54   GetRegisterContext()->InvalidateIfNeeded(false);
55 }
56 
57 void ThreadElfCore::ClearStackFrames() {
58   Unwind *unwinder = GetUnwinder();
59   if (unwinder)
60     unwinder->Clear();
61   Thread::ClearStackFrames();
62 }
63 
64 RegisterContextSP ThreadElfCore::GetRegisterContext() {
65   if (m_reg_context_sp.get() == NULL) {
66     m_reg_context_sp = CreateRegisterContextForFrame(NULL);
67   }
68   return m_reg_context_sp;
69 }
70 
71 RegisterContextSP
72 ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
73   RegisterContextSP reg_ctx_sp;
74   uint32_t concrete_frame_idx = 0;
75   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
76 
77   if (frame)
78     concrete_frame_idx = frame->GetConcreteFrameIndex();
79 
80   if (concrete_frame_idx == 0) {
81     if (m_thread_reg_ctx_sp)
82       return m_thread_reg_ctx_sp;
83 
84     ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
85     ArchSpec arch = process->GetArchitecture();
86     RegisterInfoInterface *reg_interface = NULL;
87 
88     switch (arch.GetTriple().getOS()) {
89     case llvm::Triple::FreeBSD: {
90       switch (arch.GetMachine()) {
91       case llvm::Triple::aarch64:
92         reg_interface = new RegisterInfoPOSIX_arm64(arch);
93         break;
94       case llvm::Triple::arm:
95         reg_interface = new RegisterInfoPOSIX_arm(arch);
96         break;
97       case llvm::Triple::ppc:
98         reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
99         break;
100       case llvm::Triple::ppc64:
101         reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
102         break;
103       case llvm::Triple::mips64:
104         reg_interface = new RegisterContextFreeBSD_mips64(arch);
105         break;
106       case llvm::Triple::x86:
107         reg_interface = new RegisterContextFreeBSD_i386(arch);
108         break;
109       case llvm::Triple::x86_64:
110         reg_interface = new RegisterContextFreeBSD_x86_64(arch);
111         break;
112       default:
113         break;
114       }
115       break;
116     }
117 
118     case llvm::Triple::NetBSD: {
119       switch (arch.GetMachine()) {
120       case llvm::Triple::x86_64:
121         reg_interface = new RegisterContextNetBSD_x86_64(arch);
122         break;
123       default:
124         break;
125       }
126       break;
127     }
128 
129     case llvm::Triple::Linux: {
130       switch (arch.GetMachine()) {
131       case llvm::Triple::arm:
132         reg_interface = new RegisterInfoPOSIX_arm(arch);
133         break;
134       case llvm::Triple::aarch64:
135         reg_interface = new RegisterInfoPOSIX_arm64(arch);
136         break;
137       case llvm::Triple::mipsel:
138       case llvm::Triple::mips:
139         reg_interface = new RegisterContextLinux_mips(arch);
140         break;
141       case llvm::Triple::mips64el:
142       case llvm::Triple::mips64:
143         reg_interface = new RegisterContextLinux_mips64(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     case llvm::Triple::OpenBSD: {
161       switch (arch.GetMachine()) {
162       case llvm::Triple::aarch64:
163         reg_interface = new RegisterInfoPOSIX_arm64(arch);
164         break;
165       case llvm::Triple::arm:
166         reg_interface = new RegisterInfoPOSIX_arm(arch);
167         break;
168       case llvm::Triple::x86:
169         reg_interface = new RegisterContextOpenBSD_i386(arch);
170         break;
171       case llvm::Triple::x86_64:
172         reg_interface = new RegisterContextOpenBSD_x86_64(arch);
173         break;
174       default:
175         break;
176       }
177       break;
178     }
179 
180     default:
181       break;
182     }
183 
184     if (!reg_interface) {
185       if (log)
186         log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
187                     __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
188       assert(false && "Architecture or OS not supported");
189     }
190 
191     switch (arch.GetMachine()) {
192     case llvm::Triple::aarch64:
193       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64(
194           *this, reg_interface, m_gpregset_data, m_fpregset_data));
195       break;
196     case llvm::Triple::arm:
197       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm(
198           *this, reg_interface, m_gpregset_data, m_fpregset_data));
199       break;
200     case llvm::Triple::mipsel:
201     case llvm::Triple::mips:
202       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
203          *this, reg_interface, m_gpregset_data, m_fpregset_data));
204       break;
205     case llvm::Triple::mips64:
206     case llvm::Triple::mips64el:
207       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
208           *this, reg_interface, m_gpregset_data, m_fpregset_data));
209       break;
210     case llvm::Triple::ppc:
211     case llvm::Triple::ppc64:
212       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc(
213           *this, reg_interface, m_gpregset_data, m_fpregset_data,
214           m_vregset_data));
215       break;
216     case llvm::Triple::systemz:
217       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x(
218           *this, reg_interface, m_gpregset_data, m_fpregset_data));
219       break;
220     case llvm::Triple::x86:
221     case llvm::Triple::x86_64:
222       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
223           *this, reg_interface, m_gpregset_data, m_fpregset_data));
224       break;
225     default:
226       break;
227     }
228 
229     reg_ctx_sp = m_thread_reg_ctx_sp;
230   } else if (m_unwinder_ap.get()) {
231     reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
232   }
233   return reg_ctx_sp;
234 }
235 
236 bool ThreadElfCore::CalculateStopInfo() {
237   ProcessSP process_sp(GetProcess());
238   if (process_sp) {
239     SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo));
240     return true;
241   }
242   return false;
243 }
244 
245 //----------------------------------------------------------------
246 // Parse PRSTATUS from NOTE entry
247 //----------------------------------------------------------------
248 ELFLinuxPrStatus::ELFLinuxPrStatus() {
249   memset(this, 0, sizeof(ELFLinuxPrStatus));
250 }
251 
252 size_t ELFLinuxPrStatus::GetSize(lldb_private::ArchSpec &arch) {
253   constexpr size_t mips_linux_pr_status_size_o32 = 96;
254   constexpr size_t mips_linux_pr_status_size_n32 = 72;
255   if (arch.IsMIPS()) {
256     std::string abi = arch.GetTargetABI();
257     assert(!abi.empty() && "ABI is not set");
258     if (!abi.compare("n64"))
259       return sizeof(ELFLinuxPrStatus);
260     else if (!abi.compare("o32"))
261       return mips_linux_pr_status_size_o32;
262     // N32 ABI
263     return mips_linux_pr_status_size_n32;
264   }
265   switch (arch.GetCore()) {
266   case lldb_private::ArchSpec::eCore_s390x_generic:
267   case lldb_private::ArchSpec::eCore_x86_64_x86_64:
268     return sizeof(ELFLinuxPrStatus);
269   case lldb_private::ArchSpec::eCore_x86_32_i386:
270   case lldb_private::ArchSpec::eCore_x86_32_i486:
271     return 72;
272   default:
273     return 0;
274   }
275 }
276 
277 Error ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) {
278   Error error;
279   if (GetSize(arch) > data.GetByteSize()) {
280     error.SetErrorStringWithFormat(
281         "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64,
282         GetSize(arch), data.GetByteSize());
283     return error;
284   }
285 
286   // Read field by field to correctly account for endianess
287   // of both the core dump and the platform running lldb.
288   offset_t offset = 0;
289   si_signo = data.GetU32(&offset);
290   si_code = data.GetU32(&offset);
291   si_errno = data.GetU32(&offset);
292 
293   pr_cursig = data.GetU16(&offset);
294   offset += 2; // pad
295 
296   pr_sigpend = data.GetPointer(&offset);
297   pr_sighold = data.GetPointer(&offset);
298 
299   pr_pid = data.GetU32(&offset);
300   pr_ppid = data.GetU32(&offset);
301   pr_pgrp = data.GetU32(&offset);
302   pr_sid = data.GetU32(&offset);
303 
304   pr_utime.tv_sec = data.GetPointer(&offset);
305   pr_utime.tv_usec = data.GetPointer(&offset);
306 
307   pr_stime.tv_sec = data.GetPointer(&offset);
308   pr_stime.tv_usec = data.GetPointer(&offset);
309 
310   pr_cutime.tv_sec = data.GetPointer(&offset);
311   pr_cutime.tv_usec = data.GetPointer(&offset);
312 
313   pr_cstime.tv_sec = data.GetPointer(&offset);
314   pr_cstime.tv_usec = data.GetPointer(&offset);
315 
316   return error;
317 }
318 
319 //----------------------------------------------------------------
320 // Parse PRPSINFO from NOTE entry
321 //----------------------------------------------------------------
322 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
323   memset(this, 0, sizeof(ELFLinuxPrPsInfo));
324 }
325 
326 size_t ELFLinuxPrPsInfo::GetSize(lldb_private::ArchSpec &arch) {
327   constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128;
328   if (arch.IsMIPS()) {
329     uint8_t address_byte_size = arch.GetAddressByteSize();
330     if (address_byte_size == 8)
331       return sizeof(ELFLinuxPrPsInfo);
332     return mips_linux_pr_psinfo_size_o32_n32;
333   }
334 
335   switch (arch.GetCore()) {
336   case lldb_private::ArchSpec::eCore_s390x_generic:
337   case lldb_private::ArchSpec::eCore_x86_64_x86_64:
338     return sizeof(ELFLinuxPrPsInfo);
339   case lldb_private::ArchSpec::eCore_x86_32_i386:
340   case lldb_private::ArchSpec::eCore_x86_32_i486:
341     return 124;
342   default:
343     return 0;
344   }
345 }
346 
347 Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
348   Error error;
349   ByteOrder byteorder = data.GetByteOrder();
350   if (GetSize(arch) > data.GetByteSize()) {
351     error.SetErrorStringWithFormat(
352         "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64,
353         GetSize(arch), data.GetByteSize());
354     return error;
355   }
356   size_t size = 0;
357   offset_t offset = 0;
358 
359   pr_state = data.GetU8(&offset);
360   pr_sname = data.GetU8(&offset);
361   pr_zomb = data.GetU8(&offset);
362   pr_nice = data.GetU8(&offset);
363   if (data.GetAddressByteSize() == 8) {
364     // Word align the next field on 64 bit.
365     offset += 4;
366   }
367 
368   pr_flag = data.GetPointer(&offset);
369 
370   if (arch.IsMIPS()) {
371     // The pr_uid and pr_gid is always 32 bit irrespective of platforms
372     pr_uid = data.GetU32(&offset);
373     pr_gid = data.GetU32(&offset);
374   } else {
375   // 16 bit on 32 bit platforms, 32 bit on 64 bit platforms
376   pr_uid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
377   pr_gid = data.GetMaxU64(&offset, data.GetAddressByteSize() >> 1);
378   }
379 
380   pr_pid = data.GetU32(&offset);
381   pr_ppid = data.GetU32(&offset);
382   pr_pgrp = data.GetU32(&offset);
383   pr_sid = data.GetU32(&offset);
384 
385   size = 16;
386   data.ExtractBytes(offset, size, byteorder, pr_fname);
387   offset += size;
388 
389   size = 80;
390   data.ExtractBytes(offset, size, byteorder, pr_psargs);
391   offset += size;
392 
393   return error;
394 }
395 
396 //----------------------------------------------------------------
397 // Parse SIGINFO from NOTE entry
398 //----------------------------------------------------------------
399 ELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); }
400 
401 size_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) {
402   if (arch.IsMIPS())
403     return sizeof(ELFLinuxSigInfo);
404   switch (arch.GetCore()) {
405   case lldb_private::ArchSpec::eCore_x86_64_x86_64:
406     return sizeof(ELFLinuxSigInfo);
407   case lldb_private::ArchSpec::eCore_s390x_generic:
408   case lldb_private::ArchSpec::eCore_x86_32_i386:
409   case lldb_private::ArchSpec::eCore_x86_32_i486:
410     return 12;
411   default:
412     return 0;
413   }
414 }
415 
416 Error ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
417   Error error;
418   if (GetSize(arch) > data.GetByteSize()) {
419     error.SetErrorStringWithFormat(
420         "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64,
421         GetSize(arch), data.GetByteSize());
422     return error;
423   }
424 
425   // Parsing from a 32 bit ELF core file, and populating/reusing the structure
426   // properly, because the struct is for the 64 bit version
427   offset_t offset = 0;
428   si_signo = data.GetU32(&offset);
429   si_code = data.GetU32(&offset);
430   si_errno = data.GetU32(&offset);
431 
432   return error;
433 }
434