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