1314564Sdim//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++ 2314564Sdim//-*-===// 3254721Semaste// 4353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5353358Sdim// See https://llvm.org/LICENSE.txt for license information. 6353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include <errno.h> 11321369Sdim#include <pthread.h> 12321369Sdim#include <pthread_np.h> 13321369Sdim#include <stdlib.h> 14321369Sdim#include <sys/sysctl.h> 15321369Sdim#include <sys/types.h> 16321369Sdim#include <sys/user.h> 17321369Sdim#include <machine/elf.h> 18254721Semaste 19288943Sdim#include <mutex> 20321369Sdim#include <unordered_map> 21288943Sdim 22254721Semaste#include "lldb/Core/PluginManager.h" 23344779Sdim#include "lldb/Host/FileSystem.h" 24254721Semaste#include "lldb/Host/Host.h" 25254721Semaste#include "lldb/Symbol/ObjectFile.h" 26254721Semaste#include "lldb/Target/DynamicLoader.h" 27254721Semaste#include "lldb/Target/Target.h" 28344779Sdim#include "lldb/Utility/RegisterValue.h" 29344779Sdim#include "lldb/Utility/State.h" 30254721Semaste 31314564Sdim#include "FreeBSDThread.h" 32321369Sdim#include "Plugins/Process/POSIX/ProcessPOSIXLog.h" 33314564Sdim#include "Plugins/Process/Utility/FreeBSDSignals.h" 34314564Sdim#include "Plugins/Process/Utility/InferiorCallPOSIX.h" 35254721Semaste#include "ProcessFreeBSD.h" 36314564Sdim#include "ProcessMonitor.h" 37254721Semaste 38296417Sdim#include "lldb/Breakpoint/BreakpointLocation.h" 39296417Sdim#include "lldb/Breakpoint/Watchpoint.h" 40296417Sdim#include "lldb/Core/Module.h" 41296417Sdim#include "lldb/Core/ModuleSpec.h" 42296417Sdim#include "lldb/Core/PluginManager.h" 43296417Sdim#include "lldb/Host/Host.h" 44296417Sdim#include "lldb/Symbol/ObjectFile.h" 45296417Sdim#include "lldb/Target/DynamicLoader.h" 46296417Sdim#include "lldb/Target/Platform.h" 47296417Sdim#include "lldb/Target/Target.h" 48321369Sdim#include "lldb/Utility/DataBufferHeap.h" 49321369Sdim#include "lldb/Utility/FileSpec.h" 50344779Sdim#include "lldb/Utility/State.h" 51296417Sdim 52296417Sdim#include "lldb/Host/posix/Fcntl.h" 53296417Sdim 54321369Sdim#include "llvm/Support/FileSystem.h" 55321369Sdim#include "llvm/Support/Threading.h" 56321369Sdim 57254721Semasteusing namespace lldb; 58254721Semasteusing namespace lldb_private; 59254721Semaste 60314564Sdimnamespace { 61314564SdimUnixSignalsSP &GetFreeBSDSignals() { 62314564Sdim static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals()); 63314564Sdim return s_freebsd_signals_sp; 64276479Sdim} 65314564Sdim} 66276479Sdim 67254721Semaste// Static functions. 68254721Semaste 69254721Semastelldb::ProcessSP 70296417SdimProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp, 71309124Sdim lldb::ListenerSP listener_sp, 72314564Sdim const FileSpec *crash_file_path) { 73314564Sdim lldb::ProcessSP process_sp; 74314564Sdim if (crash_file_path == NULL) 75314564Sdim process_sp.reset( 76314564Sdim new ProcessFreeBSD(target_sp, listener_sp, GetFreeBSDSignals())); 77314564Sdim return process_sp; 78254721Semaste} 79254721Semaste 80314564Sdimvoid ProcessFreeBSD::Initialize() { 81321369Sdim static llvm::once_flag g_once_flag; 82254721Semaste 83321369Sdim llvm::call_once(g_once_flag, []() { 84314564Sdim PluginManager::RegisterPlugin(GetPluginNameStatic(), 85314564Sdim GetPluginDescriptionStatic(), CreateInstance); 86314564Sdim }); 87254721Semaste} 88254721Semaste 89314564Sdimlldb_private::ConstString ProcessFreeBSD::GetPluginNameStatic() { 90314564Sdim static ConstString g_name("freebsd"); 91314564Sdim return g_name; 92254721Semaste} 93254721Semaste 94314564Sdimconst char *ProcessFreeBSD::GetPluginDescriptionStatic() { 95314564Sdim return "Process plugin for FreeBSD"; 96254721Semaste} 97254721Semaste 98254721Semaste// ProcessInterface protocol. 99254721Semaste 100314564Sdimlldb_private::ConstString ProcessFreeBSD::GetPluginName() { 101314564Sdim return GetPluginNameStatic(); 102254721Semaste} 103254721Semaste 104314564Sdimuint32_t ProcessFreeBSD::GetPluginVersion() { return 1; } 105254721Semaste 106314564Sdimvoid ProcessFreeBSD::Terminate() {} 107254721Semaste 108321369SdimStatus ProcessFreeBSD::DoDetach(bool keep_stopped) { 109321369Sdim Status error; 110314564Sdim if (keep_stopped) { 111314564Sdim error.SetErrorString("Detaching with keep_stopped true is not currently " 112314564Sdim "supported on FreeBSD."); 113314564Sdim return error; 114314564Sdim } 115258054Semaste 116314564Sdim error = m_monitor->Detach(GetID()); 117258054Semaste 118314564Sdim if (error.Success()) 119314564Sdim SetPrivateState(eStateDetached); 120258054Semaste 121314564Sdim return error; 122258054Semaste} 123258054Semaste 124321369SdimStatus ProcessFreeBSD::DoResume() { 125314564Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 126258892Semaste 127314564Sdim SetPrivateState(eStateRunning); 128258892Semaste 129314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 130314564Sdim bool do_step = false; 131321369Sdim bool software_single_step = !SupportHardwareSingleStepping(); 132258892Semaste 133314564Sdim for (tid_collection::const_iterator t_pos = m_run_tids.begin(), 134314564Sdim t_end = m_run_tids.end(); 135314564Sdim t_pos != t_end; ++t_pos) { 136314564Sdim m_monitor->ThreadSuspend(*t_pos, false); 137314564Sdim } 138314564Sdim for (tid_collection::const_iterator t_pos = m_step_tids.begin(), 139314564Sdim t_end = m_step_tids.end(); 140314564Sdim t_pos != t_end; ++t_pos) { 141314564Sdim m_monitor->ThreadSuspend(*t_pos, false); 142314564Sdim do_step = true; 143321369Sdim if (software_single_step) { 144321369Sdim Status error = SetupSoftwareSingleStepping(*t_pos); 145321369Sdim if (error.Fail()) 146321369Sdim return error; 147321369Sdim } 148314564Sdim } 149314564Sdim for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(), 150314564Sdim t_end = m_suspend_tids.end(); 151314564Sdim t_pos != t_end; ++t_pos) { 152314564Sdim m_monitor->ThreadSuspend(*t_pos, true); 153314564Sdim // XXX Cannot PT_CONTINUE properly with suspended threads. 154314564Sdim do_step = true; 155314564Sdim } 156258892Semaste 157360784Sdim LLDB_LOGF(log, "process %" PRIu64 " resuming (%s)", GetID(), 158360784Sdim do_step ? "step" : "continue"); 159321369Sdim if (do_step && !software_single_step) 160314564Sdim m_monitor->SingleStep(GetID(), m_resume_signo); 161314564Sdim else 162314564Sdim m_monitor->Resume(GetID(), m_resume_signo); 163258892Semaste 164321369Sdim return Status(); 165258892Semaste} 166258892Semaste 167314564Sdimbool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, 168314564Sdim ThreadList &new_thread_list) { 169314564Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 170360784Sdim LLDB_LOGF(log, "ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__, 171360784Sdim GetID()); 172258054Semaste 173314564Sdim std::vector<lldb::pid_t> tds; 174314564Sdim if (!GetMonitor().GetCurrentThreadIDs(tds)) { 175314564Sdim return false; 176314564Sdim } 177258054Semaste 178314564Sdim ThreadList old_thread_list_copy(old_thread_list); 179314564Sdim for (size_t i = 0; i < tds.size(); ++i) { 180314564Sdim tid_t tid = tds[i]; 181314564Sdim ThreadSP thread_sp(old_thread_list_copy.RemoveThreadByID(tid, false)); 182314564Sdim if (!thread_sp) { 183314564Sdim thread_sp.reset(new FreeBSDThread(*this, tid)); 184360784Sdim LLDB_LOGF(log, "ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, 185360784Sdim tid); 186314564Sdim } else { 187360784Sdim LLDB_LOGF(log, "ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__, 188360784Sdim tid); 189258892Semaste } 190314564Sdim new_thread_list.AddThread(thread_sp); 191314564Sdim } 192314564Sdim for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) { 193314564Sdim ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false)); 194314564Sdim if (old_thread_sp) { 195360784Sdim LLDB_LOGF(log, "ProcessFreeBSD::%s remove tid", __FUNCTION__); 196258892Semaste } 197314564Sdim } 198258054Semaste 199314564Sdim return true; 200258892Semaste} 201258054Semaste 202321369SdimStatus ProcessFreeBSD::WillResume() { 203314564Sdim m_resume_signo = 0; 204314564Sdim m_suspend_tids.clear(); 205314564Sdim m_run_tids.clear(); 206314564Sdim m_step_tids.clear(); 207314564Sdim return Process::WillResume(); 208254721Semaste} 209258892Semaste 210314564Sdimvoid ProcessFreeBSD::SendMessage(const ProcessMessage &message) { 211314564Sdim std::lock_guard<std::recursive_mutex> guard(m_message_mutex); 212258892Semaste 213314564Sdim switch (message.GetKind()) { 214314564Sdim case ProcessMessage::eInvalidMessage: 215314564Sdim return; 216258892Semaste 217314564Sdim case ProcessMessage::eAttachMessage: 218314564Sdim SetPrivateState(eStateStopped); 219314564Sdim return; 220258892Semaste 221314564Sdim case ProcessMessage::eLimboMessage: 222314564Sdim case ProcessMessage::eExitMessage: 223314564Sdim SetExitStatus(message.GetExitStatus(), NULL); 224314564Sdim break; 225258892Semaste 226314564Sdim case ProcessMessage::eSignalMessage: 227314564Sdim case ProcessMessage::eSignalDeliveredMessage: 228314564Sdim case ProcessMessage::eBreakpointMessage: 229314564Sdim case ProcessMessage::eTraceMessage: 230314564Sdim case ProcessMessage::eWatchpointMessage: 231314564Sdim case ProcessMessage::eCrashMessage: 232314564Sdim SetPrivateState(eStateStopped); 233314564Sdim break; 234258892Semaste 235314564Sdim case ProcessMessage::eNewThreadMessage: 236314564Sdim llvm_unreachable("eNewThreadMessage unexpected on FreeBSD"); 237314564Sdim break; 238258892Semaste 239314564Sdim case ProcessMessage::eExecMessage: 240314564Sdim SetPrivateState(eStateStopped); 241314564Sdim break; 242314564Sdim } 243258892Semaste 244314564Sdim m_message_queue.push(message); 245258892Semaste} 246296417Sdim 247296417Sdim// Constructors and destructors. 248296417Sdim 249314564SdimProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp, 250314564Sdim lldb::ListenerSP listener_sp, 251314564Sdim UnixSignalsSP &unix_signals_sp) 252309124Sdim : Process(target_sp, listener_sp, unix_signals_sp), 253314564Sdim m_byte_order(endian::InlHostByteOrder()), m_monitor(NULL), m_module(NULL), 254314564Sdim m_message_mutex(), m_exit_now(false), m_seen_initial_stop(), 255314564Sdim m_resume_signo(0) { 256314564Sdim // FIXME: Putting this code in the ctor and saving the byte order in a 257314564Sdim // member variable is a hack to avoid const qual issues in GetByteOrder. 258314564Sdim lldb::ModuleSP module = GetTarget().GetExecutableModule(); 259314564Sdim if (module && module->GetObjectFile()) 260314564Sdim m_byte_order = module->GetObjectFile()->GetByteOrder(); 261296417Sdim} 262296417Sdim 263314564SdimProcessFreeBSD::~ProcessFreeBSD() { delete m_monitor; } 264296417Sdim 265296417Sdim// Process protocol. 266314564Sdimvoid ProcessFreeBSD::Finalize() { 267296417Sdim Process::Finalize(); 268296417Sdim 269296417Sdim if (m_monitor) 270296417Sdim m_monitor->StopMonitor(); 271296417Sdim} 272296417Sdim 273314564Sdimbool ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp, 274314564Sdim bool plugin_specified_by_name) { 275314564Sdim // For now we are just making sure the file exists for a given module 276314564Sdim ModuleSP exe_module_sp(target_sp->GetExecutableModule()); 277314564Sdim if (exe_module_sp.get()) 278344779Sdim return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec()); 279314564Sdim // If there is no executable module, we return true since we might be 280314564Sdim // preparing to attach. 281314564Sdim return true; 282296417Sdim} 283296417Sdim 284321369SdimStatus 285321369SdimProcessFreeBSD::DoAttachToProcessWithID(lldb::pid_t pid, 286321369Sdim const ProcessAttachInfo &attach_info) { 287321369Sdim Status error; 288314564Sdim assert(m_monitor == NULL); 289296417Sdim 290314564Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 291321369Sdim LLDB_LOGV(log, "pid = {0}", GetID()); 292296417Sdim 293314564Sdim m_monitor = new ProcessMonitor(this, pid, error); 294296417Sdim 295314564Sdim if (!error.Success()) 296314564Sdim return error; 297296417Sdim 298314564Sdim PlatformSP platform_sp(GetTarget().GetPlatform()); 299314564Sdim assert(platform_sp.get()); 300314564Sdim if (!platform_sp) 301314564Sdim return error; // FIXME: Detatch? 302296417Sdim 303314564Sdim // Find out what we can about this process 304314564Sdim ProcessInstanceInfo process_info; 305314564Sdim platform_sp->GetProcessInfo(pid, process_info); 306296417Sdim 307314564Sdim // Resolve the executable module 308314564Sdim ModuleSP exe_module_sp; 309314564Sdim FileSpecList executable_search_paths( 310314564Sdim Target::GetDefaultExecutableSearchPaths()); 311314564Sdim ModuleSpec exe_module_spec(process_info.GetExecutableFile(), 312314564Sdim GetTarget().GetArchitecture()); 313314564Sdim error = platform_sp->ResolveExecutable( 314314564Sdim exe_module_spec, exe_module_sp, 315314564Sdim executable_search_paths.GetSize() ? &executable_search_paths : NULL); 316314564Sdim if (!error.Success()) 317314564Sdim return error; 318296417Sdim 319314564Sdim // Fix the target architecture if necessary 320314564Sdim const ArchSpec &module_arch = exe_module_sp->GetArchitecture(); 321314564Sdim if (module_arch.IsValid() && 322314564Sdim !GetTarget().GetArchitecture().IsExactMatch(module_arch)) 323314564Sdim GetTarget().SetArchitecture(module_arch); 324296417Sdim 325314564Sdim // Initialize the target module list 326344779Sdim GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsYes); 327296417Sdim 328314564Sdim SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); 329296417Sdim 330314564Sdim SetID(pid); 331296417Sdim 332314564Sdim return error; 333296417Sdim} 334296417Sdim 335321369SdimStatus ProcessFreeBSD::WillLaunch(Module *module) { 336321369Sdim Status error; 337314564Sdim return error; 338296417Sdim} 339296417Sdim 340296417SdimFileSpec 341296417SdimProcessFreeBSD::GetFileSpec(const lldb_private::FileAction *file_action, 342314564Sdim const FileSpec &default_file_spec, 343314564Sdim const FileSpec &dbg_pts_file_spec) { 344314564Sdim FileSpec file_spec{}; 345296417Sdim 346314564Sdim if (file_action && file_action->GetAction() == FileAction::eFileActionOpen) { 347314564Sdim file_spec = file_action->GetFileSpec(); 348341825Sdim // By default the stdio paths passed in will be pseudo-terminal (/dev/pts). 349341825Sdim // If so, convert to using a different default path instead to redirect I/O 350341825Sdim // to the debugger console. This should also handle user overrides to 351341825Sdim // /dev/null or a different file. 352314564Sdim if (!file_spec || file_spec == dbg_pts_file_spec) 353314564Sdim file_spec = default_file_spec; 354314564Sdim } 355314564Sdim return file_spec; 356296417Sdim} 357296417Sdim 358321369SdimStatus ProcessFreeBSD::DoLaunch(Module *module, 359321369Sdim ProcessLaunchInfo &launch_info) { 360321369Sdim Status error; 361314564Sdim assert(m_monitor == NULL); 362296417Sdim 363314564Sdim FileSpec working_dir = launch_info.GetWorkingDirectory(); 364344779Sdim if (working_dir) { 365344779Sdim FileSystem::Instance().Resolve(working_dir); 366344779Sdim if (!FileSystem::Instance().IsDirectory(working_dir.GetPath())) { 367344779Sdim error.SetErrorStringWithFormat("No such file or directory: %s", 368314564Sdim working_dir.GetCString()); 369344779Sdim return error; 370344779Sdim } 371314564Sdim } 372296417Sdim 373314564Sdim SetPrivateState(eStateLaunching); 374296417Sdim 375314564Sdim const lldb_private::FileAction *file_action; 376296417Sdim 377314564Sdim // Default of empty will mean to use existing open file descriptors 378314564Sdim FileSpec stdin_file_spec{}; 379314564Sdim FileSpec stdout_file_spec{}; 380314564Sdim FileSpec stderr_file_spec{}; 381296417Sdim 382344779Sdim const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0)}; 383296417Sdim 384314564Sdim file_action = launch_info.GetFileActionForFD(STDIN_FILENO); 385314564Sdim stdin_file_spec = 386314564Sdim GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec); 387296417Sdim 388314564Sdim file_action = launch_info.GetFileActionForFD(STDOUT_FILENO); 389314564Sdim stdout_file_spec = 390314564Sdim GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec); 391296417Sdim 392314564Sdim file_action = launch_info.GetFileActionForFD(STDERR_FILENO); 393314564Sdim stderr_file_spec = 394314564Sdim GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec); 395296417Sdim 396314564Sdim m_monitor = new ProcessMonitor( 397314564Sdim this, module, launch_info.GetArguments().GetConstArgumentVector(), 398341825Sdim launch_info.GetEnvironment(), stdin_file_spec, stdout_file_spec, 399341825Sdim stderr_file_spec, working_dir, launch_info, error); 400296417Sdim 401314564Sdim m_module = module; 402296417Sdim 403314564Sdim if (!error.Success()) 404314564Sdim return error; 405296417Sdim 406314564Sdim int terminal = m_monitor->GetTerminalFD(); 407314564Sdim if (terminal >= 0) { 408314564Sdim// The reader thread will close the file descriptor when done, so we pass it a 409314564Sdim// copy. 410296417Sdim#ifdef F_DUPFD_CLOEXEC 411314564Sdim int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0); 412314564Sdim if (stdio == -1) { 413314564Sdim error.SetErrorToErrno(); 414314564Sdim return error; 415314564Sdim } 416296417Sdim#else 417314564Sdim // Special case when F_DUPFD_CLOEXEC does not exist (Debian kFreeBSD) 418314564Sdim int stdio = fcntl(terminal, F_DUPFD, 0); 419314564Sdim if (stdio == -1) { 420314564Sdim error.SetErrorToErrno(); 421314564Sdim return error; 422314564Sdim } 423314564Sdim stdio = fcntl(terminal, F_SETFD, FD_CLOEXEC); 424314564Sdim if (stdio == -1) { 425314564Sdim error.SetErrorToErrno(); 426314564Sdim return error; 427314564Sdim } 428296417Sdim#endif 429314564Sdim SetSTDIOFileDescriptor(stdio); 430314564Sdim } 431296417Sdim 432314564Sdim SetID(m_monitor->GetPID()); 433314564Sdim return error; 434296417Sdim} 435296417Sdim 436314564Sdimvoid ProcessFreeBSD::DidLaunch() {} 437296417Sdim 438314564Sdimaddr_t ProcessFreeBSD::GetImageInfoAddress() { 439314564Sdim Target *target = &GetTarget(); 440314564Sdim ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); 441314564Sdim Address addr = obj_file->GetImageInfoAddress(target); 442296417Sdim 443314564Sdim if (addr.IsValid()) 444314564Sdim return addr.GetLoadAddress(target); 445314564Sdim return LLDB_INVALID_ADDRESS; 446296417Sdim} 447296417Sdim 448321369SdimStatus ProcessFreeBSD::DoHalt(bool &caused_stop) { 449321369Sdim Status error; 450296417Sdim 451314564Sdim if (IsStopped()) { 452314564Sdim caused_stop = false; 453314564Sdim } else if (kill(GetID(), SIGSTOP)) { 454314564Sdim caused_stop = false; 455314564Sdim error.SetErrorToErrno(); 456314564Sdim } else { 457314564Sdim caused_stop = true; 458314564Sdim } 459314564Sdim return error; 460296417Sdim} 461296417Sdim 462321369SdimStatus ProcessFreeBSD::DoSignal(int signal) { 463321369Sdim Status error; 464296417Sdim 465314564Sdim if (kill(GetID(), signal)) 466314564Sdim error.SetErrorToErrno(); 467296417Sdim 468314564Sdim return error; 469296417Sdim} 470296417Sdim 471321369SdimStatus ProcessFreeBSD::DoDestroy() { 472321369Sdim Status error; 473296417Sdim 474314564Sdim if (!HasExited()) { 475314564Sdim assert(m_monitor); 476314564Sdim m_exit_now = true; 477314564Sdim if (GetID() == LLDB_INVALID_PROCESS_ID) { 478314564Sdim error.SetErrorString("invalid process id"); 479314564Sdim return error; 480296417Sdim } 481314564Sdim if (!m_monitor->Kill()) { 482314564Sdim error.SetErrorToErrno(); 483314564Sdim return error; 484314564Sdim } 485296417Sdim 486314564Sdim SetPrivateState(eStateExited); 487314564Sdim } 488314564Sdim 489314564Sdim return error; 490296417Sdim} 491296417Sdim 492314564Sdimvoid ProcessFreeBSD::DoDidExec() { 493314564Sdim Target *target = &GetTarget(); 494314564Sdim if (target) { 495314564Sdim PlatformSP platform_sp(target->GetPlatform()); 496314564Sdim assert(platform_sp.get()); 497314564Sdim if (platform_sp) { 498314564Sdim ProcessInstanceInfo process_info; 499314564Sdim platform_sp->GetProcessInfo(GetID(), process_info); 500314564Sdim ModuleSP exe_module_sp; 501314564Sdim ModuleSpec exe_module_spec(process_info.GetExecutableFile(), 502314564Sdim target->GetArchitecture()); 503314564Sdim FileSpecList executable_search_paths( 504314564Sdim Target::GetDefaultExecutableSearchPaths()); 505321369Sdim Status error = platform_sp->ResolveExecutable( 506314564Sdim exe_module_spec, exe_module_sp, 507314564Sdim executable_search_paths.GetSize() ? &executable_search_paths : NULL); 508314564Sdim if (!error.Success()) 509314564Sdim return; 510344779Sdim target->SetExecutableModule(exe_module_sp, eLoadDependentsYes); 511296417Sdim } 512314564Sdim } 513296417Sdim} 514296417Sdim 515314564Sdimbool ProcessFreeBSD::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) { 516314564Sdim bool added_to_set = false; 517314564Sdim ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid); 518314564Sdim if (it == m_seen_initial_stop.end()) { 519314564Sdim m_seen_initial_stop.insert(stop_tid); 520314564Sdim added_to_set = true; 521314564Sdim } 522314564Sdim return added_to_set; 523296417Sdim} 524296417Sdim 525314564Sdimbool ProcessFreeBSD::WaitingForInitialStop(lldb::tid_t stop_tid) { 526314564Sdim return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end()); 527296417Sdim} 528296417Sdim 529296417SdimFreeBSDThread * 530314564SdimProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process, 531314564Sdim lldb::tid_t tid) { 532314564Sdim return new FreeBSDThread(process, tid); 533296417Sdim} 534296417Sdim 535314564Sdimvoid ProcessFreeBSD::RefreshStateAfterStop() { 536314564Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 537321369Sdim LLDB_LOGV(log, "message_queue size = {0}", m_message_queue.size()); 538296417Sdim 539314564Sdim std::lock_guard<std::recursive_mutex> guard(m_message_mutex); 540296417Sdim 541314564Sdim // This method used to only handle one message. Changing it to loop allows 542314564Sdim // it to handle the case where we hit a breakpoint while handling a different 543314564Sdim // breakpoint. 544314564Sdim while (!m_message_queue.empty()) { 545314564Sdim ProcessMessage &message = m_message_queue.front(); 546296417Sdim 547314564Sdim // Resolve the thread this message corresponds to and pass it along. 548314564Sdim lldb::tid_t tid = message.GetTID(); 549321369Sdim LLDB_LOGV(log, " message_queue size = {0}, pid = {1}", 550321369Sdim m_message_queue.size(), tid); 551296417Sdim 552314564Sdim m_thread_list.RefreshStateAfterStop(); 553296417Sdim 554314564Sdim FreeBSDThread *thread = static_cast<FreeBSDThread *>( 555314564Sdim GetThreadList().FindThreadByID(tid, false).get()); 556314564Sdim if (thread) 557314564Sdim thread->Notify(message); 558296417Sdim 559314564Sdim if (message.GetKind() == ProcessMessage::eExitMessage) { 560314564Sdim // FIXME: We should tell the user about this, but the limbo message is 561314564Sdim // probably better for that. 562321369Sdim LLDB_LOG(log, "removing thread, tid = {0}", tid); 563314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 564296417Sdim 565314564Sdim ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false); 566314564Sdim thread_sp.reset(); 567314564Sdim m_seen_initial_stop.erase(tid); 568314564Sdim } 569296417Sdim 570314564Sdim m_message_queue.pop(); 571314564Sdim } 572296417Sdim} 573296417Sdim 574314564Sdimbool ProcessFreeBSD::IsAlive() { 575314564Sdim StateType state = GetPrivateState(); 576314564Sdim return state != eStateDetached && state != eStateExited && 577314564Sdim state != eStateInvalid && state != eStateUnloaded; 578296417Sdim} 579296417Sdim 580314564Sdimsize_t ProcessFreeBSD::DoReadMemory(addr_t vm_addr, void *buf, size_t size, 581321369Sdim Status &error) { 582314564Sdim assert(m_monitor); 583314564Sdim return m_monitor->ReadMemory(vm_addr, buf, size, error); 584296417Sdim} 585296417Sdim 586314564Sdimsize_t ProcessFreeBSD::DoWriteMemory(addr_t vm_addr, const void *buf, 587321369Sdim size_t size, Status &error) { 588314564Sdim assert(m_monitor); 589314564Sdim return m_monitor->WriteMemory(vm_addr, buf, size, error); 590296417Sdim} 591296417Sdim 592314564Sdimaddr_t ProcessFreeBSD::DoAllocateMemory(size_t size, uint32_t permissions, 593321369Sdim Status &error) { 594314564Sdim addr_t allocated_addr = LLDB_INVALID_ADDRESS; 595296417Sdim 596314564Sdim unsigned prot = 0; 597314564Sdim if (permissions & lldb::ePermissionsReadable) 598314564Sdim prot |= eMmapProtRead; 599314564Sdim if (permissions & lldb::ePermissionsWritable) 600314564Sdim prot |= eMmapProtWrite; 601314564Sdim if (permissions & lldb::ePermissionsExecutable) 602314564Sdim prot |= eMmapProtExec; 603296417Sdim 604314564Sdim if (InferiorCallMmap(this, allocated_addr, 0, size, prot, 605314564Sdim eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) { 606314564Sdim m_addr_to_mmap_size[allocated_addr] = size; 607314564Sdim error.Clear(); 608314564Sdim } else { 609314564Sdim allocated_addr = LLDB_INVALID_ADDRESS; 610314564Sdim error.SetErrorStringWithFormat( 611314564Sdim "unable to allocate %zu bytes of memory with permissions %s", size, 612314564Sdim GetPermissionsAsCString(permissions)); 613314564Sdim } 614296417Sdim 615314564Sdim return allocated_addr; 616296417Sdim} 617296417Sdim 618321369SdimStatus ProcessFreeBSD::DoDeallocateMemory(lldb::addr_t addr) { 619321369Sdim Status error; 620314564Sdim MMapMap::iterator pos = m_addr_to_mmap_size.find(addr); 621314564Sdim if (pos != m_addr_to_mmap_size.end() && 622314564Sdim InferiorCallMunmap(this, addr, pos->second)) 623314564Sdim m_addr_to_mmap_size.erase(pos); 624314564Sdim else 625314564Sdim error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, 626314564Sdim addr); 627296417Sdim 628314564Sdim return error; 629296417Sdim} 630296417Sdim 631296417Sdimsize_t 632314564SdimProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) { 633314564Sdim static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xD4}; 634314564Sdim static const uint8_t g_i386_opcode[] = {0xCC}; 635296417Sdim 636314564Sdim ArchSpec arch = GetTarget().GetArchitecture(); 637314564Sdim const uint8_t *opcode = NULL; 638314564Sdim size_t opcode_size = 0; 639296417Sdim 640314564Sdim switch (arch.GetMachine()) { 641314564Sdim default: 642314564Sdim assert(false && "CPU type not supported!"); 643314564Sdim break; 644296417Sdim 645314564Sdim case llvm::Triple::arm: { 646341825Sdim // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the 647341825Sdim // linux kernel does otherwise. 648314564Sdim static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7}; 649314564Sdim static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde}; 650296417Sdim 651314564Sdim lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0)); 652341825Sdim AddressClass addr_class = AddressClass::eUnknown; 653296417Sdim 654314564Sdim if (bp_loc_sp) 655314564Sdim addr_class = bp_loc_sp->GetAddress().GetAddressClass(); 656296417Sdim 657341825Sdim if (addr_class == AddressClass::eCodeAlternateISA || 658341825Sdim (addr_class == AddressClass::eUnknown && 659314564Sdim bp_loc_sp->GetAddress().GetOffset() & 1)) { 660314564Sdim opcode = g_thumb_breakpoint_opcode; 661314564Sdim opcode_size = sizeof(g_thumb_breakpoint_opcode); 662314564Sdim } else { 663314564Sdim opcode = g_arm_breakpoint_opcode; 664314564Sdim opcode_size = sizeof(g_arm_breakpoint_opcode); 665296417Sdim } 666314564Sdim } break; 667314564Sdim case llvm::Triple::aarch64: 668314564Sdim opcode = g_aarch64_opcode; 669314564Sdim opcode_size = sizeof(g_aarch64_opcode); 670314564Sdim break; 671296417Sdim 672314564Sdim case llvm::Triple::x86: 673314564Sdim case llvm::Triple::x86_64: 674314564Sdim opcode = g_i386_opcode; 675314564Sdim opcode_size = sizeof(g_i386_opcode); 676314564Sdim break; 677314564Sdim } 678314564Sdim 679314564Sdim bp_site->SetTrapOpcode(opcode, opcode_size); 680314564Sdim return opcode_size; 681296417Sdim} 682296417Sdim 683321369SdimStatus ProcessFreeBSD::EnableBreakpointSite(BreakpointSite *bp_site) { 684314564Sdim return EnableSoftwareBreakpoint(bp_site); 685296417Sdim} 686296417Sdim 687321369SdimStatus ProcessFreeBSD::DisableBreakpointSite(BreakpointSite *bp_site) { 688314564Sdim return DisableSoftwareBreakpoint(bp_site); 689296417Sdim} 690296417Sdim 691321369SdimStatus ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) { 692321369Sdim Status error; 693314564Sdim if (wp) { 694314564Sdim user_id_t watchID = wp->GetID(); 695314564Sdim addr_t addr = wp->GetLoadAddress(); 696314564Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 697360784Sdim LLDB_LOGF(log, "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")", 698360784Sdim watchID); 699314564Sdim if (wp->IsEnabled()) { 700360784Sdim LLDB_LOGF(log, 701360784Sdim "ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 702360784Sdim ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", 703360784Sdim watchID, (uint64_t)addr); 704314564Sdim return error; 705314564Sdim } 706296417Sdim 707314564Sdim // Try to find a vacant watchpoint slot in the inferiors' main thread 708314564Sdim uint32_t wp_hw_index = LLDB_INVALID_INDEX32; 709314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 710314564Sdim FreeBSDThread *thread = static_cast<FreeBSDThread *>( 711314564Sdim m_thread_list.GetThreadAtIndex(0, false).get()); 712296417Sdim 713314564Sdim if (thread) 714314564Sdim wp_hw_index = thread->FindVacantWatchpointIndex(); 715314564Sdim 716314564Sdim if (wp_hw_index == LLDB_INVALID_INDEX32) { 717314564Sdim error.SetErrorString("Setting hardware watchpoint failed."); 718314564Sdim } else { 719314564Sdim wp->SetHardwareIndex(wp_hw_index); 720314564Sdim bool wp_enabled = true; 721314564Sdim uint32_t thread_count = m_thread_list.GetSize(false); 722314564Sdim for (uint32_t i = 0; i < thread_count; ++i) { 723314564Sdim thread = static_cast<FreeBSDThread *>( 724314564Sdim m_thread_list.GetThreadAtIndex(i, false).get()); 725296417Sdim if (thread) 726314564Sdim wp_enabled &= thread->EnableHardwareWatchpoint(wp); 727296417Sdim else 728314564Sdim wp_enabled = false; 729314564Sdim } 730314564Sdim if (wp_enabled) { 731314564Sdim wp->SetEnabled(true, notify); 732314564Sdim return error; 733314564Sdim } else { 734341825Sdim // Watchpoint enabling failed on at least one of the threads so roll 735341825Sdim // back all of them 736314564Sdim DisableWatchpoint(wp, false); 737314564Sdim error.SetErrorString("Setting hardware watchpoint failed"); 738314564Sdim } 739296417Sdim } 740314564Sdim } else 741314564Sdim error.SetErrorString("Watchpoint argument was NULL."); 742314564Sdim return error; 743296417Sdim} 744296417Sdim 745321369SdimStatus ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify) { 746321369Sdim Status error; 747314564Sdim if (wp) { 748314564Sdim user_id_t watchID = wp->GetID(); 749314564Sdim addr_t addr = wp->GetLoadAddress(); 750314564Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 751360784Sdim LLDB_LOGF(log, "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")", 752360784Sdim watchID); 753314564Sdim if (!wp->IsEnabled()) { 754360784Sdim LLDB_LOGF(log, 755360784Sdim "ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 756360784Sdim ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.", 757360784Sdim watchID, (uint64_t)addr); 758314564Sdim // This is needed (for now) to keep watchpoints disabled correctly 759314564Sdim wp->SetEnabled(false, notify); 760314564Sdim return error; 761314564Sdim } 762296417Sdim 763314564Sdim if (wp->IsHardware()) { 764314564Sdim bool wp_disabled = true; 765314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 766314564Sdim uint32_t thread_count = m_thread_list.GetSize(false); 767314564Sdim for (uint32_t i = 0; i < thread_count; ++i) { 768314564Sdim FreeBSDThread *thread = static_cast<FreeBSDThread *>( 769314564Sdim m_thread_list.GetThreadAtIndex(i, false).get()); 770314564Sdim if (thread) 771314564Sdim wp_disabled &= thread->DisableHardwareWatchpoint(wp); 772314564Sdim else 773314564Sdim wp_disabled = false; 774314564Sdim } 775314564Sdim if (wp_disabled) { 776314564Sdim wp->SetHardwareIndex(LLDB_INVALID_INDEX32); 777314564Sdim wp->SetEnabled(false, notify); 778314564Sdim return error; 779314564Sdim } else 780314564Sdim error.SetErrorString("Disabling hardware watchpoint failed"); 781296417Sdim } 782314564Sdim } else 783314564Sdim error.SetErrorString("Watchpoint argument was NULL."); 784314564Sdim return error; 785296417Sdim} 786296417Sdim 787321369SdimStatus ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num) { 788321369Sdim Status error; 789314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 790314564Sdim FreeBSDThread *thread = static_cast<FreeBSDThread *>( 791314564Sdim m_thread_list.GetThreadAtIndex(0, false).get()); 792314564Sdim if (thread) 793314564Sdim num = thread->NumSupportedHardwareWatchpoints(); 794314564Sdim else 795314564Sdim error.SetErrorString("Process does not exist."); 796314564Sdim return error; 797296417Sdim} 798296417Sdim 799321369SdimStatus ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after) { 800321369Sdim Status error = GetWatchpointSupportInfo(num); 801341825Sdim // Watchpoints trigger and halt the inferior after the corresponding 802341825Sdim // instruction has been executed. 803314564Sdim after = true; 804314564Sdim return error; 805296417Sdim} 806296417Sdim 807314564Sdimuint32_t ProcessFreeBSD::UpdateThreadListIfNeeded() { 808314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 809314564Sdim // Do not allow recursive updates. 810314564Sdim return m_thread_list.GetSize(false); 811296417Sdim} 812296417Sdim 813314564SdimByteOrder ProcessFreeBSD::GetByteOrder() const { 814314564Sdim // FIXME: We should be able to extract this value directly. See comment in 815314564Sdim // ProcessFreeBSD(). 816314564Sdim return m_byte_order; 817296417Sdim} 818296417Sdim 819321369Sdimsize_t ProcessFreeBSD::PutSTDIN(const char *buf, size_t len, Status &error) { 820314564Sdim ssize_t status; 821314564Sdim if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) { 822314564Sdim error.SetErrorToErrno(); 823314564Sdim return 0; 824314564Sdim } 825314564Sdim return status; 826296417Sdim} 827296417Sdim 828296417Sdim// Utility functions. 829296417Sdim 830314564Sdimbool ProcessFreeBSD::HasExited() { 831314564Sdim switch (GetPrivateState()) { 832314564Sdim default: 833314564Sdim break; 834296417Sdim 835314564Sdim case eStateDetached: 836314564Sdim case eStateExited: 837314564Sdim return true; 838314564Sdim } 839296417Sdim 840314564Sdim return false; 841296417Sdim} 842296417Sdim 843314564Sdimbool ProcessFreeBSD::IsStopped() { 844314564Sdim switch (GetPrivateState()) { 845314564Sdim default: 846314564Sdim break; 847296417Sdim 848314564Sdim case eStateStopped: 849314564Sdim case eStateCrashed: 850314564Sdim case eStateSuspended: 851314564Sdim return true; 852314564Sdim } 853296417Sdim 854314564Sdim return false; 855296417Sdim} 856296417Sdim 857314564Sdimbool ProcessFreeBSD::IsAThreadRunning() { 858314564Sdim bool is_running = false; 859314564Sdim std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex()); 860314564Sdim uint32_t thread_count = m_thread_list.GetSize(false); 861314564Sdim for (uint32_t i = 0; i < thread_count; ++i) { 862314564Sdim FreeBSDThread *thread = static_cast<FreeBSDThread *>( 863314564Sdim m_thread_list.GetThreadAtIndex(i, false).get()); 864314564Sdim StateType thread_state = thread->GetState(); 865314564Sdim if (thread_state == eStateRunning || thread_state == eStateStepping) { 866314564Sdim is_running = true; 867314564Sdim break; 868296417Sdim } 869314564Sdim } 870314564Sdim return is_running; 871296417Sdim} 872296417Sdim 873353358Sdimlldb_private::DataExtractor ProcessFreeBSD::GetAuxvData() { 874314564Sdim // If we're the local platform, we can ask the host for auxv data. 875314564Sdim PlatformSP platform_sp = GetTarget().GetPlatform(); 876321369Sdim assert(platform_sp && platform_sp->IsHost()); 877296417Sdim 878321369Sdim int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV, (int)m_process->GetID()}; 879321369Sdim size_t auxv_size = AT_COUNT * sizeof(Elf_Auxinfo); 880321369Sdim DataBufferSP buf_sp(new DataBufferHeap(auxv_size, 0)); 881321369Sdim 882321369Sdim if (::sysctl(mib, 4, buf_sp->GetBytes(), &auxv_size, NULL, 0) != 0) { 883321369Sdim perror("sysctl failed on auxv"); 884321369Sdim buf_sp.reset(); 885321369Sdim } 886321369Sdim 887353358Sdim return DataExtractor(buf_sp, GetByteOrder(), GetAddressByteSize()); 888296417Sdim} 889321369Sdim 890321369Sdimstruct EmulatorBaton { 891321369Sdim ProcessFreeBSD *m_process; 892321369Sdim RegisterContext *m_reg_context; 893321369Sdim 894321369Sdim // eRegisterKindDWARF -> RegisterValue 895321369Sdim std::unordered_map<uint32_t, RegisterValue> m_register_values; 896321369Sdim 897321369Sdim EmulatorBaton(ProcessFreeBSD *process, RegisterContext *reg_context) 898321369Sdim : m_process(process), m_reg_context(reg_context) {} 899321369Sdim}; 900321369Sdim 901321369Sdimstatic size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton, 902321369Sdim const EmulateInstruction::Context &context, 903321369Sdim lldb::addr_t addr, void *dst, size_t length) { 904321369Sdim EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton); 905321369Sdim 906321369Sdim Status error; 907321369Sdim size_t bytes_read = 908321369Sdim emulator_baton->m_process->DoReadMemory(addr, dst, length, error); 909321369Sdim if (!error.Success()) 910321369Sdim bytes_read = 0; 911321369Sdim return bytes_read; 912321369Sdim} 913321369Sdim 914321369Sdimstatic bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton, 915321369Sdim const RegisterInfo *reg_info, 916321369Sdim RegisterValue ®_value) { 917321369Sdim EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton); 918321369Sdim 919321369Sdim auto it = emulator_baton->m_register_values.find( 920321369Sdim reg_info->kinds[eRegisterKindDWARF]); 921321369Sdim if (it != emulator_baton->m_register_values.end()) { 922321369Sdim reg_value = it->second; 923321369Sdim return true; 924321369Sdim } 925321369Sdim 926321369Sdim // The emulator only fills in the dwarf register numbers (and in some cases 927321369Sdim // the generic register numbers). Get the full register info from the 928321369Sdim // register context based on the dwarf register numbers. 929321369Sdim const RegisterInfo *full_reg_info = 930321369Sdim emulator_baton->m_reg_context->GetRegisterInfo( 931321369Sdim eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]); 932321369Sdim 933321369Sdim bool error = 934321369Sdim emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value); 935321369Sdim return error; 936321369Sdim} 937321369Sdim 938321369Sdimstatic bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton, 939321369Sdim const EmulateInstruction::Context &context, 940321369Sdim const RegisterInfo *reg_info, 941321369Sdim const RegisterValue ®_value) { 942321369Sdim EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton); 943321369Sdim emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] = 944321369Sdim reg_value; 945321369Sdim return true; 946321369Sdim} 947321369Sdim 948321369Sdimstatic size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton, 949321369Sdim const EmulateInstruction::Context &context, 950321369Sdim lldb::addr_t addr, const void *dst, 951321369Sdim size_t length) { 952321369Sdim return length; 953321369Sdim} 954321369Sdim 955321369Sdimbool ProcessFreeBSD::SingleStepBreakpointHit( 956321369Sdim void *baton, lldb_private::StoppointCallbackContext *context, 957321369Sdim lldb::user_id_t break_id, lldb::user_id_t break_loc_id) { 958321369Sdim return false; 959321369Sdim} 960321369Sdim 961321369SdimStatus ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid, 962321369Sdim lldb::addr_t addr) { 963321369Sdim Status error; 964321369Sdim 965321369Sdim Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); 966321369Sdim if (log) { 967360784Sdim LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64, __FUNCTION__, addr); 968360784Sdim LLDB_LOGF(log, "SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, 969360784Sdim addr); 970321369Sdim } 971321369Sdim 972321369Sdim // Validate the address. 973321369Sdim if (addr == LLDB_INVALID_ADDRESS) 974321369Sdim return Status("ProcessFreeBSD::%s invalid load address specified.", 975321369Sdim __FUNCTION__); 976321369Sdim 977321369Sdim Breakpoint *const sw_step_break = 978321369Sdim m_process->GetTarget().CreateBreakpoint(addr, true, false).get(); 979321369Sdim sw_step_break->SetCallback(SingleStepBreakpointHit, this, true); 980360784Sdim sw_step_break->SetBreakpointKind("software-single-step"); 981321369Sdim 982360784Sdim LLDB_LOGF(log, "ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS", 983360784Sdim __FUNCTION__, addr); 984321369Sdim 985321369Sdim m_threads_stepping_with_breakpoint.insert({tid, sw_step_break->GetID()}); 986321369Sdim return Status(); 987321369Sdim} 988321369Sdim 989321369Sdimbool ProcessFreeBSD::IsSoftwareStepBreakpoint(lldb::tid_t tid) { 990321369Sdim ThreadSP thread = GetThreadList().FindThreadByID(tid); 991321369Sdim if (!thread) 992321369Sdim return false; 993321369Sdim 994321369Sdim assert(thread->GetRegisterContext()); 995321369Sdim lldb::addr_t stop_pc = thread->GetRegisterContext()->GetPC(); 996321369Sdim 997321369Sdim const auto &iter = m_threads_stepping_with_breakpoint.find(tid); 998321369Sdim if (iter == m_threads_stepping_with_breakpoint.end()) 999321369Sdim return false; 1000321369Sdim 1001321369Sdim lldb::break_id_t bp_id = iter->second; 1002321369Sdim BreakpointSP bp = GetTarget().GetBreakpointByID(bp_id); 1003321369Sdim if (!bp) 1004321369Sdim return false; 1005321369Sdim 1006321369Sdim BreakpointLocationSP bp_loc = bp->FindLocationByAddress(stop_pc); 1007321369Sdim if (!bp_loc) 1008321369Sdim return false; 1009321369Sdim 1010321369Sdim GetTarget().RemoveBreakpointByID(bp_id); 1011321369Sdim m_threads_stepping_with_breakpoint.erase(tid); 1012321369Sdim return true; 1013321369Sdim} 1014321369Sdim 1015321369Sdimbool ProcessFreeBSD::SupportHardwareSingleStepping() const { 1016321369Sdim lldb_private::ArchSpec arch = GetTarget().GetArchitecture(); 1017353358Sdim if (arch.GetMachine() == llvm::Triple::arm || arch.IsMIPS()) 1018321369Sdim return false; 1019321369Sdim return true; 1020321369Sdim} 1021321369Sdim 1022321369SdimStatus ProcessFreeBSD::SetupSoftwareSingleStepping(lldb::tid_t tid) { 1023353358Sdim std::unique_ptr<EmulateInstruction> emulator_up( 1024321369Sdim EmulateInstruction::FindPlugin(GetTarget().GetArchitecture(), 1025321369Sdim eInstructionTypePCModifying, nullptr)); 1026321369Sdim 1027353358Sdim if (emulator_up == nullptr) 1028321369Sdim return Status("Instruction emulator not found!"); 1029321369Sdim 1030321369Sdim FreeBSDThread *thread = static_cast<FreeBSDThread *>( 1031321369Sdim m_thread_list.FindThreadByID(tid, false).get()); 1032321369Sdim if (thread == NULL) 1033321369Sdim return Status("Thread not found not found!"); 1034321369Sdim 1035321369Sdim lldb::RegisterContextSP register_context_sp = thread->GetRegisterContext(); 1036321369Sdim 1037321369Sdim EmulatorBaton baton(this, register_context_sp.get()); 1038353358Sdim emulator_up->SetBaton(&baton); 1039353358Sdim emulator_up->SetReadMemCallback(&ReadMemoryCallback); 1040353358Sdim emulator_up->SetReadRegCallback(&ReadRegisterCallback); 1041353358Sdim emulator_up->SetWriteMemCallback(&WriteMemoryCallback); 1042353358Sdim emulator_up->SetWriteRegCallback(&WriteRegisterCallback); 1043321369Sdim 1044353358Sdim if (!emulator_up->ReadInstruction()) 1045321369Sdim return Status("Read instruction failed!"); 1046321369Sdim 1047321369Sdim bool emulation_result = 1048353358Sdim emulator_up->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); 1049321369Sdim const RegisterInfo *reg_info_pc = register_context_sp->GetRegisterInfo( 1050321369Sdim eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 1051321369Sdim auto pc_it = 1052321369Sdim baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]); 1053321369Sdim 1054321369Sdim lldb::addr_t next_pc; 1055321369Sdim if (emulation_result) { 1056321369Sdim assert(pc_it != baton.m_register_values.end() && 1057321369Sdim "Emulation was successful but PC wasn't updated"); 1058321369Sdim next_pc = pc_it->second.GetAsUInt64(); 1059321369Sdim } else if (pc_it == baton.m_register_values.end()) { 1060341825Sdim // Emulate instruction failed and it haven't changed PC. Advance PC with 1061341825Sdim // the size of the current opcode because the emulation of all 1062321369Sdim // PC modifying instruction should be successful. The failure most 1063321369Sdim // likely caused by a not supported instruction which don't modify PC. 1064321369Sdim next_pc = 1065353358Sdim register_context_sp->GetPC() + emulator_up->GetOpcode().GetByteSize(); 1066321369Sdim } else { 1067321369Sdim // The instruction emulation failed after it modified the PC. It is an 1068321369Sdim // unknown error where we can't continue because the next instruction is 1069321369Sdim // modifying the PC but we don't know how. 1070321369Sdim return Status("Instruction emulation failed unexpectedly"); 1071321369Sdim } 1072321369Sdim 1073321369Sdim SetSoftwareSingleStepBreakpoint(tid, next_pc); 1074321369Sdim return Status(); 1075321369Sdim} 1076