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 #include <sstream>
14 
15 #include "NativeProcessLinux.h"
16 #include "NativeRegisterContextLinux_arm64.h"
17 #include "NativeRegisterContextLinux_x86_64.h"
18 #include "NativeRegisterContextLinux_mips64.h"
19 
20 #include "lldb/Core/Log.h"
21 #include "lldb/Core/State.h"
22 #include "lldb/Host/Host.h"
23 #include "lldb/Host/HostInfo.h"
24 #include "lldb/Host/HostNativeThread.h"
25 #include "lldb/Utility/LLDBAssert.h"
26 #include "lldb/lldb-enumerations.h"
27 
28 #include "llvm/ADT/SmallString.h"
29 
30 #include "Plugins/Process/POSIX/CrashReason.h"
31 
32 #include "Plugins/Process/Utility/RegisterContextLinux_arm64.h"
33 #include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
34 #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
35 #include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
36 #include "Plugins/Process/Utility/RegisterInfoInterface.h"
37 
38 using namespace lldb;
39 using namespace lldb_private;
40 using namespace lldb_private::process_linux;
41 
42 namespace
43 {
44     void LogThreadStopInfo (Log &log, const ThreadStopInfo &stop_info, const char *const header)
45     {
46         switch (stop_info.reason)
47         {
48             case eStopReasonNone:
49                 log.Printf ("%s: %s no stop reason", __FUNCTION__, header);
50                 return;
51             case eStopReasonTrace:
52                 log.Printf ("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
53                 return;
54             case eStopReasonBreakpoint:
55                 log.Printf ("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
56                 return;
57             case eStopReasonWatchpoint:
58                 log.Printf ("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
59                 return;
60             case eStopReasonSignal:
61                 log.Printf ("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
62                 return;
63             case eStopReasonException:
64                 log.Printf ("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header, stop_info.details.exception.type);
65                 return;
66             case eStopReasonExec:
67                 log.Printf ("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header, stop_info.details.signal.signo);
68                 return;
69             case eStopReasonPlanComplete:
70                 log.Printf ("%s: %s plan complete", __FUNCTION__, header);
71                 return;
72             case eStopReasonThreadExiting:
73                 log.Printf ("%s: %s thread exiting", __FUNCTION__, header);
74                 return;
75             case eStopReasonInstrumentation:
76                 log.Printf ("%s: %s instrumentation", __FUNCTION__, header);
77                 return;
78             default:
79                 log.Printf ("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header, static_cast<uint32_t> (stop_info.reason));
80         }
81     }
82 }
83 
84 NativeThreadLinux::NativeThreadLinux (NativeProcessLinux *process, lldb::tid_t tid) :
85     NativeThreadProtocol (process, tid),
86     m_state (StateType::eStateInvalid),
87     m_stop_info (),
88     m_reg_context_sp (),
89     m_stop_description ()
90 {
91 }
92 
93 std::string
94 NativeThreadLinux::GetName()
95 {
96     NativeProcessProtocolSP process_sp = m_process_wp.lock ();
97     if (!process_sp)
98         return "<unknown: no process>";
99 
100     // const NativeProcessLinux *const process = reinterpret_cast<NativeProcessLinux*> (process_sp->get ());
101     llvm::SmallString<32> thread_name;
102     HostNativeThread::GetName(GetID(), thread_name);
103     return thread_name.c_str();
104 }
105 
106 lldb::StateType
107 NativeThreadLinux::GetState ()
108 {
109     return m_state;
110 }
111 
112 
113 bool
114 NativeThreadLinux::GetStopReason (ThreadStopInfo &stop_info, std::string& description)
115 {
116     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
117 
118     description.clear();
119 
120     switch (m_state)
121     {
122     case eStateStopped:
123     case eStateCrashed:
124     case eStateExited:
125     case eStateSuspended:
126     case eStateUnloaded:
127         if (log)
128             LogThreadStopInfo (*log, m_stop_info, "m_stop_info in thread:");
129         stop_info = m_stop_info;
130         switch (m_stop_info.reason)
131         {
132             case StopReason::eStopReasonException:
133             case StopReason::eStopReasonBreakpoint:
134             case StopReason::eStopReasonWatchpoint:
135                 description = m_stop_description;
136             default:
137                 break;
138         }
139         if (log)
140             LogThreadStopInfo (*log, stop_info, "returned stop_info:");
141 
142         return true;
143 
144     case eStateInvalid:
145     case eStateConnected:
146     case eStateAttaching:
147     case eStateLaunching:
148     case eStateRunning:
149     case eStateStepping:
150     case eStateDetached:
151         if (log)
152         {
153             log->Printf ("NativeThreadLinux::%s tid %" PRIu64 " in state %s cannot answer stop reason",
154                     __FUNCTION__, GetID (), StateAsCString (m_state));
155         }
156         return false;
157     }
158     llvm_unreachable("unhandled StateType!");
159 }
160 
161 NativeRegisterContextSP
162 NativeThreadLinux::GetRegisterContext ()
163 {
164     // Return the register context if we already created it.
165     if (m_reg_context_sp)
166         return m_reg_context_sp;
167 
168     // First select the appropriate RegisterInfoInterface.
169     RegisterInfoInterface *reg_interface = nullptr;
170     NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
171     if (!m_process_sp)
172         return NativeRegisterContextSP ();
173 
174     ArchSpec target_arch;
175     if (!m_process_sp->GetArchitecture (target_arch))
176         return NativeRegisterContextSP ();
177 
178     switch (target_arch.GetTriple().getOS())
179     {
180         case llvm::Triple::Linux:
181             switch (target_arch.GetMachine())
182             {
183             case llvm::Triple::aarch64:
184                 assert((HostInfo::GetArchitecture ().GetAddressByteSize() == 8) && "Register setting path assumes this is a 64-bit host");
185                 reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_arm64(target_arch));
186                 break;
187             case llvm::Triple::x86:
188             case llvm::Triple::x86_64:
189                 if (HostInfo::GetArchitecture().GetAddressByteSize() == 4)
190                 {
191                     // 32-bit hosts run with a RegisterContextLinux_i386 context.
192                     reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_i386(target_arch));
193                 }
194                 else
195                 {
196                     assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
197                            "Register setting path assumes this is a 64-bit host");
198                     // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the x86_64 register context.
199                     reg_interface = static_cast<RegisterInfoInterface*> (new RegisterContextLinux_x86_64 (target_arch));
200                 }
201                 break;
202             case llvm::Triple::mips64:
203             case llvm::Triple::mips64el:
204                 assert((HostInfo::GetArchitecture ().GetAddressByteSize() == 8)
205                     && "Register setting path assumes this is a 64-bit host");
206                 reg_interface = static_cast<RegisterInfoInterface*>(new RegisterContextLinux_mips64 (target_arch));
207                 break;
208             default:
209                 break;
210             }
211             break;
212         default:
213             break;
214     }
215 
216     assert(reg_interface && "OS or CPU not supported!");
217     if (!reg_interface)
218         return NativeRegisterContextSP ();
219 
220     // Now create the register context.
221     switch (target_arch.GetMachine())
222     {
223 #if 0
224         case llvm::Triple::mips64:
225         {
226             RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface);
227             m_posix_thread = reg_ctx;
228             m_reg_context_sp.reset(reg_ctx);
229             break;
230         }
231 #endif
232         case llvm::Triple::mips64:
233         case llvm::Triple::mips64el:
234         {
235             const uint32_t concrete_frame_idx = 0;
236             m_reg_context_sp.reset (new NativeRegisterContextLinux_mips64 (*this, concrete_frame_idx, reg_interface));
237             break;
238         }
239         case llvm::Triple::aarch64:
240         {
241             const uint32_t concrete_frame_idx = 0;
242             m_reg_context_sp.reset (new NativeRegisterContextLinux_arm64(*this, concrete_frame_idx, reg_interface));
243             break;
244         }
245         case llvm::Triple::x86:
246         case llvm::Triple::x86_64:
247         {
248             const uint32_t concrete_frame_idx = 0;
249             m_reg_context_sp.reset (new NativeRegisterContextLinux_x86_64(*this, concrete_frame_idx, reg_interface));
250             break;
251         }
252         default:
253             break;
254     }
255 
256     return m_reg_context_sp;
257 }
258 
259 Error
260 NativeThreadLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
261 {
262     if (!hardware)
263         return Error ("not implemented");
264     if (m_state == eStateLaunching)
265         return Error ();
266     Error error = RemoveWatchpoint(addr);
267     if (error.Fail()) return error;
268     NativeRegisterContextSP reg_ctx = GetRegisterContext ();
269     uint32_t wp_index =
270         reg_ctx->SetHardwareWatchpoint (addr, size, watch_flags);
271     if (wp_index == LLDB_INVALID_INDEX32)
272         return Error ("Setting hardware watchpoint failed.");
273     m_watchpoint_index_map.insert({addr, wp_index});
274     return Error ();
275 }
276 
277 Error
278 NativeThreadLinux::RemoveWatchpoint (lldb::addr_t addr)
279 {
280     auto wp = m_watchpoint_index_map.find(addr);
281     if (wp == m_watchpoint_index_map.end())
282         return Error ();
283     uint32_t wp_index = wp->second;
284     m_watchpoint_index_map.erase(wp);
285     if (GetRegisterContext()->ClearHardwareWatchpoint(wp_index))
286         return Error ();
287     return Error ("Clearing hardware watchpoint failed.");
288 }
289 
290 void
291 NativeThreadLinux::SetLaunching ()
292 {
293     const StateType new_state = StateType::eStateLaunching;
294     MaybeLogStateChange (new_state);
295     m_state = new_state;
296 
297     // Also mark it as stopped since launching temporarily stops the newly created thread
298     // in the ptrace machinery.
299     m_stop_info.reason = StopReason::eStopReasonSignal;
300     m_stop_info.details.signal.signo = SIGSTOP;
301 }
302 
303 
304 void
305 NativeThreadLinux::SetRunning ()
306 {
307     const StateType new_state = StateType::eStateRunning;
308     MaybeLogStateChange (new_state);
309     m_state = new_state;
310 
311     m_stop_info.reason = StopReason::eStopReasonNone;
312     m_stop_description.clear();
313 
314     // If watchpoints have been set, but none on this thread,
315     // then this is a new thread. So set all existing watchpoints.
316     if (m_watchpoint_index_map.empty())
317     {
318         const auto process_sp = GetProcess();
319         if (process_sp)
320         {
321             const auto &watchpoint_map = process_sp->GetWatchpointMap();
322             if (watchpoint_map.empty()) return;
323             GetRegisterContext()->ClearAllHardwareWatchpoints();
324             for (const auto &pair : watchpoint_map)
325             {
326                 const auto& wp = pair.second;
327                 SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
328             }
329         }
330     }
331 }
332 
333 void
334 NativeThreadLinux::SetStepping ()
335 {
336     const StateType new_state = StateType::eStateStepping;
337     MaybeLogStateChange (new_state);
338     m_state = new_state;
339 
340     m_stop_info.reason = StopReason::eStopReasonNone;
341 }
342 
343 void
344 NativeThreadLinux::SetStoppedBySignal (uint32_t signo)
345 {
346     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
347     if (log)
348         log->Printf ("NativeThreadLinux::%s called with signal 0x%02" PRIx32, __FUNCTION__, signo);
349 
350     const StateType new_state = StateType::eStateStopped;
351     MaybeLogStateChange (new_state);
352     m_state = new_state;
353 
354     m_stop_info.reason = StopReason::eStopReasonSignal;
355     m_stop_info.details.signal.signo = signo;
356 }
357 
358 bool
359 NativeThreadLinux::IsStopped (int *signo)
360 {
361     if (!StateIsStoppedState (m_state, false))
362         return false;
363 
364     // If we are stopped by a signal, return the signo.
365     if (signo &&
366         m_state == StateType::eStateStopped &&
367         m_stop_info.reason == StopReason::eStopReasonSignal)
368     {
369         *signo = m_stop_info.details.signal.signo;
370     }
371 
372     // Regardless, we are stopped.
373     return true;
374 }
375 
376 
377 void
378 NativeThreadLinux::SetStoppedByExec ()
379 {
380     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
381     if (log)
382         log->Printf ("NativeThreadLinux::%s()", __FUNCTION__);
383 
384     const StateType new_state = StateType::eStateStopped;
385     MaybeLogStateChange (new_state);
386     m_state = new_state;
387 
388     m_stop_info.reason = StopReason::eStopReasonExec;
389     m_stop_info.details.signal.signo = SIGSTOP;
390 }
391 
392 void
393 NativeThreadLinux::SetStoppedByBreakpoint ()
394 {
395     const StateType new_state = StateType::eStateStopped;
396     MaybeLogStateChange (new_state);
397     m_state = new_state;
398 
399     m_stop_info.reason = StopReason::eStopReasonBreakpoint;
400     m_stop_info.details.signal.signo = SIGTRAP;
401     m_stop_description.clear();
402 }
403 
404 void
405 NativeThreadLinux::SetStoppedByWatchpoint (uint32_t wp_index)
406 {
407     const StateType new_state = StateType::eStateStopped;
408     MaybeLogStateChange (new_state);
409     m_state = new_state;
410     m_stop_description.clear ();
411 
412     lldbassert(wp_index != LLDB_INVALID_INDEX32 &&
413                "wp_index cannot be invalid");
414 
415     std::ostringstream ostr;
416     ostr << GetRegisterContext()->GetWatchpointAddress(wp_index) << " ";
417     ostr << wp_index;
418     m_stop_description = ostr.str();
419 
420     m_stop_info.reason = StopReason::eStopReasonWatchpoint;
421     m_stop_info.details.signal.signo = SIGTRAP;
422 }
423 
424 bool
425 NativeThreadLinux::IsStoppedAtBreakpoint ()
426 {
427     return GetState () == StateType::eStateStopped &&
428         m_stop_info.reason == StopReason::eStopReasonBreakpoint;
429 }
430 
431 bool
432 NativeThreadLinux::IsStoppedAtWatchpoint ()
433 {
434     return GetState () == StateType::eStateStopped &&
435         m_stop_info.reason == StopReason::eStopReasonWatchpoint;
436 }
437 
438 void
439 NativeThreadLinux::SetStoppedByTrace ()
440 {
441     const StateType new_state = StateType::eStateStopped;
442     MaybeLogStateChange (new_state);
443     m_state = new_state;
444 
445     m_stop_info.reason = StopReason::eStopReasonTrace;
446     m_stop_info.details.signal.signo = SIGTRAP;
447 }
448 
449 void
450 NativeThreadLinux::SetCrashedWithException (const siginfo_t& info)
451 {
452     const StateType new_state = StateType::eStateCrashed;
453     MaybeLogStateChange (new_state);
454     m_state = new_state;
455 
456     m_stop_info.reason = StopReason::eStopReasonException;
457     m_stop_info.details.signal.signo = info.si_signo;
458 
459     const auto reason = GetCrashReason (info);
460     m_stop_description = GetCrashReasonString (reason, reinterpret_cast<lldb::addr_t> (info.si_addr));
461 }
462 
463 void
464 NativeThreadLinux::SetSuspended ()
465 {
466     const StateType new_state = StateType::eStateSuspended;
467     MaybeLogStateChange (new_state);
468     m_state = new_state;
469 
470     // FIXME what makes sense here? Do we need a suspended StopReason?
471     m_stop_info.reason = StopReason::eStopReasonNone;
472 }
473 
474 void
475 NativeThreadLinux::SetExited ()
476 {
477     const StateType new_state = StateType::eStateExited;
478     MaybeLogStateChange (new_state);
479     m_state = new_state;
480 
481     m_stop_info.reason = StopReason::eStopReasonThreadExiting;
482 }
483 
484 void
485 NativeThreadLinux::MaybeLogStateChange (lldb::StateType new_state)
486 {
487     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
488     // If we're not logging, we're done.
489     if (!log)
490         return;
491 
492     // If this is a state change to the same state, we're done.
493     lldb::StateType old_state = m_state;
494     if (new_state == old_state)
495         return;
496 
497     NativeProcessProtocolSP m_process_sp = m_process_wp.lock ();
498     lldb::pid_t pid = m_process_sp ? m_process_sp->GetID () : LLDB_INVALID_PROCESS_ID;
499 
500     // Log it.
501     log->Printf ("NativeThreadLinux: thread (pid=%" PRIu64 ", tid=%" PRIu64 ") changing from state %s to %s", pid, GetID (), StateAsCString (old_state), StateAsCString (new_state));
502 }
503