blob: f62a303505a602842025eeca3440778db7eea4d8 [file] [log] [blame]
Stephen Wilsonf6f40332010-07-24 02:19:04 +00001//===-- ProcessLinux.cpp ----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11// C++ Includes
12// Other libraries and framework includes
13#include "lldb/Core/PluginManager.h"
14#include "lldb/Host/Host.h"
15#include "lldb/Symbol/ObjectFile.h"
Stephen Wilson92241ef2011-01-16 19:45:39 +000016#include "lldb/Target/DynamicLoader.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000017#include "lldb/Target/Target.h"
18
19#include "ProcessLinux.h"
20#include "ProcessMonitor.h"
21#include "LinuxThread.h"
22
23using namespace lldb;
24using namespace lldb_private;
25
26//------------------------------------------------------------------------------
27// Static functions.
28
29Process*
30ProcessLinux::CreateInstance(Target& target, Listener &listener)
31{
32 return new ProcessLinux(target, listener);
33}
34
35void
36ProcessLinux::Initialize()
37{
38 static bool g_initialized = false;
39
40 if (!g_initialized)
41 {
42 PluginManager::RegisterPlugin(GetPluginNameStatic(),
43 GetPluginDescriptionStatic(),
44 CreateInstance);
45 g_initialized = true;
46 }
47}
48
49void
50ProcessLinux::Terminate()
51{
52}
53
54const char *
55ProcessLinux::GetPluginNameStatic()
56{
57 return "plugin.process.linux";
58}
59
60const char *
61ProcessLinux::GetPluginDescriptionStatic()
62{
63 return "Process plugin for Linux";
64}
65
66
67//------------------------------------------------------------------------------
68// Constructors and destructors.
69
70ProcessLinux::ProcessLinux(Target& target, Listener &listener)
71 : Process(target, listener),
72 m_monitor(NULL),
73 m_module(NULL)
74{
75 // FIXME: Putting this code in the ctor and saving the byte order in a
76 // member variable is a hack to avoid const qual issues in GetByteOrder.
77 ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
78 m_byte_order = obj_file->GetByteOrder();
79}
80
81ProcessLinux::~ProcessLinux()
82{
83 delete m_monitor;
84}
85
86//------------------------------------------------------------------------------
87// Process protocol.
88
89bool
90ProcessLinux::CanDebug(Target &target)
91{
92 // For now we are just making sure the file exists for a given module
93 ModuleSP exe_module_sp(target.GetExecutableModule());
94 if (exe_module_sp.get())
95 return exe_module_sp->GetFileSpec().Exists();
96 return false;
97}
98
99Error
100ProcessLinux::DoAttachToProcessWithID(lldb::pid_t pid)
101{
102 return Error(1, eErrorTypeGeneric);
103}
104
105Error
Stephen Wilson92241ef2011-01-16 19:45:39 +0000106ProcessLinux::WillLaunch(Module* module)
107{
108 Error error;
Stephen Wilson92241ef2011-01-16 19:45:39 +0000109 return error;
110}
111
112Error
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000113ProcessLinux::DoLaunch(Module *module,
114 char const *argv[],
115 char const *envp[],
Stephen Wilson3a804312011-01-04 21:41:31 +0000116 uint32_t launch_flags,
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000117 const char *stdin_path,
118 const char *stdout_path,
Greg Claytonde915be2011-01-23 05:56:20 +0000119 const char *stderr_path,
120 const char *working_directory)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000121{
122 Error error;
123 assert(m_monitor == NULL);
124
125 SetPrivateState(eStateLaunching);
126 m_monitor = new ProcessMonitor(this, module,
127 argv, envp,
128 stdin_path, stdout_path, stderr_path,
129 error);
130
131 m_module = module;
132
133 if (!error.Success())
134 return error;
135
Stephen Wilson1f004c62011-01-15 00:13:27 +0000136 SetID(m_monitor->GetPID());
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000137 return error;
138}
139
Stephen Wilson92241ef2011-01-16 19:45:39 +0000140void
141ProcessLinux::DidLaunch()
142{
Stephen Wilson92241ef2011-01-16 19:45:39 +0000143}
144
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000145Error
146ProcessLinux::DoResume()
147{
148 assert(GetPrivateState() == eStateStopped && "Bad state for DoResume!");
149
150 // Set our state to running. This ensures inferior threads do not post a
151 // state change first.
152 SetPrivateState(eStateRunning);
153
154 bool did_resume = false;
155 uint32_t thread_count = m_thread_list.GetSize(false);
156 for (uint32_t i = 0; i < thread_count; ++i)
157 {
158 LinuxThread *thread = static_cast<LinuxThread*>(
159 m_thread_list.GetThreadAtIndex(i, false).get());
160 did_resume = thread->Resume() || did_resume;
161 }
162 assert(did_resume && "Process resume failed!");
163
164 return Error();
165}
166
Stephen Wilson01316422011-01-15 00:10:37 +0000167addr_t
168ProcessLinux::GetImageInfoAddress()
169{
170 Target *target = &GetTarget();
171 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
172 Address addr = obj_file->GetImageInfoAddress();
173
174 if (addr.IsValid())
175 return addr.GetLoadAddress(target);
176 else
177 return LLDB_INVALID_ADDRESS;
178}
179
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000180Error
Stephen Wilson3a804312011-01-04 21:41:31 +0000181ProcessLinux::DoHalt(bool &caused_stop)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000182{
183 return Error(1, eErrorTypeGeneric);
184}
185
186Error
187ProcessLinux::DoDetach()
188{
189 return Error(1, eErrorTypeGeneric);
190}
191
192Error
193ProcessLinux::DoSignal(int signal)
194{
195 return Error(1, eErrorTypeGeneric);
196}
197
198Error
199ProcessLinux::DoDestroy()
200{
201 Error error;
202
203 if (!HasExited())
204 {
Greg Clayton5d187e52011-01-08 20:28:42 +0000205 // Shut down the private state thread as we will synchronize with events
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000206 // ourselves. Discard all current thread plans.
207 PausePrivateStateThread();
208 GetThreadList().DiscardThreadPlans();
209
210 // Bringing the inferior into limbo will be caught by our monitor
211 // thread, in turn updating the process state.
212 if (!m_monitor->BringProcessIntoLimbo())
213 {
214 error.SetErrorToGenericError();
215 error.SetErrorString("Process termination failed.");
216 return error;
217 }
218
Stephen Wilson83047fc2011-01-19 01:30:44 +0000219 // Wait for the event to arrive. This is guaranteed to be an exit event.
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000220 StateType state;
221 EventSP event;
222 do {
Stephen Wilson83047fc2011-01-19 01:30:44 +0000223 TimeValue timeout_time;
224 timeout_time = TimeValue::Now();
225 timeout_time.OffsetWithSeconds(2);
226 state = WaitForStateChangedEventsPrivate(&timeout_time, event);
227 } while (state != eStateExited && state != eStateInvalid);
228
229 // Check if we timed out waiting for the exit event to arrive.
230 if (state == eStateInvalid)
231 error.SetErrorString("ProcessLinux::DoDestroy timed out.");
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000232
233 // Restart standard event handling and send the process the final kill,
234 // driving it out of limbo.
235 ResumePrivateStateThread();
236 }
237
Stephen Wilson83047fc2011-01-19 01:30:44 +0000238 if (kill(m_monitor->GetPID(), SIGKILL) && error.Success())
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000239 error.SetErrorToErrno();
Stephen Wilson83047fc2011-01-19 01:30:44 +0000240
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000241 return error;
242}
243
244void
245ProcessLinux::SendMessage(const ProcessMessage &message)
246{
247 Mutex::Locker lock(m_message_mutex);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000248
249 switch (message.GetKind())
250 {
251 default:
252 SetPrivateState(eStateStopped);
253 break;
254
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000255 case ProcessMessage::eInvalidMessage:
256 return;
257
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000258 case ProcessMessage::eExitMessage:
259 SetExitStatus(message.GetExitStatus(), NULL);
260 break;
261
262 case ProcessMessage::eSignalMessage:
263 SetExitStatus(-1, NULL);
264 break;
265 }
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000266
267 m_message_queue.push(message);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000268}
269
270void
271ProcessLinux::RefreshStateAfterStop()
272{
273 Mutex::Locker lock(m_message_mutex);
274 if (m_message_queue.empty())
275 return;
276
277 ProcessMessage &message = m_message_queue.front();
278
279 // Resolve the thread this message corresponds to.
280 lldb::tid_t tid = message.GetTID();
281 LinuxThread *thread = static_cast<LinuxThread*>(
282 GetThreadList().FindThreadByID(tid, false).get());
283
284 switch (message.GetKind())
285 {
286 default:
287 assert(false && "Unexpected message kind!");
288 break;
289
290 case ProcessMessage::eExitMessage:
291 case ProcessMessage::eSignalMessage:
292 thread->ExitNotify();
293 break;
294
295 case ProcessMessage::eTraceMessage:
296 thread->TraceNotify();
297 break;
298
299 case ProcessMessage::eBreakpointMessage:
300 thread->BreakNotify();
301 break;
302 }
303
304 m_message_queue.pop();
305}
306
307bool
308ProcessLinux::IsAlive()
309{
310 StateType state = GetPrivateState();
311 return state != eStateExited && state != eStateInvalid;
312}
313
314size_t
315ProcessLinux::DoReadMemory(addr_t vm_addr,
316 void *buf, size_t size, Error &error)
317{
318 return m_monitor->ReadMemory(vm_addr, buf, size, error);
319}
320
321size_t
322ProcessLinux::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
323 Error &error)
324{
325 return m_monitor->WriteMemory(vm_addr, buf, size, error);
326}
327
328addr_t
329ProcessLinux::DoAllocateMemory(size_t size, uint32_t permissions,
330 Error &error)
331{
332 return 0;
333}
334
335addr_t
336ProcessLinux::AllocateMemory(size_t size, uint32_t permissions, Error &error)
337{
338 return 0;
339}
340
341Error
342ProcessLinux::DoDeallocateMemory(lldb::addr_t ptr)
343{
344 return Error(1, eErrorTypeGeneric);
345}
346
347size_t
348ProcessLinux::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
349{
350 static const uint8_t g_i386_opcode[] = { 0xCC };
351
352 ArchSpec arch = GetTarget().GetArchitecture();
353 const uint8_t *opcode = NULL;
354 size_t opcode_size = 0;
355
Stephen Wilsona1f0b722011-02-24 19:17:09 +0000356 switch (arch.GetCore())
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000357 {
358 default:
359 assert(false && "CPU type not supported!");
360 break;
361
Stephen Wilsona1f0b722011-02-24 19:17:09 +0000362 case ArchSpec::eCore_x86_32_i386:
363 case ArchSpec::eCore_x86_64_x86_64:
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000364 opcode = g_i386_opcode;
365 opcode_size = sizeof(g_i386_opcode);
366 break;
367 }
368
369 bp_site->SetTrapOpcode(opcode, opcode_size);
370 return opcode_size;
371}
372
373Error
374ProcessLinux::EnableBreakpoint(BreakpointSite *bp_site)
375{
376 return EnableSoftwareBreakpoint(bp_site);
377}
378
379Error
380ProcessLinux::DisableBreakpoint(BreakpointSite *bp_site)
381{
382 return DisableSoftwareBreakpoint(bp_site);
383}
384
385uint32_t
386ProcessLinux::UpdateThreadListIfNeeded()
387{
388 // Do not allow recursive updates.
389 return m_thread_list.GetSize(false);
390}
391
392ByteOrder
393ProcessLinux::GetByteOrder() const
394{
395 // FIXME: We should be able to extract this value directly. See comment in
396 // ProcessLinux().
397 return m_byte_order;
398}
399
400//------------------------------------------------------------------------------
401// ProcessInterface protocol.
402
403const char *
404ProcessLinux::GetPluginName()
405{
406 return "process.linux";
407}
408
409const char *
410ProcessLinux::GetShortPluginName()
411{
412 return "process.linux";
413}
414
415uint32_t
416ProcessLinux::GetPluginVersion()
417{
418 return 1;
419}
420
421void
422ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
423{
424}
425
426Error
427ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
428{
429 return Error(1, eErrorTypeGeneric);
430}
431
432Log *
433ProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
434{
435 return NULL;
436}
437
438//------------------------------------------------------------------------------
439// Utility functions.
440
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000441bool
442ProcessLinux::HasExited()
443{
444 switch (GetPrivateState())
445 {
446 default:
447 break;
448
449 case eStateUnloaded:
450 case eStateCrashed:
451 case eStateDetached:
452 case eStateExited:
453 return true;
454 }
455
456 return false;
457}