1 //===-- NativeThreadLinux.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 "NativeThreadLinux.h"
11 
12 #include <signal.h>
13 
14 #include "NativeProcessLinux.h"
15 #include "NativeRegisterContextLinux_x86_64.h"
16 
17 #include "lldb/Core/Log.h"
18 #include "lldb/Core/State.h"
19 #include "lldb/Host/Host.h"
20 #include "lldb/Host/HostInfo.h"
21 #include "lldb/lldb-enumerations.h"
22 #include "lldb/lldb-private-log.h"
23 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
24 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
25 #include "Plugins/Process/Utility/RegisterInfoInterface.h"
26 
27 using namespace lldb;
28 using namespace lldb_private;
29 
30 namespace
31 {
32     void LogThreadStopInfo (Log &log, const ThreadStopInfo &stop_info, const char *const header)
33     {
34         switch (stop_info.reason)
35         {
36             case eStopReasonSignal:
37                 log.Printf ("%s: %s signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
38                 return;
39             case eStopReasonException:
40                 log.Printf ("%s: %s exception type 0x%" PRIx64, __FUNCTION__, header, stop_info.details.exception.type);
41                 return;
42             case eStopReasonExec:
43                 log.Printf ("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
44                 return;
45             default:
46                 log.Printf ("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header, static_cast<uint32_t> (stop_info.reason));
47         }
48     }
49 }
50 
51 NativeThreadLinux::NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid) :
52     NativeThreadProtocol (process, tid),
53     m_state (StateType::eStateInvalid),
54     m_stop_info (),
55     m_reg_context_sp ()
56 {
57 }
58 
59 const char *
60 NativeThreadLinux::GetName()
61 {
62     NativeProcessProtocolSP process_sp = m_process_wp.lock ();
63     if (!process_sp)
64         return "<unknown: no process>";
65 
66     // const NativeProcessLinux *const process = reinterpret_cast<NativeProcessLinux*> (process_sp->get ());
67     return Host::GetThreadName (process_sp->GetID (), GetID ()).c_str ();
68 }
69 
70 lldb::StateType
71 NativeThreadLinux::GetState ()
72 {
73     return m_state;
74 }
75 
76 
77 bool
78 NativeThreadLinux::GetStopReason (ThreadStopInfo &stop_info)
79 {
80     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
81     switch (m_state)
82     {
83     case eStateStopped:
84     case eStateCrashed:
85     case eStateExited:
86     case eStateSuspended:
87     case eStateUnloaded:
88         if (log)
89             LogThreadStopInfo (*log, m_stop_info, "m_stop_info in thread:");
90         stop_info = m_stop_info;
91         if (log)
92             LogThreadStopInfo (*log, stop_info, "returned stop_info:");
93         return true;
94 
95     case eStateInvalid:
96     case eStateConnected:
97     case eStateAttaching:
98     case eStateLaunching:
99     case eStateRunning:
100     case eStateStepping:
101     case eStateDetached:
102         if (log)
103         {
104             log->Printf ("NativeThreadLinux::%s tid %" PRIu64 " in state %s cannot answer stop reason",
105                     __FUNCTION__, GetID (), StateAsCString (m_state));
106         }
107         return false;
108     }
109 }
110 
111 lldb_private::NativeRegisterContextSP
112 NativeThreadLinux::GetRegisterContext ()
113 {
114     // Return the register context if we already created it.
115     if (m_reg_context_sp)
116         return m_reg_context_sp;
117 
118     // First select the appropriate RegisterInfoInterface.
119     RegisterInfoInterface *reg_interface = nullptr;
120     NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
121     if (!m_process_sp)
122         return NativeRegisterContextSP ();
123 
124     ArchSpec target_arch;
125     if (!m_process_sp->GetArchitecture (target_arch))
126         return NativeRegisterContextSP ();
127 
128     switch (target_arch.GetTriple().getOS())
129     {
130         case llvm::Triple::Linux:
131             switch (target_arch.GetMachine())
132             {
133             case llvm::Triple::x86:
134             case llvm::Triple::x86_64:
135                 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4)
136                 {
137                     // 32-bit hosts run with a RegisterContextLinux_i386 context.
138                     reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_i386(target_arch));
139                 }
140                 else
141                 {
142                     assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
143                            "Register setting path assumes this is a 64-bit host");
144                     // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context.
145                     reg_interface = static_cast<RegisterInfoInterface*> (new RegisterContextLinux_x86_64 (target_arch));
146                 }
147                 break;
148             default:
149                 break;
150             }
151             break;
152         default:
153             break;
154     }
155 
156     assert(reg_interface && "OS or CPU not supported!");
157     if (!reg_interface)
158         return NativeRegisterContextSP ();
159 
160     // Now create the register context.
161     switch (target_arch.GetMachine())
162     {
163 #if 0
164         case llvm::Triple::mips64:
165         {
166             RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface);
167             m_posix_thread = reg_ctx;
168             m_reg_context_sp.reset(reg_ctx);
169             break;
170         }
171 #endif
172 #if 0
173         case llvm::Triple::x86:
174 #endif
175         case llvm::Triple::x86_64:
176         {
177             const uint32_t concrete_frame_idx = 0;
178             m_reg_context_sp.reset (new NativeRegisterContextLinux_x86_64(*this, concrete_frame_idx, reg_interface));
179             break;
180         }
181         default:
182             break;
183     }
184 
185     return m_reg_context_sp;
186 }
187 
188 Error
189 NativeThreadLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
190 {
191     // TODO implement
192     return Error ("not implemented");
193 }
194 
195 Error
196 NativeThreadLinux::RemoveWatchpoint (lldb::addr_t addr)
197 {
198     // TODO implement
199     return Error ("not implemented");
200 }
201 
202 void
203 NativeThreadLinux::SetLaunching ()
204 {
205     const StateType new_state = StateType::eStateLaunching;
206     MaybeLogStateChange (new_state);
207     m_state = new_state;
208 
209     // Also mark it as stopped since launching temporarily stops the newly created thread
210     // in the ptrace machinery.
211     m_stop_info.reason = StopReason::eStopReasonSignal;
212     m_stop_info.details.signal.signo = SIGSTOP;
213 }
214 
215 
216 void
217 NativeThreadLinux::SetRunning ()
218 {
219     const StateType new_state = StateType::eStateRunning;
220     MaybeLogStateChange (new_state);
221     m_state = new_state;
222 
223     m_stop_info.reason = StopReason::eStopReasonNone;
224 }
225 
226 void
227 NativeThreadLinux::SetStepping ()
228 {
229     const StateType new_state = StateType::eStateStepping;
230     MaybeLogStateChange (new_state);
231     m_state = new_state;
232 
233     m_stop_info.reason = StopReason::eStopReasonNone;
234 }
235 
236 void
237 NativeThreadLinux::SetStoppedBySignal (uint32_t signo)
238 {
239     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
240     if (log)
241         log->Printf ("NativeThreadLinux::%s called with signal 0x%" PRIx32, __FUNCTION__, signo);
242 
243     const StateType new_state = StateType::eStateStopped;
244     MaybeLogStateChange (new_state);
245     m_state = new_state;
246 
247     m_stop_info.reason = StopReason::eStopReasonSignal;
248     m_stop_info.details.signal.signo = signo;
249 }
250 
251 void
252 NativeThreadLinux::SetStoppedByExec ()
253 {
254     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
255     if (log)
256         log->Printf ("NativeThreadLinux::%s()", __FUNCTION__);
257 
258     const StateType new_state = StateType::eStateStopped;
259     MaybeLogStateChange (new_state);
260     m_state = new_state;
261 
262     m_stop_info.reason = StopReason::eStopReasonExec;
263     m_stop_info.details.signal.signo = SIGSTOP;
264 }
265 
266 void
267 NativeThreadLinux::SetStoppedByBreakpoint ()
268 {
269     const StateType new_state = StateType::eStateStopped;
270     MaybeLogStateChange (new_state);
271     m_state = new_state;
272 
273     m_stop_info.reason = StopReason::eStopReasonSignal;
274     m_stop_info.details.signal.signo = SIGTRAP;
275 }
276 
277 bool
278 NativeThreadLinux::IsStoppedAtBreakpoint ()
279 {
280     // Are we stopped? If not, this can't be a breakpoint.
281     if (GetState () != StateType::eStateStopped)
282         return false;
283 
284     // Was the stop reason a signal with signal number SIGTRAP? If not, not a breakpoint.
285     return (m_stop_info.reason == StopReason::eStopReasonSignal) &&
286             (m_stop_info.details.signal.signo == SIGTRAP);
287 }
288 
289 void
290 NativeThreadLinux::SetCrashedWithException (uint64_t exception_type, lldb::addr_t exception_addr)
291 {
292     const StateType new_state = StateType::eStateCrashed;
293     MaybeLogStateChange (new_state);
294     m_state = new_state;
295 
296     m_stop_info.reason = StopReason::eStopReasonException;
297     m_stop_info.details.exception.type = exception_type;
298     m_stop_info.details.exception.data_count = 1;
299     m_stop_info.details.exception.data[0] = exception_addr;
300 }
301 
302 
303 void
304 NativeThreadLinux::SetSuspended ()
305 {
306     const StateType new_state = StateType::eStateSuspended;
307     MaybeLogStateChange (new_state);
308     m_state = new_state;
309 
310     // FIXME what makes sense here? Do we need a suspended StopReason?
311     m_stop_info.reason = StopReason::eStopReasonNone;
312 }
313 
314 void
315 NativeThreadLinux::SetExited ()
316 {
317     const StateType new_state = StateType::eStateExited;
318     MaybeLogStateChange (new_state);
319     m_state = new_state;
320 
321     m_stop_info.reason = StopReason::eStopReasonThreadExiting;
322 }
323 
324 void
325 NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state)
326 {
327     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
328     // If we're not logging, we're done.
329     if (!log)
330         return;
331 
332     // If this is a state change to the same state, we're done.
333     lldb::StateType old_state = m_state;
334     if (new_state == old_state)
335         return;
336 
337     NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
338     lldb::pid_t pid = m_process_sp ? m_process_sp->GetID () : LLDB_INVALID_PROCESS_ID;
339 
340     // Log it.
341     log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state));
342 }
343 
344 uint32_t
345 NativeThreadLinux::TranslateStopInfoToGdbSignal (const ThreadStopInfo &stop_info) const
346 {
347     switch (stop_info.reason)
348     {
349         case eStopReasonSignal:
350             // No translation.
351             return stop_info.details.signal.signo;
352 
353         case eStopReasonException:
354             {
355                 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
356                 // FIXME I think the eStopReasonException is a xnu/Mach exception, which we
357                 // shouldn't see on Linux.
358                 // No translation.
359                 if (log)
360                     log->Printf ("NativeThreadLinux::%s saw an exception stop type (signo %"
361                                  PRIu64 "), not expecting to see exceptions on Linux",
362                                  __FUNCTION__,
363                                  stop_info.details.exception.type);
364                 return static_cast<uint32_t> (stop_info.details.exception.type);
365             }
366 
367         default:
368             assert (0 && "unexpected stop_info.reason found");
369             return 0;
370     }
371 }
372 
373