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 //----------------------------------------------------------------------
ThreadElfCore(Process & process,const ThreadData & td)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
~ThreadElfCore()56 ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
57
RefreshStateAfterStop()58 void ThreadElfCore::RefreshStateAfterStop() {
59 GetRegisterContext()->InvalidateIfNeeded(false);
60 }
61
GetRegisterContext()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
CreateRegisterContextForFrame(StackFrame * frame)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
CalculateStopInfo()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 //----------------------------------------------------------------
ELFLinuxPrStatus()258 ELFLinuxPrStatus::ELFLinuxPrStatus() {
259 memset(this, 0, sizeof(ELFLinuxPrStatus));
260 }
261
GetSize(const lldb_private::ArchSpec & arch)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
Parse(const DataExtractor & data,const ArchSpec & arch)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 //----------------------------------------------------------------
ELFLinuxPrPsInfo()334 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
335 memset(this, 0, sizeof(ELFLinuxPrPsInfo));
336 }
337
GetSize(const lldb_private::ArchSpec & arch)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
Parse(const DataExtractor & data,const ArchSpec & arch)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 //----------------------------------------------------------------
ELFLinuxSigInfo()412 ELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); }
413
GetSize(const lldb_private::ArchSpec & arch)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
Parse(const DataExtractor & data,const ArchSpec & arch)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 }
447