ProcessFreeBSD.cpp revision 344779
1314564Sdim//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++ 2314564Sdim//-*-===// 3254721Semaste// 4254721Semaste// The LLVM Compiler Infrastructure 5254721Semaste// 6254721Semaste// This file is distributed under the University of Illinois Open Source 7254721Semaste// License. See LICENSE.TXT for details. 8254721Semaste// 9254721Semaste//===----------------------------------------------------------------------===// 10254721Semaste 11254721Semaste#include <errno.h> 12321369Sdim#include <pthread.h> 13321369Sdim#include <pthread_np.h> 14321369Sdim#include <stdlib.h> 15321369Sdim#include <sys/sysctl.h> 16321369Sdim#include <sys/types.h> 17321369Sdim#include <sys/user.h> 18321369Sdim#include <machine/elf.h> 19254721Semaste 20288943Sdim#include <mutex> 21321369Sdim#include <unordered_map> 22288943Sdim 23254721Semaste#include "lldb/Core/PluginManager.h" 24344779Sdim#include "lldb/Host/FileSystem.h" 25254721Semaste#include "lldb/Host/Host.h" 26254721Semaste#include "lldb/Symbol/ObjectFile.h" 27254721Semaste#include "lldb/Target/DynamicLoader.h" 28254721Semaste#include "lldb/Target/Target.h" 29344779Sdim#include "lldb/Utility/RegisterValue.h" 30344779Sdim#include "lldb/Utility/State.h" 31254721Semaste 32314564Sdim#include "FreeBSDThread.h" 33321369Sdim#include "Plugins/Process/POSIX/ProcessPOSIXLog.h" 34314564Sdim#include "Plugins/Process/Utility/FreeBSDSignals.h" 35314564Sdim#include "Plugins/Process/Utility/InferiorCallPOSIX.h" 36254721Semaste#include "ProcessFreeBSD.h" 37314564Sdim#include "ProcessMonitor.h" 38254721Semaste 39296417Sdim#include "lldb/Breakpoint/BreakpointLocation.h" 40296417Sdim#include "lldb/Breakpoint/Watchpoint.h" 41296417Sdim#include "lldb/Core/Module.h" 42296417Sdim#include "lldb/Core/ModuleSpec.h" 43296417Sdim#include "lldb/Core/PluginManager.h" 44296417Sdim#include "lldb/Host/Host.h" 45296417Sdim#include "lldb/Symbol/ObjectFile.h" 46296417Sdim#include "lldb/Target/DynamicLoader.h" 47296417Sdim#include "lldb/Target/Platform.h" 48296417Sdim#include "lldb/Target/Target.h" 49321369Sdim#include "lldb/Utility/DataBufferHeap.h" 50321369Sdim#include "lldb/Utility/FileSpec.h" 51344779Sdim#include "lldb/Utility/State.h" 52296417Sdim 53296417Sdim#include "lldb/Host/posix/Fcntl.h" 54296417Sdim 55321369Sdim#include "llvm/Support/FileSystem.h" 56321369Sdim#include "llvm/Support/Threading.h" 57321369Sdim 58254721Semasteusing namespace lldb; 59254721Semasteusing namespace lldb_private; 60254721Semaste 61314564Sdimnamespace { 62314564SdimUnixSignalsSP &GetFreeBSDSignals() { 63314564Sdim static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals()); 64314564Sdim return s_freebsd_signals_sp; 65276479Sdim} 66314564Sdim} 67276479Sdim 68254721Semaste//------------------------------------------------------------------------------ 69254721Semaste// Static functions. 70254721Semaste 71254721Semastelldb::ProcessSP 72296417SdimProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp, 73309124Sdim lldb::ListenerSP listener_sp, 74314564Sdim const FileSpec *crash_file_path) { 75314564Sdim lldb::ProcessSP process_sp; 76314564Sdim if (crash_file_path == NULL) 77314564Sdim process_sp.reset( 78314564Sdim new ProcessFreeBSD(target_sp, listener_sp, GetFreeBSDSignals())); 79314564Sdim return process_sp; 80254721Semaste} 81254721Semaste 82314564Sdimvoid ProcessFreeBSD::Initialize() { 83321369Sdim static llvm::once_flag g_once_flag; 84254721Semaste 85321369Sdim llvm::call_once(g_once_flag, []() { 86314564Sdim PluginManager::RegisterPlugin(GetPluginNameStatic(), 87314564Sdim GetPluginDescriptionStatic(), CreateInstance); 88314564Sdim }); 89254721Semaste} 90254721Semaste 91314564Sdimlldb_private::ConstString ProcessFreeBSD::GetPluginNameStatic() { 92314564Sdim static ConstString g_name("freebsd"); 93314564Sdim return g_name; 94254721Semaste} 95254721Semaste 96314564Sdimconst char *ProcessFreeBSD::GetPluginDescriptionStatic() { 97314564Sdim return "Process plugin for FreeBSD"; 98254721Semaste} 99254721Semaste 100254721Semaste//------------------------------------------------------------------------------ 101254721Semaste// ProcessInterface protocol. 102254721Semaste 103314564Sdimlldb_private::ConstString ProcessFreeBSD::GetPluginName() { 104314564Sdim return GetPluginNameStatic(); 105254721Semaste} 106254721Semaste 107314564Sdimuint32_t ProcessFreeBSD::GetPluginVersion() { return 1; } 108254721Semaste 109314564Sdimvoid ProcessFreeBSD::Terminate() {} 110254721Semaste 111321369SdimStatus ProcessFreeBSD::DoDetach(bool keep_stopped) { 112321369Sdim Status error; 113314564Sdim if (keep_stopped) { 114314564Sdim error.SetErrorString("Detaching with keep_stopped true is not currently " 115314564Sdim "supported on FreeBSD."); 116314564Sdim return error; 117314564Sdim } 118258054Semaste 119314564Sdim error = m_monitor->Detach(GetID()); 120258054Semaste 121314564Sdim if (error.Success()) 122314564Sdim SetPrivateState(eStateDetached); 123258054Semaste 124314564Sdim return error; 125258054Semaste} 126258054Semaste 127321369SdimStatus ProcessFreeBSD::DoResume() { 128314564Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 129258892Semaste 130314564Sdim SetPrivateState(eStateRunning); 131258892Semaste 132314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 133314564Sdim bool do_step = false; 134321369Sdim bool software_single_step = !SupportHardwareSingleStepping(); 135258892Semaste 136314564Sdim for (tid_collection::const_iterator t_pos = m_run_tids.begin(), 137314564Sdim t_end = m_run_tids.end(); 138314564Sdim t_pos != t_end; ++t_pos) { 139314564Sdim m_monitor->ThreadSuspend(*t_pos, false); 140314564Sdim } 141314564Sdim for (tid_collection::const_iterator t_pos = m_step_tids.begin(), 142314564Sdim t_end = m_step_tids.end(); 143314564Sdim t_pos != t_end; ++t_pos) { 144314564Sdim m_monitor->ThreadSuspend(*t_pos, false); 145314564Sdim do_step = true; 146321369Sdim if (software_single_step) { 147321369Sdim Status error = SetupSoftwareSingleStepping(*t_pos); 148321369Sdim if (error.Fail()) 149321369Sdim return error; 150321369Sdim } 151314564Sdim } 152314564Sdim for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(), 153314564Sdim t_end = m_suspend_tids.end(); 154314564Sdim t_pos != t_end; ++t_pos) { 155314564Sdim m_monitor->ThreadSuspend(*t_pos, true); 156314564Sdim // XXX Cannot PT_CONTINUE properly with suspended threads. 157314564Sdim do_step = true; 158314564Sdim } 159258892Semaste 160314564Sdim if (log) 161314564Sdim log->Printf("process %" PRIu64 " resuming (%s)", GetID(), 162314564Sdim do_step ? "step" : "continue"); 163321369Sdim if (do_step && !software_single_step) 164314564Sdim m_monitor->SingleStep(GetID(), m_resume_signo); 165314564Sdim else 166314564Sdim m_monitor->Resume(GetID(), m_resume_signo); 167258892Semaste 168321369Sdim return Status(); 169258892Semaste} 170258892Semaste 171314564Sdimbool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, 172314564Sdim ThreadList &new_thread_list) { 173314564Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 174314564Sdim if (log) 175314564Sdim log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__, 176314564Sdim GetID()); 177258054Semaste 178314564Sdim std::vector<lldb::pid_t> tds; 179314564Sdim if (!GetMonitor().GetCurrentThreadIDs(tds)) { 180314564Sdim return false; 181314564Sdim } 182258054Semaste 183314564Sdim ThreadList old_thread_list_copy(old_thread_list); 184314564Sdim for (size_t i = 0; i < tds.size(); ++i) { 185314564Sdim tid_t tid = tds[i]; 186314564Sdim ThreadSP thread_sp(old_thread_list_copy.RemoveThreadByID(tid, false)); 187314564Sdim if (!thread_sp) { 188314564Sdim thread_sp.reset(new FreeBSDThread(*this, tid)); 189314564Sdim if (log) 190314564Sdim log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid); 191314564Sdim } else { 192314564Sdim if (log) 193314564Sdim log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__, 194314564Sdim tid); 195258892Semaste } 196314564Sdim new_thread_list.AddThread(thread_sp); 197314564Sdim } 198314564Sdim for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) { 199314564Sdim ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false)); 200314564Sdim if (old_thread_sp) { 201314564Sdim if (log) 202314564Sdim log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__); 203258892Semaste } 204314564Sdim } 205258054Semaste 206314564Sdim return true; 207258892Semaste} 208258054Semaste 209321369SdimStatus ProcessFreeBSD::WillResume() { 210314564Sdim m_resume_signo = 0; 211314564Sdim m_suspend_tids.clear(); 212314564Sdim m_run_tids.clear(); 213314564Sdim m_step_tids.clear(); 214314564Sdim return Process::WillResume(); 215254721Semaste} 216258892Semaste 217314564Sdimvoid ProcessFreeBSD::SendMessage(const ProcessMessage &message) { 218314564Sdim std::lock_guard<std::recursive_mutex> guard(m_message_mutex); 219258892Semaste 220314564Sdim switch (message.GetKind()) { 221314564Sdim case ProcessMessage::eInvalidMessage: 222314564Sdim return; 223258892Semaste 224314564Sdim case ProcessMessage::eAttachMessage: 225314564Sdim SetPrivateState(eStateStopped); 226314564Sdim return; 227258892Semaste 228314564Sdim case ProcessMessage::eLimboMessage: 229314564Sdim case ProcessMessage::eExitMessage: 230314564Sdim SetExitStatus(message.GetExitStatus(), NULL); 231314564Sdim break; 232258892Semaste 233314564Sdim case ProcessMessage::eSignalMessage: 234314564Sdim case ProcessMessage::eSignalDeliveredMessage: 235314564Sdim case ProcessMessage::eBreakpointMessage: 236314564Sdim case ProcessMessage::eTraceMessage: 237314564Sdim case ProcessMessage::eWatchpointMessage: 238314564Sdim case ProcessMessage::eCrashMessage: 239314564Sdim SetPrivateState(eStateStopped); 240314564Sdim break; 241258892Semaste 242314564Sdim case ProcessMessage::eNewThreadMessage: 243314564Sdim llvm_unreachable("eNewThreadMessage unexpected on FreeBSD"); 244314564Sdim break; 245258892Semaste 246314564Sdim case ProcessMessage::eExecMessage: 247314564Sdim SetPrivateState(eStateStopped); 248314564Sdim break; 249314564Sdim } 250258892Semaste 251314564Sdim m_message_queue.push(message); 252258892Semaste} 253296417Sdim 254296417Sdim//------------------------------------------------------------------------------ 255296417Sdim// Constructors and destructors. 256296417Sdim 257314564SdimProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp, 258314564Sdim lldb::ListenerSP listener_sp, 259314564Sdim UnixSignalsSP &unix_signals_sp) 260309124Sdim : Process(target_sp, listener_sp, unix_signals_sp), 261314564Sdim m_byte_order(endian::InlHostByteOrder()), m_monitor(NULL), m_module(NULL), 262314564Sdim m_message_mutex(), m_exit_now(false), m_seen_initial_stop(), 263314564Sdim m_resume_signo(0) { 264314564Sdim // FIXME: Putting this code in the ctor and saving the byte order in a 265314564Sdim // member variable is a hack to avoid const qual issues in GetByteOrder. 266314564Sdim lldb::ModuleSP module = GetTarget().GetExecutableModule(); 267314564Sdim if (module && module->GetObjectFile()) 268314564Sdim m_byte_order = module->GetObjectFile()->GetByteOrder(); 269296417Sdim} 270296417Sdim 271314564SdimProcessFreeBSD::~ProcessFreeBSD() { delete m_monitor; } 272296417Sdim 273296417Sdim//------------------------------------------------------------------------------ 274296417Sdim// Process protocol. 275314564Sdimvoid ProcessFreeBSD::Finalize() { 276296417Sdim Process::Finalize(); 277296417Sdim 278296417Sdim if (m_monitor) 279296417Sdim m_monitor->StopMonitor(); 280296417Sdim} 281296417Sdim 282314564Sdimbool ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp, 283314564Sdim bool plugin_specified_by_name) { 284314564Sdim // For now we are just making sure the file exists for a given module 285314564Sdim ModuleSP exe_module_sp(target_sp->GetExecutableModule()); 286314564Sdim if (exe_module_sp.get()) 287344779Sdim return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec()); 288314564Sdim // If there is no executable module, we return true since we might be 289314564Sdim // preparing to attach. 290314564Sdim return true; 291296417Sdim} 292296417Sdim 293321369SdimStatus 294321369SdimProcessFreeBSD::DoAttachToProcessWithID(lldb::pid_t pid, 295321369Sdim const ProcessAttachInfo &attach_info) { 296321369Sdim Status error; 297314564Sdim assert(m_monitor == NULL); 298296417Sdim 299314564Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 300321369Sdim LLDB_LOGV(log, "pid = {0}", GetID()); 301296417Sdim 302314564Sdim m_monitor = new ProcessMonitor(this, pid, error); 303296417Sdim 304314564Sdim if (!error.Success()) 305314564Sdim return error; 306296417Sdim 307314564Sdim PlatformSP platform_sp(GetTarget().GetPlatform()); 308314564Sdim assert(platform_sp.get()); 309314564Sdim if (!platform_sp) 310314564Sdim return error; // FIXME: Detatch? 311296417Sdim 312314564Sdim // Find out what we can about this process 313314564Sdim ProcessInstanceInfo process_info; 314314564Sdim platform_sp->GetProcessInfo(pid, process_info); 315296417Sdim 316314564Sdim // Resolve the executable module 317314564Sdim ModuleSP exe_module_sp; 318314564Sdim FileSpecList executable_search_paths( 319314564Sdim Target::GetDefaultExecutableSearchPaths()); 320314564Sdim ModuleSpec exe_module_spec(process_info.GetExecutableFile(), 321314564Sdim GetTarget().GetArchitecture()); 322314564Sdim error = platform_sp->ResolveExecutable( 323314564Sdim exe_module_spec, exe_module_sp, 324314564Sdim executable_search_paths.GetSize() ? &executable_search_paths : NULL); 325314564Sdim if (!error.Success()) 326314564Sdim return error; 327296417Sdim 328314564Sdim // Fix the target architecture if necessary 329314564Sdim const ArchSpec &module_arch = exe_module_sp->GetArchitecture(); 330314564Sdim if (module_arch.IsValid() && 331314564Sdim !GetTarget().GetArchitecture().IsExactMatch(module_arch)) 332314564Sdim GetTarget().SetArchitecture(module_arch); 333296417Sdim 334314564Sdim // Initialize the target module list 335344779Sdim GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsYes); 336296417Sdim 337314564Sdim SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); 338296417Sdim 339314564Sdim SetID(pid); 340296417Sdim 341314564Sdim return error; 342296417Sdim} 343296417Sdim 344321369SdimStatus ProcessFreeBSD::WillLaunch(Module *module) { 345321369Sdim Status error; 346314564Sdim return error; 347296417Sdim} 348296417Sdim 349296417SdimFileSpec 350296417SdimProcessFreeBSD::GetFileSpec(const lldb_private::FileAction *file_action, 351314564Sdim const FileSpec &default_file_spec, 352314564Sdim const FileSpec &dbg_pts_file_spec) { 353314564Sdim FileSpec file_spec{}; 354296417Sdim 355314564Sdim if (file_action && file_action->GetAction() == FileAction::eFileActionOpen) { 356314564Sdim file_spec = file_action->GetFileSpec(); 357341825Sdim // By default the stdio paths passed in will be pseudo-terminal (/dev/pts). 358341825Sdim // If so, convert to using a different default path instead to redirect I/O 359341825Sdim // to the debugger console. This should also handle user overrides to 360341825Sdim // /dev/null or a different file. 361314564Sdim if (!file_spec || file_spec == dbg_pts_file_spec) 362314564Sdim file_spec = default_file_spec; 363314564Sdim } 364314564Sdim return file_spec; 365296417Sdim} 366296417Sdim 367321369SdimStatus ProcessFreeBSD::DoLaunch(Module *module, 368321369Sdim ProcessLaunchInfo &launch_info) { 369321369Sdim Status error; 370314564Sdim assert(m_monitor == NULL); 371296417Sdim 372314564Sdim FileSpec working_dir = launch_info.GetWorkingDirectory(); 373344779Sdim if (working_dir) { 374344779Sdim FileSystem::Instance().Resolve(working_dir); 375344779Sdim if (!FileSystem::Instance().IsDirectory(working_dir.GetPath())) { 376344779Sdim error.SetErrorStringWithFormat("No such file or directory: %s", 377314564Sdim working_dir.GetCString()); 378344779Sdim return error; 379344779Sdim } 380314564Sdim } 381296417Sdim 382314564Sdim SetPrivateState(eStateLaunching); 383296417Sdim 384314564Sdim const lldb_private::FileAction *file_action; 385296417Sdim 386314564Sdim // Default of empty will mean to use existing open file descriptors 387314564Sdim FileSpec stdin_file_spec{}; 388314564Sdim FileSpec stdout_file_spec{}; 389314564Sdim FileSpec stderr_file_spec{}; 390296417Sdim 391344779Sdim const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0)}; 392296417Sdim 393314564Sdim file_action = launch_info.GetFileActionForFD(STDIN_FILENO); 394314564Sdim stdin_file_spec = 395314564Sdim GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec); 396296417Sdim 397314564Sdim file_action = launch_info.GetFileActionForFD(STDOUT_FILENO); 398314564Sdim stdout_file_spec = 399314564Sdim GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec); 400296417Sdim 401314564Sdim file_action = launch_info.GetFileActionForFD(STDERR_FILENO); 402314564Sdim stderr_file_spec = 403314564Sdim GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec); 404296417Sdim 405314564Sdim m_monitor = new ProcessMonitor( 406314564Sdim this, module, launch_info.GetArguments().GetConstArgumentVector(), 407341825Sdim launch_info.GetEnvironment(), stdin_file_spec, stdout_file_spec, 408341825Sdim stderr_file_spec, working_dir, launch_info, error); 409296417Sdim 410314564Sdim m_module = module; 411296417Sdim 412314564Sdim if (!error.Success()) 413314564Sdim return error; 414296417Sdim 415314564Sdim int terminal = m_monitor->GetTerminalFD(); 416314564Sdim if (terminal >= 0) { 417314564Sdim// The reader thread will close the file descriptor when done, so we pass it a 418314564Sdim// copy. 419296417Sdim#ifdef F_DUPFD_CLOEXEC 420314564Sdim int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0); 421314564Sdim if (stdio == -1) { 422314564Sdim error.SetErrorToErrno(); 423314564Sdim return error; 424314564Sdim } 425296417Sdim#else 426314564Sdim // Special case when F_DUPFD_CLOEXEC does not exist (Debian kFreeBSD) 427314564Sdim int stdio = fcntl(terminal, F_DUPFD, 0); 428314564Sdim if (stdio == -1) { 429314564Sdim error.SetErrorToErrno(); 430314564Sdim return error; 431314564Sdim } 432314564Sdim stdio = fcntl(terminal, F_SETFD, FD_CLOEXEC); 433314564Sdim if (stdio == -1) { 434314564Sdim error.SetErrorToErrno(); 435314564Sdim return error; 436314564Sdim } 437296417Sdim#endif 438314564Sdim SetSTDIOFileDescriptor(stdio); 439314564Sdim } 440296417Sdim 441314564Sdim SetID(m_monitor->GetPID()); 442314564Sdim return error; 443296417Sdim} 444296417Sdim 445314564Sdimvoid ProcessFreeBSD::DidLaunch() {} 446296417Sdim 447314564Sdimaddr_t ProcessFreeBSD::GetImageInfoAddress() { 448314564Sdim Target *target = &GetTarget(); 449314564Sdim ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); 450314564Sdim Address addr = obj_file->GetImageInfoAddress(target); 451296417Sdim 452314564Sdim if (addr.IsValid()) 453314564Sdim return addr.GetLoadAddress(target); 454314564Sdim return LLDB_INVALID_ADDRESS; 455296417Sdim} 456296417Sdim 457321369SdimStatus ProcessFreeBSD::DoHalt(bool &caused_stop) { 458321369Sdim Status error; 459296417Sdim 460314564Sdim if (IsStopped()) { 461314564Sdim caused_stop = false; 462314564Sdim } else if (kill(GetID(), SIGSTOP)) { 463314564Sdim caused_stop = false; 464314564Sdim error.SetErrorToErrno(); 465314564Sdim } else { 466314564Sdim caused_stop = true; 467314564Sdim } 468314564Sdim return error; 469296417Sdim} 470296417Sdim 471321369SdimStatus ProcessFreeBSD::DoSignal(int signal) { 472321369Sdim Status error; 473296417Sdim 474314564Sdim if (kill(GetID(), signal)) 475314564Sdim error.SetErrorToErrno(); 476296417Sdim 477314564Sdim return error; 478296417Sdim} 479296417Sdim 480321369SdimStatus ProcessFreeBSD::DoDestroy() { 481321369Sdim Status error; 482296417Sdim 483314564Sdim if (!HasExited()) { 484314564Sdim assert(m_monitor); 485314564Sdim m_exit_now = true; 486314564Sdim if (GetID() == LLDB_INVALID_PROCESS_ID) { 487314564Sdim error.SetErrorString("invalid process id"); 488314564Sdim return error; 489296417Sdim } 490314564Sdim if (!m_monitor->Kill()) { 491314564Sdim error.SetErrorToErrno(); 492314564Sdim return error; 493314564Sdim } 494296417Sdim 495314564Sdim SetPrivateState(eStateExited); 496314564Sdim } 497314564Sdim 498314564Sdim return error; 499296417Sdim} 500296417Sdim 501314564Sdimvoid ProcessFreeBSD::DoDidExec() { 502314564Sdim Target *target = &GetTarget(); 503314564Sdim if (target) { 504314564Sdim PlatformSP platform_sp(target->GetPlatform()); 505314564Sdim assert(platform_sp.get()); 506314564Sdim if (platform_sp) { 507314564Sdim ProcessInstanceInfo process_info; 508314564Sdim platform_sp->GetProcessInfo(GetID(), process_info); 509314564Sdim ModuleSP exe_module_sp; 510314564Sdim ModuleSpec exe_module_spec(process_info.GetExecutableFile(), 511314564Sdim target->GetArchitecture()); 512314564Sdim FileSpecList executable_search_paths( 513314564Sdim Target::GetDefaultExecutableSearchPaths()); 514321369Sdim Status error = platform_sp->ResolveExecutable( 515314564Sdim exe_module_spec, exe_module_sp, 516314564Sdim executable_search_paths.GetSize() ? &executable_search_paths : NULL); 517314564Sdim if (!error.Success()) 518314564Sdim return; 519344779Sdim target->SetExecutableModule(exe_module_sp, eLoadDependentsYes); 520296417Sdim } 521314564Sdim } 522296417Sdim} 523296417Sdim 524314564Sdimbool ProcessFreeBSD::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) { 525314564Sdim bool added_to_set = false; 526314564Sdim ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid); 527314564Sdim if (it == m_seen_initial_stop.end()) { 528314564Sdim m_seen_initial_stop.insert(stop_tid); 529314564Sdim added_to_set = true; 530314564Sdim } 531314564Sdim return added_to_set; 532296417Sdim} 533296417Sdim 534314564Sdimbool ProcessFreeBSD::WaitingForInitialStop(lldb::tid_t stop_tid) { 535314564Sdim return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end()); 536296417Sdim} 537296417Sdim 538296417SdimFreeBSDThread * 539314564SdimProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process, 540314564Sdim lldb::tid_t tid) { 541314564Sdim return new FreeBSDThread(process, tid); 542296417Sdim} 543296417Sdim 544314564Sdimvoid ProcessFreeBSD::RefreshStateAfterStop() { 545314564Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 546321369Sdim LLDB_LOGV(log, "message_queue size = {0}", m_message_queue.size()); 547296417Sdim 548314564Sdim std::lock_guard<std::recursive_mutex> guard(m_message_mutex); 549296417Sdim 550314564Sdim // This method used to only handle one message. Changing it to loop allows 551314564Sdim // it to handle the case where we hit a breakpoint while handling a different 552314564Sdim // breakpoint. 553314564Sdim while (!m_message_queue.empty()) { 554314564Sdim ProcessMessage &message = m_message_queue.front(); 555296417Sdim 556314564Sdim // Resolve the thread this message corresponds to and pass it along. 557314564Sdim lldb::tid_t tid = message.GetTID(); 558321369Sdim LLDB_LOGV(log, " message_queue size = {0}, pid = {1}", 559321369Sdim m_message_queue.size(), tid); 560296417Sdim 561314564Sdim m_thread_list.RefreshStateAfterStop(); 562296417Sdim 563314564Sdim FreeBSDThread *thread = static_cast<FreeBSDThread *>( 564314564Sdim GetThreadList().FindThreadByID(tid, false).get()); 565314564Sdim if (thread) 566314564Sdim thread->Notify(message); 567296417Sdim 568314564Sdim if (message.GetKind() == ProcessMessage::eExitMessage) { 569314564Sdim // FIXME: We should tell the user about this, but the limbo message is 570314564Sdim // probably better for that. 571321369Sdim LLDB_LOG(log, "removing thread, tid = {0}", tid); 572314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 573296417Sdim 574314564Sdim ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false); 575314564Sdim thread_sp.reset(); 576314564Sdim m_seen_initial_stop.erase(tid); 577314564Sdim } 578296417Sdim 579314564Sdim m_message_queue.pop(); 580314564Sdim } 581296417Sdim} 582296417Sdim 583314564Sdimbool ProcessFreeBSD::IsAlive() { 584314564Sdim StateType state = GetPrivateState(); 585314564Sdim return state != eStateDetached && state != eStateExited && 586314564Sdim state != eStateInvalid && state != eStateUnloaded; 587296417Sdim} 588296417Sdim 589314564Sdimsize_t ProcessFreeBSD::DoReadMemory(addr_t vm_addr, void *buf, size_t size, 590321369Sdim Status &error) { 591314564Sdim assert(m_monitor); 592314564Sdim return m_monitor->ReadMemory(vm_addr, buf, size, error); 593296417Sdim} 594296417Sdim 595314564Sdimsize_t ProcessFreeBSD::DoWriteMemory(addr_t vm_addr, const void *buf, 596321369Sdim size_t size, Status &error) { 597314564Sdim assert(m_monitor); 598314564Sdim return m_monitor->WriteMemory(vm_addr, buf, size, error); 599296417Sdim} 600296417Sdim 601314564Sdimaddr_t ProcessFreeBSD::DoAllocateMemory(size_t size, uint32_t permissions, 602321369Sdim Status &error) { 603314564Sdim addr_t allocated_addr = LLDB_INVALID_ADDRESS; 604296417Sdim 605314564Sdim unsigned prot = 0; 606314564Sdim if (permissions & lldb::ePermissionsReadable) 607314564Sdim prot |= eMmapProtRead; 608314564Sdim if (permissions & lldb::ePermissionsWritable) 609314564Sdim prot |= eMmapProtWrite; 610314564Sdim if (permissions & lldb::ePermissionsExecutable) 611314564Sdim prot |= eMmapProtExec; 612296417Sdim 613314564Sdim if (InferiorCallMmap(this, allocated_addr, 0, size, prot, 614314564Sdim eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) { 615314564Sdim m_addr_to_mmap_size[allocated_addr] = size; 616314564Sdim error.Clear(); 617314564Sdim } else { 618314564Sdim allocated_addr = LLDB_INVALID_ADDRESS; 619314564Sdim error.SetErrorStringWithFormat( 620314564Sdim "unable to allocate %zu bytes of memory with permissions %s", size, 621314564Sdim GetPermissionsAsCString(permissions)); 622314564Sdim } 623296417Sdim 624314564Sdim return allocated_addr; 625296417Sdim} 626296417Sdim 627321369SdimStatus ProcessFreeBSD::DoDeallocateMemory(lldb::addr_t addr) { 628321369Sdim Status error; 629314564Sdim MMapMap::iterator pos = m_addr_to_mmap_size.find(addr); 630314564Sdim if (pos != m_addr_to_mmap_size.end() && 631314564Sdim InferiorCallMunmap(this, addr, pos->second)) 632314564Sdim m_addr_to_mmap_size.erase(pos); 633314564Sdim else 634314564Sdim error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, 635314564Sdim addr); 636296417Sdim 637314564Sdim return error; 638296417Sdim} 639296417Sdim 640296417Sdimsize_t 641314564SdimProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) { 642314564Sdim static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xD4}; 643314564Sdim static const uint8_t g_i386_opcode[] = {0xCC}; 644296417Sdim 645314564Sdim ArchSpec arch = GetTarget().GetArchitecture(); 646314564Sdim const uint8_t *opcode = NULL; 647314564Sdim size_t opcode_size = 0; 648296417Sdim 649314564Sdim switch (arch.GetMachine()) { 650314564Sdim default: 651314564Sdim assert(false && "CPU type not supported!"); 652314564Sdim break; 653296417Sdim 654314564Sdim case llvm::Triple::arm: { 655341825Sdim // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the 656341825Sdim // linux kernel does otherwise. 657314564Sdim static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7}; 658314564Sdim static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde}; 659296417Sdim 660314564Sdim lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0)); 661341825Sdim AddressClass addr_class = AddressClass::eUnknown; 662296417Sdim 663314564Sdim if (bp_loc_sp) 664314564Sdim addr_class = bp_loc_sp->GetAddress().GetAddressClass(); 665296417Sdim 666341825Sdim if (addr_class == AddressClass::eCodeAlternateISA || 667341825Sdim (addr_class == AddressClass::eUnknown && 668314564Sdim bp_loc_sp->GetAddress().GetOffset() & 1)) { 669314564Sdim opcode = g_thumb_breakpoint_opcode; 670314564Sdim opcode_size = sizeof(g_thumb_breakpoint_opcode); 671314564Sdim } else { 672314564Sdim opcode = g_arm_breakpoint_opcode; 673314564Sdim opcode_size = sizeof(g_arm_breakpoint_opcode); 674296417Sdim } 675314564Sdim } break; 676314564Sdim case llvm::Triple::aarch64: 677314564Sdim opcode = g_aarch64_opcode; 678314564Sdim opcode_size = sizeof(g_aarch64_opcode); 679314564Sdim break; 680296417Sdim 681314564Sdim case llvm::Triple::x86: 682314564Sdim case llvm::Triple::x86_64: 683314564Sdim opcode = g_i386_opcode; 684314564Sdim opcode_size = sizeof(g_i386_opcode); 685314564Sdim break; 686314564Sdim } 687314564Sdim 688314564Sdim bp_site->SetTrapOpcode(opcode, opcode_size); 689314564Sdim return opcode_size; 690296417Sdim} 691296417Sdim 692321369SdimStatus ProcessFreeBSD::EnableBreakpointSite(BreakpointSite *bp_site) { 693314564Sdim return EnableSoftwareBreakpoint(bp_site); 694296417Sdim} 695296417Sdim 696321369SdimStatus ProcessFreeBSD::DisableBreakpointSite(BreakpointSite *bp_site) { 697314564Sdim return DisableSoftwareBreakpoint(bp_site); 698296417Sdim} 699296417Sdim 700321369SdimStatus ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) { 701321369Sdim Status error; 702314564Sdim if (wp) { 703314564Sdim user_id_t watchID = wp->GetID(); 704314564Sdim addr_t addr = wp->GetLoadAddress(); 705314564Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 706314564Sdim if (log) 707314564Sdim log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")", 708314564Sdim watchID); 709314564Sdim if (wp->IsEnabled()) { 710314564Sdim if (log) 711314564Sdim log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 712314564Sdim ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", 713314564Sdim watchID, (uint64_t)addr); 714314564Sdim return error; 715314564Sdim } 716296417Sdim 717314564Sdim // Try to find a vacant watchpoint slot in the inferiors' main thread 718314564Sdim uint32_t wp_hw_index = LLDB_INVALID_INDEX32; 719314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 720314564Sdim FreeBSDThread *thread = static_cast<FreeBSDThread *>( 721314564Sdim m_thread_list.GetThreadAtIndex(0, false).get()); 722296417Sdim 723314564Sdim if (thread) 724314564Sdim wp_hw_index = thread->FindVacantWatchpointIndex(); 725314564Sdim 726314564Sdim if (wp_hw_index == LLDB_INVALID_INDEX32) { 727314564Sdim error.SetErrorString("Setting hardware watchpoint failed."); 728314564Sdim } else { 729314564Sdim wp->SetHardwareIndex(wp_hw_index); 730314564Sdim bool wp_enabled = true; 731314564Sdim uint32_t thread_count = m_thread_list.GetSize(false); 732314564Sdim for (uint32_t i = 0; i < thread_count; ++i) { 733314564Sdim thread = static_cast<FreeBSDThread *>( 734314564Sdim m_thread_list.GetThreadAtIndex(i, false).get()); 735296417Sdim if (thread) 736314564Sdim wp_enabled &= thread->EnableHardwareWatchpoint(wp); 737296417Sdim else 738314564Sdim wp_enabled = false; 739314564Sdim } 740314564Sdim if (wp_enabled) { 741314564Sdim wp->SetEnabled(true, notify); 742314564Sdim return error; 743314564Sdim } else { 744341825Sdim // Watchpoint enabling failed on at least one of the threads so roll 745341825Sdim // back all of them 746314564Sdim DisableWatchpoint(wp, false); 747314564Sdim error.SetErrorString("Setting hardware watchpoint failed"); 748314564Sdim } 749296417Sdim } 750314564Sdim } else 751314564Sdim error.SetErrorString("Watchpoint argument was NULL."); 752314564Sdim return error; 753296417Sdim} 754296417Sdim 755321369SdimStatus ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify) { 756321369Sdim Status error; 757314564Sdim if (wp) { 758314564Sdim user_id_t watchID = wp->GetID(); 759314564Sdim addr_t addr = wp->GetLoadAddress(); 760314564Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 761314564Sdim if (log) 762314564Sdim log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")", 763314564Sdim watchID); 764314564Sdim if (!wp->IsEnabled()) { 765314564Sdim if (log) 766314564Sdim log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 767314564Sdim ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.", 768314564Sdim watchID, (uint64_t)addr); 769314564Sdim // This is needed (for now) to keep watchpoints disabled correctly 770314564Sdim wp->SetEnabled(false, notify); 771314564Sdim return error; 772314564Sdim } 773296417Sdim 774314564Sdim if (wp->IsHardware()) { 775314564Sdim bool wp_disabled = true; 776314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 777314564Sdim uint32_t thread_count = m_thread_list.GetSize(false); 778314564Sdim for (uint32_t i = 0; i < thread_count; ++i) { 779314564Sdim FreeBSDThread *thread = static_cast<FreeBSDThread *>( 780314564Sdim m_thread_list.GetThreadAtIndex(i, false).get()); 781314564Sdim if (thread) 782314564Sdim wp_disabled &= thread->DisableHardwareWatchpoint(wp); 783314564Sdim else 784314564Sdim wp_disabled = false; 785314564Sdim } 786314564Sdim if (wp_disabled) { 787314564Sdim wp->SetHardwareIndex(LLDB_INVALID_INDEX32); 788314564Sdim wp->SetEnabled(false, notify); 789314564Sdim return error; 790314564Sdim } else 791314564Sdim error.SetErrorString("Disabling hardware watchpoint failed"); 792296417Sdim } 793314564Sdim } else 794314564Sdim error.SetErrorString("Watchpoint argument was NULL."); 795314564Sdim return error; 796296417Sdim} 797296417Sdim 798321369SdimStatus ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num) { 799321369Sdim Status error; 800314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 801314564Sdim FreeBSDThread *thread = static_cast<FreeBSDThread *>( 802314564Sdim m_thread_list.GetThreadAtIndex(0, false).get()); 803314564Sdim if (thread) 804314564Sdim num = thread->NumSupportedHardwareWatchpoints(); 805314564Sdim else 806314564Sdim error.SetErrorString("Process does not exist."); 807314564Sdim return error; 808296417Sdim} 809296417Sdim 810321369SdimStatus ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after) { 811321369Sdim Status error = GetWatchpointSupportInfo(num); 812341825Sdim // Watchpoints trigger and halt the inferior after the corresponding 813341825Sdim // instruction has been executed. 814314564Sdim after = true; 815314564Sdim return error; 816296417Sdim} 817296417Sdim 818314564Sdimuint32_t ProcessFreeBSD::UpdateThreadListIfNeeded() { 819314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 820314564Sdim // Do not allow recursive updates. 821314564Sdim return m_thread_list.GetSize(false); 822296417Sdim} 823296417Sdim 824314564SdimByteOrder ProcessFreeBSD::GetByteOrder() const { 825314564Sdim // FIXME: We should be able to extract this value directly. See comment in 826314564Sdim // ProcessFreeBSD(). 827314564Sdim return m_byte_order; 828296417Sdim} 829296417Sdim 830321369Sdimsize_t ProcessFreeBSD::PutSTDIN(const char *buf, size_t len, Status &error) { 831314564Sdim ssize_t status; 832314564Sdim if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) { 833314564Sdim error.SetErrorToErrno(); 834314564Sdim return 0; 835314564Sdim } 836314564Sdim return status; 837296417Sdim} 838296417Sdim 839296417Sdim//------------------------------------------------------------------------------ 840296417Sdim// Utility functions. 841296417Sdim 842314564Sdimbool ProcessFreeBSD::HasExited() { 843314564Sdim switch (GetPrivateState()) { 844314564Sdim default: 845314564Sdim break; 846296417Sdim 847314564Sdim case eStateDetached: 848314564Sdim case eStateExited: 849314564Sdim return true; 850314564Sdim } 851296417Sdim 852314564Sdim return false; 853296417Sdim} 854296417Sdim 855314564Sdimbool ProcessFreeBSD::IsStopped() { 856314564Sdim switch (GetPrivateState()) { 857314564Sdim default: 858314564Sdim break; 859296417Sdim 860314564Sdim case eStateStopped: 861314564Sdim case eStateCrashed: 862314564Sdim case eStateSuspended: 863314564Sdim return true; 864314564Sdim } 865296417Sdim 866314564Sdim return false; 867296417Sdim} 868296417Sdim 869314564Sdimbool ProcessFreeBSD::IsAThreadRunning() { 870314564Sdim bool is_running = false; 871314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 872314564Sdim uint32_t thread_count = m_thread_list.GetSize(false); 873314564Sdim for (uint32_t i = 0; i < thread_count; ++i) { 874314564Sdim FreeBSDThread *thread = static_cast<FreeBSDThread *>( 875314564Sdim m_thread_list.GetThreadAtIndex(i, false).get()); 876314564Sdim StateType thread_state = thread->GetState(); 877314564Sdim if (thread_state == eStateRunning || thread_state == eStateStepping) { 878314564Sdim is_running = true; 879314564Sdim break; 880296417Sdim } 881314564Sdim } 882314564Sdim return is_running; 883296417Sdim} 884296417Sdim 885314564Sdimconst DataBufferSP ProcessFreeBSD::GetAuxvData() { 886314564Sdim // If we're the local platform, we can ask the host for auxv data. 887314564Sdim PlatformSP platform_sp = GetTarget().GetPlatform(); 888321369Sdim assert(platform_sp && platform_sp->IsHost()); 889296417Sdim 890321369Sdim int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV, (int)m_process->GetID()}; 891321369Sdim size_t auxv_size = AT_COUNT * sizeof(Elf_Auxinfo); 892321369Sdim DataBufferSP buf_sp(new DataBufferHeap(auxv_size, 0)); 893321369Sdim 894321369Sdim if (::sysctl(mib, 4, buf_sp->GetBytes(), &auxv_size, NULL, 0) != 0) { 895321369Sdim perror("sysctl failed on auxv"); 896321369Sdim buf_sp.reset(); 897321369Sdim } 898321369Sdim 899321369Sdim return buf_sp; 900296417Sdim} 901321369Sdim 902321369Sdimstruct EmulatorBaton { 903321369Sdim ProcessFreeBSD *m_process; 904321369Sdim RegisterContext *m_reg_context; 905321369Sdim 906321369Sdim // eRegisterKindDWARF -> RegisterValue 907321369Sdim std::unordered_map<uint32_t, RegisterValue> m_register_values; 908321369Sdim 909321369Sdim EmulatorBaton(ProcessFreeBSD *process, RegisterContext *reg_context) 910321369Sdim : m_process(process), m_reg_context(reg_context) {} 911321369Sdim}; 912321369Sdim 913321369Sdimstatic size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton, 914321369Sdim const EmulateInstruction::Context &context, 915321369Sdim lldb::addr_t addr, void *dst, size_t length) { 916321369Sdim EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton); 917321369Sdim 918321369Sdim Status error; 919321369Sdim size_t bytes_read = 920321369Sdim emulator_baton->m_process->DoReadMemory(addr, dst, length, error); 921321369Sdim if (!error.Success()) 922321369Sdim bytes_read = 0; 923321369Sdim return bytes_read; 924321369Sdim} 925321369Sdim 926321369Sdimstatic bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton, 927321369Sdim const RegisterInfo *reg_info, 928321369Sdim RegisterValue ®_value) { 929321369Sdim EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton); 930321369Sdim 931321369Sdim auto it = emulator_baton->m_register_values.find( 932321369Sdim reg_info->kinds[eRegisterKindDWARF]); 933321369Sdim if (it != emulator_baton->m_register_values.end()) { 934321369Sdim reg_value = it->second; 935321369Sdim return true; 936321369Sdim } 937321369Sdim 938321369Sdim // The emulator only fills in the dwarf register numbers (and in some cases 939321369Sdim // the generic register numbers). Get the full register info from the 940321369Sdim // register context based on the dwarf register numbers. 941321369Sdim const RegisterInfo *full_reg_info = 942321369Sdim emulator_baton->m_reg_context->GetRegisterInfo( 943321369Sdim eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]); 944321369Sdim 945321369Sdim bool error = 946321369Sdim emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value); 947321369Sdim return error; 948321369Sdim} 949321369Sdim 950321369Sdimstatic bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton, 951321369Sdim const EmulateInstruction::Context &context, 952321369Sdim const RegisterInfo *reg_info, 953321369Sdim const RegisterValue ®_value) { 954321369Sdim EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton); 955321369Sdim emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] = 956321369Sdim reg_value; 957321369Sdim return true; 958321369Sdim} 959321369Sdim 960321369Sdimstatic size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton, 961321369Sdim const EmulateInstruction::Context &context, 962321369Sdim lldb::addr_t addr, const void *dst, 963321369Sdim size_t length) { 964321369Sdim return length; 965321369Sdim} 966321369Sdim 967321369Sdimbool ProcessFreeBSD::SingleStepBreakpointHit( 968321369Sdim void *baton, lldb_private::StoppointCallbackContext *context, 969321369Sdim lldb::user_id_t break_id, lldb::user_id_t break_loc_id) { 970321369Sdim return false; 971321369Sdim} 972321369Sdim 973321369SdimStatus ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid, 974321369Sdim lldb::addr_t addr) { 975321369Sdim Status error; 976321369Sdim 977321369Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 978321369Sdim if (log) { 979321369Sdim log->Printf("ProcessFreeBSD::%s addr = 0x%" PRIx64, __FUNCTION__, addr); 980321369Sdim log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr); 981321369Sdim } 982321369Sdim 983321369Sdim // Validate the address. 984321369Sdim if (addr == LLDB_INVALID_ADDRESS) 985321369Sdim return Status("ProcessFreeBSD::%s invalid load address specified.", 986321369Sdim __FUNCTION__); 987321369Sdim 988321369Sdim Breakpoint *const sw_step_break = 989321369Sdim m_process->GetTarget().CreateBreakpoint(addr, true, false).get(); 990321369Sdim sw_step_break->SetCallback(SingleStepBreakpointHit, this, true); 991321369Sdim sw_step_break->SetBreakpointKind("software-signle-step"); 992321369Sdim 993321369Sdim if (log) 994321369Sdim log->Printf("ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS", 995321369Sdim __FUNCTION__, addr); 996321369Sdim 997321369Sdim m_threads_stepping_with_breakpoint.insert({tid, sw_step_break->GetID()}); 998321369Sdim return Status(); 999321369Sdim} 1000321369Sdim 1001321369Sdimbool ProcessFreeBSD::IsSoftwareStepBreakpoint(lldb::tid_t tid) { 1002321369Sdim ThreadSP thread = GetThreadList().FindThreadByID(tid); 1003321369Sdim if (!thread) 1004321369Sdim return false; 1005321369Sdim 1006321369Sdim assert(thread->GetRegisterContext()); 1007321369Sdim lldb::addr_t stop_pc = thread->GetRegisterContext()->GetPC(); 1008321369Sdim 1009321369Sdim const auto &iter = m_threads_stepping_with_breakpoint.find(tid); 1010321369Sdim if (iter == m_threads_stepping_with_breakpoint.end()) 1011321369Sdim return false; 1012321369Sdim 1013321369Sdim lldb::break_id_t bp_id = iter->second; 1014321369Sdim BreakpointSP bp = GetTarget().GetBreakpointByID(bp_id); 1015321369Sdim if (!bp) 1016321369Sdim return false; 1017321369Sdim 1018321369Sdim BreakpointLocationSP bp_loc = bp->FindLocationByAddress(stop_pc); 1019321369Sdim if (!bp_loc) 1020321369Sdim return false; 1021321369Sdim 1022321369Sdim GetTarget().RemoveBreakpointByID(bp_id); 1023321369Sdim m_threads_stepping_with_breakpoint.erase(tid); 1024321369Sdim return true; 1025321369Sdim} 1026321369Sdim 1027321369Sdimbool ProcessFreeBSD::SupportHardwareSingleStepping() const { 1028321369Sdim lldb_private::ArchSpec arch = GetTarget().GetArchitecture(); 1029321369Sdim if (arch.GetMachine() == llvm::Triple::arm || 1030321369Sdim arch.GetMachine() == llvm::Triple::mips64 || 1031321369Sdim arch.GetMachine() == llvm::Triple::mips64el || 1032321369Sdim arch.GetMachine() == llvm::Triple::mips || 1033321369Sdim arch.GetMachine() == llvm::Triple::mipsel) 1034321369Sdim return false; 1035321369Sdim return true; 1036321369Sdim} 1037321369Sdim 1038321369SdimStatus ProcessFreeBSD::SetupSoftwareSingleStepping(lldb::tid_t tid) { 1039321369Sdim std::unique_ptr<EmulateInstruction> emulator_ap( 1040321369Sdim EmulateInstruction::FindPlugin(GetTarget().GetArchitecture(), 1041321369Sdim eInstructionTypePCModifying, nullptr)); 1042321369Sdim 1043321369Sdim if (emulator_ap == nullptr) 1044321369Sdim return Status("Instruction emulator not found!"); 1045321369Sdim 1046321369Sdim FreeBSDThread *thread = static_cast<FreeBSDThread *>( 1047321369Sdim m_thread_list.FindThreadByID(tid, false).get()); 1048321369Sdim if (thread == NULL) 1049321369Sdim return Status("Thread not found not found!"); 1050321369Sdim 1051321369Sdim lldb::RegisterContextSP register_context_sp = thread->GetRegisterContext(); 1052321369Sdim 1053321369Sdim EmulatorBaton baton(this, register_context_sp.get()); 1054321369Sdim emulator_ap->SetBaton(&baton); 1055321369Sdim emulator_ap->SetReadMemCallback(&ReadMemoryCallback); 1056321369Sdim emulator_ap->SetReadRegCallback(&ReadRegisterCallback); 1057321369Sdim emulator_ap->SetWriteMemCallback(&WriteMemoryCallback); 1058321369Sdim emulator_ap->SetWriteRegCallback(&WriteRegisterCallback); 1059321369Sdim 1060321369Sdim if (!emulator_ap->ReadInstruction()) 1061321369Sdim return Status("Read instruction failed!"); 1062321369Sdim 1063321369Sdim bool emulation_result = 1064321369Sdim emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 1065321369Sdim const RegisterInfo *reg_info_pc = register_context_sp->GetRegisterInfo( 1066321369Sdim eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 1067321369Sdim auto pc_it = 1068321369Sdim baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]); 1069321369Sdim 1070321369Sdim lldb::addr_t next_pc; 1071321369Sdim if (emulation_result) { 1072321369Sdim assert(pc_it != baton.m_register_values.end() && 1073321369Sdim "Emulation was successful but PC wasn't updated"); 1074321369Sdim next_pc = pc_it->second.GetAsUInt64(); 1075321369Sdim } else if (pc_it == baton.m_register_values.end()) { 1076341825Sdim // Emulate instruction failed and it haven't changed PC. Advance PC with 1077341825Sdim // the size of the current opcode because the emulation of all 1078321369Sdim // PC modifying instruction should be successful. The failure most 1079321369Sdim // likely caused by a not supported instruction which don't modify PC. 1080321369Sdim next_pc = 1081321369Sdim register_context_sp->GetPC() + emulator_ap->GetOpcode().GetByteSize(); 1082321369Sdim } else { 1083321369Sdim // The instruction emulation failed after it modified the PC. It is an 1084321369Sdim // unknown error where we can't continue because the next instruction is 1085321369Sdim // modifying the PC but we don't know how. 1086321369Sdim return Status("Instruction emulation failed unexpectedly"); 1087321369Sdim } 1088321369Sdim 1089321369Sdim SetSoftwareSingleStepBreakpoint(tid, next_pc); 1090321369Sdim return Status(); 1091321369Sdim} 1092