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