blob: abdbb8bb9d1aa42c653f1e83fe708aab3b57865b [file] [log] [blame]
Kate Stoneb9c1b512016-09-06 20:57:50 +00001//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++
2//-*-===//
Johnny Chen9ed5b492012-01-05 21:48:15 +00003//
4// The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11// C Includes
12#include <errno.h>
Pavel Labathb7f0f452017-03-17 11:08:40 +000013#include <pthread.h>
14#include <pthread_np.h>
15#include <stdlib.h>
16#include <sys/sysctl.h>
17#include <sys/types.h>
18#include <sys/user.h>
Pavel Labath5b116232017-03-17 11:33:57 +000019#include <machine/elf.h>
Johnny Chen9ed5b492012-01-05 21:48:15 +000020
21// C++ Includes
Benjamin Kramer3f69fa62015-04-03 10:55:00 +000022#include <mutex>
Ed Maste31f01802017-01-24 14:34:49 +000023#include <unordered_map>
Benjamin Kramer3f69fa62015-04-03 10:55:00 +000024
Johnny Chen9ed5b492012-01-05 21:48:15 +000025// Other libraries and framework includes
26#include "lldb/Core/PluginManager.h"
27#include "lldb/Core/State.h"
28#include "lldb/Host/Host.h"
29#include "lldb/Symbol/ObjectFile.h"
30#include "lldb/Target/DynamicLoader.h"
31#include "lldb/Target/Target.h"
32
Ed Maste7fd845c2013-12-09 15:51:17 +000033#include "FreeBSDThread.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000034#include "Plugins/Process/Utility/FreeBSDSignals.h"
35#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
36#include "ProcessFreeBSD.h"
37#include "ProcessMonitor.h"
38#include "ProcessPOSIXLog.h"
Johnny Chen9ed5b492012-01-05 21:48:15 +000039
Ed Mastefe5a6422015-07-28 15:45:57 +000040// Other libraries and framework includes
41#include "lldb/Breakpoint/BreakpointLocation.h"
42#include "lldb/Breakpoint/Watchpoint.h"
43#include "lldb/Core/Module.h"
44#include "lldb/Core/ModuleSpec.h"
45#include "lldb/Core/PluginManager.h"
46#include "lldb/Core/State.h"
Ed Mastefe5a6422015-07-28 15:45:57 +000047#include "lldb/Host/Host.h"
48#include "lldb/Symbol/ObjectFile.h"
49#include "lldb/Target/DynamicLoader.h"
50#include "lldb/Target/Platform.h"
51#include "lldb/Target/Target.h"
Pavel Labath5b116232017-03-17 11:33:57 +000052#include "lldb/Utility/DataBufferHeap.h"
Zachary Turner5713a052017-03-22 18:40:07 +000053#include "lldb/Utility/FileSpec.h"
Ed Mastefe5a6422015-07-28 15:45:57 +000054
55#include "lldb/Host/posix/Fcntl.h"
56
Zachary Turner7d86ee52017-03-08 17:56:08 +000057#include "llvm/Support/FileSystem.h"
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000058#include "llvm/Support/Threading.h"
59
Johnny Chen9ed5b492012-01-05 21:48:15 +000060using namespace lldb;
61using namespace lldb_private;
62
Kate Stoneb9c1b512016-09-06 20:57:50 +000063namespace {
64UnixSignalsSP &GetFreeBSDSignals() {
65 static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals());
66 return s_freebsd_signals_sp;
67}
Todd Fiala4ceced32014-08-29 17:35:57 +000068}
69
Johnny Chen9ed5b492012-01-05 21:48:15 +000070//------------------------------------------------------------------------------
71// Static functions.
72
Greg Clayton29d19302012-02-27 18:40:48 +000073lldb::ProcessSP
Zachary Turner12004eb2015-09-02 16:47:47 +000074ProcessFreeBSD::CreateInstance(lldb::TargetSP target_sp,
Jim Ingham583bbb12016-03-07 21:50:25 +000075 lldb::ListenerSP listener_sp,
Kate Stoneb9c1b512016-09-06 20:57:50 +000076 const FileSpec *crash_file_path) {
77 lldb::ProcessSP process_sp;
78 if (crash_file_path == NULL)
79 process_sp.reset(
80 new ProcessFreeBSD(target_sp, listener_sp, GetFreeBSDSignals()));
81 return process_sp;
Johnny Chen9ed5b492012-01-05 21:48:15 +000082}
83
Kate Stoneb9c1b512016-09-06 20:57:50 +000084void ProcessFreeBSD::Initialize() {
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000085 static llvm::once_flag g_once_flag;
Johnny Chen9ed5b492012-01-05 21:48:15 +000086
Kamil Rytarowskic5f28e22017-02-06 17:55:02 +000087 llvm::call_once(g_once_flag, []() {
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 PluginManager::RegisterPlugin(GetPluginNameStatic(),
89 GetPluginDescriptionStatic(), CreateInstance);
Kate Stoneb9c1b512016-09-06 20:57:50 +000090 });
Johnny Chen9ed5b492012-01-05 21:48:15 +000091}
92
Kate Stoneb9c1b512016-09-06 20:57:50 +000093lldb_private::ConstString ProcessFreeBSD::GetPluginNameStatic() {
94 static ConstString g_name("freebsd");
95 return g_name;
Johnny Chen9ed5b492012-01-05 21:48:15 +000096}
97
Kate Stoneb9c1b512016-09-06 20:57:50 +000098const char *ProcessFreeBSD::GetPluginDescriptionStatic() {
99 return "Process plugin for FreeBSD";
Johnny Chen9ed5b492012-01-05 21:48:15 +0000100}
101
102//------------------------------------------------------------------------------
103// ProcessInterface protocol.
104
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105lldb_private::ConstString ProcessFreeBSD::GetPluginName() {
106 return GetPluginNameStatic();
Johnny Chen9ed5b492012-01-05 21:48:15 +0000107}
108
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109uint32_t ProcessFreeBSD::GetPluginVersion() { return 1; }
Johnny Chen9ed5b492012-01-05 21:48:15 +0000110
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111void ProcessFreeBSD::Terminate() {}
Johnny Chen9ed5b492012-01-05 21:48:15 +0000112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113Error ProcessFreeBSD::DoDetach(bool keep_stopped) {
114 Error error;
115 if (keep_stopped) {
116 error.SetErrorString("Detaching with keep_stopped true is not currently "
117 "supported on FreeBSD.");
Ed Maste7dcb77d2013-08-30 13:11:30 +0000118 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 }
120
121 error = m_monitor->Detach(GetID());
122
123 if (error.Success())
124 SetPrivateState(eStateDetached);
125
126 return error;
Ed Maste7dcb77d2013-08-30 13:11:30 +0000127}
128
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129Error ProcessFreeBSD::DoResume() {
130 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
Ed Maste7fd845c2013-12-09 15:51:17 +0000131
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132 SetPrivateState(eStateRunning);
Ed Maste7fd845c2013-12-09 15:51:17 +0000133
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
135 bool do_step = false;
Ed Maste31f01802017-01-24 14:34:49 +0000136 bool software_single_step = !SupportHardwareSingleStepping();
Ed Maste7fd845c2013-12-09 15:51:17 +0000137
Kate Stoneb9c1b512016-09-06 20:57:50 +0000138 for (tid_collection::const_iterator t_pos = m_run_tids.begin(),
139 t_end = m_run_tids.end();
140 t_pos != t_end; ++t_pos) {
141 m_monitor->ThreadSuspend(*t_pos, false);
142 }
143 for (tid_collection::const_iterator t_pos = m_step_tids.begin(),
144 t_end = m_step_tids.end();
145 t_pos != t_end; ++t_pos) {
146 m_monitor->ThreadSuspend(*t_pos, false);
147 do_step = true;
Ed Maste31f01802017-01-24 14:34:49 +0000148 if (software_single_step) {
149 Error error = SetupSoftwareSingleStepping(*t_pos);
150 if (error.Fail())
151 return error;
152 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000153 }
154 for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(),
155 t_end = m_suspend_tids.end();
156 t_pos != t_end; ++t_pos) {
157 m_monitor->ThreadSuspend(*t_pos, true);
158 // XXX Cannot PT_CONTINUE properly with suspended threads.
159 do_step = true;
160 }
Ed Maste7fd845c2013-12-09 15:51:17 +0000161
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162 if (log)
163 log->Printf("process %" PRIu64 " resuming (%s)", GetID(),
164 do_step ? "step" : "continue");
Ed Maste31f01802017-01-24 14:34:49 +0000165 if (do_step && !software_single_step)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166 m_monitor->SingleStep(GetID(), m_resume_signo);
167 else
168 m_monitor->Resume(GetID(), m_resume_signo);
Ed Maste7fd845c2013-12-09 15:51:17 +0000169
Mehdi Amini665be502016-11-11 05:07:57 +0000170 return Error();
Ed Maste7fd845c2013-12-09 15:51:17 +0000171}
172
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173bool ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list,
174 ThreadList &new_thread_list) {
175 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
176 if (log)
177 log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__,
178 GetID());
Daniel Maleae0f8f572013-08-26 23:57:52 +0000179
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180 std::vector<lldb::pid_t> tds;
181 if (!GetMonitor().GetCurrentThreadIDs(tds)) {
182 return false;
183 }
Daniel Maleae0f8f572013-08-26 23:57:52 +0000184
Kate Stoneb9c1b512016-09-06 20:57:50 +0000185 ThreadList old_thread_list_copy(old_thread_list);
186 for (size_t i = 0; i < tds.size(); ++i) {
187 tid_t tid = tds[i];
188 ThreadSP thread_sp(old_thread_list_copy.RemoveThreadByID(tid, false));
189 if (!thread_sp) {
190 thread_sp.reset(new FreeBSDThread(*this, tid));
191 if (log)
192 log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid);
193 } else {
194 if (log)
195 log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__,
196 tid);
Ed Maste7fd845c2013-12-09 15:51:17 +0000197 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198 new_thread_list.AddThread(thread_sp);
199 }
200 for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i) {
201 ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
202 if (old_thread_sp) {
203 if (log)
204 log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__);
Ed Maste7fd845c2013-12-09 15:51:17 +0000205 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206 }
Daniel Maleae0f8f572013-08-26 23:57:52 +0000207
Kate Stoneb9c1b512016-09-06 20:57:50 +0000208 return true;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000209}
Ed Maste7fd845c2013-12-09 15:51:17 +0000210
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211Error ProcessFreeBSD::WillResume() {
212 m_resume_signo = 0;
213 m_suspend_tids.clear();
214 m_run_tids.clear();
215 m_step_tids.clear();
216 return Process::WillResume();
Ed Maste7fd845c2013-12-09 15:51:17 +0000217}
218
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219void ProcessFreeBSD::SendMessage(const ProcessMessage &message) {
220 std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
Ed Maste7fd845c2013-12-09 15:51:17 +0000221
Kate Stoneb9c1b512016-09-06 20:57:50 +0000222 switch (message.GetKind()) {
223 case ProcessMessage::eInvalidMessage:
224 return;
Ed Maste7fd845c2013-12-09 15:51:17 +0000225
Kate Stoneb9c1b512016-09-06 20:57:50 +0000226 case ProcessMessage::eAttachMessage:
227 SetPrivateState(eStateStopped);
228 return;
Ed Maste7fd845c2013-12-09 15:51:17 +0000229
Kate Stoneb9c1b512016-09-06 20:57:50 +0000230 case ProcessMessage::eLimboMessage:
231 case ProcessMessage::eExitMessage:
232 SetExitStatus(message.GetExitStatus(), NULL);
233 break;
Ed Maste7fd845c2013-12-09 15:51:17 +0000234
Kate Stoneb9c1b512016-09-06 20:57:50 +0000235 case ProcessMessage::eSignalMessage:
236 case ProcessMessage::eSignalDeliveredMessage:
237 case ProcessMessage::eBreakpointMessage:
238 case ProcessMessage::eTraceMessage:
239 case ProcessMessage::eWatchpointMessage:
240 case ProcessMessage::eCrashMessage:
241 SetPrivateState(eStateStopped);
242 break;
Ed Maste7fd845c2013-12-09 15:51:17 +0000243
Kate Stoneb9c1b512016-09-06 20:57:50 +0000244 case ProcessMessage::eNewThreadMessage:
245 llvm_unreachable("eNewThreadMessage unexpected on FreeBSD");
246 break;
Ed Maste7fd845c2013-12-09 15:51:17 +0000247
Kate Stoneb9c1b512016-09-06 20:57:50 +0000248 case ProcessMessage::eExecMessage:
249 SetPrivateState(eStateStopped);
250 break;
251 }
Ed Maste7fd845c2013-12-09 15:51:17 +0000252
Kate Stoneb9c1b512016-09-06 20:57:50 +0000253 m_message_queue.push(message);
Ed Maste7fd845c2013-12-09 15:51:17 +0000254}
Ed Mastefe5a6422015-07-28 15:45:57 +0000255
256//------------------------------------------------------------------------------
257// Constructors and destructors.
258
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259ProcessFreeBSD::ProcessFreeBSD(lldb::TargetSP target_sp,
260 lldb::ListenerSP listener_sp,
261 UnixSignalsSP &unix_signals_sp)
Jim Ingham583bbb12016-03-07 21:50:25 +0000262 : Process(target_sp, listener_sp, unix_signals_sp),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000263 m_byte_order(endian::InlHostByteOrder()), m_monitor(NULL), m_module(NULL),
264 m_message_mutex(), m_exit_now(false), m_seen_initial_stop(),
265 m_resume_signo(0) {
266 // FIXME: Putting this code in the ctor and saving the byte order in a
267 // member variable is a hack to avoid const qual issues in GetByteOrder.
268 lldb::ModuleSP module = GetTarget().GetExecutableModule();
269 if (module && module->GetObjectFile())
270 m_byte_order = module->GetObjectFile()->GetByteOrder();
Ed Mastefe5a6422015-07-28 15:45:57 +0000271}
272
Kate Stoneb9c1b512016-09-06 20:57:50 +0000273ProcessFreeBSD::~ProcessFreeBSD() { delete m_monitor; }
Ed Mastefe5a6422015-07-28 15:45:57 +0000274
275//------------------------------------------------------------------------------
276// Process protocol.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277void ProcessFreeBSD::Finalize() {
Ed Mastefe5a6422015-07-28 15:45:57 +0000278 Process::Finalize();
279
280 if (m_monitor)
281 m_monitor->StopMonitor();
282}
283
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284bool ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp,
285 bool plugin_specified_by_name) {
286 // For now we are just making sure the file exists for a given module
287 ModuleSP exe_module_sp(target_sp->GetExecutableModule());
288 if (exe_module_sp.get())
289 return exe_module_sp->GetFileSpec().Exists();
290 // If there is no executable module, we return true since we might be
291 // preparing to attach.
292 return true;
Ed Mastefe5a6422015-07-28 15:45:57 +0000293}
294
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295Error ProcessFreeBSD::DoAttachToProcessWithID(
296 lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
297 Error error;
298 assert(m_monitor == NULL);
Ed Mastefe5a6422015-07-28 15:45:57 +0000299
Kate Stoneb9c1b512016-09-06 20:57:50 +0000300 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
Pavel Labathaafe0532017-02-06 19:31:05 +0000301 LLDB_LOGV(log, "pid = {0}", GetID());
Ed Mastefe5a6422015-07-28 15:45:57 +0000302
Kate Stoneb9c1b512016-09-06 20:57:50 +0000303 m_monitor = new ProcessMonitor(this, pid, error);
Ed Mastefe5a6422015-07-28 15:45:57 +0000304
Kate Stoneb9c1b512016-09-06 20:57:50 +0000305 if (!error.Success())
Ed Mastefe5a6422015-07-28 15:45:57 +0000306 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000307
308 PlatformSP platform_sp(GetTarget().GetPlatform());
309 assert(platform_sp.get());
310 if (!platform_sp)
311 return error; // FIXME: Detatch?
312
313 // Find out what we can about this process
314 ProcessInstanceInfo process_info;
315 platform_sp->GetProcessInfo(pid, process_info);
316
317 // Resolve the executable module
318 ModuleSP exe_module_sp;
319 FileSpecList executable_search_paths(
320 Target::GetDefaultExecutableSearchPaths());
321 ModuleSpec exe_module_spec(process_info.GetExecutableFile(),
322 GetTarget().GetArchitecture());
323 error = platform_sp->ResolveExecutable(
324 exe_module_spec, exe_module_sp,
325 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
326 if (!error.Success())
327 return error;
328
329 // Fix the target architecture if necessary
330 const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
331 if (module_arch.IsValid() &&
332 !GetTarget().GetArchitecture().IsExactMatch(module_arch))
333 GetTarget().SetArchitecture(module_arch);
334
335 // Initialize the target module list
336 GetTarget().SetExecutableModule(exe_module_sp, true);
337
338 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
339
340 SetID(pid);
341
342 return error;
Ed Mastefe5a6422015-07-28 15:45:57 +0000343}
344
Kate Stoneb9c1b512016-09-06 20:57:50 +0000345Error ProcessFreeBSD::WillLaunch(Module *module) {
346 Error error;
347 return error;
Ed Mastefe5a6422015-07-28 15:45:57 +0000348}
349
350FileSpec
351ProcessFreeBSD::GetFileSpec(const lldb_private::FileAction *file_action,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000352 const FileSpec &default_file_spec,
353 const FileSpec &dbg_pts_file_spec) {
354 FileSpec file_spec{};
Ed Mastefe5a6422015-07-28 15:45:57 +0000355
Kate Stoneb9c1b512016-09-06 20:57:50 +0000356 if (file_action && file_action->GetAction() == FileAction::eFileActionOpen) {
357 file_spec = file_action->GetFileSpec();
358 // By default the stdio paths passed in will be pseudo-terminal
359 // (/dev/pts). If so, convert to using a different default path
360 // instead to redirect I/O to the debugger console. This should
361 // also handle user overrides to /dev/null or a different file.
362 if (!file_spec || file_spec == dbg_pts_file_spec)
363 file_spec = default_file_spec;
364 }
365 return file_spec;
Ed Mastefe5a6422015-07-28 15:45:57 +0000366}
367
Kate Stoneb9c1b512016-09-06 20:57:50 +0000368Error ProcessFreeBSD::DoLaunch(Module *module, ProcessLaunchInfo &launch_info) {
369 Error error;
370 assert(m_monitor == NULL);
Ed Mastefe5a6422015-07-28 15:45:57 +0000371
Kate Stoneb9c1b512016-09-06 20:57:50 +0000372 FileSpec working_dir = launch_info.GetWorkingDirectory();
Zachary Turner7d86ee52017-03-08 17:56:08 +0000373 namespace fs = llvm::sys::fs;
374 if (working_dir && (!working_dir.ResolvePath() ||
375 !fs::is_directory(working_dir.GetPath()))) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000376 error.SetErrorStringWithFormat("No such file or directory: %s",
377 working_dir.GetCString());
378 return error;
379 }
Ed Mastefe5a6422015-07-28 15:45:57 +0000380
Kate Stoneb9c1b512016-09-06 20:57:50 +0000381 SetPrivateState(eStateLaunching);
Ed Mastefe5a6422015-07-28 15:45:57 +0000382
Kate Stoneb9c1b512016-09-06 20:57:50 +0000383 const lldb_private::FileAction *file_action;
Ed Mastefe5a6422015-07-28 15:45:57 +0000384
Kate Stoneb9c1b512016-09-06 20:57:50 +0000385 // Default of empty will mean to use existing open file descriptors
386 FileSpec stdin_file_spec{};
387 FileSpec stdout_file_spec{};
388 FileSpec stderr_file_spec{};
Ed Mastefe5a6422015-07-28 15:45:57 +0000389
Kate Stoneb9c1b512016-09-06 20:57:50 +0000390 const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0),
391 false};
Ed Mastefe5a6422015-07-28 15:45:57 +0000392
Kate Stoneb9c1b512016-09-06 20:57:50 +0000393 file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
394 stdin_file_spec =
395 GetFileSpec(file_action, stdin_file_spec, dbg_pts_file_spec);
Ed Mastefe5a6422015-07-28 15:45:57 +0000396
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397 file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);
398 stdout_file_spec =
399 GetFileSpec(file_action, stdout_file_spec, dbg_pts_file_spec);
Ed Mastefe5a6422015-07-28 15:45:57 +0000400
Kate Stoneb9c1b512016-09-06 20:57:50 +0000401 file_action = launch_info.GetFileActionForFD(STDERR_FILENO);
402 stderr_file_spec =
403 GetFileSpec(file_action, stderr_file_spec, dbg_pts_file_spec);
Ed Mastefe5a6422015-07-28 15:45:57 +0000404
Kate Stoneb9c1b512016-09-06 20:57:50 +0000405 m_monitor = new ProcessMonitor(
406 this, module, launch_info.GetArguments().GetConstArgumentVector(),
407 launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
408 stdin_file_spec, stdout_file_spec, stderr_file_spec, working_dir,
409 launch_info, error);
Ed Mastefe5a6422015-07-28 15:45:57 +0000410
Kate Stoneb9c1b512016-09-06 20:57:50 +0000411 m_module = module;
Ed Mastefe5a6422015-07-28 15:45:57 +0000412
Kate Stoneb9c1b512016-09-06 20:57:50 +0000413 if (!error.Success())
414 return error;
Ed Mastefe5a6422015-07-28 15:45:57 +0000415
Kate Stoneb9c1b512016-09-06 20:57:50 +0000416 int terminal = m_monitor->GetTerminalFD();
417 if (terminal >= 0) {
418// The reader thread will close the file descriptor when done, so we pass it a
419// copy.
Sylvestre Ledru79cb0092015-08-28 12:24:07 +0000420#ifdef F_DUPFD_CLOEXEC
Kate Stoneb9c1b512016-09-06 20:57:50 +0000421 int stdio = fcntl(terminal, F_DUPFD_CLOEXEC, 0);
422 if (stdio == -1) {
423 error.SetErrorToErrno();
424 return error;
425 }
Sylvestre Ledru79cb0092015-08-28 12:24:07 +0000426#else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000427 // Special case when F_DUPFD_CLOEXEC does not exist (Debian kFreeBSD)
428 int stdio = fcntl(terminal, F_DUPFD, 0);
429 if (stdio == -1) {
430 error.SetErrorToErrno();
431 return error;
432 }
433 stdio = fcntl(terminal, F_SETFD, FD_CLOEXEC);
434 if (stdio == -1) {
435 error.SetErrorToErrno();
436 return error;
437 }
Sylvestre Ledru79cb0092015-08-28 12:24:07 +0000438#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000439 SetSTDIOFileDescriptor(stdio);
440 }
441
442 SetID(m_monitor->GetPID());
443 return error;
444}
445
446void ProcessFreeBSD::DidLaunch() {}
447
448addr_t ProcessFreeBSD::GetImageInfoAddress() {
449 Target *target = &GetTarget();
450 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
451 Address addr = obj_file->GetImageInfoAddress(target);
452
453 if (addr.IsValid())
454 return addr.GetLoadAddress(target);
455 return LLDB_INVALID_ADDRESS;
456}
457
458Error ProcessFreeBSD::DoHalt(bool &caused_stop) {
459 Error error;
460
461 if (IsStopped()) {
462 caused_stop = false;
463 } else if (kill(GetID(), SIGSTOP)) {
464 caused_stop = false;
465 error.SetErrorToErrno();
466 } else {
467 caused_stop = true;
468 }
469 return error;
470}
471
472Error ProcessFreeBSD::DoSignal(int signal) {
473 Error error;
474
475 if (kill(GetID(), signal))
476 error.SetErrorToErrno();
477
478 return error;
479}
480
481Error ProcessFreeBSD::DoDestroy() {
482 Error error;
483
484 if (!HasExited()) {
485 assert(m_monitor);
486 m_exit_now = true;
487 if (GetID() == LLDB_INVALID_PROCESS_ID) {
488 error.SetErrorString("invalid process id");
489 return error;
490 }
491 if (!m_monitor->Kill()) {
492 error.SetErrorToErrno();
493 return error;
Ed Mastefe5a6422015-07-28 15:45:57 +0000494 }
495
Kate Stoneb9c1b512016-09-06 20:57:50 +0000496 SetPrivateState(eStateExited);
497 }
498
499 return error;
Ed Mastefe5a6422015-07-28 15:45:57 +0000500}
501
Kate Stoneb9c1b512016-09-06 20:57:50 +0000502void ProcessFreeBSD::DoDidExec() {
503 Target *target = &GetTarget();
504 if (target) {
505 PlatformSP platform_sp(target->GetPlatform());
506 assert(platform_sp.get());
507 if (platform_sp) {
508 ProcessInstanceInfo process_info;
509 platform_sp->GetProcessInfo(GetID(), process_info);
510 ModuleSP exe_module_sp;
511 ModuleSpec exe_module_spec(process_info.GetExecutableFile(),
512 target->GetArchitecture());
513 FileSpecList executable_search_paths(
514 Target::GetDefaultExecutableSearchPaths());
515 Error error = platform_sp->ResolveExecutable(
516 exe_module_spec, exe_module_sp,
517 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
518 if (!error.Success())
519 return;
520 target->SetExecutableModule(exe_module_sp, true);
Ed Mastefe5a6422015-07-28 15:45:57 +0000521 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000522 }
Ed Mastefe5a6422015-07-28 15:45:57 +0000523}
524
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525bool ProcessFreeBSD::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) {
526 bool added_to_set = false;
527 ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
528 if (it == m_seen_initial_stop.end()) {
529 m_seen_initial_stop.insert(stop_tid);
530 added_to_set = true;
531 }
532 return added_to_set;
Ed Mastefe5a6422015-07-28 15:45:57 +0000533}
534
Kate Stoneb9c1b512016-09-06 20:57:50 +0000535bool ProcessFreeBSD::WaitingForInitialStop(lldb::tid_t stop_tid) {
536 return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
Ed Mastefe5a6422015-07-28 15:45:57 +0000537}
538
539FreeBSDThread *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000540ProcessFreeBSD::CreateNewFreeBSDThread(lldb_private::Process &process,
541 lldb::tid_t tid) {
542 return new FreeBSDThread(process, tid);
Ed Mastefe5a6422015-07-28 15:45:57 +0000543}
544
Kate Stoneb9c1b512016-09-06 20:57:50 +0000545void ProcessFreeBSD::RefreshStateAfterStop() {
546 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
Pavel Labathaafe0532017-02-06 19:31:05 +0000547 LLDB_LOGV(log, "message_queue size = {0}", m_message_queue.size());
Ed Mastefe5a6422015-07-28 15:45:57 +0000548
Kate Stoneb9c1b512016-09-06 20:57:50 +0000549 std::lock_guard<std::recursive_mutex> guard(m_message_mutex);
Ed Mastefe5a6422015-07-28 15:45:57 +0000550
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551 // This method used to only handle one message. Changing it to loop allows
552 // it to handle the case where we hit a breakpoint while handling a different
553 // breakpoint.
554 while (!m_message_queue.empty()) {
555 ProcessMessage &message = m_message_queue.front();
Ed Mastefe5a6422015-07-28 15:45:57 +0000556
Kate Stoneb9c1b512016-09-06 20:57:50 +0000557 // Resolve the thread this message corresponds to and pass it along.
558 lldb::tid_t tid = message.GetTID();
Pavel Labathaafe0532017-02-06 19:31:05 +0000559 LLDB_LOGV(log, " message_queue size = {0}, pid = {1}",
560 m_message_queue.size(), tid);
Ed Mastefe5a6422015-07-28 15:45:57 +0000561
Kate Stoneb9c1b512016-09-06 20:57:50 +0000562 m_thread_list.RefreshStateAfterStop();
Ed Mastefe5a6422015-07-28 15:45:57 +0000563
Kate Stoneb9c1b512016-09-06 20:57:50 +0000564 FreeBSDThread *thread = static_cast<FreeBSDThread *>(
565 GetThreadList().FindThreadByID(tid, false).get());
Ed Mastefe5a6422015-07-28 15:45:57 +0000566 if (thread)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000567 thread->Notify(message);
568
569 if (message.GetKind() == ProcessMessage::eExitMessage) {
570 // FIXME: We should tell the user about this, but the limbo message is
571 // probably better for that.
Pavel Labathaafe0532017-02-06 19:31:05 +0000572 LLDB_LOG(log, "removing thread, tid = {0}", tid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000573 std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
574
575 ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
576 thread_sp.reset();
577 m_seen_initial_stop.erase(tid);
578 }
579
580 m_message_queue.pop();
581 }
Ed Mastefe5a6422015-07-28 15:45:57 +0000582}
583
Kate Stoneb9c1b512016-09-06 20:57:50 +0000584bool ProcessFreeBSD::IsAlive() {
585 StateType state = GetPrivateState();
586 return state != eStateDetached && state != eStateExited &&
587 state != eStateInvalid && state != eStateUnloaded;
Ed Mastefe5a6422015-07-28 15:45:57 +0000588}
589
Kate Stoneb9c1b512016-09-06 20:57:50 +0000590size_t ProcessFreeBSD::DoReadMemory(addr_t vm_addr, void *buf, size_t size,
591 Error &error) {
592 assert(m_monitor);
593 return m_monitor->ReadMemory(vm_addr, buf, size, error);
594}
595
596size_t ProcessFreeBSD::DoWriteMemory(addr_t vm_addr, const void *buf,
597 size_t size, Error &error) {
598 assert(m_monitor);
599 return m_monitor->WriteMemory(vm_addr, buf, size, error);
600}
601
602addr_t ProcessFreeBSD::DoAllocateMemory(size_t size, uint32_t permissions,
603 Error &error) {
604 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
605
606 unsigned prot = 0;
607 if (permissions & lldb::ePermissionsReadable)
608 prot |= eMmapProtRead;
609 if (permissions & lldb::ePermissionsWritable)
610 prot |= eMmapProtWrite;
611 if (permissions & lldb::ePermissionsExecutable)
612 prot |= eMmapProtExec;
613
614 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
615 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
616 m_addr_to_mmap_size[allocated_addr] = size;
617 error.Clear();
618 } else {
619 allocated_addr = LLDB_INVALID_ADDRESS;
620 error.SetErrorStringWithFormat(
621 "unable to allocate %zu bytes of memory with permissions %s", size,
622 GetPermissionsAsCString(permissions));
623 }
624
625 return allocated_addr;
626}
627
628Error ProcessFreeBSD::DoDeallocateMemory(lldb::addr_t addr) {
629 Error error;
630 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
631 if (pos != m_addr_to_mmap_size.end() &&
632 InferiorCallMunmap(this, addr, pos->second))
633 m_addr_to_mmap_size.erase(pos);
634 else
635 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64,
636 addr);
637
638 return error;
639}
640
641size_t
642ProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) {
643 static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xD4};
644 static const uint8_t g_i386_opcode[] = {0xCC};
645
646 ArchSpec arch = GetTarget().GetArchitecture();
647 const uint8_t *opcode = NULL;
648 size_t opcode_size = 0;
649
650 switch (arch.GetMachine()) {
651 default:
652 assert(false && "CPU type not supported!");
653 break;
654
655 case llvm::Triple::arm: {
656 // The ARM reference recommends the use of 0xe7fddefe and 0xdefe
657 // but the linux kernel does otherwise.
658 static const uint8_t g_arm_breakpoint_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
659 static const uint8_t g_thumb_breakpoint_opcode[] = {0x01, 0xde};
660
661 lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0));
662 AddressClass addr_class = eAddressClassUnknown;
663
664 if (bp_loc_sp)
665 addr_class = bp_loc_sp->GetAddress().GetAddressClass();
666
667 if (addr_class == eAddressClassCodeAlternateISA ||
668 (addr_class == eAddressClassUnknown &&
669 bp_loc_sp->GetAddress().GetOffset() & 1)) {
670 opcode = g_thumb_breakpoint_opcode;
671 opcode_size = sizeof(g_thumb_breakpoint_opcode);
672 } else {
673 opcode = g_arm_breakpoint_opcode;
674 opcode_size = sizeof(g_arm_breakpoint_opcode);
675 }
676 } break;
677 case llvm::Triple::aarch64:
678 opcode = g_aarch64_opcode;
679 opcode_size = sizeof(g_aarch64_opcode);
680 break;
681
682 case llvm::Triple::x86:
683 case llvm::Triple::x86_64:
684 opcode = g_i386_opcode;
685 opcode_size = sizeof(g_i386_opcode);
686 break;
687 }
688
689 bp_site->SetTrapOpcode(opcode, opcode_size);
690 return opcode_size;
691}
692
693Error ProcessFreeBSD::EnableBreakpointSite(BreakpointSite *bp_site) {
694 return EnableSoftwareBreakpoint(bp_site);
695}
696
697Error ProcessFreeBSD::DisableBreakpointSite(BreakpointSite *bp_site) {
698 return DisableSoftwareBreakpoint(bp_site);
699}
700
701Error ProcessFreeBSD::EnableWatchpoint(Watchpoint *wp, bool notify) {
702 Error error;
703 if (wp) {
704 user_id_t watchID = wp->GetID();
705 addr_t addr = wp->GetLoadAddress();
706 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
707 if (log)
708 log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64 ")",
709 watchID);
710 if (wp->IsEnabled()) {
711 if (log)
712 log->Printf("ProcessFreeBSD::EnableWatchpoint(watchID = %" PRIu64
713 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
714 watchID, (uint64_t)addr);
715 return error;
716 }
717
718 // Try to find a vacant watchpoint slot in the inferiors' main thread
719 uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +0000720 std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000721 FreeBSDThread *thread = static_cast<FreeBSDThread *>(
722 m_thread_list.GetThreadAtIndex(0, false).get());
723
724 if (thread)
725 wp_hw_index = thread->FindVacantWatchpointIndex();
726
727 if (wp_hw_index == LLDB_INVALID_INDEX32) {
728 error.SetErrorString("Setting hardware watchpoint failed.");
729 } else {
730 wp->SetHardwareIndex(wp_hw_index);
731 bool wp_enabled = true;
732 uint32_t thread_count = m_thread_list.GetSize(false);
733 for (uint32_t i = 0; i < thread_count; ++i) {
734 thread = static_cast<FreeBSDThread *>(
735 m_thread_list.GetThreadAtIndex(i, false).get());
736 if (thread)
737 wp_enabled &= thread->EnableHardwareWatchpoint(wp);
738 else
739 wp_enabled = false;
740 }
741 if (wp_enabled) {
742 wp->SetEnabled(true, notify);
743 return error;
744 } else {
745 // Watchpoint enabling failed on at least one
746 // of the threads so roll back all of them
747 DisableWatchpoint(wp, false);
748 error.SetErrorString("Setting hardware watchpoint failed");
749 }
750 }
751 } else
752 error.SetErrorString("Watchpoint argument was NULL.");
753 return error;
754}
755
756Error ProcessFreeBSD::DisableWatchpoint(Watchpoint *wp, bool notify) {
757 Error error;
758 if (wp) {
759 user_id_t watchID = wp->GetID();
760 addr_t addr = wp->GetLoadAddress();
761 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
762 if (log)
763 log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64 ")",
764 watchID);
765 if (!wp->IsEnabled()) {
766 if (log)
767 log->Printf("ProcessFreeBSD::DisableWatchpoint(watchID = %" PRIu64
768 ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
769 watchID, (uint64_t)addr);
770 // This is needed (for now) to keep watchpoints disabled correctly
771 wp->SetEnabled(false, notify);
772 return error;
773 }
774
775 if (wp->IsHardware()) {
776 bool wp_disabled = true;
777 std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
778 uint32_t thread_count = m_thread_list.GetSize(false);
779 for (uint32_t i = 0; i < thread_count; ++i) {
780 FreeBSDThread *thread = static_cast<FreeBSDThread *>(
781 m_thread_list.GetThreadAtIndex(i, false).get());
782 if (thread)
783 wp_disabled &= thread->DisableHardwareWatchpoint(wp);
784 else
785 wp_disabled = false;
786 }
787 if (wp_disabled) {
788 wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
789 wp->SetEnabled(false, notify);
790 return error;
791 } else
792 error.SetErrorString("Disabling hardware watchpoint failed");
793 }
794 } else
795 error.SetErrorString("Watchpoint argument was NULL.");
796 return error;
797}
798
799Error ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num) {
800 Error error;
801 std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
802 FreeBSDThread *thread = static_cast<FreeBSDThread *>(
803 m_thread_list.GetThreadAtIndex(0, false).get());
804 if (thread)
805 num = thread->NumSupportedHardwareWatchpoints();
806 else
807 error.SetErrorString("Process does not exist.");
808 return error;
809}
810
811Error ProcessFreeBSD::GetWatchpointSupportInfo(uint32_t &num, bool &after) {
812 Error error = GetWatchpointSupportInfo(num);
813 // Watchpoints trigger and halt the inferior after
814 // the corresponding instruction has been executed.
815 after = true;
816 return error;
817}
818
819uint32_t ProcessFreeBSD::UpdateThreadListIfNeeded() {
820 std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
821 // Do not allow recursive updates.
822 return m_thread_list.GetSize(false);
Ed Mastefe5a6422015-07-28 15:45:57 +0000823}
824
825#if 0
826bool
827ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
828{
829 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
830 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
831 log->Printf ("ProcessFreeBSD::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
832
833 bool has_updated = false;
834 // Update the process thread list with this new thread.
835 // FIXME: We should be using tid, not pid.
836 assert(m_monitor);
837 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
838 if (!thread_sp) {
839 thread_sp.reset(CreateNewFreeBSDThread(*this, GetID()));
840 has_updated = true;
841 }
842
843 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
844 log->Printf ("ProcessFreeBSD::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
845 new_thread_list.AddThread(thread_sp);
846
847 return has_updated; // the list has been updated
848}
849#endif
850
Kate Stoneb9c1b512016-09-06 20:57:50 +0000851ByteOrder ProcessFreeBSD::GetByteOrder() const {
852 // FIXME: We should be able to extract this value directly. See comment in
853 // ProcessFreeBSD().
854 return m_byte_order;
Ed Mastefe5a6422015-07-28 15:45:57 +0000855}
856
Kate Stoneb9c1b512016-09-06 20:57:50 +0000857size_t ProcessFreeBSD::PutSTDIN(const char *buf, size_t len, Error &error) {
858 ssize_t status;
859 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) {
860 error.SetErrorToErrno();
861 return 0;
862 }
863 return status;
Ed Mastefe5a6422015-07-28 15:45:57 +0000864}
865
866//------------------------------------------------------------------------------
867// Utility functions.
868
Kate Stoneb9c1b512016-09-06 20:57:50 +0000869bool ProcessFreeBSD::HasExited() {
870 switch (GetPrivateState()) {
871 default:
872 break;
Ed Mastefe5a6422015-07-28 15:45:57 +0000873
Kate Stoneb9c1b512016-09-06 20:57:50 +0000874 case eStateDetached:
875 case eStateExited:
876 return true;
877 }
Ed Mastefe5a6422015-07-28 15:45:57 +0000878
Kate Stoneb9c1b512016-09-06 20:57:50 +0000879 return false;
Ed Mastefe5a6422015-07-28 15:45:57 +0000880}
881
Kate Stoneb9c1b512016-09-06 20:57:50 +0000882bool ProcessFreeBSD::IsStopped() {
883 switch (GetPrivateState()) {
884 default:
885 break;
Ed Mastefe5a6422015-07-28 15:45:57 +0000886
Kate Stoneb9c1b512016-09-06 20:57:50 +0000887 case eStateStopped:
888 case eStateCrashed:
889 case eStateSuspended:
890 return true;
891 }
Ed Mastefe5a6422015-07-28 15:45:57 +0000892
Kate Stoneb9c1b512016-09-06 20:57:50 +0000893 return false;
Ed Mastefe5a6422015-07-28 15:45:57 +0000894}
895
Kate Stoneb9c1b512016-09-06 20:57:50 +0000896bool ProcessFreeBSD::IsAThreadRunning() {
897 bool is_running = false;
898 std::lock_guard<std::recursive_mutex> guard(m_thread_list.GetMutex());
899 uint32_t thread_count = m_thread_list.GetSize(false);
900 for (uint32_t i = 0; i < thread_count; ++i) {
901 FreeBSDThread *thread = static_cast<FreeBSDThread *>(
902 m_thread_list.GetThreadAtIndex(i, false).get());
903 StateType thread_state = thread->GetState();
904 if (thread_state == eStateRunning || thread_state == eStateStepping) {
905 is_running = true;
906 break;
Ed Mastefe5a6422015-07-28 15:45:57 +0000907 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000908 }
909 return is_running;
Ed Mastefe5a6422015-07-28 15:45:57 +0000910}
911
Kate Stoneb9c1b512016-09-06 20:57:50 +0000912const DataBufferSP ProcessFreeBSD::GetAuxvData() {
913 // If we're the local platform, we can ask the host for auxv data.
914 PlatformSP platform_sp = GetTarget().GetPlatform();
Pavel Labathb7f0f452017-03-17 11:08:40 +0000915 assert(platform_sp && platform_sp->IsHost());
Ed Mastefe5a6422015-07-28 15:45:57 +0000916
Pavel Labath5b116232017-03-17 11:33:57 +0000917 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV, (int)m_process->GetID()};
Pavel Labathb7f0f452017-03-17 11:08:40 +0000918 size_t auxv_size = AT_COUNT * sizeof(Elf_Auxinfo);
919 DataBufferSP buf_sp(new DataBufferHeap(auxv_size, 0));
920
Pavel Labath5b116232017-03-17 11:33:57 +0000921 if (::sysctl(mib, 4, buf_sp->GetBytes(), &auxv_size, NULL, 0) != 0) {
Pavel Labathb7f0f452017-03-17 11:08:40 +0000922 perror("sysctl failed on auxv");
923 buf_sp.reset();
924 }
925
926 return buf_sp;
Ed Mastefe5a6422015-07-28 15:45:57 +0000927}
Ed Maste31f01802017-01-24 14:34:49 +0000928
929struct EmulatorBaton {
930 ProcessFreeBSD *m_process;
931 RegisterContext *m_reg_context;
932
933 // eRegisterKindDWARF -> RegisterValue
934 std::unordered_map<uint32_t, RegisterValue> m_register_values;
935
936 EmulatorBaton(ProcessFreeBSD *process, RegisterContext *reg_context)
937 : m_process(process), m_reg_context(reg_context) {}
938};
939
940static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
941 const EmulateInstruction::Context &context,
942 lldb::addr_t addr, void *dst, size_t length) {
943 EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
944
945 Error error;
946 size_t bytes_read =
947 emulator_baton->m_process->DoReadMemory(addr, dst, length, error);
948 if (!error.Success())
949 bytes_read = 0;
950 return bytes_read;
951}
952
953static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
954 const RegisterInfo *reg_info,
955 RegisterValue &reg_value) {
956 EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
957
958 auto it = emulator_baton->m_register_values.find(
959 reg_info->kinds[eRegisterKindDWARF]);
960 if (it != emulator_baton->m_register_values.end()) {
961 reg_value = it->second;
962 return true;
963 }
964
965 // The emulator only fills in the dwarf register numbers (and in some cases
966 // the generic register numbers). Get the full register info from the
967 // register context based on the dwarf register numbers.
968 const RegisterInfo *full_reg_info =
969 emulator_baton->m_reg_context->GetRegisterInfo(
970 eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
971
972 bool error =
973 emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
974 return error;
975}
976
977static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
978 const EmulateInstruction::Context &context,
979 const RegisterInfo *reg_info,
980 const RegisterValue &reg_value) {
981 EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
982 emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] =
983 reg_value;
984 return true;
985}
986
987static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
988 const EmulateInstruction::Context &context,
989 lldb::addr_t addr, const void *dst,
990 size_t length) {
991 return length;
992}
993
994bool ProcessFreeBSD::SingleStepBreakpointHit(
995 void *baton, lldb_private::StoppointCallbackContext *context,
996 lldb::user_id_t break_id, lldb::user_id_t break_loc_id) {
997 return false;
998}
999
1000Error ProcessFreeBSD::SetSoftwareSingleStepBreakpoint(lldb::tid_t tid,
1001 lldb::addr_t addr) {
1002 Error error;
1003
1004 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
1005 if (log) {
1006 log->Printf("ProcessFreeBSD::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
1007 log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
1008 }
1009
1010 // Validate the address.
1011 if (addr == LLDB_INVALID_ADDRESS)
1012 return Error("ProcessFreeBSD::%s invalid load address specified.",
1013 __FUNCTION__);
1014
1015 Breakpoint *const sw_step_break =
1016 m_process->GetTarget().CreateBreakpoint(addr, true, false).get();
1017 sw_step_break->SetCallback(SingleStepBreakpointHit, this, true);
1018 sw_step_break->SetBreakpointKind("software-signle-step");
1019
1020 if (log)
1021 log->Printf("ProcessFreeBSD::%s addr = 0x%" PRIx64 " -- SUCCESS",
1022 __FUNCTION__, addr);
1023
1024 m_threads_stepping_with_breakpoint.insert({tid, sw_step_break->GetID()});
1025 return Error();
1026}
1027
1028bool ProcessFreeBSD::IsSoftwareStepBreakpoint(lldb::tid_t tid) {
1029 ThreadSP thread = GetThreadList().FindThreadByID(tid);
1030 if (!thread)
1031 return false;
1032
1033 assert(thread->GetRegisterContext());
1034 lldb::addr_t stop_pc = thread->GetRegisterContext()->GetPC();
1035
1036 const auto &iter = m_threads_stepping_with_breakpoint.find(tid);
1037 if (iter == m_threads_stepping_with_breakpoint.end())
1038 return false;
1039
1040 lldb::break_id_t bp_id = iter->second;
1041 BreakpointSP bp = GetTarget().GetBreakpointByID(bp_id);
1042 if (!bp)
1043 return false;
1044
1045 BreakpointLocationSP bp_loc = bp->FindLocationByAddress(stop_pc);
1046 if (!bp_loc)
1047 return false;
1048
1049 GetTarget().RemoveBreakpointByID(bp_id);
1050 m_threads_stepping_with_breakpoint.erase(tid);
1051 return true;
1052}
1053
1054bool ProcessFreeBSD::SupportHardwareSingleStepping() const {
1055 lldb_private::ArchSpec arch = GetTarget().GetArchitecture();
1056 if (arch.GetMachine() == llvm::Triple::arm ||
1057 arch.GetMachine() == llvm::Triple::mips64 ||
1058 arch.GetMachine() == llvm::Triple::mips64el ||
1059 arch.GetMachine() == llvm::Triple::mips ||
1060 arch.GetMachine() == llvm::Triple::mipsel)
1061 return false;
1062 return true;
1063}
1064
1065Error ProcessFreeBSD::SetupSoftwareSingleStepping(lldb::tid_t tid) {
1066 std::unique_ptr<EmulateInstruction> emulator_ap(
1067 EmulateInstruction::FindPlugin(GetTarget().GetArchitecture(),
1068 eInstructionTypePCModifying, nullptr));
1069
1070 if (emulator_ap == nullptr)
1071 return Error("Instruction emulator not found!");
1072
1073 FreeBSDThread *thread = static_cast<FreeBSDThread *>(
1074 m_thread_list.FindThreadByID(tid, false).get());
1075 if (thread == NULL)
1076 return Error("Thread not found not found!");
1077
1078 lldb::RegisterContextSP register_context_sp = thread->GetRegisterContext();
1079
1080 EmulatorBaton baton(this, register_context_sp.get());
1081 emulator_ap->SetBaton(&baton);
1082 emulator_ap->SetReadMemCallback(&ReadMemoryCallback);
1083 emulator_ap->SetReadRegCallback(&ReadRegisterCallback);
1084 emulator_ap->SetWriteMemCallback(&WriteMemoryCallback);
1085 emulator_ap->SetWriteRegCallback(&WriteRegisterCallback);
1086
1087 if (!emulator_ap->ReadInstruction())
1088 return Error("Read instruction failed!");
1089
1090 bool emulation_result =
1091 emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
1092 const RegisterInfo *reg_info_pc = register_context_sp->GetRegisterInfo(
1093 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1094 auto pc_it =
1095 baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
1096
1097 lldb::addr_t next_pc;
1098 if (emulation_result) {
1099 assert(pc_it != baton.m_register_values.end() &&
1100 "Emulation was successful but PC wasn't updated");
1101 next_pc = pc_it->second.GetAsUInt64();
1102 } else if (pc_it == baton.m_register_values.end()) {
1103 // Emulate instruction failed and it haven't changed PC. Advance PC
1104 // with the size of the current opcode because the emulation of all
1105 // PC modifying instruction should be successful. The failure most
1106 // likely caused by a not supported instruction which don't modify PC.
1107 next_pc =
1108 register_context_sp->GetPC() + emulator_ap->GetOpcode().GetByteSize();
1109 } else {
1110 // The instruction emulation failed after it modified the PC. It is an
1111 // unknown error where we can't continue because the next instruction is
1112 // modifying the PC but we don't know how.
1113 return Error("Instruction emulation failed unexpectedly");
1114 }
1115
1116 SetSoftwareSingleStepBreakpoint(tid, next_pc);
1117 return Error();
1118}