blob: 9e5c1ab27d5a1b17b9b21d873025ca6a2c960782 [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,
Greg Clayton452bf612010-08-31 18:35:14 +0000124 uint32_t launch_flags,
Chris Lattner24943d22010-06-08 16:52:24 +0000125 bool stop_at_entry
126)
127{
128 SBProcess process(GetProcess ());
129 if (!process.IsValid())
130 process = CreateProcess();
131 if (process.IsValid())
132 {
Greg Clayton452bf612010-08-31 18:35:14 +0000133 Error error (process->Launch (argv, envp, launch_flags, tty, tty, tty));
Chris Lattner24943d22010-06-08 16:52:24 +0000134 if (error.Success())
135 {
136 if (!stop_at_entry)
137 {
138 StateType state = process->WaitForProcessToStop (NULL);
139 if (state == eStateStopped)
140 process->Resume();
141 }
142 }
143 }
144 return process;
145}
146
147SBFileSpec
148SBTarget::GetExecutable ()
149{
150 SBFileSpec exe_file_spec;
Greg Clayton63094e02010-06-23 01:19:29 +0000151 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000152 {
Greg Clayton63094e02010-06-23 01:19:29 +0000153 ModuleSP exe_module_sp (m_opaque_sp->GetExecutableModule ());
Chris Lattner24943d22010-06-08 16:52:24 +0000154 if (exe_module_sp)
155 exe_file_spec.SetFileSpec (exe_module_sp->GetFileSpec());
156 }
157 return exe_file_spec;
158}
159
160
161bool
162SBTarget::DeleteTargetFromList (TargetList *list)
163{
Greg Clayton63094e02010-06-23 01:19:29 +0000164 if (m_opaque_sp)
165 return list->DeleteTarget (m_opaque_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000166 else
167 return false;
168}
169
170bool
Chris Lattner24943d22010-06-08 16:52:24 +0000171SBTarget::operator == (const SBTarget &rhs) const
172{
Greg Clayton63094e02010-06-23 01:19:29 +0000173 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000174}
175
176bool
177SBTarget::operator != (const SBTarget &rhs) const
178{
Greg Clayton63094e02010-06-23 01:19:29 +0000179 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000180}
181
182lldb_private::Target *
Greg Clayton63094e02010-06-23 01:19:29 +0000183SBTarget::operator ->() const
Chris Lattner24943d22010-06-08 16:52:24 +0000184{
Greg Clayton63094e02010-06-23 01:19:29 +0000185 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000186}
Greg Clayton63094e02010-06-23 01:19:29 +0000187
188lldb_private::Target *
189SBTarget::get() const
Chris Lattner24943d22010-06-08 16:52:24 +0000190{
Greg Clayton63094e02010-06-23 01:19:29 +0000191 return m_opaque_sp.get();
192}
193
194void
195SBTarget::reset (const lldb::TargetSP& target_sp)
196{
197 m_opaque_sp = target_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000198}
199
200SBBreakpoint
201SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line)
202{
203 SBBreakpoint sb_bp;
204 if (file != NULL && line != 0)
205 sb_bp = BreakpointCreateByLocation (SBFileSpec (file), line);
206 return sb_bp;
207}
208
209SBBreakpoint
210SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line)
211{
212 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000213 if (m_opaque_sp.get() && line != 0)
214 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, *sb_file_spec, line, true, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000215 return sb_bp;
216}
217
218SBBreakpoint
219SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name)
220{
221 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000222 if (m_opaque_sp.get() && symbol_name && symbol_name[0])
Chris Lattner24943d22010-06-08 16:52:24 +0000223 {
224 if (module_name && module_name[0])
225 {
226 FileSpec module_file_spec(module_name);
Greg Clayton63094e02010-06-23 01:19:29 +0000227 *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, symbol_name, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000228 }
229 else
230 {
Greg Clayton63094e02010-06-23 01:19:29 +0000231 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, symbol_name, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000232 }
233 }
234 return sb_bp;
235}
236
237SBBreakpoint
238SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name)
239{
240 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000241 if (m_opaque_sp.get() && symbol_name_regex && symbol_name_regex[0])
Chris Lattner24943d22010-06-08 16:52:24 +0000242 {
243 RegularExpression regexp(symbol_name_regex);
244
245 if (module_name && module_name[0])
246 {
247 FileSpec module_file_spec(module_name);
248
Greg Clayton63094e02010-06-23 01:19:29 +0000249 *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, regexp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000250 }
251 else
252 {
Greg Clayton63094e02010-06-23 01:19:29 +0000253 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, regexp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000254 }
255 }
256 return sb_bp;
257}
258
259
260
261SBBreakpoint
262SBTarget::BreakpointCreateByAddress (addr_t address)
263{
264 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000265 if (m_opaque_sp.get())
266 *sb_bp = m_opaque_sp->CreateBreakpoint (address, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000267 return sb_bp;
268}
269
Chris Lattner24943d22010-06-08 16:52:24 +0000270SBBreakpoint
271SBTarget::FindBreakpointByID (break_id_t bp_id)
272{
273 SBBreakpoint sb_breakpoint;
Greg Clayton63094e02010-06-23 01:19:29 +0000274 if (m_opaque_sp && bp_id != LLDB_INVALID_BREAK_ID)
275 *sb_breakpoint = m_opaque_sp->GetBreakpointByID (bp_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000276 return sb_breakpoint;
277}
278
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000279uint32_t
280SBTarget::GetNumBreakpoints () const
281{
282 if (m_opaque_sp)
283 return m_opaque_sp->GetBreakpointList().GetSize();
284 return 0;
285}
286
287SBBreakpoint
288SBTarget::GetBreakpointAtIndex (uint32_t idx) const
289{
290 SBBreakpoint sb_breakpoint;
291 if (m_opaque_sp)
292 *sb_breakpoint = m_opaque_sp->GetBreakpointList().GetBreakpointAtIndex(idx);
293 return sb_breakpoint;
294}
Chris Lattner24943d22010-06-08 16:52:24 +0000295
296bool
297SBTarget::BreakpointDelete (break_id_t bp_id)
298{
Greg Clayton63094e02010-06-23 01:19:29 +0000299 if (m_opaque_sp)
300 return m_opaque_sp->RemoveBreakpointByID (bp_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000301 return false;
302}
303
304bool
305SBTarget::EnableAllBreakpoints ()
306{
Greg Clayton63094e02010-06-23 01:19:29 +0000307 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000308 {
Greg Clayton63094e02010-06-23 01:19:29 +0000309 m_opaque_sp->EnableAllBreakpoints ();
Chris Lattner24943d22010-06-08 16:52:24 +0000310 return true;
311 }
312 return false;
313}
314
315bool
316SBTarget::DisableAllBreakpoints ()
317{
Greg Clayton63094e02010-06-23 01:19:29 +0000318 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000319 {
Greg Clayton63094e02010-06-23 01:19:29 +0000320 m_opaque_sp->DisableAllBreakpoints ();
Chris Lattner24943d22010-06-08 16:52:24 +0000321 return true;
322 }
323 return false;
324}
325
326bool
327SBTarget::DeleteAllBreakpoints ()
328{
Greg Clayton63094e02010-06-23 01:19:29 +0000329 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000330 {
Greg Clayton63094e02010-06-23 01:19:29 +0000331 m_opaque_sp->RemoveAllBreakpoints ();
Chris Lattner24943d22010-06-08 16:52:24 +0000332 return true;
333 }
334 return false;
335}
336
337
338uint32_t
339SBTarget::GetNumModules () const
340{
Greg Clayton63094e02010-06-23 01:19:29 +0000341 if (m_opaque_sp)
342 return m_opaque_sp->GetImages().GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000343 return 0;
344}
345
Greg Clayton43490d12010-07-30 20:12:55 +0000346void
347SBTarget::Clear ()
348{
349 m_opaque_sp.reset();
350}
351
352
Chris Lattner24943d22010-06-08 16:52:24 +0000353SBModule
354SBTarget::FindModule (const SBFileSpec &sb_file_spec)
355{
356 SBModule sb_module;
Greg Clayton63094e02010-06-23 01:19:29 +0000357 if (m_opaque_sp && sb_file_spec.IsValid())
358 sb_module.SetModule (m_opaque_sp->GetImages().FindFirstModuleForFileSpec (*sb_file_spec, NULL));
Chris Lattner24943d22010-06-08 16:52:24 +0000359 return sb_module;
360}
361
362SBModule
363SBTarget::GetModuleAtIndex (uint32_t idx)
364{
365 SBModule sb_module;
Greg Clayton63094e02010-06-23 01:19:29 +0000366 if (m_opaque_sp)
367 sb_module.SetModule(m_opaque_sp->GetImages().GetModuleAtIndex(idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000368 return sb_module;
369}
370
371
372SBBroadcaster
373SBTarget::GetBroadcaster () const
374{
Greg Clayton63094e02010-06-23 01:19:29 +0000375 SBBroadcaster broadcaster(m_opaque_sp.get(), false);
Chris Lattner24943d22010-06-08 16:52:24 +0000376 return broadcaster;
377}
378
379void
Greg Clayton70436352010-06-30 23:03:03 +0000380SBTarget::Disassemble (lldb::addr_t start_addr, lldb::addr_t end_addr, const char *module_name)
Chris Lattner24943d22010-06-08 16:52:24 +0000381{
Greg Clayton70436352010-06-30 23:03:03 +0000382 if (start_addr == LLDB_INVALID_ADDRESS)
Chris Lattner24943d22010-06-08 16:52:24 +0000383 return;
384
Greg Clayton63094e02010-06-23 01:19:29 +0000385 FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000386 if (out == NULL)
387 return;
388
Greg Clayton63094e02010-06-23 01:19:29 +0000389 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000390 {
Greg Clayton70436352010-06-30 23:03:03 +0000391 ModuleSP module_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000392 if (module_name != NULL)
393 {
Greg Clayton70436352010-06-30 23:03:03 +0000394 FileSpec module_file_spec (module_name);
395 module_sp = m_opaque_sp->GetImages().FindFirstModuleForFileSpec (module_file_spec, NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000396 }
Greg Clayton70436352010-06-30 23:03:03 +0000397
398 AddressRange range;
399
400 // Make sure the process object is alive if we have one (it might be
401 // created but we might not be launched yet).
Greg Claytoneea26402010-09-14 23:36:40 +0000402
Greg Clayton70436352010-06-30 23:03:03 +0000403 Process *process = m_opaque_sp->GetProcessSP().get();
404 if (process && !process->IsAlive())
405 process = NULL;
406
407 // If we are given a module, then "start_addr" is a file address in
408 // that module.
409 if (module_sp)
410 {
411 if (!module_sp->ResolveFileAddress (start_addr, range.GetBaseAddress()))
412 range.GetBaseAddress().SetOffset(start_addr);
413 }
Greg Claytoneea26402010-09-14 23:36:40 +0000414 else if (m_opaque_sp->GetSectionLoadList().IsEmpty() == false)
Greg Clayton70436352010-06-30 23:03:03 +0000415 {
416 // We don't have a module, se we need to figure out if "start_addr"
417 // resolves to anything in a running process.
Greg Claytoneea26402010-09-14 23:36:40 +0000418 if (!m_opaque_sp->GetSectionLoadList().ResolveLoadAddress (start_addr, range.GetBaseAddress()))
Greg Clayton70436352010-06-30 23:03:03 +0000419 range.GetBaseAddress().SetOffset(start_addr);
420 }
421 else
422 {
423 if (m_opaque_sp->GetImages().ResolveFileAddress (start_addr, range.GetBaseAddress()))
424 range.GetBaseAddress().SetOffset(start_addr);
425 }
Chris Lattner24943d22010-06-08 16:52:24 +0000426
427 // For now, we need a process; the disassembly functions insist. If we don't have one already,
428 // make one.
429
Greg Clayton70436352010-06-30 23:03:03 +0000430 ExecutionContext exe_ctx;
Chris Lattner24943d22010-06-08 16:52:24 +0000431
Greg Clayton70436352010-06-30 23:03:03 +0000432 if (process)
433 process->Calculate(exe_ctx);
434 else
435 m_opaque_sp->Calculate(exe_ctx);
Chris Lattner24943d22010-06-08 16:52:24 +0000436
Greg Clayton70436352010-06-30 23:03:03 +0000437 if (end_addr == LLDB_INVALID_ADDRESS || end_addr < start_addr)
438 range.SetByteSize( DEFAULT_DISASM_BYTE_SIZE);
439 else
440 range.SetByteSize(end_addr - start_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000441
Greg Clayton70436352010-06-30 23:03:03 +0000442 StreamFile out_stream (out);
Chris Lattner24943d22010-06-08 16:52:24 +0000443
Greg Clayton70436352010-06-30 23:03:03 +0000444 Disassembler::Disassemble (m_opaque_sp->GetDebugger(),
445 m_opaque_sp->GetArchitecture(),
446 exe_ctx,
447 range,
448 3,
449 false,
450 out_stream);
Chris Lattner24943d22010-06-08 16:52:24 +0000451 }
452}
453
454void
455SBTarget::Disassemble (const char *function_name, const char *module_name)
456{
457 if (function_name == NULL)
458 return;
459
Greg Clayton63094e02010-06-23 01:19:29 +0000460 FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000461 if (out == NULL)
462 return;
463
Greg Clayton63094e02010-06-23 01:19:29 +0000464 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000465 {
Greg Clayton70436352010-06-30 23:03:03 +0000466 Disassembler *disassembler = Disassembler::FindPlugin (m_opaque_sp->GetArchitecture());
Chris Lattner24943d22010-06-08 16:52:24 +0000467 if (disassembler == NULL)
468 return;
469
Greg Clayton70436352010-06-30 23:03:03 +0000470 ModuleSP module_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000471 if (module_name != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000472 {
Greg Clayton70436352010-06-30 23:03:03 +0000473 FileSpec module_file_spec (module_name);
474 module_sp = m_opaque_sp->GetImages().FindFirstModuleForFileSpec (module_file_spec, NULL);
Chris Lattner24943d22010-06-08 16:52:24 +0000475 }
Greg Clayton70436352010-06-30 23:03:03 +0000476
477 ExecutionContext exe_ctx;
478
479 // Make sure the process object is alive if we have one (it might be
480 // created but we might not be launched yet).
481 Process *process = m_opaque_sp->GetProcessSP().get();
482 if (process && !process->IsAlive())
483 process = NULL;
484
485 if (process)
486 process->Calculate(exe_ctx);
487 else
488 m_opaque_sp->Calculate(exe_ctx);
489
490
491 StreamFile out_stream (out);
492
493 Disassembler::Disassemble (m_opaque_sp->GetDebugger(),
494 m_opaque_sp->GetArchitecture(),
495 exe_ctx,
496 ConstString (function_name),
497 module_sp.get(),
498 3,
499 false,
500 out_stream);
Chris Lattner24943d22010-06-08 16:52:24 +0000501 }
502}