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