1 //===-- ThreadElfCore.h -----------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H
10 #define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H
12 #include "Plugins/Process/elf-core/RegisterUtilities.h"
13 #include "lldb/Target/Thread.h"
14 #include "lldb/Utility/DataExtractor.h"
15 #include "llvm/ADT/DenseMap.h"
19 struct compat_timeval
{
20 alignas(8) uint64_t tv_sec
;
21 alignas(8) uint64_t tv_usec
;
24 namespace lldb_private
{
25 class ProcessInstanceInfo
;
28 // PRSTATUS structure's size differs based on architecture.
29 // This is the layout in the x86-64 arch.
30 // In the i386 case we parse it manually and fill it again
31 // in the same structure
32 // The gp registers are also a part of this struct, but they are handled
41 struct ELFLinuxPrStatus
{
48 alignas(8) uint64_t pr_sigpend
;
49 alignas(8) uint64_t pr_sighold
;
56 compat_timeval pr_utime
;
57 compat_timeval pr_stime
;
58 compat_timeval pr_cutime
;
59 compat_timeval pr_cstime
;
63 lldb_private::Status
Parse(const lldb_private::DataExtractor
&data
,
64 const lldb_private::ArchSpec
&arch
);
66 static std::optional
<ELFLinuxPrStatus
>
67 Populate(const lldb::ThreadSP
&thread_sp
);
69 // Return the bytesize of the structure
70 // 64 bit - just sizeof
71 // 32 bit - hardcoded because we are reusing the struct, but some of the
72 // members are smaller -
73 // so the layout is not the same
74 static size_t GetSize(const lldb_private::ArchSpec
&arch
);
77 static_assert(sizeof(ELFLinuxPrStatus
) == 112,
78 "sizeof ELFLinuxPrStatus is not correct!");
80 struct ELFLinuxSigInfo
{
82 int32_t si_signo
; // Order matters for the first 3.
85 // Copied from siginfo_t so we don't have to include signal.h on non 'Nix
86 // builds. Slight modifications to ensure no 32b vs 64b differences.
88 lldb::addr_t si_addr
; /* faulting insn/memory ref. */
89 int16_t si_addr_lsb
; /* Valid LSB of the reported address. */
91 /* used when si_code=SEGV_BNDERR */
96 /* used when si_code=SEGV_PKUERR */
101 enum SigInfoNoteType
: uint8_t { eUnspecified
, eNT_SIGINFO
};
102 SigInfoNoteType note_type
;
106 lldb_private::Status
Parse(const lldb_private::DataExtractor
&data
,
107 const lldb_private::ArchSpec
&arch
,
108 const lldb_private::UnixSignals
&unix_signals
);
111 GetDescription(const lldb_private::UnixSignals
&unix_signals
) const;
113 // Return the bytesize of the structure
114 // 64 bit - just sizeof
115 // 32 bit - hardcoded because we are reusing the struct, but some of the
116 // members are smaller -
117 // so the layout is not the same
118 static size_t GetSize(const lldb_private::ArchSpec
&arch
);
121 static_assert(sizeof(ELFLinuxSigInfo
) == 56,
122 "sizeof ELFLinuxSigInfo is not correct!");
124 // PRPSINFO structure's size differs based on architecture.
125 // This is the layout in the x86-64 arch case.
126 // In the i386 case we parse it manually and fill it again
127 // in the same structure
128 struct ELFLinuxPrPsInfo
{
133 alignas(8) uint64_t pr_flag
;
145 lldb_private::Status
Parse(const lldb_private::DataExtractor
&data
,
146 const lldb_private::ArchSpec
&arch
);
148 static std::optional
<ELFLinuxPrPsInfo
>
149 Populate(const lldb::ProcessSP
&process_sp
);
151 static std::optional
<ELFLinuxPrPsInfo
>
152 Populate(const lldb_private::ProcessInstanceInfo
&info
,
153 lldb::StateType state
);
155 // Return the bytesize of the structure
156 // 64 bit - just sizeof
157 // 32 bit - hardcoded because we are reusing the struct, but some of the
158 // members are smaller -
159 // so the layout is not the same
160 static size_t GetSize(const lldb_private::ArchSpec
&arch
);
163 static_assert(sizeof(ELFLinuxPrPsInfo
) == 136,
164 "sizeof ELFLinuxPrPsInfo is not correct!");
167 lldb_private::DataExtractor gpregset
;
168 std::vector
<lldb_private::CoreNote
> notes
;
171 ELFLinuxSigInfo siginfo
;
172 int prstatus_sig
= 0;
175 class ThreadElfCore
: public lldb_private::Thread
{
177 ThreadElfCore(lldb_private::Process
&process
, const ThreadData
&td
);
179 ~ThreadElfCore() override
;
181 void RefreshStateAfterStop() override
;
183 lldb::RegisterContextSP
GetRegisterContext() override
;
185 lldb::RegisterContextSP
186 CreateRegisterContextForFrame(lldb_private::StackFrame
*frame
) override
;
188 static bool ThreadIDIsValid(lldb::tid_t thread
) { return thread
!= 0; }
190 const char *GetName() override
{
191 if (m_thread_name
.empty())
193 return m_thread_name
.c_str();
196 void SetName(const char *name
) override
{
198 m_thread_name
.assign(name
);
200 m_thread_name
.clear();
203 void CreateStopFromSigInfo(const ELFLinuxSigInfo
&siginfo
,
204 const lldb_private::UnixSignals
&unix_signals
);
208 std::string m_thread_name
;
209 lldb::RegisterContextSP m_thread_reg_ctx_sp
;
211 lldb_private::DataExtractor m_gpregset_data
;
212 std::vector
<lldb_private::CoreNote
> m_notes
;
213 ELFLinuxSigInfo m_siginfo
;
215 bool CalculateStopInfo() override
;
218 #endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_THREADELFCORE_H