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