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