1 //===-- ThreadElfCore.cpp --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
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"
47 using namespace lldb_private;
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) {}
56 ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
58 void ThreadElfCore::RefreshStateAfterStop() {
59 GetRegisterContext()->InvalidateIfNeeded(false);
62 RegisterContextSP ThreadElfCore::GetRegisterContext() {
63 if (!m_reg_context_sp) {
64 m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
66 return m_reg_context_sp;
70 ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
71 RegisterContextSP reg_ctx_sp;
72 uint32_t concrete_frame_idx = 0;
73 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
76 concrete_frame_idx = frame->GetConcreteFrameIndex();
78 if (concrete_frame_idx == 0) {
79 if (m_thread_reg_ctx_sp)
80 return m_thread_reg_ctx_sp;
82 ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
83 ArchSpec arch = process->GetArchitecture();
84 RegisterInfoInterface *reg_interface = nullptr;
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);
92 case llvm::Triple::arm:
93 reg_interface = new RegisterInfoPOSIX_arm(arch);
95 case llvm::Triple::ppc:
96 reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
98 case llvm::Triple::ppc64:
99 reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
101 case llvm::Triple::mips64:
102 reg_interface = new RegisterContextFreeBSD_mips64(arch);
104 case llvm::Triple::x86:
105 reg_interface = new RegisterContextFreeBSD_i386(arch);
107 case llvm::Triple::x86_64:
108 reg_interface = new RegisterContextFreeBSD_x86_64(arch);
116 case llvm::Triple::NetBSD: {
117 switch (arch.GetMachine()) {
118 case llvm::Triple::x86_64:
119 reg_interface = new RegisterContextNetBSD_x86_64(arch);
127 case llvm::Triple::Linux: {
128 switch (arch.GetMachine()) {
129 case llvm::Triple::arm:
130 reg_interface = new RegisterInfoPOSIX_arm(arch);
132 case llvm::Triple::aarch64:
133 reg_interface = new RegisterInfoPOSIX_arm64(arch);
135 case llvm::Triple::mipsel:
136 case llvm::Triple::mips:
137 reg_interface = new RegisterContextLinux_mips(arch);
139 case llvm::Triple::mips64el:
140 case llvm::Triple::mips64:
141 reg_interface = new RegisterContextLinux_mips64(arch);
143 case llvm::Triple::ppc64le:
144 reg_interface = new RegisterInfoPOSIX_ppc64le(arch);
146 #ifdef LLDB_ENABLE_ALL
147 case llvm::Triple::systemz:
148 reg_interface = new RegisterContextLinux_s390x(arch);
150 #endif // LLDB_ENABLE_ALL
151 case llvm::Triple::x86:
152 reg_interface = new RegisterContextLinux_i386(arch);
154 case llvm::Triple::x86_64:
155 reg_interface = new RegisterContextLinux_x86_64(arch);
163 case llvm::Triple::OpenBSD: {
164 switch (arch.GetMachine()) {
165 case llvm::Triple::aarch64:
166 reg_interface = new RegisterInfoPOSIX_arm64(arch);
168 case llvm::Triple::arm:
169 reg_interface = new RegisterInfoPOSIX_arm(arch);
171 case llvm::Triple::x86:
172 reg_interface = new RegisterContextOpenBSD_i386(arch);
174 case llvm::Triple::x86_64:
175 reg_interface = new RegisterContextOpenBSD_x86_64(arch);
187 if (!reg_interface) {
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");
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));
199 case llvm::Triple::arm:
200 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm(
201 *this, reg_interface, m_gpregset_data, m_notes));
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));
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));
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));
218 case llvm::Triple::ppc64le:
219 m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_ppc64le(
220 *this, reg_interface, m_gpregset_data, m_notes));
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));
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));
237 reg_ctx_sp = m_thread_reg_ctx_sp;
239 Unwind *unwinder = GetUnwinder();
240 if (unwinder != nullptr)
241 reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
246 bool ThreadElfCore::CalculateStopInfo() {
247 ProcessSP process_sp(GetProcess());
249 SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo));
255 //----------------------------------------------------------------
256 // Parse PRSTATUS from NOTE entry
257 //----------------------------------------------------------------
258 ELFLinuxPrStatus::ELFLinuxPrStatus() {
259 memset(this, 0, sizeof(ELFLinuxPrStatus));
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;
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;
273 return mips_linux_pr_status_size_n32;
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:
288 Status ELFLinuxPrStatus::Parse(const DataExtractor &data,
289 const ArchSpec &arch) {
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());
298 // Read field by field to correctly account for endianess of both the core
299 // dump and the platform running lldb.
301 si_signo = data.GetU32(&offset);
302 si_code = data.GetU32(&offset);
303 si_errno = data.GetU32(&offset);
305 pr_cursig = data.GetU16(&offset);
308 pr_sigpend = data.GetPointer(&offset);
309 pr_sighold = data.GetPointer(&offset);
311 pr_pid = data.GetU32(&offset);
312 pr_ppid = data.GetU32(&offset);
313 pr_pgrp = data.GetU32(&offset);
314 pr_sid = data.GetU32(&offset);
316 pr_utime.tv_sec = data.GetPointer(&offset);
317 pr_utime.tv_usec = data.GetPointer(&offset);
319 pr_stime.tv_sec = data.GetPointer(&offset);
320 pr_stime.tv_usec = data.GetPointer(&offset);
322 pr_cutime.tv_sec = data.GetPointer(&offset);
323 pr_cutime.tv_usec = data.GetPointer(&offset);
325 pr_cstime.tv_sec = data.GetPointer(&offset);
326 pr_cstime.tv_usec = data.GetPointer(&offset);
331 //----------------------------------------------------------------
332 // Parse PRPSINFO from NOTE entry
333 //----------------------------------------------------------------
334 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
335 memset(this, 0, sizeof(ELFLinuxPrPsInfo));
338 size_t ELFLinuxPrPsInfo::GetSize(const lldb_private::ArchSpec &arch) {
339 constexpr size_t mips_linux_pr_psinfo_size_o32_n32 = 128;
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;
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:
359 Status ELFLinuxPrPsInfo::Parse(const DataExtractor &data,
360 const ArchSpec &arch) {
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());
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.
381 pr_flag = data.GetPointer(&offset);
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);
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);
393 pr_pid = data.GetU32(&offset);
394 pr_ppid = data.GetU32(&offset);
395 pr_pgrp = data.GetU32(&offset);
396 pr_sid = data.GetU32(&offset);
399 data.ExtractBytes(offset, size, byteorder, pr_fname);
403 data.ExtractBytes(offset, size, byteorder, pr_psargs);
409 //----------------------------------------------------------------
410 // Parse SIGINFO from NOTE entry
411 //----------------------------------------------------------------
412 ELFLinuxSigInfo::ELFLinuxSigInfo() { memset(this, 0, sizeof(ELFLinuxSigInfo)); }
414 size_t ELFLinuxSigInfo::GetSize(const lldb_private::ArchSpec &arch) {
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:
429 Status ELFLinuxSigInfo::Parse(const DataExtractor &data, const ArchSpec &arch) {
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());
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
441 si_signo = data.GetU32(&offset);
442 si_code = data.GetU32(&offset);
443 si_errno = data.GetU32(&offset);