blob: f964409813fdcdeac94558c2f511df47bc591e62 [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
170SBTarget::MakeCurrentTarget ()
171{
Greg Clayton63094e02010-06-23 01:19:29 +0000172 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000173 {
Greg Clayton63094e02010-06-23 01:19:29 +0000174 m_opaque_sp->GetDebugger().GetTargetList().SetCurrentTarget (m_opaque_sp.get());
Chris Lattner24943d22010-06-08 16:52:24 +0000175 return true;
176 }
177 return false;
178}
179
180bool
181SBTarget::operator == (const SBTarget &rhs) const
182{
Greg Clayton63094e02010-06-23 01:19:29 +0000183 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000184}
185
186bool
187SBTarget::operator != (const SBTarget &rhs) const
188{
Greg Clayton63094e02010-06-23 01:19:29 +0000189 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000190}
191
192lldb_private::Target *
Greg Clayton63094e02010-06-23 01:19:29 +0000193SBTarget::operator ->() const
Chris Lattner24943d22010-06-08 16:52:24 +0000194{
Greg Clayton63094e02010-06-23 01:19:29 +0000195 return m_opaque_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000196}
Greg Clayton63094e02010-06-23 01:19:29 +0000197
198lldb_private::Target *
199SBTarget::get() const
Chris Lattner24943d22010-06-08 16:52:24 +0000200{
Greg Clayton63094e02010-06-23 01:19:29 +0000201 return m_opaque_sp.get();
202}
203
204void
205SBTarget::reset (const lldb::TargetSP& target_sp)
206{
207 m_opaque_sp = target_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000208}
209
210SBBreakpoint
211SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line)
212{
213 SBBreakpoint sb_bp;
214 if (file != NULL && line != 0)
215 sb_bp = BreakpointCreateByLocation (SBFileSpec (file), line);
216 return sb_bp;
217}
218
219SBBreakpoint
220SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line)
221{
222 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000223 if (m_opaque_sp.get() && line != 0)
224 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, *sb_file_spec, line, true, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000225 return sb_bp;
226}
227
228SBBreakpoint
229SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name)
230{
231 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000232 if (m_opaque_sp.get() && symbol_name && symbol_name[0])
Chris Lattner24943d22010-06-08 16:52:24 +0000233 {
234 if (module_name && module_name[0])
235 {
236 FileSpec module_file_spec(module_name);
Greg Clayton63094e02010-06-23 01:19:29 +0000237 *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, symbol_name, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000238 }
239 else
240 {
Greg Clayton63094e02010-06-23 01:19:29 +0000241 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, symbol_name, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000242 }
243 }
244 return sb_bp;
245}
246
247SBBreakpoint
248SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name)
249{
250 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000251 if (m_opaque_sp.get() && symbol_name_regex && symbol_name_regex[0])
Chris Lattner24943d22010-06-08 16:52:24 +0000252 {
253 RegularExpression regexp(symbol_name_regex);
254
255 if (module_name && module_name[0])
256 {
257 FileSpec module_file_spec(module_name);
258
Greg Clayton63094e02010-06-23 01:19:29 +0000259 *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, regexp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000260 }
261 else
262 {
Greg Clayton63094e02010-06-23 01:19:29 +0000263 *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, regexp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000264 }
265 }
266 return sb_bp;
267}
268
269
270
271SBBreakpoint
272SBTarget::BreakpointCreateByAddress (addr_t address)
273{
274 SBBreakpoint sb_bp;
Greg Clayton63094e02010-06-23 01:19:29 +0000275 if (m_opaque_sp.get())
276 *sb_bp = m_opaque_sp->CreateBreakpoint (address, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000277 return sb_bp;
278}
279
280void
281SBTarget::ListAllBreakpoints ()
282{
Greg Clayton63094e02010-06-23 01:19:29 +0000283 FILE *out_file = m_opaque_sp->GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000284
285 if (out_file == NULL)
286 return;
287
Greg Clayton63094e02010-06-23 01:19:29 +0000288 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000289 {
Greg Clayton63094e02010-06-23 01:19:29 +0000290 const BreakpointList &bp_list = m_opaque_sp->GetBreakpointList();
Chris Lattner24943d22010-06-08 16:52:24 +0000291 size_t num_bps = bp_list.GetSize();
292 for (int i = 0; i < num_bps; ++i)
293 {
294 SBBreakpoint sb_breakpoint (bp_list.GetBreakpointByIndex (i));
295 sb_breakpoint.GetDescription (out_file, "full");
296 }
297 }
298}
299
300SBBreakpoint
301SBTarget::FindBreakpointByID (break_id_t bp_id)
302{
303 SBBreakpoint sb_breakpoint;
Greg Clayton63094e02010-06-23 01:19:29 +0000304 if (m_opaque_sp && bp_id != LLDB_INVALID_BREAK_ID)
305 *sb_breakpoint = m_opaque_sp->GetBreakpointByID (bp_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000306 return sb_breakpoint;
307}
308
309
310bool
311SBTarget::BreakpointDelete (break_id_t bp_id)
312{
Greg Clayton63094e02010-06-23 01:19:29 +0000313 if (m_opaque_sp)
314 return m_opaque_sp->RemoveBreakpointByID (bp_id);
Chris Lattner24943d22010-06-08 16:52:24 +0000315 return false;
316}
317
318bool
319SBTarget::EnableAllBreakpoints ()
320{
Greg Clayton63094e02010-06-23 01:19:29 +0000321 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000322 {
Greg Clayton63094e02010-06-23 01:19:29 +0000323 m_opaque_sp->EnableAllBreakpoints ();
Chris Lattner24943d22010-06-08 16:52:24 +0000324 return true;
325 }
326 return false;
327}
328
329bool
330SBTarget::DisableAllBreakpoints ()
331{
Greg Clayton63094e02010-06-23 01:19:29 +0000332 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000333 {
Greg Clayton63094e02010-06-23 01:19:29 +0000334 m_opaque_sp->DisableAllBreakpoints ();
Chris Lattner24943d22010-06-08 16:52:24 +0000335 return true;
336 }
337 return false;
338}
339
340bool
341SBTarget::DeleteAllBreakpoints ()
342{
Greg Clayton63094e02010-06-23 01:19:29 +0000343 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000344 {
Greg Clayton63094e02010-06-23 01:19:29 +0000345 m_opaque_sp->RemoveAllBreakpoints ();
Chris Lattner24943d22010-06-08 16:52:24 +0000346 return true;
347 }
348 return false;
349}
350
351
352uint32_t
353SBTarget::GetNumModules () const
354{
Greg Clayton63094e02010-06-23 01:19:29 +0000355 if (m_opaque_sp)
356 return m_opaque_sp->GetImages().GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000357 return 0;
358}
359
360SBModule
361SBTarget::FindModule (const SBFileSpec &sb_file_spec)
362{
363 SBModule sb_module;
Greg Clayton63094e02010-06-23 01:19:29 +0000364 if (m_opaque_sp && sb_file_spec.IsValid())
365 sb_module.SetModule (m_opaque_sp->GetImages().FindFirstModuleForFileSpec (*sb_file_spec, NULL));
Chris Lattner24943d22010-06-08 16:52:24 +0000366 return sb_module;
367}
368
369SBModule
370SBTarget::GetModuleAtIndex (uint32_t idx)
371{
372 SBModule sb_module;
Greg Clayton63094e02010-06-23 01:19:29 +0000373 if (m_opaque_sp)
374 sb_module.SetModule(m_opaque_sp->GetImages().GetModuleAtIndex(idx));
Chris Lattner24943d22010-06-08 16:52:24 +0000375 return sb_module;
376}
377
378
379SBBroadcaster
380SBTarget::GetBroadcaster () const
381{
Greg Clayton63094e02010-06-23 01:19:29 +0000382 SBBroadcaster broadcaster(m_opaque_sp.get(), false);
Chris Lattner24943d22010-06-08 16:52:24 +0000383 return broadcaster;
384}
385
386void
387SBTarget::Disassemble (lldb::addr_t file_address_start, lldb::addr_t file_address_end, const char *module_name)
388{
389 if (file_address_start == LLDB_INVALID_ADDRESS)
390 return;
391
Greg Clayton63094e02010-06-23 01:19:29 +0000392 FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000393 if (out == NULL)
394 return;
395
Greg Clayton63094e02010-06-23 01:19:29 +0000396 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000397 {
398 SBModule module;
399 if (module_name != NULL)
400 {
401 SBFileSpec file_spec (module_name);
402 module = FindModule (file_spec);
403 }
Greg Clayton63094e02010-06-23 01:19:29 +0000404 ArchSpec arch (m_opaque_sp->GetArchitecture());
Chris Lattner24943d22010-06-08 16:52:24 +0000405 if (!arch.IsValid())
406 return;
407 Disassembler *disassembler = Disassembler::FindPlugin (arch);
408 if (disassembler == NULL)
409 return;
410
411 // For now, we need a process; the disassembly functions insist. If we don't have one already,
412 // make one.
413
414 SBProcess process = GetProcess();
415 if (! process.IsValid())
416 process = CreateProcess();
417
418 ExecutionContext exe_context (process.get());
419
420 if (file_address_end == LLDB_INVALID_ADDRESS
421 || file_address_end < file_address_start)
422 file_address_end = file_address_start + DEFAULT_DISASM_BYTE_SIZE;
423
424 // TO BE FIXED: SOMEHOW WE NEED TO SPECIFY/USE THE MODULE, IF THE USER SPECIFIED ONE. I'M NOT
425 // SURE HOW TO DO THAT AT THE MOMENT. WE ALSO NEED TO FIGURE OUT WHAT TO DO IF THERE ARE MULTIPLE
426 // MODULES CONTAINING THE SPECIFIED ADDRESSES (E.G. THEY HAVEN'T ALL LOADED & BEEN GIVEN UNIQUE
427 // ADDRESSES YET).
428
429 DataExtractor data;
430 size_t bytes_disassembled = disassembler->ParseInstructions (&exe_context, eAddressTypeLoad,
431 file_address_start,
432 file_address_end - file_address_start, data);
433
434 if (bytes_disassembled > 0)
435 {
436 size_t num_instructions = disassembler->GetInstructionList().GetSize();
437 uint32_t offset = 0;
438 StreamFile out_stream (out);
439
440 for (size_t i = 0; i < num_instructions; ++i)
441 {
442 Disassembler::Instruction *inst = disassembler->GetInstructionList().GetInstructionAtIndex (i);
443 if (inst)
444 {
445 lldb::addr_t cur_addr = file_address_start + offset;
446 size_t inst_byte_size = inst->GetByteSize();
447 inst->Dump (&out_stream, cur_addr, &data, offset, exe_context, false);
448 out_stream.EOL();
449 offset += inst_byte_size;
450 }
451 }
452 }
453 }
454}
455
456void
457SBTarget::Disassemble (const char *function_name, const char *module_name)
458{
459 if (function_name == NULL)
460 return;
461
Greg Clayton63094e02010-06-23 01:19:29 +0000462 FILE *out = m_opaque_sp->GetDebugger().GetOutputFileHandle();
Chris Lattner24943d22010-06-08 16:52:24 +0000463 if (out == NULL)
464 return;
465
Greg Clayton63094e02010-06-23 01:19:29 +0000466 if (m_opaque_sp)
Chris Lattner24943d22010-06-08 16:52:24 +0000467 {
468 SBModule module;
469
470 if (module_name != NULL)
471 {
472 SBFileSpec file_spec (module_name);
473 module = FindModule (file_spec);
474 }
475
Greg Clayton63094e02010-06-23 01:19:29 +0000476 ArchSpec arch (m_opaque_sp->GetArchitecture());
Chris Lattner24943d22010-06-08 16:52:24 +0000477 if (!arch.IsValid())
478 return;
479
480 Disassembler *disassembler = Disassembler::FindPlugin (arch);
481 if (disassembler == NULL)
482 return;
483
484 // For now, we need a process; the disassembly functions insist. If we don't have one already,
485 // make one.
486
487 SBProcess process = GetProcess();
488 if (! process.IsValid()
489 || process.GetProcessID() == 0)
490 {
491 fprintf (out, "Cannot disassemble functions until after process has launched.\n");
492 return;
493 }
494
495 ExecutionContext exe_context (process.get());
496
497 FileSpec *containing_module = NULL;
498
499 if (module_name != NULL)
500 containing_module = new FileSpec (module_name);
501
Greg Clayton63094e02010-06-23 01:19:29 +0000502 SearchFilterSP filter_sp (m_opaque_sp->GetSearchFilterForModule (containing_module));
Chris Lattner24943d22010-06-08 16:52:24 +0000503 AddressResolverSP resolver_sp (new AddressResolverName (function_name));
504
505 resolver_sp->ResolveAddress (*filter_sp);
506
507 size_t num_matches_found = resolver_sp->GetNumberOfAddresses();
508
509 if (num_matches_found == 1)
510 {
511 DataExtractor data;
512
513 AddressRange func_addresses = resolver_sp->GetAddressRangeAtIndex (0);
514 Address start_addr = func_addresses.GetBaseAddress();
515 lldb::addr_t num_bytes = func_addresses.GetByteSize();
516
517 lldb::addr_t addr = LLDB_INVALID_ADDRESS;
518 size_t bytes_disassembled = 0;
519
520
521 if (process.GetProcessID() == 0)
522 {
523 // Leave this branch in for now, but it should not be reached, since we exit above if the PID is 0.
524 addr = start_addr.GetFileAddress ();
525 bytes_disassembled = disassembler->ParseInstructions (&exe_context, eAddressTypeFile, addr,
526 num_bytes, data);
527
528 }
529 else
530 {
531 addr = start_addr.GetLoadAddress (process.get());
532 bytes_disassembled = disassembler->ParseInstructions (&exe_context, eAddressTypeLoad, addr,
533 num_bytes, data);
534
535 }
536
537 if (bytes_disassembled > 0)
538 {
539 size_t num_instructions = disassembler->GetInstructionList().GetSize();
540 uint32_t offset = 0;
541 StreamFile out_stream (out);
542
543 for (size_t i = 0; i < num_instructions; ++i)
544 {
545 Disassembler::Instruction *inst = disassembler->GetInstructionList().GetInstructionAtIndex (i);
546 if (inst)
547 {
548 lldb::addr_t cur_addr = addr + offset;
549 size_t inst_byte_size = inst->GetByteSize();
550 inst->Dump (&out_stream, cur_addr, &data, offset, exe_context, false);
551 out_stream.EOL();
552 offset += inst_byte_size;
553 }
554 }
555 }
556 }
557 else if (num_matches_found > 1)
558 {
559 // TO BE FIXED: Eventually we want to list/disassemble all functions found.
560 fprintf (out, "Function '%s' was found in multiple modules; please specify the desired module name.\n",
561 function_name);
562 }
563 else
564 fprintf (out, "Function '%s' was not found.\n", function_name);
565 }
566}