blob: c863bc779b6b72b6dfa425e340bc81994dc419c3 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- SBTarget.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
Eli Friedman7a62c8b2010-06-09 07:44:37 +000010#include "lldb/API/SBTarget.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12#include "lldb/lldb-include.h"
13
14#include "lldb/API/SBFileSpec.h"
15#include "lldb/API/SBModule.h"
16#include "lldb/Breakpoint/BreakpointID.h"
17#include "lldb/Breakpoint/BreakpointIDList.h"
18#include "lldb/Breakpoint/BreakpointList.h"
19#include "lldb/Breakpoint/BreakpointLocation.h"
20#include "lldb/Core/Address.h"
21#include "lldb/Core/AddressResolver.h"
22#include "lldb/Core/AddressResolverName.h"
Jim Ingham84cdc152010-06-15 19:49:27 +000023#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Core/ArchSpec.h"
25#include "lldb/Core/Debugger.h"
26#include "lldb/Core/Disassembler.h"
27#include "lldb/Core/FileSpec.h"
28#include "lldb/Core/RegularExpression.h"
29#include "lldb/Core/SearchFilter.h"
30#include "lldb/Core/STLUtils.h"
31#include "lldb/Target/Process.h"
32#include "lldb/Target/Target.h"
33#include "lldb/Target/TargetList.h"
34
35#include "lldb/Interpreter/CommandReturnObject.h"
36#include "../source/Commands/CommandObjectBreakpoint.h"
37
Eli Friedman7a62c8b2010-06-09 07:44:37 +000038#include "lldb/API/SBDebugger.h"
39#include "lldb/API/SBProcess.h"
40#include "lldb/API/SBListener.h"
41#include "lldb/API/SBBreakpoint.h"
Chris Lattner24943d22010-06-08 16:52:24 +000042
43using namespace lldb;
44using namespace lldb_private;
45
46#define DEFAULT_DISASM_BYTE_SIZE 32
47
48//----------------------------------------------------------------------
49// SBTarget constructor
50//----------------------------------------------------------------------
51SBTarget::SBTarget ()
52{
53}
54
55SBTarget::SBTarget (const SBTarget& rhs) :
Greg Clayton63094e02010-06-23 01:19:29 +000056 m_opaque_sp (rhs.m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000057{
58}
59
60SBTarget::SBTarget(const TargetSP& target_sp) :
Greg Clayton63094e02010-06-23 01:19:29 +000061 m_opaque_sp (target_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000062{
63}
64
65const SBTarget&
66SBTarget::Assign (const SBTarget& rhs)
67{
68 if (this != &rhs)
69 {
Greg Clayton63094e02010-06-23 01:19:29 +000070 m_opaque_sp = rhs.m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000071 }
72 return *this;
73}
74
75
76//----------------------------------------------------------------------
77// Destructor
78//----------------------------------------------------------------------
79SBTarget::~SBTarget()
80{
81}
82
83bool
84SBTarget::IsValid () const
85{
Greg Clayton63094e02010-06-23 01:19:29 +000086 return m_opaque_sp.get() != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +000087}
88
89SBProcess
90SBTarget::GetProcess ()
91{
92 SBProcess sb_process;
Greg Clayton63094e02010-06-23 01:19:29 +000093 if (m_opaque_sp)
94 sb_process.SetProcess (m_opaque_sp->GetProcessSP());
Chris Lattner24943d22010-06-08 16:52:24 +000095 return sb_process;
96}
97
Greg Clayton63094e02010-06-23 01:19:29 +000098SBDebugger
99SBTarget::GetDebugger () const
100{
101 SBDebugger debugger;
102 if (m_opaque_sp)
103 debugger.reset (m_opaque_sp->GetDebugger().GetSP());
104 return debugger;
105}
106
Chris Lattner24943d22010-06-08 16:52:24 +0000107SBProcess
108SBTarget::CreateProcess ()
109{
110 SBProcess sb_process;
111
Greg Clayton63094e02010-06-23 01:19:29 +0000112 if (m_opaque_sp)
Greg Clayton034a7c32010-06-29 01:42:03 +0000113 sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
114
Chris Lattner24943d22010-06-08 16:52:24 +0000115 return sb_process;
116}
117
118SBProcess
119SBTarget::LaunchProcess
120(
121 char const **argv,
122 char const **envp,
123 const char *tty,
124 bool stop_at_entry
125)
126{
127 SBProcess process(GetProcess ());
128 if (!process.IsValid())
129 process = CreateProcess();
130 if (process.IsValid())
131 {
132 Error error (process->Launch (argv, envp, tty, tty, tty));
133 if (error.Success())
134 {
135 if (!stop_at_entry)
136 {
137 StateType state = process->WaitForProcessToStop (NULL);
138 if (state == eStateStopped)
139 process->Resume();
140 }
141 }
142 }
143 return process;
144}
145
146SBFileSpec
147SBTarget::GetExecutable ()
148{
149 SBFileSpec exe_file_spec;
Greg Clayton63094e02010-06-23 01:19:29 +0000150 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000151 {
Greg Clayton63094e02010-06-23 01:19:29 +0000152 ModuleSP exe_module_sp (m_opaque_sp->GetExecutableModule ());
Chris Lattner24943d22010-06-08 16:52:24 +0000153 if (exe_module_sp)
154 exe_file_spec.SetFileSpec (exe_module_sp->GetFileSpec());
155 }
156 return exe_file_spec;
157}
158
159
160bool
161SBTarget::DeleteTargetFromList (TargetList *list)
162{
Greg Clayton63094e02010-06-23 01:19:29 +0000163 if (m_opaque_sp)
164 return list->DeleteTarget (m_opaque_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000165 else
166 return false;
167}
168
169bool
Chris Lattner24943d22010-06-08 16:52:24 +0000170SBTarget::operator == (const SBTarget &rhs) const
171{
Greg Clayton63094e02010-06-23 01:19:29 +0000172 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000173}
174
175bool
176SBTarget::operator != (const SBTarget &rhs) const
177{
Greg Clayton63094e02010-06-23 01:19:29 +0000178 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000179}
180
181lldb_private::Target *
Greg Clayton63094e02010-06-23 01:19:29 +0000182SBTarget::operator ->() const
Chris Lattner24943d22010-06-08 16:52:24 +0000183{
Greg Clayton63094e02010-06-23 01:19:29 +0000184 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000185}
Greg Clayton63094e02010-06-23 01:19:29 +0000186
187lldb_private::Target *
188SBTarget::get() const
Chris Lattner24943d22010-06-08 16:52:24 +0000189{
Greg Clayton63094e02010-06-23 01:19:29 +0000190 return m_opaque_sp.get();
191}
192
193void
194SBTarget::reset (const lldb::TargetSP& target_sp)
195{
196 m_opaque_sp = target_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000197}
198
199SBBreakpoint
200SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line)
201{
202 SBBreakpoint sb_bp;
203 if (file != NULL && line != 0)
204 sb_bp = BreakpointCreateByLocation (SBFileSpec (file), line);
205 return sb_bp;
206}
207
208SBBreakpoint
209SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line)
210{
211 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000212 if (m_opaque_sp.get() && line != 0)
213 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, *sb_file_spec, line, true, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000214 return sb_bp;
215}
216
217SBBreakpoint
218SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name)
219{
220 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000221 if (m_opaque_sp.get() && symbol_name && symbol_name[0])
Chris Lattner24943d22010-06-08 16:52:24 +0000222 {
223 if (module_name && module_name[0])
224 {
225 FileSpec module_file_spec(module_name);
Greg Clayton63094e02010-06-23 01:19:29 +0000226 *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, symbol_name, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000227 }
228 else
229 {
Greg Clayton63094e02010-06-23 01:19:29 +0000230 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, symbol_name, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000231 }
232 }
233 return sb_bp;
234}
235
236SBBreakpoint
237SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name)
238{
239 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000240 if (m_opaque_sp.get() && symbol_name_regex && symbol_name_regex[0])
Chris Lattner24943d22010-06-08 16:52:24 +0000241 {
242 RegularExpression regexp(symbol_name_regex);
243
244 if (module_name && module_name[0])
245 {
246 FileSpec module_file_spec(module_name);
247
Greg Clayton63094e02010-06-23 01:19:29 +0000248 *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, regexp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000249 }
250 else
251 {
Greg Clayton63094e02010-06-23 01:19:29 +0000252 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, regexp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000253 }
254 }
255 return sb_bp;
256}
257
258
259
260SBBreakpoint
261SBTarget::BreakpointCreateByAddress (addr_t address)
262{
263 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000264 if (m_opaque_sp.get())
265 *sb_bp = m_opaque_sp->CreateBreakpoint (address, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000266 return sb_bp;
267}
268
Chris Lattner24943d22010-06-08 16:52:24 +0000269SBBreakpoint
270SBTarget::FindBreakpointByID (break_id_t bp_id)
271{
272 SBBreakpoint sb_breakpoint;
Greg Clayton63094e02010-06-23 01:19:29 +0000273 if (m_opaque_sp && bp_id != LLDB_INVALID_BREAK_ID)
274 *sb_breakpoint = m_opaque_sp->GetBreakpointByID (bp_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000275 return sb_breakpoint;
276}
277
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000278uint32_t
279SBTarget::GetNumBreakpoints () const
280{
281 if (m_opaque_sp)
282 return m_opaque_sp->GetBreakpointList().GetSize();
283 return 0;
284}
285
286SBBreakpoint
287SBTarget::GetBreakpointAtIndex (uint32_t idx) const
288{
289 SBBreakpoint sb_breakpoint;
290 if (m_opaque_sp)
291 *sb_breakpoint = m_opaque_sp->GetBreakpointList().GetBreakpointAtIndex(idx);
292 return sb_breakpoint;
293}
Chris Lattner24943d22010-06-08 16:52:24 +0000294
295bool
296SBTarget::BreakpointDelete (break_id_t bp_id)
297{
Greg Clayton63094e02010-06-23 01:19:29 +0000298 if (m_opaque_sp)
299 return m_opaque_sp->RemoveBreakpointByID (bp_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000300 return false;
301}
302
303bool
304SBTarget::EnableAllBreakpoints ()
305{
Greg Clayton63094e02010-06-23 01:19:29 +0000306 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000307 {
Greg Clayton63094e02010-06-23 01:19:29 +0000308 m_opaque_sp->EnableAllBreakpoints ();
Chris Lattner24943d22010-06-08 16:52:24 +0000309 return true;
310 }
311 return false;
312}
313
314bool
315SBTarget::DisableAllBreakpoints ()
316{
Greg Clayton63094e02010-06-23 01:19:29 +0000317 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000318 {
Greg Clayton63094e02010-06-23 01:19:29 +0000319 m_opaque_sp->DisableAllBreakpoints ();
Chris Lattner24943d22010-06-08 16:52:24 +0000320 return true;
321 }
322 return false;
323}
324
325bool
326SBTarget::DeleteAllBreakpoints ()
327{
Greg Clayton63094e02010-06-23 01:19:29 +0000328 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000329 {
Greg Clayton63094e02010-06-23 01:19:29 +0000330 m_opaque_sp->RemoveAllBreakpoints ();
Chris Lattner24943d22010-06-08 16:52:24 +0000331 return true;
332 }
333 return false;
334}
335
336
337uint32_t
338SBTarget::GetNumModules () const
339{
Greg Clayton63094e02010-06-23 01:19:29 +0000340 if (m_opaque_sp)
341 return m_opaque_sp->GetImages().GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000342 return 0;
343}
344
Greg Clayton43490d12010-07-30 20:12:55 +0000345void
346SBTarget::Clear ()
347{
348 m_opaque_sp.reset();
349}
350
351
Chris Lattner24943d22010-06-08 16:52:24 +0000352SBModule
353SBTarget::FindModule (const SBFileSpec &sb_file_spec)
354{
355 SBModule sb_module;
Greg Clayton63094e02010-06-23 01:19:29 +0000356 if (m_opaque_sp && sb_file_spec.IsValid())
357 sb_module.SetModule (m_opaque_sp->GetImages().FindFirstModuleForFileSpec (*sb_file_spec, NULL));
Chris Lattner24943d22010-06-08 16:52:24 +0000358 return sb_module;
359}
360
361SBModule
362SBTarget::GetModuleAtIndex (uint32_t idx)
363{
364 SBModule sb_module;
Greg Clayton63094e02010-06-23 01:19:29 +0000365 if (m_opaque_sp)
366 sb_module.SetModule(m_opaque_sp->GetImages().GetModuleAtIndex(idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000367 return sb_module;
368}
369
370
371SBBroadcaster
372SBTarget::GetBroadcaster () const
373{
Greg Clayton63094e02010-06-23 01:19:29 +0000374 SBBroadcaster broadcaster(m_opaque_sp.get(), false);
Chris Lattner24943d22010-06-08 16:52:24 +0000375 return broadcaster;
376}
377
378void
Greg Clayton70436352010-06-30 23:03:03 +0000379SBTarget::Disassemble (lldb::addr_t start_addr, lldb::addr_t end_addr, const char *module_name)
Chris Lattner24943d22010-06-08 16:52:24 +0000380{
Greg Clayton70436352010-06-30 23:03:03 +0000381 if (start_addr == LLDB_INVALID_ADDRESS)
Chris Lattner24943d22010-06-08 16:52:24 +0000382 return;
383
Greg Clayton63094e02010-06-23 01:19:29 +0000384 FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000385 if (out == NULL)
386 return;
387
Greg Clayton63094e02010-06-23 01:19:29 +0000388 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000389 {
Greg Clayton70436352010-06-30 23:03:03 +0000390 ModuleSP module_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000391 if (module_name != NULL)
392 {
Greg Clayton70436352010-06-30 23:03:03 +0000393 FileSpec module_file_spec (module_name);
394 module_sp = m_opaque_sp->GetImages().FindFirstModuleForFileSpec (module_file_spec, NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000395 }
Greg Clayton70436352010-06-30 23:03:03 +0000396
397 AddressRange range;
398
399 // Make sure the process object is alive if we have one (it might be
400 // created but we might not be launched yet).
401 Process *process = m_opaque_sp->GetProcessSP().get();
402 if (process && !process->IsAlive())
403 process = NULL;
404
405 // If we are given a module, then "start_addr" is a file address in
406 // that module.
407 if (module_sp)
408 {
409 if (!module_sp->ResolveFileAddress (start_addr, range.GetBaseAddress()))
410 range.GetBaseAddress().SetOffset(start_addr);
411 }
412 else if (process)
413 {
414 // We don't have a module, se we need to figure out if "start_addr"
415 // resolves to anything in a running process.
416 if (!process->ResolveLoadAddress(start_addr, range.GetBaseAddress()))
417 range.GetBaseAddress().SetOffset(start_addr);
418 }
419 else
420 {
421 if (m_opaque_sp->GetImages().ResolveFileAddress (start_addr, range.GetBaseAddress()))
422 range.GetBaseAddress().SetOffset(start_addr);
423 }
Chris Lattner24943d22010-06-08 16:52:24 +0000424
425 // For now, we need a process; the disassembly functions insist. If we don't have one already,
426 // make one.
427
Greg Clayton70436352010-06-30 23:03:03 +0000428 ExecutionContext exe_ctx;
Chris Lattner24943d22010-06-08 16:52:24 +0000429
Greg Clayton70436352010-06-30 23:03:03 +0000430 if (process)
431 process->Calculate(exe_ctx);
432 else
433 m_opaque_sp->Calculate(exe_ctx);
Chris Lattner24943d22010-06-08 16:52:24 +0000434
Greg Clayton70436352010-06-30 23:03:03 +0000435 if (end_addr == LLDB_INVALID_ADDRESS || end_addr < start_addr)
436 range.SetByteSize( DEFAULT_DISASM_BYTE_SIZE);
437 else
438 range.SetByteSize(end_addr - start_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000439
Greg Clayton70436352010-06-30 23:03:03 +0000440 StreamFile out_stream (out);
Chris Lattner24943d22010-06-08 16:52:24 +0000441
Greg Clayton70436352010-06-30 23:03:03 +0000442 Disassembler::Disassemble (m_opaque_sp->GetDebugger(),
443 m_opaque_sp->GetArchitecture(),
444 exe_ctx,
445 range,
446 3,
447 false,
448 out_stream);
Chris Lattner24943d22010-06-08 16:52:24 +0000449 }
450}
451
452void
453SBTarget::Disassemble (const char *function_name, const char *module_name)
454{
455 if (function_name == NULL)
456 return;
457
Greg Clayton63094e02010-06-23 01:19:29 +0000458 FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000459 if (out == NULL)
460 return;
461
Greg Clayton63094e02010-06-23 01:19:29 +0000462 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000463 {
Greg Clayton70436352010-06-30 23:03:03 +0000464 Disassembler *disassembler = Disassembler::FindPlugin (m_opaque_sp->GetArchitecture());
Chris Lattner24943d22010-06-08 16:52:24 +0000465 if (disassembler == NULL)
466 return;
467
Greg Clayton70436352010-06-30 23:03:03 +0000468 ModuleSP module_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000469 if (module_name != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000470 {
Greg Clayton70436352010-06-30 23:03:03 +0000471 FileSpec module_file_spec (module_name);
472 module_sp = m_opaque_sp->GetImages().FindFirstModuleForFileSpec (module_file_spec, NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000473 }
Greg Clayton70436352010-06-30 23:03:03 +0000474
475 ExecutionContext exe_ctx;
476
477 // Make sure the process object is alive if we have one (it might be
478 // created but we might not be launched yet).
479 Process *process = m_opaque_sp->GetProcessSP().get();
480 if (process && !process->IsAlive())
481 process = NULL;
482
483 if (process)
484 process->Calculate(exe_ctx);
485 else
486 m_opaque_sp->Calculate(exe_ctx);
487
488
489 StreamFile out_stream (out);
490
491 Disassembler::Disassemble (m_opaque_sp->GetDebugger(),
492 m_opaque_sp->GetArchitecture(),
493 exe_ctx,
494 ConstString (function_name),
495 module_sp.get(),
496 3,
497 false,
498 out_stream);
Chris Lattner24943d22010-06-08 16:52:24 +0000499 }
500}