1 //===-- ThreadElfCore.cpp --------------------------------------*- 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 #include "lldb/Core/DataExtractor.h"
11 #include "lldb/Core/Log.h"
12 #include "lldb/Target/RegisterContext.h"
13 #include "lldb/Target/StopInfo.h"
14 #include "lldb/Target/Target.h"
15 #include "lldb/Target/Unwind.h"
16 
17 #include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h"
18 #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
19 #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
20 #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
21 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
22 #include "Plugins/Process/Utility/RegisterContextLinux_arm.h"
23 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
24 #include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
25 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
26 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
27 #include "ProcessElfCore.h"
28 #include "RegisterContextPOSIXCore_arm.h"
29 #include "RegisterContextPOSIXCore_arm64.h"
30 #include "RegisterContextPOSIXCore_mips64.h"
31 #include "RegisterContextPOSIXCore_powerpc.h"
32 #include "RegisterContextPOSIXCore_s390x.h"
33 #include "RegisterContextPOSIXCore_x86_64.h"
34 #include "ThreadElfCore.h"
35 
36 using namespace lldb;
37 using namespace lldb_private;
38 
39 //----------------------------------------------------------------------
40 // Construct a Thread object with given data
41 //----------------------------------------------------------------------
42 ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td)
43     : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(),
44       m_signo(td.signo), m_gpregset_data(td.gpregset),
45       m_fpregset_data(td.fpregset), m_vregset_data(td.vregset) {}
46 
47 ThreadElfCore::~ThreadElfCore() { DestroyThread(); }
48 
49 void ThreadElfCore::RefreshStateAfterStop() {
50   GetRegisterContext()->InvalidateIfNeeded(false);
51 }
52 
53 void ThreadElfCore::ClearStackFrames() {
54   Unwind *unwinder = GetUnwinder();
55   if (unwinder)
56     unwinder->Clear();
57   Thread::ClearStackFrames();
58 }
59 
60 RegisterContextSP ThreadElfCore::GetRegisterContext() {
61   if (m_reg_context_sp.get() == NULL) {
62     m_reg_context_sp = CreateRegisterContextForFrame(NULL);
63   }
64   return m_reg_context_sp;
65 }
66 
67 RegisterContextSP
68 ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
69   RegisterContextSP reg_ctx_sp;
70   uint32_t concrete_frame_idx = 0;
71   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
72 
73   if (frame)
74     concrete_frame_idx = frame->GetConcreteFrameIndex();
75 
76   if (concrete_frame_idx == 0) {
77     if (m_thread_reg_ctx_sp)
78       return m_thread_reg_ctx_sp;
79 
80     ProcessElfCore *process = static_cast<ProcessElfCore *>(GetProcess().get());
81     ArchSpec arch = process->GetArchitecture();
82     RegisterInfoInterface *reg_interface = NULL;
83 
84     switch (arch.GetTriple().getOS()) {
85     case llvm::Triple::FreeBSD: {
86       switch (arch.GetMachine()) {
87       case llvm::Triple::aarch64:
88         reg_interface = new RegisterInfoPOSIX_arm64(arch);
89         break;
90       case llvm::Triple::arm:
91         reg_interface = new RegisterContextFreeBSD_arm(arch);
92         break;
93       case llvm::Triple::ppc:
94         reg_interface = new RegisterContextFreeBSD_powerpc32(arch);
95         break;
96       case llvm::Triple::ppc64:
97         reg_interface = new RegisterContextFreeBSD_powerpc64(arch);
98         break;
99       case llvm::Triple::mips64:
100         reg_interface = new RegisterContextFreeBSD_mips64(arch);
101         break;
102       case llvm::Triple::x86:
103         reg_interface = new RegisterContextFreeBSD_i386(arch);
104         break;
105       case llvm::Triple::x86_64:
106         reg_interface = new RegisterContextFreeBSD_x86_64(arch);
107         break;
108       default:
109         break;
110       }
111       break;
112     }
113 
114     case llvm::Triple::Linux: {
115       switch (arch.GetMachine()) {
116       case llvm::Triple::arm:
117         reg_interface = new RegisterContextLinux_arm(arch);
118         break;
119       case llvm::Triple::aarch64:
120         reg_interface = new RegisterInfoPOSIX_arm64(arch);
121         break;
122       case llvm::Triple::systemz:
123         reg_interface = new RegisterContextLinux_s390x(arch);
124         break;
125       case llvm::Triple::x86:
126         reg_interface = new RegisterContextLinux_i386(arch);
127         break;
128       case llvm::Triple::x86_64:
129         reg_interface = new RegisterContextLinux_x86_64(arch);
130         break;
131       default:
132         break;
133       }
134       break;
135     }
136 
137     default:
138       break;
139     }
140 
141     if (!reg_interface) {
142       if (log)
143         log->Printf("elf-core::%s:: Architecture(%d) or OS(%d) not supported",
144                     __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
145       assert(false && "Architecture or OS not supported");
146     }
147 
148     switch (arch.GetMachine()) {
149     case llvm::Triple::aarch64:
150       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm64(
151           *this, reg_interface, m_gpregset_data, m_fpregset_data));
152       break;
153     case llvm::Triple::arm:
154       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_arm(
155           *this, reg_interface, m_gpregset_data, m_fpregset_data));
156       break;
157     case llvm::Triple::mips64:
158       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_mips64(
159           *this, reg_interface, m_gpregset_data, m_fpregset_data));
160       break;
161     case llvm::Triple::ppc:
162     case llvm::Triple::ppc64:
163       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_powerpc(
164           *this, reg_interface, m_gpregset_data, m_fpregset_data,
165           m_vregset_data));
166       break;
167     case llvm::Triple::systemz:
168       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_s390x(
169           *this, reg_interface, m_gpregset_data, m_fpregset_data));
170       break;
171     case llvm::Triple::x86:
172     case llvm::Triple::x86_64:
173       m_thread_reg_ctx_sp.reset(new RegisterContextCorePOSIX_x86_64(
174           *this, reg_interface, m_gpregset_data, m_fpregset_data));
175       break;
176     default:
177       break;
178     }
179 
180     reg_ctx_sp = m_thread_reg_ctx_sp;
181   } else if (m_unwinder_ap.get()) {
182     reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame(frame);
183   }
184   return reg_ctx_sp;
185 }
186 
187 bool ThreadElfCore::CalculateStopInfo() {
188   ProcessSP process_sp(GetProcess());
189   if (process_sp) {
190     SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo));
191     return true;
192   }
193   return false;
194 }
195 
196 //----------------------------------------------------------------
197 // Parse PRSTATUS from NOTE entry
198 //----------------------------------------------------------------
199 ELFLinuxPrStatus::ELFLinuxPrStatus() {
200   memset(this, 0, sizeof(ELFLinuxPrStatus));
201 }
202 
203 Error ELFLinuxPrStatus::Parse(DataExtractor &data, ArchSpec &arch) {
204   Error error;
205   ByteOrder byteorder = data.GetByteOrder();
206   if (GetSize(arch) > data.GetByteSize()) {
207     error.SetErrorStringWithFormat(
208         "NT_PRSTATUS size should be %zu, but the remaining bytes are: %" PRIu64,
209         GetSize(arch), data.GetByteSize());
210     return error;
211   }
212 
213   switch (arch.GetCore()) {
214   case ArchSpec::eCore_s390x_generic:
215   case ArchSpec::eCore_x86_64_x86_64:
216     data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this);
217     break;
218   case ArchSpec::eCore_x86_32_i386:
219   case ArchSpec::eCore_x86_32_i486: {
220     // Parsing from a 32 bit ELF core file, and populating/reusing the structure
221     // properly, because the struct is for the 64 bit version
222     offset_t offset = 0;
223     si_signo = data.GetU32(&offset);
224     si_code = data.GetU32(&offset);
225     si_errno = data.GetU32(&offset);
226 
227     pr_cursig = data.GetU16(&offset);
228     offset += 2; // pad
229 
230     pr_sigpend = data.GetU32(&offset);
231     pr_sighold = data.GetU32(&offset);
232 
233     pr_pid = data.GetU32(&offset);
234     pr_ppid = data.GetU32(&offset);
235     pr_pgrp = data.GetU32(&offset);
236     pr_sid = data.GetU32(&offset);
237 
238     pr_utime.tv_sec = data.GetU32(&offset);
239     pr_utime.tv_usec = data.GetU32(&offset);
240 
241     pr_stime.tv_sec = data.GetU32(&offset);
242     pr_stime.tv_usec = data.GetU32(&offset);
243 
244     pr_cutime.tv_sec = data.GetU32(&offset);
245     pr_cutime.tv_usec = data.GetU32(&offset);
246 
247     pr_cstime.tv_sec = data.GetU32(&offset);
248     pr_cstime.tv_usec = data.GetU32(&offset);
249 
250     break;
251   }
252   default:
253     error.SetErrorStringWithFormat("ELFLinuxPrStatus::%s Unknown architecture",
254                                    __FUNCTION__);
255     break;
256   }
257 
258   return error;
259 }
260 
261 //----------------------------------------------------------------
262 // Parse PRPSINFO from NOTE entry
263 //----------------------------------------------------------------
264 ELFLinuxPrPsInfo::ELFLinuxPrPsInfo() {
265   memset(this, 0, sizeof(ELFLinuxPrPsInfo));
266 }
267 
268 Error ELFLinuxPrPsInfo::Parse(DataExtractor &data, ArchSpec &arch) {
269   Error error;
270   ByteOrder byteorder = data.GetByteOrder();
271   if (GetSize(arch) > data.GetByteSize()) {
272     error.SetErrorStringWithFormat(
273         "NT_PRPSINFO size should be %zu, but the remaining bytes are: %" PRIu64,
274         GetSize(arch), data.GetByteSize());
275     return error;
276   }
277 
278   switch (arch.GetCore()) {
279   case ArchSpec::eCore_s390x_generic:
280   case ArchSpec::eCore_x86_64_x86_64:
281     data.ExtractBytes(0, sizeof(ELFLinuxPrPsInfo), byteorder, this);
282     break;
283   case ArchSpec::eCore_x86_32_i386:
284   case ArchSpec::eCore_x86_32_i486: {
285     // Parsing from a 32 bit ELF core file, and populating/reusing the structure
286     // properly, because the struct is for the 64 bit version
287     size_t size = 0;
288     offset_t offset = 0;
289 
290     pr_state = data.GetU8(&offset);
291     pr_sname = data.GetU8(&offset);
292     pr_zomb = data.GetU8(&offset);
293     pr_nice = data.GetU8(&offset);
294 
295     pr_flag = data.GetU32(&offset);
296     pr_uid = data.GetU16(&offset);
297     pr_gid = data.GetU16(&offset);
298 
299     pr_pid = data.GetU32(&offset);
300     pr_ppid = data.GetU32(&offset);
301     pr_pgrp = data.GetU32(&offset);
302     pr_sid = data.GetU32(&offset);
303 
304     size = 16;
305     data.ExtractBytes(offset, size, byteorder, pr_fname);
306     offset += size;
307 
308     size = 80;
309     data.ExtractBytes(offset, size, byteorder, pr_psargs);
310     offset += size;
311 
312     break;
313   }
314   default:
315     error.SetErrorStringWithFormat("ELFLinuxPrPsInfo::%s Unknown architecture",
316                                    __FUNCTION__);
317     break;
318   }
319 
320   return error;
321 }
322 
323 //----------------------------------------------------------------
324 // Parse SIGINFO from NOTE entry
325 //----------------------------------------------------------------
326 ELFLinuxSigInfo::ELFLinuxSigInfo() {
327   memset(this, 0, sizeof(ELFLinuxSigInfo));
328 }
329 
330 Error ELFLinuxSigInfo::Parse(DataExtractor &data, const ArchSpec &arch) {
331   Error error;
332   ByteOrder byteorder = data.GetByteOrder();
333   if (GetSize(arch) > data.GetByteSize()) {
334     error.SetErrorStringWithFormat(
335         "NT_SIGINFO size should be %zu, but the remaining bytes are: %" PRIu64,
336         GetSize(arch), data.GetByteSize());
337     return error;
338   }
339 
340   switch (arch.GetCore()) {
341   case ArchSpec::eCore_x86_64_x86_64:
342     data.ExtractBytes(0, sizeof(ELFLinuxPrStatus), byteorder, this);
343     break;
344   case ArchSpec::eCore_s390x_generic:
345   case ArchSpec::eCore_x86_32_i386:
346   case ArchSpec::eCore_x86_32_i486: {
347     // Parsing from a 32 bit ELF core file, and populating/reusing the structure
348     // properly, because the struct is for the 64 bit version
349     offset_t offset = 0;
350     si_signo = data.GetU32(&offset);
351     si_code = data.GetU32(&offset);
352     si_errno = data.GetU32(&offset);
353 
354     break;
355   }
356   default:
357     error.SetErrorStringWithFormat("ELFLinuxSigInfo::%s Unknown architecture",
358                                    __FUNCTION__);
359     break;
360   }
361 
362   return error;
363 }
364