blob: 0e8774f4d6148eb3dbbc52da9d4ea26a19675da4 [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);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000247
248 switch (message.GetKind())
249 {
250 default:
251 SetPrivateState(eStateStopped);
252 break;
253
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000254 case ProcessMessage::eInvalidMessage:
255 return;
256
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000257 case ProcessMessage::eExitMessage:
258 SetExitStatus(message.GetExitStatus(), NULL);
259 break;
260
261 case ProcessMessage::eSignalMessage:
262 SetExitStatus(-1, NULL);
263 break;
264 }
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000265
266 m_message_queue.push(message);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000267}
268
269void
270ProcessLinux::RefreshStateAfterStop()
271{
272 Mutex::Locker lock(m_message_mutex);
273 if (m_message_queue.empty())
274 return;
275
276 ProcessMessage &message = m_message_queue.front();
277
278 // Resolve the thread this message corresponds to.
279 lldb::tid_t tid = message.GetTID();
280 LinuxThread *thread = static_cast<LinuxThread*>(
281 GetThreadList().FindThreadByID(tid, false).get());
282
283 switch (message.GetKind())
284 {
285 default:
286 assert(false && "Unexpected message kind!");
287 break;
288
289 case ProcessMessage::eExitMessage:
290 case ProcessMessage::eSignalMessage:
291 thread->ExitNotify();
292 break;
293
294 case ProcessMessage::eTraceMessage:
295 thread->TraceNotify();
296 break;
297
298 case ProcessMessage::eBreakpointMessage:
299 thread->BreakNotify();
300 break;
301 }
302
303 m_message_queue.pop();
304}
305
306bool
307ProcessLinux::IsAlive()
308{
309 StateType state = GetPrivateState();
310 return state != eStateExited && state != eStateInvalid;
311}
312
313size_t
314ProcessLinux::DoReadMemory(addr_t vm_addr,
315 void *buf, size_t size, Error &error)
316{
317 return m_monitor->ReadMemory(vm_addr, buf, size, error);
318}
319
320size_t
321ProcessLinux::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
322 Error &error)
323{
324 return m_monitor->WriteMemory(vm_addr, buf, size, error);
325}
326
327addr_t
328ProcessLinux::DoAllocateMemory(size_t size, uint32_t permissions,
329 Error &error)
330{
331 return 0;
332}
333
334addr_t
335ProcessLinux::AllocateMemory(size_t size, uint32_t permissions, Error &error)
336{
337 return 0;
338}
339
340Error
341ProcessLinux::DoDeallocateMemory(lldb::addr_t ptr)
342{
343 return Error(1, eErrorTypeGeneric);
344}
345
346size_t
347ProcessLinux::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
348{
349 static const uint8_t g_i386_opcode[] = { 0xCC };
350
351 ArchSpec arch = GetTarget().GetArchitecture();
352 const uint8_t *opcode = NULL;
353 size_t opcode_size = 0;
354
355 switch (arch.GetGenericCPUType())
356 {
357 default:
358 assert(false && "CPU type not supported!");
359 break;
360
361 case ArchSpec::eCPU_i386:
362 case ArchSpec::eCPU_x86_64:
363 opcode = g_i386_opcode;
364 opcode_size = sizeof(g_i386_opcode);
365 break;
366 }
367
368 bp_site->SetTrapOpcode(opcode, opcode_size);
369 return opcode_size;
370}
371
372Error
373ProcessLinux::EnableBreakpoint(BreakpointSite *bp_site)
374{
375 return EnableSoftwareBreakpoint(bp_site);
376}
377
378Error
379ProcessLinux::DisableBreakpoint(BreakpointSite *bp_site)
380{
381 return DisableSoftwareBreakpoint(bp_site);
382}
383
384uint32_t
385ProcessLinux::UpdateThreadListIfNeeded()
386{
387 // Do not allow recursive updates.
388 return m_thread_list.GetSize(false);
389}
390
391ByteOrder
392ProcessLinux::GetByteOrder() const
393{
394 // FIXME: We should be able to extract this value directly. See comment in
395 // ProcessLinux().
396 return m_byte_order;
397}
398
Stephen Wilson92241ef2011-01-16 19:45:39 +0000399DynamicLoader *
400ProcessLinux::GetDynamicLoader()
401{
402 return m_dyld_ap.get();
403}
404
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000405//------------------------------------------------------------------------------
406// ProcessInterface protocol.
407
408const char *
409ProcessLinux::GetPluginName()
410{
411 return "process.linux";
412}
413
414const char *
415ProcessLinux::GetShortPluginName()
416{
417 return "process.linux";
418}
419
420uint32_t
421ProcessLinux::GetPluginVersion()
422{
423 return 1;
424}
425
426void
427ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
428{
429}
430
431Error
432ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
433{
434 return Error(1, eErrorTypeGeneric);
435}
436
437Log *
438ProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
439{
440 return NULL;
441}
442
443//------------------------------------------------------------------------------
444// Utility functions.
445
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000446bool
447ProcessLinux::HasExited()
448{
449 switch (GetPrivateState())
450 {
451 default:
452 break;
453
454 case eStateUnloaded:
455 case eStateCrashed:
456 case eStateDetached:
457 case eStateExited:
458 return true;
459 }
460
461 return false;
462}