xref: /llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h (revision b9c1b51e45b845debb76d8658edabca70ca56079)
1 //===-- ThreadElfCore.h -----------------------------------------*- 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 #ifndef liblldb_ThreadElfCore_h_
11 #define liblldb_ThreadElfCore_h_
12 
13 // C Includes
14 // C++ Includes
15 #include <string>
16 
17 // Other libraries and framework includes
18 // Project includes
19 #include "lldb/Core/DataExtractor.h"
20 #include "lldb/Target/Thread.h"
21 
22 struct compat_timeval {
23   alignas(8) uint64_t tv_sec;
24   alignas(8) uint64_t tv_usec;
25 };
26 
27 // PRSTATUS structure's size differs based on architecture.
28 // This is the layout in the x86-64 arch.
29 // In the i386 case we parse it manually and fill it again
30 // in the same structure
31 // The gp registers are also a part of this struct, but they are handled
32 // separately
33 
34 #undef si_signo
35 #undef si_code
36 #undef si_errno
37 
38 struct ELFLinuxPrStatus {
39   int32_t si_signo;
40   int32_t si_code;
41   int32_t si_errno;
42 
43   int16_t pr_cursig;
44 
45   alignas(8) uint64_t pr_sigpend;
46   alignas(8) uint64_t pr_sighold;
47 
48   uint32_t pr_pid;
49   uint32_t pr_ppid;
50   uint32_t pr_pgrp;
51   uint32_t pr_sid;
52 
53   compat_timeval pr_utime;
54   compat_timeval pr_stime;
55   compat_timeval pr_cutime;
56   compat_timeval pr_cstime;
57 
58   ELFLinuxPrStatus();
59 
60   lldb_private::Error Parse(lldb_private::DataExtractor &data,
61                             lldb_private::ArchSpec &arch);
62 
63   // Return the bytesize of the structure
64   // 64 bit - just sizeof
65   // 32 bit - hardcoded because we are reusing the struct, but some of the
66   // members are smaller -
67   // so the layout is not the same
68   static size_t GetSize(lldb_private::ArchSpec &arch) {
69     switch (arch.GetCore()) {
70     case lldb_private::ArchSpec::eCore_s390x_generic:
71     case lldb_private::ArchSpec::eCore_x86_64_x86_64:
72       return sizeof(ELFLinuxPrStatus);
73     case lldb_private::ArchSpec::eCore_x86_32_i386:
74     case lldb_private::ArchSpec::eCore_x86_32_i486:
75       return 72;
76     default:
77       return 0;
78     }
79   }
80 };
81 
82 static_assert(sizeof(ELFLinuxPrStatus) == 112,
83               "sizeof ELFLinuxPrStatus is not correct!");
84 
85 // PRPSINFO structure's size differs based on architecture.
86 // This is the layout in the x86-64 arch case.
87 // In the i386 case we parse it manually and fill it again
88 // in the same structure
89 struct ELFLinuxPrPsInfo {
90   char pr_state;
91   char pr_sname;
92   char pr_zomb;
93   char pr_nice;
94   alignas(8) uint64_t pr_flag;
95   uint32_t pr_uid;
96   uint32_t pr_gid;
97   int32_t pr_pid;
98   int32_t pr_ppid;
99   int32_t pr_pgrp;
100   int32_t pr_sid;
101   char pr_fname[16];
102   char pr_psargs[80];
103 
104   ELFLinuxPrPsInfo();
105 
106   lldb_private::Error Parse(lldb_private::DataExtractor &data,
107                             lldb_private::ArchSpec &arch);
108 
109   // Return the bytesize of the structure
110   // 64 bit - just sizeof
111   // 32 bit - hardcoded because we are reusing the struct, but some of the
112   // members are smaller -
113   // so the layout is not the same
114   static size_t GetSize(lldb_private::ArchSpec &arch) {
115     switch (arch.GetCore()) {
116     case lldb_private::ArchSpec::eCore_s390x_generic:
117     case lldb_private::ArchSpec::eCore_x86_64_x86_64:
118       return sizeof(ELFLinuxPrPsInfo);
119     case lldb_private::ArchSpec::eCore_x86_32_i386:
120     case lldb_private::ArchSpec::eCore_x86_32_i486:
121       return 124;
122     default:
123       return 0;
124     }
125   }
126 };
127 
128 static_assert(sizeof(ELFLinuxPrPsInfo) == 136,
129               "sizeof ELFLinuxPrPsInfo is not correct!");
130 
131 struct ThreadData {
132   lldb_private::DataExtractor gpregset;
133   lldb_private::DataExtractor fpregset;
134   lldb_private::DataExtractor vregset;
135   lldb::tid_t tid;
136   int signo;
137   std::string name;
138 };
139 
140 class ThreadElfCore : public lldb_private::Thread {
141 public:
142   ThreadElfCore(lldb_private::Process &process, const ThreadData &td);
143 
144   ~ThreadElfCore() override;
145 
146   void RefreshStateAfterStop() override;
147 
148   lldb::RegisterContextSP GetRegisterContext() override;
149 
150   lldb::RegisterContextSP
151   CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
152 
153   void ClearStackFrames() override;
154 
155   static bool ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
156 
157   const char *GetName() override {
158     if (m_thread_name.empty())
159       return NULL;
160     return m_thread_name.c_str();
161   }
162 
163   void SetName(const char *name) override {
164     if (name && name[0])
165       m_thread_name.assign(name);
166     else
167       m_thread_name.clear();
168   }
169 
170 protected:
171   //------------------------------------------------------------------
172   // Member variables.
173   //------------------------------------------------------------------
174   std::string m_thread_name;
175   lldb::RegisterContextSP m_thread_reg_ctx_sp;
176 
177   int m_signo;
178 
179   lldb_private::DataExtractor m_gpregset_data;
180   lldb_private::DataExtractor m_fpregset_data;
181   lldb_private::DataExtractor m_vregset_data;
182 
183   bool CalculateStopInfo() override;
184 };
185 
186 #endif // liblldb_ThreadElfCore_h_
187