ProcessFreeBSD.cpp revision 296417
1254721Semaste//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste// C Includes 11254721Semaste#include <errno.h> 12254721Semaste 13254721Semaste// C++ Includes 14288943Sdim#include <mutex> 15288943Sdim 16254721Semaste// Other libraries and framework includes 17254721Semaste#include "lldb/Core/PluginManager.h" 18254721Semaste#include "lldb/Core/State.h" 19254721Semaste#include "lldb/Host/Host.h" 20254721Semaste#include "lldb/Symbol/ObjectFile.h" 21254721Semaste#include "lldb/Target/DynamicLoader.h" 22254721Semaste#include "lldb/Target/Target.h" 23254721Semaste 24254721Semaste#include "ProcessFreeBSD.h" 25254721Semaste#include "ProcessPOSIXLog.h" 26254721Semaste#include "Plugins/Process/Utility/InferiorCallPOSIX.h" 27276479Sdim#include "Plugins/Process/Utility/FreeBSDSignals.h" 28254721Semaste#include "ProcessMonitor.h" 29258892Semaste#include "FreeBSDThread.h" 30254721Semaste 31296417Sdim// Other libraries and framework includes 32296417Sdim#include "lldb/Breakpoint/BreakpointLocation.h" 33296417Sdim#include "lldb/Breakpoint/Watchpoint.h" 34296417Sdim#include "lldb/Core/Module.h" 35296417Sdim#include "lldb/Core/ModuleSpec.h" 36296417Sdim#include "lldb/Core/PluginManager.h" 37296417Sdim#include "lldb/Core/State.h" 38296417Sdim#include "lldb/Host/FileSpec.h" 39296417Sdim#include "lldb/Host/Host.h" 40296417Sdim#include "lldb/Symbol/ObjectFile.h" 41296417Sdim#include "lldb/Target/DynamicLoader.h" 42296417Sdim#include "lldb/Target/Platform.h" 43296417Sdim#include "lldb/Target/Target.h" 44296417Sdim 45296417Sdim#include "lldb/Host/posix/Fcntl.h" 46296417Sdim 47296417Sdim 48254721Semasteusing namespace lldb; 49254721Semasteusing namespace lldb_private; 50254721Semaste 51276479Sdimnamespace 52276479Sdim{ 53276479Sdim UnixSignalsSP& 54276479Sdim GetFreeBSDSignals () 55276479Sdim { 56276479Sdim static UnixSignalsSP s_freebsd_signals_sp (new FreeBSDSignals ()); 57276479Sdim return s_freebsd_signals_sp; 58276479Sdim } 59276479Sdim} 60276479Sdim 61254721Semaste//------------------------------------------------------------------------------ 62254721Semaste// Static functions. 63254721Semaste 64254721Semastelldb::ProcessSP 65296417SdimProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp, 66254721Semaste Listener &listener, 67254721Semaste const FileSpec *crash_file_path) 68254721Semaste{ 69254721Semaste lldb::ProcessSP process_sp; 70254721Semaste if (crash_file_path == NULL) 71296417Sdim process_sp.reset(new ProcessFreeBSD (target_sp, listener, GetFreeBSDSignals())); 72254721Semaste return process_sp; 73254721Semaste} 74254721Semaste 75254721Semastevoid 76254721SemasteProcessFreeBSD::Initialize() 77254721Semaste{ 78288943Sdim static std::once_flag g_once_flag; 79254721Semaste 80288943Sdim std::call_once(g_once_flag, []() { 81254721Semaste PluginManager::RegisterPlugin(GetPluginNameStatic(), 82254721Semaste GetPluginDescriptionStatic(), 83254721Semaste CreateInstance); 84288943Sdim ProcessPOSIXLog::Initialize(GetPluginNameStatic()); 85288943Sdim }); 86254721Semaste} 87254721Semaste 88254721Semastelldb_private::ConstString 89254721SemasteProcessFreeBSD::GetPluginNameStatic() 90254721Semaste{ 91254721Semaste static ConstString g_name("freebsd"); 92254721Semaste return g_name; 93254721Semaste} 94254721Semaste 95254721Semasteconst char * 96254721SemasteProcessFreeBSD::GetPluginDescriptionStatic() 97254721Semaste{ 98254721Semaste return "Process plugin for FreeBSD"; 99254721Semaste} 100254721Semaste 101254721Semaste//------------------------------------------------------------------------------ 102254721Semaste// ProcessInterface protocol. 103254721Semaste 104254721Semastelldb_private::ConstString 105254721SemasteProcessFreeBSD::GetPluginName() 106254721Semaste{ 107254721Semaste return GetPluginNameStatic(); 108254721Semaste} 109254721Semaste 110254721Semasteuint32_t 111254721SemasteProcessFreeBSD::GetPluginVersion() 112254721Semaste{ 113254721Semaste return 1; 114254721Semaste} 115254721Semaste 116254721Semastevoid 117254721SemasteProcessFreeBSD::Terminate() 118254721Semaste{ 119254721Semaste} 120254721Semaste 121258054SemasteError 122258054SemasteProcessFreeBSD::DoDetach(bool keep_stopped) 123258054Semaste{ 124258054Semaste Error error; 125258054Semaste if (keep_stopped) 126258054Semaste { 127258054Semaste error.SetErrorString("Detaching with keep_stopped true is not currently supported on FreeBSD."); 128258054Semaste return error; 129258054Semaste } 130258054Semaste 131258054Semaste error = m_monitor->Detach(GetID()); 132258054Semaste 133258054Semaste if (error.Success()) 134258054Semaste SetPrivateState(eStateDetached); 135258054Semaste 136258054Semaste return error; 137258054Semaste} 138258054Semaste 139258892SemasteError 140258892SemasteProcessFreeBSD::DoResume() 141258892Semaste{ 142258892Semaste Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); 143258892Semaste 144258892Semaste SetPrivateState(eStateRunning); 145258892Semaste 146258892Semaste Mutex::Locker lock(m_thread_list.GetMutex()); 147258892Semaste bool do_step = false; 148258892Semaste 149258892Semaste for (tid_collection::const_iterator t_pos = m_run_tids.begin(), t_end = m_run_tids.end(); t_pos != t_end; ++t_pos) 150258892Semaste { 151258892Semaste m_monitor->ThreadSuspend(*t_pos, false); 152258892Semaste } 153258892Semaste for (tid_collection::const_iterator t_pos = m_step_tids.begin(), t_end = m_step_tids.end(); t_pos != t_end; ++t_pos) 154258892Semaste { 155258892Semaste m_monitor->ThreadSuspend(*t_pos, false); 156258892Semaste do_step = true; 157258892Semaste } 158258892Semaste for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(), t_end = m_suspend_tids.end(); t_pos != t_end; ++t_pos) 159258892Semaste { 160258892Semaste m_monitor->ThreadSuspend(*t_pos, true); 161258892Semaste // XXX Cannot PT_CONTINUE properly with suspended threads. 162258892Semaste do_step = true; 163258892Semaste } 164258892Semaste 165258892Semaste if (log) 166276479Sdim log->Printf("process %" PRIu64 " resuming (%s)", GetID(), do_step ? "step" : "continue"); 167258892Semaste if (do_step) 168276479Sdim m_monitor->SingleStep(GetID(), m_resume_signo); 169258892Semaste else 170276479Sdim m_monitor->Resume(GetID(), m_resume_signo); 171258892Semaste 172258892Semaste return Error(); 173258892Semaste} 174258892Semaste 175254721Semastebool 176254721SemasteProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) 177254721Semaste{ 178258892Semaste Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); 179258892Semaste if (log) 180258892Semaste log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID()); 181258054Semaste 182258892Semaste std::vector<lldb::pid_t> tds; 183258892Semaste if (!GetMonitor().GetCurrentThreadIDs(tds)) 184258892Semaste { 185258892Semaste return false; 186258054Semaste } 187258054Semaste 188258892Semaste ThreadList old_thread_list_copy(old_thread_list); 189258892Semaste for (size_t i = 0; i < tds.size(); ++i) 190258892Semaste { 191258892Semaste tid_t tid = tds[i]; 192258892Semaste ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByID(tid, false)); 193258892Semaste if (!thread_sp) 194258892Semaste { 195258892Semaste thread_sp.reset(new FreeBSDThread(*this, tid)); 196258892Semaste if (log) 197258892Semaste log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid); 198258892Semaste } 199258892Semaste else 200258892Semaste { 201258892Semaste if (log) 202258892Semaste log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__, tid); 203258892Semaste } 204258892Semaste new_thread_list.AddThread(thread_sp); 205258892Semaste } 206258892Semaste for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) 207258892Semaste { 208258892Semaste ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false)); 209258892Semaste if (old_thread_sp) 210258892Semaste { 211258892Semaste if (log) 212258892Semaste log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__); 213258892Semaste } 214258892Semaste } 215258054Semaste 216258892Semaste return true; 217258892Semaste} 218258054Semaste 219258892SemasteError 220258892SemasteProcessFreeBSD::WillResume() 221258892Semaste{ 222276479Sdim m_resume_signo = 0; 223258892Semaste m_suspend_tids.clear(); 224258892Semaste m_run_tids.clear(); 225258892Semaste m_step_tids.clear(); 226296417Sdim return Process::WillResume(); 227254721Semaste} 228258892Semaste 229258892Semastevoid 230258892SemasteProcessFreeBSD::SendMessage(const ProcessMessage &message) 231258892Semaste{ 232258892Semaste Mutex::Locker lock(m_message_mutex); 233258892Semaste 234258892Semaste switch (message.GetKind()) 235258892Semaste { 236258892Semaste case ProcessMessage::eInvalidMessage: 237258892Semaste return; 238258892Semaste 239258892Semaste case ProcessMessage::eAttachMessage: 240258892Semaste SetPrivateState(eStateStopped); 241258892Semaste return; 242258892Semaste 243258892Semaste case ProcessMessage::eLimboMessage: 244258892Semaste case ProcessMessage::eExitMessage: 245280031Sdim SetExitStatus(message.GetExitStatus(), NULL); 246258892Semaste break; 247258892Semaste 248258892Semaste case ProcessMessage::eSignalMessage: 249258892Semaste case ProcessMessage::eSignalDeliveredMessage: 250258892Semaste case ProcessMessage::eBreakpointMessage: 251258892Semaste case ProcessMessage::eTraceMessage: 252258892Semaste case ProcessMessage::eWatchpointMessage: 253258892Semaste case ProcessMessage::eCrashMessage: 254258892Semaste SetPrivateState(eStateStopped); 255258892Semaste break; 256258892Semaste 257258892Semaste case ProcessMessage::eNewThreadMessage: 258296417Sdim llvm_unreachable("eNewThreadMessage unexpected on FreeBSD"); 259258892Semaste break; 260258892Semaste 261258892Semaste case ProcessMessage::eExecMessage: 262258892Semaste SetPrivateState(eStateStopped); 263258892Semaste break; 264258892Semaste } 265258892Semaste 266258892Semaste m_message_queue.push(message); 267258892Semaste} 268296417Sdim 269296417Sdim//------------------------------------------------------------------------------ 270296417Sdim// Constructors and destructors. 271296417Sdim 272296417SdimProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp, Listener &listener, UnixSignalsSP &unix_signals_sp) 273296417Sdim : Process(target_sp, listener, unix_signals_sp), 274296417Sdim m_byte_order(endian::InlHostByteOrder()), 275296417Sdim m_monitor(NULL), 276296417Sdim m_module(NULL), 277296417Sdim m_message_mutex (Mutex::eMutexTypeRecursive), 278296417Sdim m_exit_now(false), 279296417Sdim m_seen_initial_stop(), 280296417Sdim m_resume_signo(0) 281296417Sdim{ 282296417Sdim // FIXME: Putting this code in the ctor and saving the byte order in a 283296417Sdim // member variable is a hack to avoid const qual issues in GetByteOrder. 284296417Sdim lldb::ModuleSP module = GetTarget().GetExecutableModule(); 285296417Sdim if (module && module->GetObjectFile()) 286296417Sdim m_byte_order = module->GetObjectFile()->GetByteOrder(); 287296417Sdim} 288296417Sdim 289296417SdimProcessFreeBSD::~ProcessFreeBSD() 290296417Sdim{ 291296417Sdim delete m_monitor; 292296417Sdim} 293296417Sdim 294296417Sdim//------------------------------------------------------------------------------ 295296417Sdim// Process protocol. 296296417Sdimvoid 297296417SdimProcessFreeBSD::Finalize() 298296417Sdim{ 299296417Sdim Process::Finalize(); 300296417Sdim 301296417Sdim if (m_monitor) 302296417Sdim m_monitor->StopMonitor(); 303296417Sdim} 304296417Sdim 305296417Sdimbool 306296417SdimProcessFreeBSD::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) 307296417Sdim{ 308296417Sdim // For now we are just making sure the file exists for a given module 309296417Sdim ModuleSP exe_module_sp(target_sp->GetExecutableModule()); 310296417Sdim if (exe_module_sp.get()) 311296417Sdim return exe_module_sp->GetFileSpec().Exists(); 312296417Sdim // If there is no executable module, we return true since we might be preparing to attach. 313296417Sdim return true; 314296417Sdim} 315296417Sdim 316296417SdimError 317296417SdimProcessFreeBSD::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info) 318296417Sdim{ 319296417Sdim Error error; 320296417Sdim assert(m_monitor == NULL); 321296417Sdim 322296417Sdim Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); 323296417Sdim if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 324296417Sdim log->Printf ("ProcessFreeBSD::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID()); 325296417Sdim 326296417Sdim m_monitor = new ProcessMonitor(this, pid, error); 327296417Sdim 328296417Sdim if (!error.Success()) 329296417Sdim return error; 330296417Sdim 331296417Sdim PlatformSP platform_sp (GetTarget().GetPlatform ()); 332296417Sdim assert (platform_sp.get()); 333296417Sdim if (!platform_sp) 334296417Sdim return error; // FIXME: Detatch? 335296417Sdim 336296417Sdim // Find out what we can about this process 337296417Sdim ProcessInstanceInfo process_info; 338296417Sdim platform_sp->GetProcessInfo (pid, process_info); 339296417Sdim 340296417Sdim // Resolve the executable module 341296417Sdim ModuleSP exe_module_sp; 342296417Sdim FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 343296417Sdim ModuleSpec exe_module_spec(process_info.GetExecutableFile(), GetTarget().GetArchitecture()); 344296417Sdim error = platform_sp->ResolveExecutable(exe_module_spec, 345296417Sdim exe_module_sp, 346296417Sdim executable_search_paths.GetSize() ? &executable_search_paths : NULL); 347296417Sdim if (!error.Success()) 348296417Sdim return error; 349296417Sdim 350296417Sdim // Fix the target architecture if necessary 351296417Sdim const ArchSpec &module_arch = exe_module_sp->GetArchitecture(); 352296417Sdim if (module_arch.IsValid() && !GetTarget().GetArchitecture().IsExactMatch(module_arch)) 353296417Sdim GetTarget().SetArchitecture(module_arch); 354296417Sdim 355296417Sdim // Initialize the target module list 356296417Sdim GetTarget().SetExecutableModule (exe_module_sp, true); 357296417Sdim 358296417Sdim SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); 359296417Sdim 360296417Sdim SetID(pid); 361296417Sdim 362296417Sdim return error; 363296417Sdim} 364296417Sdim 365296417SdimError 366296417SdimProcessFreeBSD::WillLaunch(Module* module) 367296417Sdim{ 368296417Sdim Error error; 369296417Sdim return error; 370296417Sdim} 371296417Sdim 372296417SdimFileSpec 373296417SdimProcessFreeBSD::GetFileSpec(const lldb_private::FileAction *file_action, 374296417Sdim const FileSpec &default_file_spec, 375296417Sdim const FileSpec &dbg_pts_file_spec) 376296417Sdim{ 377296417Sdim FileSpec file_spec{}; 378296417Sdim 379296417Sdim if (file_action && file_action->GetAction() == FileAction::eFileActionOpen) 380296417Sdim { 381296417Sdim file_spec = file_action->GetFileSpec(); 382296417Sdim // By default the stdio paths passed in will be pseudo-terminal 383296417Sdim // (/dev/pts). If so, convert to using a different default path 384296417Sdim // instead to redirect I/O to the debugger console. This should 385296417Sdim // also handle user overrides to /dev/null or a different file. 386296417Sdim if (!file_spec || file_spec == dbg_pts_file_spec) 387296417Sdim file_spec = default_file_spec; 388296417Sdim } 389296417Sdim return file_spec; 390296417Sdim} 391296417Sdim 392296417SdimError 393296417SdimProcessFreeBSD::DoLaunch (Module *module, 394296417Sdim ProcessLaunchInfo &launch_info) 395296417Sdim{ 396296417Sdim Error error; 397296417Sdim assert(m_monitor == NULL); 398296417Sdim 399296417Sdim FileSpec working_dir = launch_info.GetWorkingDirectory(); 400296417Sdim if (working_dir && 401296417Sdim (!working_dir.ResolvePath() || 402296417Sdim working_dir.GetFileType() != FileSpec::eFileTypeDirectory)) 403296417Sdim { 404296417Sdim error.SetErrorStringWithFormat("No such file or directory: %s", 405296417Sdim working_dir.GetCString()); 406296417Sdim return error; 407296417Sdim } 408296417Sdim 409296417Sdim SetPrivateState(eStateLaunching); 410296417Sdim 411296417Sdim const lldb_private::FileAction *file_action; 412296417Sdim 413296417Sdim // Default of empty will mean to use existing open file descriptors 414296417Sdim FileSpec stdin_file_spec{}; 415296417Sdim FileSpec stdout_file_spec{}; 416296417Sdim FileSpec stderr_file_spec{}; 417296417Sdim 418296417Sdim const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL,0), false}; 419296417Sdim 420296417Sdim file_action = launch_info.GetFileActionForFD (STDIN_FILENO); 421296417Sdim stdin_file_spec = GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec); 422296417Sdim 423296417Sdim file_action = launch_info.GetFileActionForFD (STDOUT_FILENO); 424296417Sdim stdout_file_spec = GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec); 425296417Sdim 426296417Sdim file_action = launch_info.GetFileActionForFD (STDERR_FILENO); 427296417Sdim stderr_file_spec = GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec); 428296417Sdim 429296417Sdim m_monitor = new ProcessMonitor(this, 430296417Sdim module, 431296417Sdim launch_info.GetArguments().GetConstArgumentVector(), 432296417Sdim launch_info.GetEnvironmentEntries().GetConstArgumentVector(), 433296417Sdim stdin_file_spec, 434296417Sdim stdout_file_spec, 435296417Sdim stderr_file_spec, 436296417Sdim working_dir, 437296417Sdim launch_info, 438296417Sdim error); 439296417Sdim 440296417Sdim m_module = module; 441296417Sdim 442296417Sdim if (!error.Success()) 443296417Sdim return error; 444296417Sdim 445296417Sdim int terminal = m_monitor->GetTerminalFD(); 446296417Sdim if (terminal >= 0) { 447296417Sdim // The reader thread will close the file descriptor when done, so we pass it a copy. 448296417Sdim#ifdef F_DUPFD_CLOEXEC 449296417Sdim int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0); 450296417Sdim if (stdio == -1) { 451296417Sdim error.SetErrorToErrno(); 452296417Sdim return error; 453296417Sdim } 454296417Sdim#else 455296417Sdim // Special case when F_DUPFD_CLOEXEC does not exist (Debian kFreeBSD) 456296417Sdim int stdio = fcntl(terminal, F_DUPFD, 0); 457296417Sdim if (stdio == -1) { 458296417Sdim error.SetErrorToErrno(); 459296417Sdim return error; 460296417Sdim } 461296417Sdim stdio = fcntl(terminal, F_SETFD, FD_CLOEXEC); 462296417Sdim if (stdio == -1) { 463296417Sdim error.SetErrorToErrno(); 464296417Sdim return error; 465296417Sdim } 466296417Sdim#endif 467296417Sdim SetSTDIOFileDescriptor(stdio); 468296417Sdim } 469296417Sdim 470296417Sdim SetID(m_monitor->GetPID()); 471296417Sdim return error; 472296417Sdim} 473296417Sdim 474296417Sdimvoid 475296417SdimProcessFreeBSD::DidLaunch() 476296417Sdim{ 477296417Sdim} 478296417Sdim 479296417Sdimaddr_t 480296417SdimProcessFreeBSD::GetImageInfoAddress() 481296417Sdim{ 482296417Sdim Target *target = &GetTarget(); 483296417Sdim ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); 484296417Sdim Address addr = obj_file->GetImageInfoAddress(target); 485296417Sdim 486296417Sdim if (addr.IsValid()) 487296417Sdim return addr.GetLoadAddress(target); 488296417Sdim return LLDB_INVALID_ADDRESS; 489296417Sdim} 490296417Sdim 491296417SdimError 492296417SdimProcessFreeBSD::DoHalt(bool &caused_stop) 493296417Sdim{ 494296417Sdim Error error; 495296417Sdim 496296417Sdim if (IsStopped()) 497296417Sdim { 498296417Sdim caused_stop = false; 499296417Sdim } 500296417Sdim else if (kill(GetID(), SIGSTOP)) 501296417Sdim { 502296417Sdim caused_stop = false; 503296417Sdim error.SetErrorToErrno(); 504296417Sdim } 505296417Sdim else 506296417Sdim { 507296417Sdim caused_stop = true; 508296417Sdim } 509296417Sdim return error; 510296417Sdim} 511296417Sdim 512296417SdimError 513296417SdimProcessFreeBSD::DoSignal(int signal) 514296417Sdim{ 515296417Sdim Error error; 516296417Sdim 517296417Sdim if (kill(GetID(), signal)) 518296417Sdim error.SetErrorToErrno(); 519296417Sdim 520296417Sdim return error; 521296417Sdim} 522296417Sdim 523296417SdimError 524296417SdimProcessFreeBSD::DoDestroy() 525296417Sdim{ 526296417Sdim Error error; 527296417Sdim 528296417Sdim if (!HasExited()) 529296417Sdim { 530296417Sdim assert(m_monitor); 531296417Sdim m_exit_now = true; 532296417Sdim if (GetID() == LLDB_INVALID_PROCESS_ID) 533296417Sdim { 534296417Sdim error.SetErrorString("invalid process id"); 535296417Sdim return error; 536296417Sdim } 537296417Sdim if (!m_monitor->Kill()) 538296417Sdim { 539296417Sdim error.SetErrorToErrno(); 540296417Sdim return error; 541296417Sdim } 542296417Sdim 543296417Sdim SetPrivateState(eStateExited); 544296417Sdim } 545296417Sdim 546296417Sdim return error; 547296417Sdim} 548296417Sdim 549296417Sdimvoid 550296417SdimProcessFreeBSD::DoDidExec() 551296417Sdim{ 552296417Sdim Target *target = &GetTarget(); 553296417Sdim if (target) 554296417Sdim { 555296417Sdim PlatformSP platform_sp (target->GetPlatform()); 556296417Sdim assert (platform_sp.get()); 557296417Sdim if (platform_sp) 558296417Sdim { 559296417Sdim ProcessInstanceInfo process_info; 560296417Sdim platform_sp->GetProcessInfo(GetID(), process_info); 561296417Sdim ModuleSP exe_module_sp; 562296417Sdim ModuleSpec exe_module_spec(process_info.GetExecutableFile(), target->GetArchitecture()); 563296417Sdim FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 564296417Sdim Error error = platform_sp->ResolveExecutable(exe_module_spec, 565296417Sdim exe_module_sp, 566296417Sdim executable_search_paths.GetSize() ? &executable_search_paths : NULL); 567296417Sdim if (!error.Success()) 568296417Sdim return; 569296417Sdim target->SetExecutableModule(exe_module_sp, true); 570296417Sdim } 571296417Sdim } 572296417Sdim} 573296417Sdim 574296417Sdimbool 575296417SdimProcessFreeBSD::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) 576296417Sdim{ 577296417Sdim bool added_to_set = false; 578296417Sdim ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid); 579296417Sdim if (it == m_seen_initial_stop.end()) 580296417Sdim { 581296417Sdim m_seen_initial_stop.insert(stop_tid); 582296417Sdim added_to_set = true; 583296417Sdim } 584296417Sdim return added_to_set; 585296417Sdim} 586296417Sdim 587296417Sdimbool 588296417SdimProcessFreeBSD::WaitingForInitialStop(lldb::tid_t stop_tid) 589296417Sdim{ 590296417Sdim return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end()); 591296417Sdim} 592296417Sdim 593296417SdimFreeBSDThread * 594296417SdimProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process, lldb::tid_t tid) 595296417Sdim{ 596296417Sdim return new FreeBSDThread(process, tid); 597296417Sdim} 598296417Sdim 599296417Sdimvoid 600296417SdimProcessFreeBSD::RefreshStateAfterStop() 601296417Sdim{ 602296417Sdim Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); 603296417Sdim if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 604296417Sdim log->Printf ("ProcessFreeBSD::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size()); 605296417Sdim 606296417Sdim Mutex::Locker lock(m_message_mutex); 607296417Sdim 608296417Sdim // This method used to only handle one message. Changing it to loop allows 609296417Sdim // it to handle the case where we hit a breakpoint while handling a different 610296417Sdim // breakpoint. 611296417Sdim while (!m_message_queue.empty()) 612296417Sdim { 613296417Sdim ProcessMessage &message = m_message_queue.front(); 614296417Sdim 615296417Sdim // Resolve the thread this message corresponds to and pass it along. 616296417Sdim lldb::tid_t tid = message.GetTID(); 617296417Sdim if (log) 618296417Sdim log->Printf ("ProcessFreeBSD::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid); 619296417Sdim 620296417Sdim m_thread_list.RefreshStateAfterStop(); 621296417Sdim 622296417Sdim FreeBSDThread *thread = static_cast<FreeBSDThread*>( 623296417Sdim GetThreadList().FindThreadByID(tid, false).get()); 624296417Sdim if (thread) 625296417Sdim thread->Notify(message); 626296417Sdim 627296417Sdim if (message.GetKind() == ProcessMessage::eExitMessage) 628296417Sdim { 629296417Sdim // FIXME: We should tell the user about this, but the limbo message is probably better for that. 630296417Sdim if (log) 631296417Sdim log->Printf ("ProcessFreeBSD::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid); 632296417Sdim 633296417Sdim Mutex::Locker lock(m_thread_list.GetMutex()); 634296417Sdim 635296417Sdim ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false); 636296417Sdim thread_sp.reset(); 637296417Sdim m_seen_initial_stop.erase(tid); 638296417Sdim } 639296417Sdim 640296417Sdim m_message_queue.pop(); 641296417Sdim } 642296417Sdim} 643296417Sdim 644296417Sdimbool 645296417SdimProcessFreeBSD::IsAlive() 646296417Sdim{ 647296417Sdim StateType state = GetPrivateState(); 648296417Sdim return state != eStateDetached 649296417Sdim && state != eStateExited 650296417Sdim && state != eStateInvalid 651296417Sdim && state != eStateUnloaded; 652296417Sdim} 653296417Sdim 654296417Sdimsize_t 655296417SdimProcessFreeBSD::DoReadMemory(addr_t vm_addr, 656296417Sdim void *buf, size_t size, Error &error) 657296417Sdim{ 658296417Sdim assert(m_monitor); 659296417Sdim return m_monitor->ReadMemory(vm_addr, buf, size, error); 660296417Sdim} 661296417Sdim 662296417Sdimsize_t 663296417SdimProcessFreeBSD::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size, 664296417Sdim Error &error) 665296417Sdim{ 666296417Sdim assert(m_monitor); 667296417Sdim return m_monitor->WriteMemory(vm_addr, buf, size, error); 668296417Sdim} 669296417Sdim 670296417Sdimaddr_t 671296417SdimProcessFreeBSD::DoAllocateMemory(size_t size, uint32_t permissions, 672296417Sdim Error &error) 673296417Sdim{ 674296417Sdim addr_t allocated_addr = LLDB_INVALID_ADDRESS; 675296417Sdim 676296417Sdim unsigned prot = 0; 677296417Sdim if (permissions & lldb::ePermissionsReadable) 678296417Sdim prot |= eMmapProtRead; 679296417Sdim if (permissions & lldb::ePermissionsWritable) 680296417Sdim prot |= eMmapProtWrite; 681296417Sdim if (permissions & lldb::ePermissionsExecutable) 682296417Sdim prot |= eMmapProtExec; 683296417Sdim 684296417Sdim if (InferiorCallMmap(this, allocated_addr, 0, size, prot, 685296417Sdim eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) { 686296417Sdim m_addr_to_mmap_size[allocated_addr] = size; 687296417Sdim error.Clear(); 688296417Sdim } else { 689296417Sdim allocated_addr = LLDB_INVALID_ADDRESS; 690296417Sdim error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions)); 691296417Sdim } 692296417Sdim 693296417Sdim return allocated_addr; 694296417Sdim} 695296417Sdim 696296417SdimError 697296417SdimProcessFreeBSD::DoDeallocateMemory(lldb::addr_t addr) 698296417Sdim{ 699296417Sdim Error error; 700296417Sdim MMapMap::iterator pos = m_addr_to_mmap_size.find(addr); 701296417Sdim if (pos != m_addr_to_mmap_size.end() && 702296417Sdim InferiorCallMunmap(this, addr, pos->second)) 703296417Sdim m_addr_to_mmap_size.erase (pos); 704296417Sdim else 705296417Sdim error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr); 706296417Sdim 707296417Sdim return error; 708296417Sdim} 709296417Sdim 710296417Sdimsize_t 711296417SdimProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site) 712296417Sdim{ 713296417Sdim static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xD4 }; 714296417Sdim static const uint8_t g_i386_opcode[] = { 0xCC }; 715296417Sdim 716296417Sdim ArchSpec arch = GetTarget().GetArchitecture(); 717296417Sdim const uint8_t *opcode = NULL; 718296417Sdim size_t opcode_size = 0; 719296417Sdim 720296417Sdim switch (arch.GetMachine()) 721296417Sdim { 722296417Sdim default: 723296417Sdim assert(false && "CPU type not supported!"); 724296417Sdim break; 725296417Sdim 726296417Sdim case llvm::Triple::arm: 727296417Sdim { 728296417Sdim // The ARM reference recommends the use of 0xe7fddefe and 0xdefe 729296417Sdim // but the linux kernel does otherwise. 730296417Sdim static const uint8_t g_arm_breakpoint_opcode[] = { 0xf0, 0x01, 0xf0, 0xe7 }; 731296417Sdim static const uint8_t g_thumb_breakpoint_opcode[] = { 0x01, 0xde }; 732296417Sdim 733296417Sdim lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0)); 734296417Sdim AddressClass addr_class = eAddressClassUnknown; 735296417Sdim 736296417Sdim if (bp_loc_sp) 737296417Sdim addr_class = bp_loc_sp->GetAddress ().GetAddressClass (); 738296417Sdim 739296417Sdim if (addr_class == eAddressClassCodeAlternateISA 740296417Sdim || (addr_class == eAddressClassUnknown 741296417Sdim && bp_loc_sp->GetAddress().GetOffset() & 1)) 742296417Sdim { 743296417Sdim opcode = g_thumb_breakpoint_opcode; 744296417Sdim opcode_size = sizeof(g_thumb_breakpoint_opcode); 745296417Sdim } 746296417Sdim else 747296417Sdim { 748296417Sdim opcode = g_arm_breakpoint_opcode; 749296417Sdim opcode_size = sizeof(g_arm_breakpoint_opcode); 750296417Sdim } 751296417Sdim } 752296417Sdim break; 753296417Sdim case llvm::Triple::aarch64: 754296417Sdim opcode = g_aarch64_opcode; 755296417Sdim opcode_size = sizeof(g_aarch64_opcode); 756296417Sdim break; 757296417Sdim 758296417Sdim case llvm::Triple::x86: 759296417Sdim case llvm::Triple::x86_64: 760296417Sdim opcode = g_i386_opcode; 761296417Sdim opcode_size = sizeof(g_i386_opcode); 762296417Sdim break; 763296417Sdim } 764296417Sdim 765296417Sdim bp_site->SetTrapOpcode(opcode, opcode_size); 766296417Sdim return opcode_size; 767296417Sdim} 768296417Sdim 769296417SdimError 770296417SdimProcessFreeBSD::EnableBreakpointSite(BreakpointSite *bp_site) 771296417Sdim{ 772296417Sdim return EnableSoftwareBreakpoint(bp_site); 773296417Sdim} 774296417Sdim 775296417SdimError 776296417SdimProcessFreeBSD::DisableBreakpointSite(BreakpointSite *bp_site) 777296417Sdim{ 778296417Sdim return DisableSoftwareBreakpoint(bp_site); 779296417Sdim} 780296417Sdim 781296417SdimError 782296417SdimProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) 783296417Sdim{ 784296417Sdim Error error; 785296417Sdim if (wp) 786296417Sdim { 787296417Sdim user_id_t watchID = wp->GetID(); 788296417Sdim addr_t addr = wp->GetLoadAddress(); 789296417Sdim Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 790296417Sdim if (log) 791296417Sdim log->Printf ("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")", 792296417Sdim watchID); 793296417Sdim if (wp->IsEnabled()) 794296417Sdim { 795296417Sdim if (log) 796296417Sdim log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 797296417Sdim ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", 798296417Sdim watchID, (uint64_t)addr); 799296417Sdim return error; 800296417Sdim } 801296417Sdim 802296417Sdim // Try to find a vacant watchpoint slot in the inferiors' main thread 803296417Sdim uint32_t wp_hw_index = LLDB_INVALID_INDEX32; 804296417Sdim Mutex::Locker lock(m_thread_list.GetMutex()); 805296417Sdim FreeBSDThread *thread = static_cast<FreeBSDThread*>( 806296417Sdim m_thread_list.GetThreadAtIndex(0, false).get()); 807296417Sdim 808296417Sdim if (thread) 809296417Sdim wp_hw_index = thread->FindVacantWatchpointIndex(); 810296417Sdim 811296417Sdim if (wp_hw_index == LLDB_INVALID_INDEX32) 812296417Sdim { 813296417Sdim error.SetErrorString("Setting hardware watchpoint failed."); 814296417Sdim } 815296417Sdim else 816296417Sdim { 817296417Sdim wp->SetHardwareIndex(wp_hw_index); 818296417Sdim bool wp_enabled = true; 819296417Sdim uint32_t thread_count = m_thread_list.GetSize(false); 820296417Sdim for (uint32_t i = 0; i < thread_count; ++i) 821296417Sdim { 822296417Sdim thread = static_cast<FreeBSDThread*>( 823296417Sdim m_thread_list.GetThreadAtIndex(i, false).get()); 824296417Sdim if (thread) 825296417Sdim wp_enabled &= thread->EnableHardwareWatchpoint(wp); 826296417Sdim else 827296417Sdim wp_enabled = false; 828296417Sdim } 829296417Sdim if (wp_enabled) 830296417Sdim { 831296417Sdim wp->SetEnabled(true, notify); 832296417Sdim return error; 833296417Sdim } 834296417Sdim else 835296417Sdim { 836296417Sdim // Watchpoint enabling failed on at least one 837296417Sdim // of the threads so roll back all of them 838296417Sdim DisableWatchpoint(wp, false); 839296417Sdim error.SetErrorString("Setting hardware watchpoint failed"); 840296417Sdim } 841296417Sdim } 842296417Sdim } 843296417Sdim else 844296417Sdim error.SetErrorString("Watchpoint argument was NULL."); 845296417Sdim return error; 846296417Sdim} 847296417Sdim 848296417SdimError 849296417SdimProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify) 850296417Sdim{ 851296417Sdim Error error; 852296417Sdim if (wp) 853296417Sdim { 854296417Sdim user_id_t watchID = wp->GetID(); 855296417Sdim addr_t addr = wp->GetLoadAddress(); 856296417Sdim Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 857296417Sdim if (log) 858296417Sdim log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")", 859296417Sdim watchID); 860296417Sdim if (!wp->IsEnabled()) 861296417Sdim { 862296417Sdim if (log) 863296417Sdim log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 864296417Sdim ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.", 865296417Sdim watchID, (uint64_t)addr); 866296417Sdim // This is needed (for now) to keep watchpoints disabled correctly 867296417Sdim wp->SetEnabled(false, notify); 868296417Sdim return error; 869296417Sdim } 870296417Sdim 871296417Sdim if (wp->IsHardware()) 872296417Sdim { 873296417Sdim bool wp_disabled = true; 874296417Sdim Mutex::Locker lock(m_thread_list.GetMutex()); 875296417Sdim uint32_t thread_count = m_thread_list.GetSize(false); 876296417Sdim for (uint32_t i = 0; i < thread_count; ++i) 877296417Sdim { 878296417Sdim FreeBSDThread *thread = static_cast<FreeBSDThread*>( 879296417Sdim m_thread_list.GetThreadAtIndex(i, false).get()); 880296417Sdim if (thread) 881296417Sdim wp_disabled &= thread->DisableHardwareWatchpoint(wp); 882296417Sdim else 883296417Sdim wp_disabled = false; 884296417Sdim } 885296417Sdim if (wp_disabled) 886296417Sdim { 887296417Sdim wp->SetHardwareIndex(LLDB_INVALID_INDEX32); 888296417Sdim wp->SetEnabled(false, notify); 889296417Sdim return error; 890296417Sdim } 891296417Sdim else 892296417Sdim error.SetErrorString("Disabling hardware watchpoint failed"); 893296417Sdim } 894296417Sdim } 895296417Sdim else 896296417Sdim error.SetErrorString("Watchpoint argument was NULL."); 897296417Sdim return error; 898296417Sdim} 899296417Sdim 900296417SdimError 901296417SdimProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num) 902296417Sdim{ 903296417Sdim Error error; 904296417Sdim Mutex::Locker lock(m_thread_list.GetMutex()); 905296417Sdim FreeBSDThread *thread = static_cast<FreeBSDThread*>( 906296417Sdim m_thread_list.GetThreadAtIndex(0, false).get()); 907296417Sdim if (thread) 908296417Sdim num = thread->NumSupportedHardwareWatchpoints(); 909296417Sdim else 910296417Sdim error.SetErrorString("Process does not exist."); 911296417Sdim return error; 912296417Sdim} 913296417Sdim 914296417SdimError 915296417SdimProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after) 916296417Sdim{ 917296417Sdim Error error = GetWatchpointSupportInfo(num); 918296417Sdim // Watchpoints trigger and halt the inferior after 919296417Sdim // the corresponding instruction has been executed. 920296417Sdim after = true; 921296417Sdim return error; 922296417Sdim} 923296417Sdim 924296417Sdimuint32_t 925296417SdimProcessFreeBSD::UpdateThreadListIfNeeded() 926296417Sdim{ 927296417Sdim Mutex::Locker lock(m_thread_list.GetMutex()); 928296417Sdim // Do not allow recursive updates. 929296417Sdim return m_thread_list.GetSize(false); 930296417Sdim} 931296417Sdim 932296417Sdim#if 0 933296417Sdimbool 934296417SdimProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) 935296417Sdim{ 936296417Sdim Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 937296417Sdim if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 938296417Sdim log->Printf ("ProcessFreeBSD::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID()); 939296417Sdim 940296417Sdim bool has_updated = false; 941296417Sdim // Update the process thread list with this new thread. 942296417Sdim // FIXME: We should be using tid, not pid. 943296417Sdim assert(m_monitor); 944296417Sdim ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false)); 945296417Sdim if (!thread_sp) { 946296417Sdim thread_sp.reset(CreateNewFreeBSDThread(*this, GetID())); 947296417Sdim has_updated = true; 948296417Sdim } 949296417Sdim 950296417Sdim if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 951296417Sdim log->Printf ("ProcessFreeBSD::%s() updated pid = %" PRIi64, __FUNCTION__, GetID()); 952296417Sdim new_thread_list.AddThread(thread_sp); 953296417Sdim 954296417Sdim return has_updated; // the list has been updated 955296417Sdim} 956296417Sdim#endif 957296417Sdim 958296417SdimByteOrder 959296417SdimProcessFreeBSD::GetByteOrder() const 960296417Sdim{ 961296417Sdim // FIXME: We should be able to extract this value directly. See comment in 962296417Sdim // ProcessFreeBSD(). 963296417Sdim return m_byte_order; 964296417Sdim} 965296417Sdim 966296417Sdimsize_t 967296417SdimProcessFreeBSD::PutSTDIN(const char *buf, size_t len, Error &error) 968296417Sdim{ 969296417Sdim ssize_t status; 970296417Sdim if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) 971296417Sdim { 972296417Sdim error.SetErrorToErrno(); 973296417Sdim return 0; 974296417Sdim } 975296417Sdim return status; 976296417Sdim} 977296417Sdim 978296417Sdim//------------------------------------------------------------------------------ 979296417Sdim// Utility functions. 980296417Sdim 981296417Sdimbool 982296417SdimProcessFreeBSD::HasExited() 983296417Sdim{ 984296417Sdim switch (GetPrivateState()) 985296417Sdim { 986296417Sdim default: 987296417Sdim break; 988296417Sdim 989296417Sdim case eStateDetached: 990296417Sdim case eStateExited: 991296417Sdim return true; 992296417Sdim } 993296417Sdim 994296417Sdim return false; 995296417Sdim} 996296417Sdim 997296417Sdimbool 998296417SdimProcessFreeBSD::IsStopped() 999296417Sdim{ 1000296417Sdim switch (GetPrivateState()) 1001296417Sdim { 1002296417Sdim default: 1003296417Sdim break; 1004296417Sdim 1005296417Sdim case eStateStopped: 1006296417Sdim case eStateCrashed: 1007296417Sdim case eStateSuspended: 1008296417Sdim return true; 1009296417Sdim } 1010296417Sdim 1011296417Sdim return false; 1012296417Sdim} 1013296417Sdim 1014296417Sdimbool 1015296417SdimProcessFreeBSD::IsAThreadRunning() 1016296417Sdim{ 1017296417Sdim bool is_running = false; 1018296417Sdim Mutex::Locker lock(m_thread_list.GetMutex()); 1019296417Sdim uint32_t thread_count = m_thread_list.GetSize(false); 1020296417Sdim for (uint32_t i = 0; i < thread_count; ++i) 1021296417Sdim { 1022296417Sdim FreeBSDThread *thread = static_cast<FreeBSDThread*>( 1023296417Sdim m_thread_list.GetThreadAtIndex(i, false).get()); 1024296417Sdim StateType thread_state = thread->GetState(); 1025296417Sdim if (thread_state == eStateRunning || thread_state == eStateStepping) 1026296417Sdim { 1027296417Sdim is_running = true; 1028296417Sdim break; 1029296417Sdim } 1030296417Sdim } 1031296417Sdim return is_running; 1032296417Sdim} 1033296417Sdim 1034296417Sdimconst DataBufferSP 1035296417SdimProcessFreeBSD::GetAuxvData () 1036296417Sdim{ 1037296417Sdim // If we're the local platform, we can ask the host for auxv data. 1038296417Sdim PlatformSP platform_sp = GetTarget().GetPlatform (); 1039296417Sdim if (platform_sp && platform_sp->IsHost ()) 1040296417Sdim return lldb_private::Host::GetAuxvData(this); 1041296417Sdim 1042296417Sdim // Somewhat unexpected - the process is not running locally or we don't have a platform. 1043296417Sdim assert (false && "no platform or not the host - how did we get here with ProcessFreeBSD?"); 1044296417Sdim return DataBufferSP (); 1045296417Sdim} 1046