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/Target/Thread.h"
20 #include "lldb/Core/DataExtractor.h"
21 
22 struct compat_timeval
23 {
24     int64_t tv_sec;
25     int32_t tv_usec;
26 };
27 
28 // PRSTATUS structure's size differs based on architecture.
29 // Currently parsing done only for x86-64 architecture by
30 // simply reading data from the buffer.
31 // The following macros are used to specify the size.
32 // Calculating size using sizeof() wont work because of padding.
33 #define ELFLINUXPRSTATUS64_SIZE (112)
34 #define ELFLINUXPRPSINFO64_SIZE (132)
35 
36 #undef si_signo
37 #undef si_code
38 #undef si_errno
39 
40 struct ELFLinuxPrStatus
41 {
42     int32_t         si_signo;
43     int32_t         si_code;
44     int32_t         si_errno;
45 
46     int16_t         pr_cursig;
47 
48     uint64_t        pr_sigpend;
49     uint64_t        pr_sighold;
50 
51     uint32_t        pr_pid;
52     uint32_t        pr_ppid;
53     uint32_t        pr_pgrp;
54     uint32_t        pr_sid;
55 
56     compat_timeval  pr_utime;
57     compat_timeval  pr_stime;
58     compat_timeval  pr_cutime;
59     compat_timeval  pr_cstime;
60 
61     ELFLinuxPrStatus();
62 
63     bool
64     Parse(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch);
65 
66     static size_t
67     GetSize(lldb_private::ArchSpec &arch)
68     {
69         switch(arch.GetCore())
70         {
71             case lldb_private::ArchSpec::eCore_x86_64_x86_64:
72                 return ELFLINUXPRSTATUS64_SIZE;
73             default:
74                 return 0;
75         }
76     }
77 };
78 
79 struct ELFLinuxPrPsInfo
80 {
81     char        pr_state;
82     char        pr_sname;
83     char        pr_zomb;
84     char        pr_nice;
85     uint64_t    pr_flag;
86     uint32_t    pr_uid;
87     uint32_t    pr_gid;
88     int32_t     pr_pid;
89     int32_t     pr_ppid;
90     int32_t     pr_pgrp;
91     int32_t     pr_sid;
92     char        pr_fname[16];
93     char        pr_psargs[80];
94 
95     ELFLinuxPrPsInfo();
96 
97     bool
98     Parse(lldb_private::DataExtractor &data, lldb_private::ArchSpec &arch);
99 
100     static size_t
101     GetSize(lldb_private::ArchSpec &arch)
102     {
103         switch(arch.GetCore())
104         {
105             case lldb_private::ArchSpec::eCore_x86_64_x86_64:
106                 return ELFLINUXPRPSINFO64_SIZE;
107             default:
108                 return 0;
109         }
110     }
111 };
112 
113 struct ThreadData
114 {
115     lldb_private::DataExtractor gpregset;
116     lldb_private::DataExtractor fpregset;
117     lldb_private::DataExtractor vregset;
118     lldb::tid_t tid;
119     int signo;
120     std::string name;
121 };
122 
123 class ThreadElfCore : public lldb_private::Thread
124 {
125 public:
126     ThreadElfCore (lldb_private::Process &process, const ThreadData &td);
127 
128     ~ThreadElfCore() override;
129 
130     void
131     RefreshStateAfterStop() override;
132 
133     lldb::RegisterContextSP
134     GetRegisterContext() override;
135 
136     lldb::RegisterContextSP
137     CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
138 
139     void
140     ClearStackFrames() override;
141 
142     static bool
143     ThreadIDIsValid (lldb::tid_t thread)
144     {
145         return thread != 0;
146     }
147 
148     const char *
149     GetName() override
150     {
151         if (m_thread_name.empty())
152             return NULL;
153         return m_thread_name.c_str();
154     }
155 
156     void
157     SetName(const char *name) override
158     {
159         if (name && name[0])
160             m_thread_name.assign (name);
161         else
162             m_thread_name.clear();
163     }
164 
165 protected:
166     //------------------------------------------------------------------
167     // Member variables.
168     //------------------------------------------------------------------
169     std::string m_thread_name;
170     lldb::RegisterContextSP m_thread_reg_ctx_sp;
171 
172     int m_signo;
173 
174     lldb_private::DataExtractor m_gpregset_data;
175     lldb_private::DataExtractor m_fpregset_data;
176     lldb_private::DataExtractor m_vregset_data;
177 
178     bool CalculateStopInfo() override;
179 };
180 
181 #endif // liblldb_ThreadElfCore_h_
182