blob: f34b0142cb22d00858508ea9ce89b380750a7edc [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"
Caroline Tice98f930f2010-09-20 05:20:02 +000016#include "lldb/API/SBStream.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Breakpoint/BreakpointID.h"
18#include "lldb/Breakpoint/BreakpointIDList.h"
19#include "lldb/Breakpoint/BreakpointList.h"
20#include "lldb/Breakpoint/BreakpointLocation.h"
21#include "lldb/Core/Address.h"
22#include "lldb/Core/AddressResolver.h"
23#include "lldb/Core/AddressResolverName.h"
Jim Ingham84cdc152010-06-15 19:49:27 +000024#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Core/ArchSpec.h"
26#include "lldb/Core/Debugger.h"
27#include "lldb/Core/Disassembler.h"
28#include "lldb/Core/FileSpec.h"
29#include "lldb/Core/RegularExpression.h"
30#include "lldb/Core/SearchFilter.h"
31#include "lldb/Core/STLUtils.h"
32#include "lldb/Target/Process.h"
33#include "lldb/Target/Target.h"
34#include "lldb/Target/TargetList.h"
35
36#include "lldb/Interpreter/CommandReturnObject.h"
37#include "../source/Commands/CommandObjectBreakpoint.h"
38
Eli Friedman7a62c8b2010-06-09 07:44:37 +000039#include "lldb/API/SBDebugger.h"
40#include "lldb/API/SBProcess.h"
41#include "lldb/API/SBListener.h"
42#include "lldb/API/SBBreakpoint.h"
Chris Lattner24943d22010-06-08 16:52:24 +000043
44using namespace lldb;
45using namespace lldb_private;
46
47#define DEFAULT_DISASM_BYTE_SIZE 32
48
49//----------------------------------------------------------------------
50// SBTarget constructor
51//----------------------------------------------------------------------
52SBTarget::SBTarget ()
53{
54}
55
56SBTarget::SBTarget (const SBTarget& rhs) :
Greg Clayton63094e02010-06-23 01:19:29 +000057 m_opaque_sp (rhs.m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000058{
59}
60
61SBTarget::SBTarget(const TargetSP& target_sp) :
Greg Clayton63094e02010-06-23 01:19:29 +000062 m_opaque_sp (target_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000063{
64}
65
66const SBTarget&
67SBTarget::Assign (const SBTarget& rhs)
68{
69 if (this != &rhs)
70 {
Greg Clayton63094e02010-06-23 01:19:29 +000071 m_opaque_sp = rhs.m_opaque_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000072 }
73 return *this;
74}
75
76
77//----------------------------------------------------------------------
78// Destructor
79//----------------------------------------------------------------------
80SBTarget::~SBTarget()
81{
82}
83
84bool
85SBTarget::IsValid () const
86{
Greg Clayton63094e02010-06-23 01:19:29 +000087 return m_opaque_sp.get() != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +000088}
89
90SBProcess
91SBTarget::GetProcess ()
92{
93 SBProcess sb_process;
Greg Clayton63094e02010-06-23 01:19:29 +000094 if (m_opaque_sp)
95 sb_process.SetProcess (m_opaque_sp->GetProcessSP());
Chris Lattner24943d22010-06-08 16:52:24 +000096 return sb_process;
97}
98
Greg Clayton63094e02010-06-23 01:19:29 +000099SBDebugger
100SBTarget::GetDebugger () const
101{
102 SBDebugger debugger;
103 if (m_opaque_sp)
104 debugger.reset (m_opaque_sp->GetDebugger().GetSP());
105 return debugger;
106}
107
Chris Lattner24943d22010-06-08 16:52:24 +0000108SBProcess
109SBTarget::CreateProcess ()
110{
111 SBProcess sb_process;
112
Greg Clayton63094e02010-06-23 01:19:29 +0000113 if (m_opaque_sp)
Greg Clayton034a7c32010-06-29 01:42:03 +0000114 sb_process.SetProcess (m_opaque_sp->CreateProcess (m_opaque_sp->GetDebugger().GetListener()));
115
Chris Lattner24943d22010-06-08 16:52:24 +0000116 return sb_process;
117}
118
119SBProcess
120SBTarget::LaunchProcess
121(
122 char const **argv,
123 char const **envp,
124 const char *tty,
Greg Clayton452bf612010-08-31 18:35:14 +0000125 uint32_t launch_flags,
Chris Lattner24943d22010-06-08 16:52:24 +0000126 bool stop_at_entry
127)
128{
129 SBProcess process(GetProcess ());
130 if (!process.IsValid())
131 process = CreateProcess();
132 if (process.IsValid())
133 {
Greg Clayton452bf612010-08-31 18:35:14 +0000134 Error error (process->Launch (argv, envp, launch_flags, tty, tty, tty));
Chris Lattner24943d22010-06-08 16:52:24 +0000135 if (error.Success())
136 {
137 if (!stop_at_entry)
138 {
139 StateType state = process->WaitForProcessToStop (NULL);
140 if (state == eStateStopped)
141 process->Resume();
142 }
143 }
144 }
145 return process;
146}
147
148SBFileSpec
149SBTarget::GetExecutable ()
150{
151 SBFileSpec exe_file_spec;
Greg Clayton63094e02010-06-23 01:19:29 +0000152 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000153 {
Greg Clayton63094e02010-06-23 01:19:29 +0000154 ModuleSP exe_module_sp (m_opaque_sp->GetExecutableModule ());
Chris Lattner24943d22010-06-08 16:52:24 +0000155 if (exe_module_sp)
156 exe_file_spec.SetFileSpec (exe_module_sp->GetFileSpec());
157 }
158 return exe_file_spec;
159}
160
161
162bool
163SBTarget::DeleteTargetFromList (TargetList *list)
164{
Greg Clayton63094e02010-06-23 01:19:29 +0000165 if (m_opaque_sp)
166 return list->DeleteTarget (m_opaque_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000167 else
168 return false;
169}
170
171bool
Chris Lattner24943d22010-06-08 16:52:24 +0000172SBTarget::operator == (const SBTarget &rhs) const
173{
Greg Clayton63094e02010-06-23 01:19:29 +0000174 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000175}
176
177bool
178SBTarget::operator != (const SBTarget &rhs) const
179{
Greg Clayton63094e02010-06-23 01:19:29 +0000180 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000181}
182
183lldb_private::Target *
Greg Clayton63094e02010-06-23 01:19:29 +0000184SBTarget::operator ->() const
Chris Lattner24943d22010-06-08 16:52:24 +0000185{
Greg Clayton63094e02010-06-23 01:19:29 +0000186 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000187}
Greg Clayton63094e02010-06-23 01:19:29 +0000188
189lldb_private::Target *
190SBTarget::get() const
Chris Lattner24943d22010-06-08 16:52:24 +0000191{
Greg Clayton63094e02010-06-23 01:19:29 +0000192 return m_opaque_sp.get();
193}
194
195void
196SBTarget::reset (const lldb::TargetSP& target_sp)
197{
198 m_opaque_sp = target_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000199}
200
201SBBreakpoint
202SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line)
203{
204 SBBreakpoint sb_bp;
205 if (file != NULL && line != 0)
206 sb_bp = BreakpointCreateByLocation (SBFileSpec (file), line);
207 return sb_bp;
208}
209
210SBBreakpoint
211SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line)
212{
213 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000214 if (m_opaque_sp.get() && line != 0)
215 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, *sb_file_spec, line, true, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000216 return sb_bp;
217}
218
219SBBreakpoint
220SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name)
221{
222 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000223 if (m_opaque_sp.get() && symbol_name && symbol_name[0])
Chris Lattner24943d22010-06-08 16:52:24 +0000224 {
225 if (module_name && module_name[0])
226 {
227 FileSpec module_file_spec(module_name);
Greg Clayton63094e02010-06-23 01:19:29 +0000228 *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, symbol_name, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000229 }
230 else
231 {
Greg Clayton63094e02010-06-23 01:19:29 +0000232 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, symbol_name, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000233 }
234 }
235 return sb_bp;
236}
237
238SBBreakpoint
239SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name)
240{
241 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000242 if (m_opaque_sp.get() && symbol_name_regex && symbol_name_regex[0])
Chris Lattner24943d22010-06-08 16:52:24 +0000243 {
244 RegularExpression regexp(symbol_name_regex);
245
246 if (module_name && module_name[0])
247 {
248 FileSpec module_file_spec(module_name);
249
Greg Clayton63094e02010-06-23 01:19:29 +0000250 *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, regexp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000251 }
252 else
253 {
Greg Clayton63094e02010-06-23 01:19:29 +0000254 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, regexp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000255 }
256 }
257 return sb_bp;
258}
259
260
261
262SBBreakpoint
263SBTarget::BreakpointCreateByAddress (addr_t address)
264{
265 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000266 if (m_opaque_sp.get())
267 *sb_bp = m_opaque_sp->CreateBreakpoint (address, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000268 return sb_bp;
269}
270
Chris Lattner24943d22010-06-08 16:52:24 +0000271SBBreakpoint
272SBTarget::FindBreakpointByID (break_id_t bp_id)
273{
274 SBBreakpoint sb_breakpoint;
Greg Clayton63094e02010-06-23 01:19:29 +0000275 if (m_opaque_sp && bp_id != LLDB_INVALID_BREAK_ID)
276 *sb_breakpoint = m_opaque_sp->GetBreakpointByID (bp_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000277 return sb_breakpoint;
278}
279
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000280uint32_t
281SBTarget::GetNumBreakpoints () const
282{
283 if (m_opaque_sp)
284 return m_opaque_sp->GetBreakpointList().GetSize();
285 return 0;
286}
287
288SBBreakpoint
289SBTarget::GetBreakpointAtIndex (uint32_t idx) const
290{
291 SBBreakpoint sb_breakpoint;
292 if (m_opaque_sp)
293 *sb_breakpoint = m_opaque_sp->GetBreakpointList().GetBreakpointAtIndex(idx);
294 return sb_breakpoint;
295}
Chris Lattner24943d22010-06-08 16:52:24 +0000296
297bool
298SBTarget::BreakpointDelete (break_id_t bp_id)
299{
Greg Clayton63094e02010-06-23 01:19:29 +0000300 if (m_opaque_sp)
301 return m_opaque_sp->RemoveBreakpointByID (bp_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000302 return false;
303}
304
305bool
306SBTarget::EnableAllBreakpoints ()
307{
Greg Clayton63094e02010-06-23 01:19:29 +0000308 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000309 {
Greg Clayton63094e02010-06-23 01:19:29 +0000310 m_opaque_sp->EnableAllBreakpoints ();
Chris Lattner24943d22010-06-08 16:52:24 +0000311 return true;
312 }
313 return false;
314}
315
316bool
317SBTarget::DisableAllBreakpoints ()
318{
Greg Clayton63094e02010-06-23 01:19:29 +0000319 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000320 {
Greg Clayton63094e02010-06-23 01:19:29 +0000321 m_opaque_sp->DisableAllBreakpoints ();
Chris Lattner24943d22010-06-08 16:52:24 +0000322 return true;
323 }
324 return false;
325}
326
327bool
328SBTarget::DeleteAllBreakpoints ()
329{
Greg Clayton63094e02010-06-23 01:19:29 +0000330 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000331 {
Greg Clayton63094e02010-06-23 01:19:29 +0000332 m_opaque_sp->RemoveAllBreakpoints ();
Chris Lattner24943d22010-06-08 16:52:24 +0000333 return true;
334 }
335 return false;
336}
337
338
339uint32_t
340SBTarget::GetNumModules () const
341{
Greg Clayton63094e02010-06-23 01:19:29 +0000342 if (m_opaque_sp)
343 return m_opaque_sp->GetImages().GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000344 return 0;
345}
346
Greg Clayton43490d12010-07-30 20:12:55 +0000347void
348SBTarget::Clear ()
349{
350 m_opaque_sp.reset();
351}
352
353
Chris Lattner24943d22010-06-08 16:52:24 +0000354SBModule
355SBTarget::FindModule (const SBFileSpec &sb_file_spec)
356{
357 SBModule sb_module;
Greg Clayton63094e02010-06-23 01:19:29 +0000358 if (m_opaque_sp && sb_file_spec.IsValid())
359 sb_module.SetModule (m_opaque_sp->GetImages().FindFirstModuleForFileSpec (*sb_file_spec, NULL));
Chris Lattner24943d22010-06-08 16:52:24 +0000360 return sb_module;
361}
362
363SBModule
364SBTarget::GetModuleAtIndex (uint32_t idx)
365{
366 SBModule sb_module;
Greg Clayton63094e02010-06-23 01:19:29 +0000367 if (m_opaque_sp)
368 sb_module.SetModule(m_opaque_sp->GetImages().GetModuleAtIndex(idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000369 return sb_module;
370}
371
372
373SBBroadcaster
374SBTarget::GetBroadcaster () const
375{
Greg Clayton63094e02010-06-23 01:19:29 +0000376 SBBroadcaster broadcaster(m_opaque_sp.get(), false);
Chris Lattner24943d22010-06-08 16:52:24 +0000377 return broadcaster;
378}
379
380void
Greg Clayton70436352010-06-30 23:03:03 +0000381SBTarget::Disassemble (lldb::addr_t start_addr, lldb::addr_t end_addr, const char *module_name)
Chris Lattner24943d22010-06-08 16:52:24 +0000382{
Greg Clayton70436352010-06-30 23:03:03 +0000383 if (start_addr == LLDB_INVALID_ADDRESS)
Chris Lattner24943d22010-06-08 16:52:24 +0000384 return;
385
Greg Clayton63094e02010-06-23 01:19:29 +0000386 FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000387 if (out == NULL)
388 return;
389
Greg Clayton63094e02010-06-23 01:19:29 +0000390 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000391 {
Greg Clayton70436352010-06-30 23:03:03 +0000392 ModuleSP module_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000393 if (module_name != NULL)
394 {
Greg Clayton70436352010-06-30 23:03:03 +0000395 FileSpec module_file_spec (module_name);
396 module_sp = m_opaque_sp->GetImages().FindFirstModuleForFileSpec (module_file_spec, NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000397 }
Greg Clayton70436352010-06-30 23:03:03 +0000398
399 AddressRange range;
400
401 // Make sure the process object is alive if we have one (it might be
402 // created but we might not be launched yet).
Greg Claytoneea26402010-09-14 23:36:40 +0000403
Greg Clayton70436352010-06-30 23:03:03 +0000404 Process *process = m_opaque_sp->GetProcessSP().get();
405 if (process && !process->IsAlive())
406 process = NULL;
407
408 // If we are given a module, then "start_addr" is a file address in
409 // that module.
410 if (module_sp)
411 {
412 if (!module_sp->ResolveFileAddress (start_addr, range.GetBaseAddress()))
413 range.GetBaseAddress().SetOffset(start_addr);
414 }
Greg Claytoneea26402010-09-14 23:36:40 +0000415 else if (m_opaque_sp->GetSectionLoadList().IsEmpty() == false)
Greg Clayton70436352010-06-30 23:03:03 +0000416 {
417 // We don't have a module, se we need to figure out if "start_addr"
418 // resolves to anything in a running process.
Greg Claytoneea26402010-09-14 23:36:40 +0000419 if (!m_opaque_sp->GetSectionLoadList().ResolveLoadAddress (start_addr, range.GetBaseAddress()))
Greg Clayton70436352010-06-30 23:03:03 +0000420 range.GetBaseAddress().SetOffset(start_addr);
421 }
422 else
423 {
424 if (m_opaque_sp->GetImages().ResolveFileAddress (start_addr, range.GetBaseAddress()))
425 range.GetBaseAddress().SetOffset(start_addr);
426 }
Chris Lattner24943d22010-06-08 16:52:24 +0000427
428 // For now, we need a process; the disassembly functions insist. If we don't have one already,
429 // make one.
430
Greg Clayton70436352010-06-30 23:03:03 +0000431 ExecutionContext exe_ctx;
Chris Lattner24943d22010-06-08 16:52:24 +0000432
Greg Clayton70436352010-06-30 23:03:03 +0000433 if (process)
434 process->Calculate(exe_ctx);
435 else
436 m_opaque_sp->Calculate(exe_ctx);
Chris Lattner24943d22010-06-08 16:52:24 +0000437
Greg Clayton70436352010-06-30 23:03:03 +0000438 if (end_addr == LLDB_INVALID_ADDRESS || end_addr < start_addr)
439 range.SetByteSize( DEFAULT_DISASM_BYTE_SIZE);
440 else
441 range.SetByteSize(end_addr - start_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000442
Greg Clayton70436352010-06-30 23:03:03 +0000443 StreamFile out_stream (out);
Chris Lattner24943d22010-06-08 16:52:24 +0000444
Greg Clayton70436352010-06-30 23:03:03 +0000445 Disassembler::Disassemble (m_opaque_sp->GetDebugger(),
446 m_opaque_sp->GetArchitecture(),
447 exe_ctx,
448 range,
449 3,
450 false,
451 out_stream);
Chris Lattner24943d22010-06-08 16:52:24 +0000452 }
453}
454
455void
456SBTarget::Disassemble (const char *function_name, const char *module_name)
457{
458 if (function_name == NULL)
459 return;
460
Greg Clayton63094e02010-06-23 01:19:29 +0000461 FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000462 if (out == NULL)
463 return;
464
Greg Clayton63094e02010-06-23 01:19:29 +0000465 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000466 {
Greg Clayton70436352010-06-30 23:03:03 +0000467 Disassembler *disassembler = Disassembler::FindPlugin (m_opaque_sp->GetArchitecture());
Chris Lattner24943d22010-06-08 16:52:24 +0000468 if (disassembler == NULL)
469 return;
470
Greg Clayton70436352010-06-30 23:03:03 +0000471 ModuleSP module_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000472 if (module_name != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000473 {
Greg Clayton70436352010-06-30 23:03:03 +0000474 FileSpec module_file_spec (module_name);
475 module_sp = m_opaque_sp->GetImages().FindFirstModuleForFileSpec (module_file_spec, NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000476 }
Greg Clayton70436352010-06-30 23:03:03 +0000477
478 ExecutionContext exe_ctx;
479
480 // Make sure the process object is alive if we have one (it might be
481 // created but we might not be launched yet).
482 Process *process = m_opaque_sp->GetProcessSP().get();
483 if (process && !process->IsAlive())
484 process = NULL;
485
486 if (process)
487 process->Calculate(exe_ctx);
488 else
489 m_opaque_sp->Calculate(exe_ctx);
490
491
492 StreamFile out_stream (out);
493
494 Disassembler::Disassemble (m_opaque_sp->GetDebugger(),
495 m_opaque_sp->GetArchitecture(),
496 exe_ctx,
497 ConstString (function_name),
498 module_sp.get(),
499 3,
500 false,
501 out_stream);
Chris Lattner24943d22010-06-08 16:52:24 +0000502 }
503}
Caroline Tice98f930f2010-09-20 05:20:02 +0000504
505bool
506SBTarget::GetDescription (SBStream &description)
507{
508 if (m_opaque_sp)
Caroline Ticee7a566e2010-09-20 16:21:41 +0000509 {
Caroline Ticee49ec182010-09-22 23:01:29 +0000510 description.ref();
Caroline Tice98f930f2010-09-20 05:20:02 +0000511 m_opaque_sp->Dump (description.get());
Caroline Ticee7a566e2010-09-20 16:21:41 +0000512 }
Caroline Tice98f930f2010-09-20 05:20:02 +0000513 else
514 description.Printf ("No value");
515
516 return true;
517}