blob: 2bc76f3a8655ce0ba65ddace62dd47fb473c24e8 [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
Stephen Wilsond1fbbb42011-03-23 02:14:42 +000011#include <errno.h>
12
Stephen Wilsonf6f40332010-07-24 02:19:04 +000013// C++ Includes
14// Other libraries and framework includes
15#include "lldb/Core/PluginManager.h"
Peter Collingbournead115462011-06-03 20:40:44 +000016#include "lldb/Core/State.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000017#include "lldb/Host/Host.h"
18#include "lldb/Symbol/ObjectFile.h"
Stephen Wilson92241ef2011-01-16 19:45:39 +000019#include "lldb/Target/DynamicLoader.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000020#include "lldb/Target/Target.h"
21
22#include "ProcessLinux.h"
Peter Collingbournead115462011-06-03 20:40:44 +000023#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
Stephen Wilsonf6f40332010-07-24 02:19:04 +000024#include "ProcessMonitor.h"
25#include "LinuxThread.h"
26
27using namespace lldb;
28using namespace lldb_private;
29
30//------------------------------------------------------------------------------
31// Static functions.
32
33Process*
34ProcessLinux::CreateInstance(Target& target, Listener &listener)
35{
36 return new ProcessLinux(target, listener);
37}
38
39void
40ProcessLinux::Initialize()
41{
42 static bool g_initialized = false;
43
44 if (!g_initialized)
45 {
46 PluginManager::RegisterPlugin(GetPluginNameStatic(),
47 GetPluginDescriptionStatic(),
48 CreateInstance);
49 g_initialized = true;
50 }
51}
52
53void
54ProcessLinux::Terminate()
55{
56}
57
58const char *
59ProcessLinux::GetPluginNameStatic()
60{
61 return "plugin.process.linux";
62}
63
64const char *
65ProcessLinux::GetPluginDescriptionStatic()
66{
67 return "Process plugin for Linux";
68}
69
70
71//------------------------------------------------------------------------------
72// Constructors and destructors.
73
74ProcessLinux::ProcessLinux(Target& target, Listener &listener)
75 : Process(target, listener),
76 m_monitor(NULL),
Stephen Wilson67d9f7e2011-03-30 15:55:52 +000077 m_module(NULL),
78 m_in_limbo(false),
79 m_exit_now(false)
Stephen Wilsonf6f40332010-07-24 02:19:04 +000080{
81 // FIXME: Putting this code in the ctor and saving the byte order in a
82 // member variable is a hack to avoid const qual issues in GetByteOrder.
83 ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
84 m_byte_order = obj_file->GetByteOrder();
85}
86
87ProcessLinux::~ProcessLinux()
88{
89 delete m_monitor;
90}
91
92//------------------------------------------------------------------------------
93// Process protocol.
94
95bool
Peter Collingbourne47556982011-07-22 19:12:53 +000096ProcessLinux::CanDebug(Target &target, bool plugin_specified_by_name)
Stephen Wilsonf6f40332010-07-24 02:19:04 +000097{
98 // For now we are just making sure the file exists for a given module
99 ModuleSP exe_module_sp(target.GetExecutableModule());
100 if (exe_module_sp.get())
101 return exe_module_sp->GetFileSpec().Exists();
102 return false;
103}
104
105Error
106ProcessLinux::DoAttachToProcessWithID(lldb::pid_t pid)
107{
Johnny Chen9bab8d42011-06-14 19:19:50 +0000108 Error error;
109 assert(m_monitor == NULL);
110
111 m_monitor = new ProcessMonitor(this, pid, error);
112
113 if (!error.Success())
114 return error;
115
116 SetID(pid);
117 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000118}
119
120Error
Stephen Wilson92241ef2011-01-16 19:45:39 +0000121ProcessLinux::WillLaunch(Module* module)
122{
123 Error error;
Stephen Wilson92241ef2011-01-16 19:45:39 +0000124 return error;
125}
126
127Error
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000128ProcessLinux::DoLaunch(Module *module,
129 char const *argv[],
130 char const *envp[],
Stephen Wilson3a804312011-01-04 21:41:31 +0000131 uint32_t launch_flags,
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000132 const char *stdin_path,
133 const char *stdout_path,
Greg Claytonde915be2011-01-23 05:56:20 +0000134 const char *stderr_path,
135 const char *working_directory)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000136{
137 Error error;
138 assert(m_monitor == NULL);
139
140 SetPrivateState(eStateLaunching);
141 m_monitor = new ProcessMonitor(this, module,
142 argv, envp,
143 stdin_path, stdout_path, stderr_path,
144 error);
145
146 m_module = module;
147
148 if (!error.Success())
149 return error;
150
Stephen Wilson1f004c62011-01-15 00:13:27 +0000151 SetID(m_monitor->GetPID());
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000152 return error;
153}
154
Stephen Wilson92241ef2011-01-16 19:45:39 +0000155void
156ProcessLinux::DidLaunch()
157{
Stephen Wilson92241ef2011-01-16 19:45:39 +0000158}
159
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000160Error
161ProcessLinux::DoResume()
162{
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000163 StateType state = GetPrivateState();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000164
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000165 assert(state == eStateStopped || state == eStateCrashed);
166
167 // We are about to resume a thread that will cause the process to exit so
168 // set our exit status now. Do not change our state if the inferior
169 // crashed.
170 if (state == eStateStopped)
171 {
172 if (m_in_limbo)
173 SetExitStatus(m_exit_status, NULL);
174 else
175 SetPrivateState(eStateRunning);
176 }
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000177
178 bool did_resume = false;
179 uint32_t thread_count = m_thread_list.GetSize(false);
180 for (uint32_t i = 0; i < thread_count; ++i)
181 {
182 LinuxThread *thread = static_cast<LinuxThread*>(
183 m_thread_list.GetThreadAtIndex(i, false).get());
184 did_resume = thread->Resume() || did_resume;
185 }
186 assert(did_resume && "Process resume failed!");
187
188 return Error();
189}
190
Stephen Wilson01316422011-01-15 00:10:37 +0000191addr_t
192ProcessLinux::GetImageInfoAddress()
193{
194 Target *target = &GetTarget();
195 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
196 Address addr = obj_file->GetImageInfoAddress();
197
198 if (addr.IsValid())
199 return addr.GetLoadAddress(target);
200 else
201 return LLDB_INVALID_ADDRESS;
202}
203
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000204Error
Stephen Wilson3a804312011-01-04 21:41:31 +0000205ProcessLinux::DoHalt(bool &caused_stop)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000206{
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000207 Error error;
208
209 if (IsStopped())
210 {
211 caused_stop = false;
212 }
213 else if (kill(GetID(), SIGSTOP))
214 {
215 caused_stop = false;
216 error.SetErrorToErrno();
217 }
218 else
219 {
220 caused_stop = true;
221 }
222
223 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000224}
225
226Error
227ProcessLinux::DoDetach()
228{
229 return Error(1, eErrorTypeGeneric);
230}
231
232Error
233ProcessLinux::DoSignal(int signal)
234{
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000235 Error error;
236
237 if (kill(GetID(), signal))
238 error.SetErrorToErrno();
239
240 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000241}
242
243Error
244ProcessLinux::DoDestroy()
245{
246 Error error;
247
248 if (!HasExited())
249 {
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000250 // Drive the exit event to completion (do not keep the inferior in
251 // limbo).
252 m_exit_now = true;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000253
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000254 if (kill(m_monitor->GetPID(), SIGKILL) && error.Success())
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000255 {
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000256 error.SetErrorToErrno();
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000257 return error;
258 }
259
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000260 SetPrivateState(eStateExited);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000261 }
262
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000263 return error;
264}
265
266void
267ProcessLinux::SendMessage(const ProcessMessage &message)
268{
269 Mutex::Locker lock(m_message_mutex);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000270
271 switch (message.GetKind())
272 {
273 default:
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000274 assert(false && "Unexpected process message!");
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000275 break;
276
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000277 case ProcessMessage::eInvalidMessage:
278 return;
279
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000280 case ProcessMessage::eLimboMessage:
281 m_in_limbo = true;
282 m_exit_status = message.GetExitStatus();
283 if (m_exit_now)
284 {
285 SetPrivateState(eStateExited);
286 m_monitor->Detach();
287 }
288 else
289 SetPrivateState(eStateStopped);
290 break;
291
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000292 case ProcessMessage::eExitMessage:
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000293 m_exit_status = message.GetExitStatus();
294 SetExitStatus(m_exit_status, NULL);
295 break;
296
297 case ProcessMessage::eTraceMessage:
298 case ProcessMessage::eBreakpointMessage:
299 SetPrivateState(eStateStopped);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000300 break;
301
302 case ProcessMessage::eSignalMessage:
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000303 case ProcessMessage::eSignalDeliveredMessage:
304 SetPrivateState(eStateStopped);
305 break;
306
307 case ProcessMessage::eCrashMessage:
308 SetPrivateState(eStateCrashed);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000309 break;
310 }
Stephen Wilson07fc7a92011-01-19 01:29:39 +0000311
312 m_message_queue.push(message);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000313}
314
315void
316ProcessLinux::RefreshStateAfterStop()
317{
318 Mutex::Locker lock(m_message_mutex);
319 if (m_message_queue.empty())
320 return;
321
322 ProcessMessage &message = m_message_queue.front();
323
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000324 // Resolve the thread this message corresponds to and pass it along.
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000325 lldb::tid_t tid = message.GetTID();
326 LinuxThread *thread = static_cast<LinuxThread*>(
327 GetThreadList().FindThreadByID(tid, false).get());
328
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000329 thread->Notify(message);
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000330
331 m_message_queue.pop();
332}
333
334bool
335ProcessLinux::IsAlive()
336{
337 StateType state = GetPrivateState();
338 return state != eStateExited && state != eStateInvalid;
339}
340
341size_t
342ProcessLinux::DoReadMemory(addr_t vm_addr,
343 void *buf, size_t size, Error &error)
344{
345 return m_monitor->ReadMemory(vm_addr, buf, size, error);
346}
347
348size_t
349ProcessLinux::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
350 Error &error)
351{
352 return m_monitor->WriteMemory(vm_addr, buf, size, error);
353}
354
355addr_t
356ProcessLinux::DoAllocateMemory(size_t size, uint32_t permissions,
357 Error &error)
358{
Peter Collingbournead115462011-06-03 20:40:44 +0000359 addr_t allocated_addr = LLDB_INVALID_ADDRESS;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000360
Peter Collingbournead115462011-06-03 20:40:44 +0000361 unsigned prot = 0;
362 if (permissions & lldb::ePermissionsReadable)
363 prot |= eMmapProtRead;
364 if (permissions & lldb::ePermissionsWritable)
365 prot |= eMmapProtWrite;
366 if (permissions & lldb::ePermissionsExecutable)
367 prot |= eMmapProtExec;
368
369 if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
370 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
371 m_addr_to_mmap_size[allocated_addr] = size;
372 error.Clear();
373 } else {
374 allocated_addr = LLDB_INVALID_ADDRESS;
375 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
376 }
377
378 return allocated_addr;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000379}
380
381Error
Peter Collingbournead115462011-06-03 20:40:44 +0000382ProcessLinux::DoDeallocateMemory(lldb::addr_t addr)
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000383{
Peter Collingbournead115462011-06-03 20:40:44 +0000384 Error error;
385 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
386 if (pos != m_addr_to_mmap_size.end() &&
387 InferiorCallMunmap(this, addr, pos->second))
388 m_addr_to_mmap_size.erase (pos);
389 else
390 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
391
392 return error;
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000393}
394
395size_t
396ProcessLinux::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
397{
398 static const uint8_t g_i386_opcode[] = { 0xCC };
399
400 ArchSpec arch = GetTarget().GetArchitecture();
401 const uint8_t *opcode = NULL;
402 size_t opcode_size = 0;
403
Stephen Wilsona1f0b722011-02-24 19:17:09 +0000404 switch (arch.GetCore())
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000405 {
406 default:
407 assert(false && "CPU type not supported!");
408 break;
409
Stephen Wilsona1f0b722011-02-24 19:17:09 +0000410 case ArchSpec::eCore_x86_32_i386:
411 case ArchSpec::eCore_x86_64_x86_64:
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000412 opcode = g_i386_opcode;
413 opcode_size = sizeof(g_i386_opcode);
414 break;
415 }
416
417 bp_site->SetTrapOpcode(opcode, opcode_size);
418 return opcode_size;
419}
420
421Error
422ProcessLinux::EnableBreakpoint(BreakpointSite *bp_site)
423{
424 return EnableSoftwareBreakpoint(bp_site);
425}
426
427Error
428ProcessLinux::DisableBreakpoint(BreakpointSite *bp_site)
429{
430 return DisableSoftwareBreakpoint(bp_site);
431}
432
433uint32_t
434ProcessLinux::UpdateThreadListIfNeeded()
435{
436 // Do not allow recursive updates.
437 return m_thread_list.GetSize(false);
438}
439
Johnny Chenb8f74aa2011-10-10 23:11:50 +0000440uint32_t
441ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
442{
443 // FIXME: Should this be implemented?
444 return 0;
445}
446
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000447ByteOrder
448ProcessLinux::GetByteOrder() const
449{
450 // FIXME: We should be able to extract this value directly. See comment in
451 // ProcessLinux().
452 return m_byte_order;
453}
454
Stephen Wilsond1fbbb42011-03-23 02:14:42 +0000455size_t
456ProcessLinux::PutSTDIN(const char *buf, size_t len, Error &error)
457{
458 ssize_t status;
459 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
460 {
461 error.SetErrorToErrno();
462 return 0;
463 }
464 return status;
465}
466
467size_t
468ProcessLinux::GetSTDOUT(char *buf, size_t len, Error &error)
469{
470 ssize_t bytes_read;
471
472 // The terminal file descriptor is always in non-block mode.
473 if ((bytes_read = read(m_monitor->GetTerminalFD(), buf, len)) < 0)
474 {
475 if (errno != EAGAIN)
476 error.SetErrorToErrno();
477 return 0;
478 }
479 return bytes_read;
480}
481
482size_t
483ProcessLinux::GetSTDERR(char *buf, size_t len, Error &error)
484{
485 return GetSTDOUT(buf, len, error);
486}
487
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000488UnixSignals &
489ProcessLinux::GetUnixSignals()
490{
491 return m_linux_signals;
492}
Stephen Wilsond1fbbb42011-03-23 02:14:42 +0000493
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000494//------------------------------------------------------------------------------
495// ProcessInterface protocol.
496
497const char *
498ProcessLinux::GetPluginName()
499{
500 return "process.linux";
501}
502
503const char *
504ProcessLinux::GetShortPluginName()
505{
506 return "process.linux";
507}
508
509uint32_t
510ProcessLinux::GetPluginVersion()
511{
512 return 1;
513}
514
515void
516ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
517{
518}
519
520Error
521ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
522{
523 return Error(1, eErrorTypeGeneric);
524}
525
526Log *
527ProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
528{
529 return NULL;
530}
531
532//------------------------------------------------------------------------------
533// Utility functions.
534
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000535bool
536ProcessLinux::HasExited()
537{
538 switch (GetPrivateState())
539 {
540 default:
541 break;
542
Stephen Wilsonf6f40332010-07-24 02:19:04 +0000543 case eStateDetached:
544 case eStateExited:
545 return true;
546 }
547
548 return false;
549}
Stephen Wilson67d9f7e2011-03-30 15:55:52 +0000550
551bool
552ProcessLinux::IsStopped()
553{
554 switch (GetPrivateState())
555 {
556 default:
557 break;
558
559 case eStateStopped:
560 case eStateCrashed:
561 case eStateSuspended:
562 return true;
563 }
564
565 return false;
566}