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