blob: 83f1da78d01d03eb0ebe19dfb1efad9747675e23 [file] [log] [blame]
Kamil Rytarowski1a3d19d2017-03-21 17:30:47 +00001//===-- NativeThreadNetBSD.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 "NativeThreadNetBSD.h"
11#include "NativeRegisterContextNetBSD.h"
12
13#include "NativeProcessNetBSD.h"
14
Kamil Rytarowskif07a9992017-03-28 22:43:17 +000015#include "Plugins/Process/POSIX/CrashReason.h"
16#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
17#include "lldb/Core/RegisterValue.h"
18#include "lldb/Core/State.h"
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +000019#include "lldb/Utility/LLDBAssert.h"
20
21#include <sstream>
Kamil Rytarowskif07a9992017-03-28 22:43:17 +000022
Kamil Rytarowski1a3d19d2017-03-21 17:30:47 +000023using namespace lldb;
24using namespace lldb_private;
25using namespace lldb_private::process_netbsd;
26
Pavel Labath82abefa2017-07-18 09:24:48 +000027NativeThreadNetBSD::NativeThreadNetBSD(NativeProcessNetBSD &process,
Kamil Rytarowski1a3d19d2017-03-21 17:30:47 +000028 lldb::tid_t tid)
Kamil Rytarowskif07a9992017-03-28 22:43:17 +000029 : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
Pavel Labathd37349f2017-11-10 11:05:49 +000030 m_stop_info(), m_reg_context_up(
31NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(process.GetArchitecture(), *this)
32), m_stop_description() {}
Kamil Rytarowskif07a9992017-03-28 22:43:17 +000033
34void NativeThreadNetBSD::SetStoppedBySignal(uint32_t signo,
35 const siginfo_t *info) {
36 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
37 LLDB_LOG(log, "tid = {0} in called with signal {1}", GetID(), signo);
38
39 SetStopped();
40
41 m_stop_info.reason = StopReason::eStopReasonSignal;
42 m_stop_info.details.signal.signo = signo;
43
44 m_stop_description.clear();
45 if (info) {
46 switch (signo) {
47 case SIGSEGV:
48 case SIGBUS:
49 case SIGFPE:
50 case SIGILL:
51 const auto reason = GetCrashReason(*info);
52 m_stop_description = GetCrashReasonString(reason, *info);
53 break;
54 }
55 }
56}
57
58void NativeThreadNetBSD::SetStoppedByBreakpoint() {
59 SetStopped();
60 m_stop_info.reason = StopReason::eStopReasonBreakpoint;
61 m_stop_info.details.signal.signo = SIGTRAP;
62}
63
Kamil Rytarowski3eef2b52017-03-30 20:25:29 +000064void NativeThreadNetBSD::SetStoppedByTrace() {
65 SetStopped();
66 m_stop_info.reason = StopReason::eStopReasonTrace;
67 m_stop_info.details.signal.signo = SIGTRAP;
68}
69
70void NativeThreadNetBSD::SetStoppedByExec() {
71 SetStopped();
72 m_stop_info.reason = StopReason::eStopReasonExec;
73 m_stop_info.details.signal.signo = SIGTRAP;
74}
75
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +000076void NativeThreadNetBSD::SetStoppedByWatchpoint(uint32_t wp_index) {
77 SetStopped();
78
79 lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
80
81 std::ostringstream ostr;
Pavel Labathd37349f2017-11-10 11:05:49 +000082 ostr << GetRegisterContext().GetWatchpointAddress(wp_index) << " ";
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +000083 ostr << wp_index;
84
Pavel Labathd37349f2017-11-10 11:05:49 +000085 ostr << " " << GetRegisterContext().GetWatchpointHitAddress(wp_index);
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +000086
87 m_stop_description = ostr.str();
88
89 m_stop_info.reason = StopReason::eStopReasonWatchpoint;
90 m_stop_info.details.signal.signo = SIGTRAP;
91}
92
Kamil Rytarowskif07a9992017-03-28 22:43:17 +000093void NativeThreadNetBSD::SetStopped() {
94 const StateType new_state = StateType::eStateStopped;
95 m_state = new_state;
96 m_stop_description.clear();
97}
98
99void NativeThreadNetBSD::SetRunning() {
100 m_state = StateType::eStateRunning;
101 m_stop_info.reason = StopReason::eStopReasonNone;
102}
103
Kamil Rytarowski3eef2b52017-03-30 20:25:29 +0000104void NativeThreadNetBSD::SetStepping() {
105 m_state = StateType::eStateStepping;
106 m_stop_info.reason = StopReason::eStopReasonNone;
107}
108
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000109std::string NativeThreadNetBSD::GetName() { return std::string(""); }
110
111lldb::StateType NativeThreadNetBSD::GetState() { return m_state; }
112
113bool NativeThreadNetBSD::GetStopReason(ThreadStopInfo &stop_info,
114 std::string &description) {
115 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
116
117 description.clear();
118
119 switch (m_state) {
120 case eStateStopped:
121 case eStateCrashed:
122 case eStateExited:
123 case eStateSuspended:
124 case eStateUnloaded:
125 stop_info = m_stop_info;
126 description = m_stop_description;
127
128 return true;
129
130 case eStateInvalid:
131 case eStateConnected:
132 case eStateAttaching:
133 case eStateLaunching:
134 case eStateRunning:
135 case eStateStepping:
136 case eStateDetached:
137 LLDB_LOG(log, "tid = {0} in state {1} cannot answer stop reason", GetID(),
138 StateAsCString(m_state));
139 return false;
140 }
141 llvm_unreachable("unhandled StateType!");
142}
143
Pavel Labathd37349f2017-11-10 11:05:49 +0000144NativeRegisterContext& NativeThreadNetBSD::GetRegisterContext() {
145 assert(m_reg_context_up);
146return *m_reg_context_up;
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000147}
148
Zachary Turner97206d52017-05-12 04:51:55 +0000149Status NativeThreadNetBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
150 uint32_t watch_flags, bool hardware) {
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000151 if (!hardware)
Zachary Turner97206d52017-05-12 04:51:55 +0000152 return Status("not implemented");
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000153 if (m_state == eStateLaunching)
Zachary Turner97206d52017-05-12 04:51:55 +0000154 return Status();
155 Status error = RemoveWatchpoint(addr);
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000156 if (error.Fail())
157 return error;
Pavel Labathd37349f2017-11-10 11:05:49 +0000158 uint32_t wp_index = GetRegisterContext().SetHardwareWatchpoint(addr, size, watch_flags);
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000159 if (wp_index == LLDB_INVALID_INDEX32)
Zachary Turner97206d52017-05-12 04:51:55 +0000160 return Status("Setting hardware watchpoint failed.");
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000161 m_watchpoint_index_map.insert({addr, wp_index});
Zachary Turner97206d52017-05-12 04:51:55 +0000162 return Status();
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000163}
164
Zachary Turner97206d52017-05-12 04:51:55 +0000165Status NativeThreadNetBSD::RemoveWatchpoint(lldb::addr_t addr) {
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000166 auto wp = m_watchpoint_index_map.find(addr);
167 if (wp == m_watchpoint_index_map.end())
Zachary Turner97206d52017-05-12 04:51:55 +0000168 return Status();
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000169 uint32_t wp_index = wp->second;
170 m_watchpoint_index_map.erase(wp);
Pavel Labathd37349f2017-11-10 11:05:49 +0000171 if (GetRegisterContext().ClearHardwareWatchpoint(wp_index))
Zachary Turner97206d52017-05-12 04:51:55 +0000172 return Status();
173 return Status("Clearing hardware watchpoint failed.");
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000174}
175
Zachary Turner97206d52017-05-12 04:51:55 +0000176Status NativeThreadNetBSD::SetHardwareBreakpoint(lldb::addr_t addr,
177 size_t size) {
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000178 if (m_state == eStateLaunching)
Zachary Turner97206d52017-05-12 04:51:55 +0000179 return Status();
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000180
Zachary Turner97206d52017-05-12 04:51:55 +0000181 Status error = RemoveHardwareBreakpoint(addr);
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000182 if (error.Fail())
183 return error;
184
Pavel Labathd37349f2017-11-10 11:05:49 +0000185 uint32_t bp_index = GetRegisterContext().SetHardwareBreakpoint(addr, size);
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000186
187 if (bp_index == LLDB_INVALID_INDEX32)
Zachary Turner97206d52017-05-12 04:51:55 +0000188 return Status("Setting hardware breakpoint failed.");
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000189
190 m_hw_break_index_map.insert({addr, bp_index});
Zachary Turner97206d52017-05-12 04:51:55 +0000191 return Status();
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000192}
193
Zachary Turner97206d52017-05-12 04:51:55 +0000194Status NativeThreadNetBSD::RemoveHardwareBreakpoint(lldb::addr_t addr) {
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000195 auto bp = m_hw_break_index_map.find(addr);
196 if (bp == m_hw_break_index_map.end())
Zachary Turner97206d52017-05-12 04:51:55 +0000197 return Status();
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000198
199 uint32_t bp_index = bp->second;
Pavel Labathd37349f2017-11-10 11:05:49 +0000200 if (GetRegisterContext().ClearHardwareBreakpoint(bp_index)) {
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000201 m_hw_break_index_map.erase(bp);
Zachary Turner97206d52017-05-12 04:51:55 +0000202 return Status();
Kamil Rytarowski36e23ec2017-04-18 12:53:35 +0000203 }
204
Zachary Turner97206d52017-05-12 04:51:55 +0000205 return Status("Clearing hardware breakpoint failed.");
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000206}