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