blob: fa5b5b70ec32432ccdca611c86df4459ea77f560 [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;
109
110 m_dyld_ap.reset(DynamicLoader::FindPlugin(this, "dynamic-loader.linux-dyld"));
111 if (m_dyld_ap.get() == NULL)
112 error.SetErrorString("unable to find the dynamic loader named "
113 "'dynamic-loader.linux-dyld'");
114
115 return error;
116}
117
118Error
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000119ProcessLinux::DoLaunch(Module *module,
120 char const *argv[],
121 char const *envp[],
Stephen Wilson3a804312011-01-04 21:41:31 +0000122 uint32_t launch_flags,
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000123 const char *stdin_path,
124 const char *stdout_path,
Greg Claytonde915be2011-01-23 05:56:20 +0000125 const char *stderr_path,
126 const char *working_directory)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000127{
128 Error error;
129 assert(m_monitor == NULL);
130
131 SetPrivateState(eStateLaunching);
132 m_monitor = new ProcessMonitor(this, module,
133 argv, envp,
134 stdin_path, stdout_path, stderr_path,
135 error);
136
137 m_module = module;
138
139 if (!error.Success())
140 return error;
141
Stephen Wilson1f004c62011-01-15 00:13:27 +0000142 SetID(m_monitor->GetPID());
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000143 return error;
144}
145
Stephen Wilson92241ef2011-01-16 19:45:39 +0000146void
147ProcessLinux::DidLaunch()
148{
149 if (m_dyld_ap.get() != NULL)
150 m_dyld_ap->DidLaunch();
151}
152
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000153Error
154ProcessLinux::DoResume()
155{
156 assert(GetPrivateState() == eStateStopped && "Bad state for DoResume!");
157
158 // Set our state to running. This ensures inferior threads do not post a
159 // state change first.
160 SetPrivateState(eStateRunning);
161
162 bool did_resume = false;
163 uint32_t thread_count = m_thread_list.GetSize(false);
164 for (uint32_t i = 0; i < thread_count; ++i)
165 {
166 LinuxThread *thread = static_cast<LinuxThread*>(
167 m_thread_list.GetThreadAtIndex(i, false).get());
168 did_resume = thread->Resume() || did_resume;
169 }
170 assert(did_resume && "Process resume failed!");
171
172 return Error();
173}
174
Stephen Wilson01316422011-01-15 00:10:37 +0000175addr_t
176ProcessLinux::GetImageInfoAddress()
177{
178 Target *target = &GetTarget();
179 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
180 Address addr = obj_file->GetImageInfoAddress();
181
182 if (addr.IsValid())
183 return addr.GetLoadAddress(target);
184 else
185 return LLDB_INVALID_ADDRESS;
186}
187
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000188Error
Stephen Wilson3a804312011-01-04 21:41:31 +0000189ProcessLinux::DoHalt(bool &caused_stop)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000190{
191 return Error(1, eErrorTypeGeneric);
192}
193
194Error
195ProcessLinux::DoDetach()
196{
197 return Error(1, eErrorTypeGeneric);
198}
199
200Error
201ProcessLinux::DoSignal(int signal)
202{
203 return Error(1, eErrorTypeGeneric);
204}
205
206Error
207ProcessLinux::DoDestroy()
208{
209 Error error;
210
211 if (!HasExited())
212 {
Greg Clayton5d187e52011-01-08 20:28:42 +0000213 // Shut down the private state thread as we will synchronize with events
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000214 // ourselves. Discard all current thread plans.
215 PausePrivateStateThread();
216 GetThreadList().DiscardThreadPlans();
217
218 // Bringing the inferior into limbo will be caught by our monitor
219 // thread, in turn updating the process state.
220 if (!m_monitor->BringProcessIntoLimbo())
221 {
222 error.SetErrorToGenericError();
223 error.SetErrorString("Process termination failed.");
224 return error;
225 }
226
Stephen Wilson83047fc2011-01-19 01:30:44 +0000227 // Wait for the event to arrive. This is guaranteed to be an exit event.
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000228 StateType state;
229 EventSP event;
230 do {
Stephen Wilson83047fc2011-01-19 01:30:44 +0000231 TimeValue timeout_time;
232 timeout_time = TimeValue::Now();
233 timeout_time.OffsetWithSeconds(2);
234 state = WaitForStateChangedEventsPrivate(&timeout_time, event);
235 } while (state != eStateExited && state != eStateInvalid);
236
237 // Check if we timed out waiting for the exit event to arrive.
238 if (state == eStateInvalid)
239 error.SetErrorString("ProcessLinux::DoDestroy timed out.");
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000240
241 // Restart standard event handling and send the process the final kill,
242 // driving it out of limbo.
243 ResumePrivateStateThread();
244 }
245
Stephen Wilson83047fc2011-01-19 01:30:44 +0000246 if (kill(m_monitor->GetPID(), SIGKILL) && error.Success())
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000247 error.SetErrorToErrno();
Stephen Wilson83047fc2011-01-19 01:30:44 +0000248
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000249 return error;
250}
251
252void
253ProcessLinux::SendMessage(const ProcessMessage &message)
254{
255 Mutex::Locker lock(m_message_mutex);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000256
257 switch (message.GetKind())
258 {
259 default:
260 SetPrivateState(eStateStopped);
261 break;
262
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000263 case ProcessMessage::eInvalidMessage:
264 return;
265
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000266 case ProcessMessage::eExitMessage:
267 SetExitStatus(message.GetExitStatus(), NULL);
268 break;
269
270 case ProcessMessage::eSignalMessage:
271 SetExitStatus(-1, NULL);
272 break;
273 }
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000274
275 m_message_queue.push(message);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000276}
277
278void
279ProcessLinux::RefreshStateAfterStop()
280{
281 Mutex::Locker lock(m_message_mutex);
282 if (m_message_queue.empty())
283 return;
284
285 ProcessMessage &message = m_message_queue.front();
286
287 // Resolve the thread this message corresponds to.
288 lldb::tid_t tid = message.GetTID();
289 LinuxThread *thread = static_cast<LinuxThread*>(
290 GetThreadList().FindThreadByID(tid, false).get());
291
292 switch (message.GetKind())
293 {
294 default:
295 assert(false && "Unexpected message kind!");
296 break;
297
298 case ProcessMessage::eExitMessage:
299 case ProcessMessage::eSignalMessage:
300 thread->ExitNotify();
301 break;
302
303 case ProcessMessage::eTraceMessage:
304 thread->TraceNotify();
305 break;
306
307 case ProcessMessage::eBreakpointMessage:
308 thread->BreakNotify();
309 break;
310 }
311
312 m_message_queue.pop();
313}
314
315bool
316ProcessLinux::IsAlive()
317{
318 StateType state = GetPrivateState();
319 return state != eStateExited && state != eStateInvalid;
320}
321
322size_t
323ProcessLinux::DoReadMemory(addr_t vm_addr,
324 void *buf, size_t size, Error &error)
325{
326 return m_monitor->ReadMemory(vm_addr, buf, size, error);
327}
328
329size_t
330ProcessLinux::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
331 Error &error)
332{
333 return m_monitor->WriteMemory(vm_addr, buf, size, error);
334}
335
336addr_t
337ProcessLinux::DoAllocateMemory(size_t size, uint32_t permissions,
338 Error &error)
339{
340 return 0;
341}
342
343addr_t
344ProcessLinux::AllocateMemory(size_t size, uint32_t permissions, Error &error)
345{
346 return 0;
347}
348
349Error
350ProcessLinux::DoDeallocateMemory(lldb::addr_t ptr)
351{
352 return Error(1, eErrorTypeGeneric);
353}
354
355size_t
356ProcessLinux::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
357{
358 static const uint8_t g_i386_opcode[] = { 0xCC };
359
360 ArchSpec arch = GetTarget().GetArchitecture();
361 const uint8_t *opcode = NULL;
362 size_t opcode_size = 0;
363
364 switch (arch.GetGenericCPUType())
365 {
366 default:
367 assert(false && "CPU type not supported!");
368 break;
369
370 case ArchSpec::eCPU_i386:
371 case ArchSpec::eCPU_x86_64:
372 opcode = g_i386_opcode;
373 opcode_size = sizeof(g_i386_opcode);
374 break;
375 }
376
377 bp_site->SetTrapOpcode(opcode, opcode_size);
378 return opcode_size;
379}
380
381Error
382ProcessLinux::EnableBreakpoint(BreakpointSite *bp_site)
383{
384 return EnableSoftwareBreakpoint(bp_site);
385}
386
387Error
388ProcessLinux::DisableBreakpoint(BreakpointSite *bp_site)
389{
390 return DisableSoftwareBreakpoint(bp_site);
391}
392
393uint32_t
394ProcessLinux::UpdateThreadListIfNeeded()
395{
396 // Do not allow recursive updates.
397 return m_thread_list.GetSize(false);
398}
399
400ByteOrder
401ProcessLinux::GetByteOrder() const
402{
403 // FIXME: We should be able to extract this value directly. See comment in
404 // ProcessLinux().
405 return m_byte_order;
406}
407
Stephen Wilson92241ef2011-01-16 19:45:39 +0000408DynamicLoader *
409ProcessLinux::GetDynamicLoader()
410{
411 return m_dyld_ap.get();
412}
413
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000414//------------------------------------------------------------------------------
415// ProcessInterface protocol.
416
417const char *
418ProcessLinux::GetPluginName()
419{
420 return "process.linux";
421}
422
423const char *
424ProcessLinux::GetShortPluginName()
425{
426 return "process.linux";
427}
428
429uint32_t
430ProcessLinux::GetPluginVersion()
431{
432 return 1;
433}
434
435void
436ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
437{
438}
439
440Error
441ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
442{
443 return Error(1, eErrorTypeGeneric);
444}
445
446Log *
447ProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
448{
449 return NULL;
450}
451
452//------------------------------------------------------------------------------
453// Utility functions.
454
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000455bool
456ProcessLinux::HasExited()
457{
458 switch (GetPrivateState())
459 {
460 default:
461 break;
462
463 case eStateUnloaded:
464 case eStateCrashed:
465 case eStateDetached:
466 case eStateExited:
467 return true;
468 }
469
470 return false;
471}