1//===-- NativeThreadLinux.cpp ---------------------------------------------===//
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#include "NativeThreadLinux.h"
10
11#include <csignal>
12#include <sstream>
13
14#include "NativeProcessLinux.h"
15#include "NativeRegisterContextLinux.h"
16#include "SingleStepCheck.h"
17
18#include "lldb/Host/HostNativeThread.h"
19#include "lldb/Host/linux/Ptrace.h"
20#include "lldb/Host/linux/Support.h"
21#include "lldb/Utility/LLDBAssert.h"
22#include "lldb/Utility/LLDBLog.h"
23#include "lldb/Utility/Log.h"
24#include "lldb/Utility/State.h"
25#include "lldb/lldb-enumerations.h"
26
27#include "llvm/ADT/SmallString.h"
28
29#include "Plugins/Process/POSIX/CrashReason.h"
30#include "Plugins/Process/Utility/MemoryTagManagerAArch64MTE.h"
31
32#include <sys/syscall.h>
33// Try to define a macro to encapsulate the tgkill syscall
34#define tgkill(pid, tid, sig)                                                  \
35  syscall(__NR_tgkill, static_cast<::pid_t>(pid), static_cast<::pid_t>(tid),   \
36          sig)
37
38using namespace lldb;
39using namespace lldb_private;
40using namespace lldb_private::process_linux;
41
42namespace {
43void LogThreadStopInfo(Log &log, const ThreadStopInfo &stop_info,
44                       const char *const header) {
45  switch (stop_info.reason) {
46  case eStopReasonNone:
47    log.Printf("%s: %s no stop reason", __FUNCTION__, header);
48    return;
49  case eStopReasonTrace:
50    log.Printf("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header,
51               stop_info.signo);
52    return;
53  case eStopReasonBreakpoint:
54    log.Printf("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
55               header, stop_info.signo);
56    return;
57  case eStopReasonWatchpoint:
58    log.Printf("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
59               header, stop_info.signo);
60    return;
61  case eStopReasonSignal:
62    log.Printf("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header,
63               stop_info.signo);
64    return;
65  case eStopReasonException:
66    log.Printf("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header,
67               stop_info.details.exception.type);
68    return;
69  case eStopReasonExec:
70    log.Printf("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header,
71               stop_info.signo);
72    return;
73  case eStopReasonPlanComplete:
74    log.Printf("%s: %s plan complete", __FUNCTION__, header);
75    return;
76  case eStopReasonThreadExiting:
77    log.Printf("%s: %s thread exiting", __FUNCTION__, header);
78    return;
79  case eStopReasonInstrumentation:
80    log.Printf("%s: %s instrumentation", __FUNCTION__, header);
81    return;
82  case eStopReasonProcessorTrace:
83    log.Printf("%s: %s processor trace", __FUNCTION__, header);
84    return;
85  default:
86    log.Printf("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header,
87               static_cast<uint32_t>(stop_info.reason));
88  }
89}
90}
91
92NativeThreadLinux::NativeThreadLinux(NativeProcessLinux &process,
93                                     lldb::tid_t tid)
94    : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
95      m_stop_info(),
96      m_reg_context_up(
97          NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
98              process.GetArchitecture(), *this)),
99      m_stop_description() {}
100
101std::string NativeThreadLinux::GetName() {
102  NativeProcessLinux &process = GetProcess();
103
104  auto BufferOrError = getProcFile(process.GetID(), GetID(), "comm");
105  if (!BufferOrError)
106    return "";
107  return std::string(BufferOrError.get()->getBuffer().rtrim('\n'));
108}
109
110lldb::StateType NativeThreadLinux::GetState() { return m_state; }
111
112bool NativeThreadLinux::GetStopReason(ThreadStopInfo &stop_info,
113                                      std::string &description) {
114  Log *log = GetLog(LLDBLog::Thread);
115
116  description.clear();
117
118  switch (m_state) {
119  case eStateStopped:
120  case eStateCrashed:
121  case eStateExited:
122  case eStateSuspended:
123  case eStateUnloaded:
124    if (log)
125      LogThreadStopInfo(*log, m_stop_info, "m_stop_info in thread:");
126    stop_info = m_stop_info;
127    description = m_stop_description;
128    if (log)
129      LogThreadStopInfo(*log, stop_info, "returned stop_info:");
130
131    return true;
132
133  case eStateInvalid:
134  case eStateConnected:
135  case eStateAttaching:
136  case eStateLaunching:
137  case eStateRunning:
138  case eStateStepping:
139  case eStateDetached:
140    if (log) {
141      LLDB_LOGF(log,
142                "NativeThreadLinux::%s tid %" PRIu64
143                " in state %s cannot answer stop reason",
144                __FUNCTION__, GetID(), StateAsCString(m_state));
145    }
146    return false;
147  }
148  llvm_unreachable("unhandled StateType!");
149}
150
151Status NativeThreadLinux::SetWatchpoint(lldb::addr_t addr, size_t size,
152                                        uint32_t watch_flags, bool hardware) {
153  if (!hardware)
154    return Status("not implemented");
155  if (m_state == eStateLaunching)
156    return Status();
157  Status error = RemoveWatchpoint(addr);
158  if (error.Fail())
159    return error;
160  uint32_t wp_index =
161      m_reg_context_up->SetHardwareWatchpoint(addr, size, watch_flags);
162  if (wp_index == LLDB_INVALID_INDEX32)
163    return Status("Setting hardware watchpoint failed.");
164  m_watchpoint_index_map.insert({addr, wp_index});
165  return Status();
166}
167
168Status NativeThreadLinux::RemoveWatchpoint(lldb::addr_t addr) {
169  auto wp = m_watchpoint_index_map.find(addr);
170  if (wp == m_watchpoint_index_map.end())
171    return Status();
172  uint32_t wp_index = wp->second;
173  m_watchpoint_index_map.erase(wp);
174  if (m_reg_context_up->ClearHardwareWatchpoint(wp_index))
175    return Status();
176  return Status("Clearing hardware watchpoint failed.");
177}
178
179Status NativeThreadLinux::SetHardwareBreakpoint(lldb::addr_t addr,
180                                                size_t size) {
181  if (m_state == eStateLaunching)
182    return Status();
183
184  Status error = RemoveHardwareBreakpoint(addr);
185  if (error.Fail())
186    return error;
187
188  uint32_t bp_index = m_reg_context_up->SetHardwareBreakpoint(addr, size);
189
190  if (bp_index == LLDB_INVALID_INDEX32)
191    return Status("Setting hardware breakpoint failed.");
192
193  m_hw_break_index_map.insert({addr, bp_index});
194  return Status();
195}
196
197Status NativeThreadLinux::RemoveHardwareBreakpoint(lldb::addr_t addr) {
198  auto bp = m_hw_break_index_map.find(addr);
199  if (bp == m_hw_break_index_map.end())
200    return Status();
201
202  uint32_t bp_index = bp->second;
203  if (m_reg_context_up->ClearHardwareBreakpoint(bp_index)) {
204    m_hw_break_index_map.erase(bp);
205    return Status();
206  }
207
208  return Status("Clearing hardware breakpoint failed.");
209}
210
211Status NativeThreadLinux::Resume(uint32_t signo) {
212  const StateType new_state = StateType::eStateRunning;
213  MaybeLogStateChange(new_state);
214  m_state = new_state;
215
216  m_stop_info.reason = StopReason::eStopReasonNone;
217  m_stop_description.clear();
218
219  // If watchpoints have been set, but none on this thread, then this is a new
220  // thread. So set all existing watchpoints.
221  if (m_watchpoint_index_map.empty()) {
222    NativeProcessLinux &process = GetProcess();
223
224    const auto &watchpoint_map = process.GetWatchpointMap();
225    m_reg_context_up->ClearAllHardwareWatchpoints();
226    for (const auto &pair : watchpoint_map) {
227      const auto &wp = pair.second;
228      SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
229    }
230  }
231
232  // Set all active hardware breakpoint on all threads.
233  if (m_hw_break_index_map.empty()) {
234    NativeProcessLinux &process = GetProcess();
235
236    const auto &hw_breakpoint_map = process.GetHardwareBreakpointMap();
237    m_reg_context_up->ClearAllHardwareBreakpoints();
238    for (const auto &pair : hw_breakpoint_map) {
239      const auto &bp = pair.second;
240      SetHardwareBreakpoint(bp.m_addr, bp.m_size);
241    }
242  }
243
244  intptr_t data = 0;
245
246  if (signo != LLDB_INVALID_SIGNAL_NUMBER)
247    data = signo;
248
249  return NativeProcessLinux::PtraceWrapper(PTRACE_CONT, GetID(), nullptr,
250                                           reinterpret_cast<void *>(data));
251}
252
253Status NativeThreadLinux::SingleStep(uint32_t signo) {
254  const StateType new_state = StateType::eStateStepping;
255  MaybeLogStateChange(new_state);
256  m_state = new_state;
257  m_stop_info.reason = StopReason::eStopReasonNone;
258
259  if(!m_step_workaround) {
260    // If we already hava a workaround inplace, don't reset it. Otherwise, the
261    // destructor of the existing instance will run after the new instance has
262    // fetched the cpu mask, and the thread will end up with the wrong mask.
263    m_step_workaround = SingleStepWorkaround::Get(m_tid);
264  }
265
266  intptr_t data = 0;
267  if (signo != LLDB_INVALID_SIGNAL_NUMBER)
268    data = signo;
269
270  // If hardware single-stepping is not supported, we just do a continue. The
271  // breakpoint on the next instruction has been setup in
272  // NativeProcessLinux::Resume.
273  return NativeProcessLinux::PtraceWrapper(
274      GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
275                                                   : PTRACE_CONT,
276      m_tid, nullptr, reinterpret_cast<void *>(data));
277}
278
279void NativeThreadLinux::SetStoppedBySignal(uint32_t signo,
280                                           const siginfo_t *info) {
281  Log *log = GetLog(LLDBLog::Thread);
282  LLDB_LOGF(log, "NativeThreadLinux::%s called with signal 0x%02" PRIx32,
283            __FUNCTION__, signo);
284
285  SetStopped();
286
287  m_stop_info.reason = StopReason::eStopReasonSignal;
288  m_stop_info.signo = signo;
289
290  m_stop_description.clear();
291  if (info) {
292    switch (signo) {
293    case SIGSEGV:
294    case SIGBUS:
295    case SIGFPE:
296    case SIGILL:
297      // In case of MIPS64 target, SI_KERNEL is generated for invalid 64bit
298      // address.
299      const auto reason =
300          (info->si_signo == SIGBUS && info->si_code == SI_KERNEL)
301              ? CrashReason::eInvalidAddress
302              : GetCrashReason(*info);
303      m_stop_description = GetCrashReasonString(reason, *info);
304
305      if (reason == CrashReason::eSyncTagCheckFault) {
306        AnnotateSyncTagCheckFault(info);
307      }
308
309      break;
310    }
311  }
312}
313
314void NativeThreadLinux::AnnotateSyncTagCheckFault(const siginfo_t *info) {
315  int32_t allocation_tag_type = 0;
316  switch (GetProcess().GetArchitecture().GetMachine()) {
317  // aarch64_32 deliberately not here because there's no 32 bit MTE
318  case llvm::Triple::aarch64:
319  case llvm::Triple::aarch64_be:
320    allocation_tag_type = MemoryTagManagerAArch64MTE::eMTE_allocation;
321    break;
322  default:
323    return;
324  }
325
326  auto details =
327      GetRegisterContext().GetMemoryTaggingDetails(allocation_tag_type);
328  if (!details) {
329    llvm::consumeError(details.takeError());
330    return;
331  }
332
333  // We assume that the stop description is currently:
334  // signal SIGSEGV: sync tag check fault (fault address: <addr>)
335  // Remove the closing )
336  m_stop_description.pop_back();
337
338  std::stringstream ss;
339  lldb::addr_t fault_addr = reinterpret_cast<uintptr_t>(info->si_addr);
340  std::unique_ptr<MemoryTagManager> manager(std::move(details->manager));
341
342  ss << " logical tag: 0x" << std::hex << manager->GetLogicalTag(fault_addr);
343
344  std::vector<uint8_t> allocation_tag_data;
345  // The fault address may not be granule aligned. ReadMemoryTags will granule
346  // align any range you give it, potentially making it larger.
347  // To prevent this set len to 1. This always results in a range that is at
348  // most 1 granule in size and includes fault_addr.
349  Status status = GetProcess().ReadMemoryTags(allocation_tag_type, fault_addr,
350                                              1, allocation_tag_data);
351
352  if (status.Success()) {
353    llvm::Expected<std::vector<lldb::addr_t>> allocation_tag =
354        manager->UnpackTagsData(allocation_tag_data, 1);
355    if (allocation_tag) {
356      ss << " allocation tag: 0x" << std::hex << allocation_tag->front() << ")";
357    } else {
358      llvm::consumeError(allocation_tag.takeError());
359      ss << ")";
360    }
361  } else
362    ss << ")";
363
364  m_stop_description += ss.str();
365}
366
367bool NativeThreadLinux::IsStopped(int *signo) {
368  if (!StateIsStoppedState(m_state, false))
369    return false;
370
371  // If we are stopped by a signal, return the signo.
372  if (signo && m_state == StateType::eStateStopped &&
373      m_stop_info.reason == StopReason::eStopReasonSignal) {
374    *signo = m_stop_info.signo;
375  }
376
377  // Regardless, we are stopped.
378  return true;
379}
380
381void NativeThreadLinux::SetStopped() {
382  if (m_state == StateType::eStateStepping)
383    m_step_workaround.reset();
384
385  // On every stop, clear any cached register data structures
386  GetRegisterContext().InvalidateAllRegisters();
387
388  const StateType new_state = StateType::eStateStopped;
389  MaybeLogStateChange(new_state);
390  m_state = new_state;
391  m_stop_description.clear();
392}
393
394void NativeThreadLinux::SetStoppedByExec() {
395  Log *log = GetLog(LLDBLog::Thread);
396  LLDB_LOGF(log, "NativeThreadLinux::%s()", __FUNCTION__);
397
398  SetStopped();
399
400  m_stop_info.reason = StopReason::eStopReasonExec;
401  m_stop_info.signo = SIGSTOP;
402}
403
404void NativeThreadLinux::SetStoppedByBreakpoint() {
405  SetStopped();
406
407  m_stop_info.reason = StopReason::eStopReasonBreakpoint;
408  m_stop_info.signo = SIGTRAP;
409  m_stop_description.clear();
410}
411
412void NativeThreadLinux::SetStoppedByWatchpoint(uint32_t wp_index) {
413  SetStopped();
414
415  lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
416
417  std::ostringstream ostr;
418  ostr << m_reg_context_up->GetWatchpointAddress(wp_index) << " ";
419  ostr << wp_index;
420
421  /*
422   * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For
423   * example:
424   * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at
425   * 'm', then
426   * watch exception is generated even when 'n' is read/written. To handle this
427   * case,
428   * find the base address of the load/store instruction and append it in the
429   * stop-info
430   * packet.
431  */
432  ostr << " " << m_reg_context_up->GetWatchpointHitAddress(wp_index);
433
434  m_stop_description = ostr.str();
435
436  m_stop_info.reason = StopReason::eStopReasonWatchpoint;
437  m_stop_info.signo = SIGTRAP;
438}
439
440bool NativeThreadLinux::IsStoppedAtBreakpoint() {
441  return GetState() == StateType::eStateStopped &&
442         m_stop_info.reason == StopReason::eStopReasonBreakpoint;
443}
444
445bool NativeThreadLinux::IsStoppedAtWatchpoint() {
446  return GetState() == StateType::eStateStopped &&
447         m_stop_info.reason == StopReason::eStopReasonWatchpoint;
448}
449
450void NativeThreadLinux::SetStoppedByTrace() {
451  SetStopped();
452
453  m_stop_info.reason = StopReason::eStopReasonTrace;
454  m_stop_info.signo = SIGTRAP;
455}
456
457void NativeThreadLinux::SetStoppedByFork(bool is_vfork, lldb::pid_t child_pid) {
458  SetStopped();
459
460  m_stop_info.reason =
461      is_vfork ? StopReason::eStopReasonVFork : StopReason::eStopReasonFork;
462  m_stop_info.signo = SIGTRAP;
463  m_stop_info.details.fork.child_pid = child_pid;
464  m_stop_info.details.fork.child_tid = child_pid;
465}
466
467void NativeThreadLinux::SetStoppedByVForkDone() {
468  SetStopped();
469
470  m_stop_info.reason = StopReason::eStopReasonVForkDone;
471  m_stop_info.signo = SIGTRAP;
472}
473
474void NativeThreadLinux::SetStoppedWithNoReason() {
475  SetStopped();
476
477  m_stop_info.reason = StopReason::eStopReasonNone;
478  m_stop_info.signo = 0;
479}
480
481void NativeThreadLinux::SetStoppedByProcessorTrace(
482    llvm::StringRef description) {
483  SetStopped();
484
485  m_stop_info.reason = StopReason::eStopReasonProcessorTrace;
486  m_stop_info.signo = 0;
487  m_stop_description = description.str();
488}
489
490void NativeThreadLinux::SetExited() {
491  const StateType new_state = StateType::eStateExited;
492  MaybeLogStateChange(new_state);
493  m_state = new_state;
494
495  m_stop_info.reason = StopReason::eStopReasonThreadExiting;
496}
497
498Status NativeThreadLinux::RequestStop() {
499  Log *log = GetLog(LLDBLog::Thread);
500
501  NativeProcessLinux &process = GetProcess();
502
503  lldb::pid_t pid = process.GetID();
504  lldb::tid_t tid = GetID();
505
506  LLDB_LOGF(log,
507            "NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64
508            ", tid: %" PRIu64 ")",
509            __FUNCTION__, pid, tid);
510
511  Status err;
512  errno = 0;
513  if (::tgkill(pid, tid, SIGSTOP) != 0) {
514    err.SetErrorToErrno();
515    LLDB_LOGF(log,
516              "NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64
517              ", SIGSTOP) failed: %s",
518              __FUNCTION__, pid, tid, err.AsCString());
519  }
520
521  return err;
522}
523
524void NativeThreadLinux::MaybeLogStateChange(lldb::StateType new_state) {
525  Log *log = GetLog(LLDBLog::Thread);
526  // If we're not logging, we're done.
527  if (!log)
528    return;
529
530  // If this is a state change to the same state, we're done.
531  lldb::StateType old_state = m_state;
532  if (new_state == old_state)
533    return;
534
535  LLDB_LOG(log, "pid={0}, tid={1}: changing from state {2} to {3}",
536           m_process.GetID(), GetID(), old_state, new_state);
537}
538
539NativeProcessLinux &NativeThreadLinux::GetProcess() {
540  return static_cast<NativeProcessLinux &>(m_process);
541}
542
543const NativeProcessLinux &NativeThreadLinux::GetProcess() const {
544  return static_cast<const NativeProcessLinux &>(m_process);
545}
546
547llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
548NativeThreadLinux::GetSiginfo() const {
549  auto siginfo_buf =
550      llvm::WritableMemoryBuffer::getNewUninitMemBuffer(sizeof(siginfo_t));
551  Status error =
552      GetProcess().GetSignalInfo(GetID(), siginfo_buf->getBufferStart());
553  if (!error.Success())
554    return error.ToError();
555  return std::move(siginfo_buf);
556}
557