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