blob: fdff5ad3818cd623ad71f00ee0794a33f1051f91 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- Target.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#include "lldb/Target/Target.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Breakpoint/BreakpointResolver.h"
17#include "lldb/Breakpoint/BreakpointResolverAddress.h"
18#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
19#include "lldb/Breakpoint/BreakpointResolverName.h"
20#include "lldb/Core/Event.h"
21#include "lldb/Core/Log.h"
22#include "lldb/Core/Timer.h"
23#include "lldb/Core/StreamString.h"
24#include "lldb/Host/Host.h"
25#include "lldb/lldb-private-log.h"
26#include "lldb/Symbol/ObjectFile.h"
27#include "lldb/Target/Process.h"
28#include "lldb/Core/Debugger.h"
29
30using namespace lldb;
31using namespace lldb_private;
32
33//----------------------------------------------------------------------
34// Target constructor
35//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +000036Target::Target(Debugger &debugger) :
Chris Lattner24943d22010-06-08 16:52:24 +000037 Broadcaster("Target"),
Greg Clayton63094e02010-06-23 01:19:29 +000038 m_debugger (debugger),
Chris Lattner24943d22010-06-08 16:52:24 +000039 m_images(),
40 m_breakpoint_list (false),
41 m_internal_breakpoint_list (true),
42 m_process_sp(),
43 m_triple(),
44 m_search_filter_sp(),
45 m_image_search_paths (ImageSearchPathsChanged, this),
46 m_scratch_ast_context_ap(NULL)
47{
48 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
49 if (log)
50 log->Printf ("%p Target::Target()", this);
51}
52
53//----------------------------------------------------------------------
54// Destructor
55//----------------------------------------------------------------------
56Target::~Target()
57{
58 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
59 if (log)
60 log->Printf ("%p Target::~Target()", this);
61 DeleteCurrentProcess ();
62}
63
64void
65Target::Dump (Stream *s)
66{
67 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
68 s->Indent();
69 s->PutCString("Target\n");
70 s->IndentMore();
71 m_images.Dump(s);
72 m_breakpoint_list.Dump(s);
73 m_internal_breakpoint_list.Dump(s);
74// if (m_process_sp.get())
75// m_process_sp->Dump(s);
76 s->IndentLess();
77}
78
79void
80Target::DeleteCurrentProcess ()
81{
82 if (m_process_sp.get())
83 {
84 if (m_process_sp->IsAlive())
85 m_process_sp->Destroy();
86 else
87 m_process_sp->Finalize();
88
89 // Do any cleanup of the target we need to do between process instances.
90 // NB It is better to do this before destroying the process in case the
91 // clean up needs some help from the process.
92 m_breakpoint_list.ClearAllBreakpointSites();
93 m_internal_breakpoint_list.ClearAllBreakpointSites();
94 m_process_sp.reset();
95 }
96}
97
98const lldb::ProcessSP &
99Target::CreateProcess (Listener &listener, const char *plugin_name)
100{
101 DeleteCurrentProcess ();
102 m_process_sp.reset(Process::FindPlugin(*this, plugin_name, listener));
103 return m_process_sp;
104}
105
106const lldb::ProcessSP &
107Target::GetProcessSP () const
108{
109 return m_process_sp;
110}
111
112lldb::TargetSP
113Target::GetSP()
114{
Greg Clayton63094e02010-06-23 01:19:29 +0000115 return m_debugger.GetTargetList().GetTargetSP(this);
Chris Lattner24943d22010-06-08 16:52:24 +0000116}
117
118BreakpointList &
119Target::GetBreakpointList(bool internal)
120{
121 if (internal)
122 return m_internal_breakpoint_list;
123 else
124 return m_breakpoint_list;
125}
126
127const BreakpointList &
128Target::GetBreakpointList(bool internal) const
129{
130 if (internal)
131 return m_internal_breakpoint_list;
132 else
133 return m_breakpoint_list;
134}
135
136BreakpointSP
137Target::GetBreakpointByID (break_id_t break_id)
138{
139 BreakpointSP bp_sp;
140
141 if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
142 bp_sp = m_internal_breakpoint_list.FindBreakpointByID (break_id);
143 else
144 bp_sp = m_breakpoint_list.FindBreakpointByID (break_id);
145
146 return bp_sp;
147}
148
149BreakpointSP
150Target::CreateBreakpoint (const FileSpec *containingModule, const FileSpec &file, uint32_t line_no, bool check_inlines, bool internal)
151{
152 SearchFilterSP filter_sp(GetSearchFilterForModule (containingModule));
153 BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine (NULL, file, line_no, check_inlines));
154 return CreateBreakpoint (filter_sp, resolver_sp, internal);
155}
156
157
158BreakpointSP
159Target::CreateBreakpoint (lldb::addr_t load_addr, bool internal)
160{
161 BreakpointSP bp_sp;
162 Address so_addr;
163 // Attempt to resolve our load address if possible, though it is ok if
164 // it doesn't resolve to section/offset.
165
166 Process *process = GetProcessSP().get();
167 if (process && process->ResolveLoadAddress(load_addr, so_addr))
168 bp_sp = CreateBreakpoint(so_addr, internal);
169 return bp_sp;
170}
171
172BreakpointSP
173Target::CreateBreakpoint (Address &addr, bool internal)
174{
175 TargetSP target_sp = this->GetSP();
176 SearchFilterSP filter_sp(new SearchFilter (target_sp));
177 BreakpointResolverSP resolver_sp (new BreakpointResolverAddress (NULL, addr));
178 return CreateBreakpoint (filter_sp, resolver_sp, internal);
179}
180
181BreakpointSP
Greg Clayton12bec712010-06-28 21:30:43 +0000182Target::CreateBreakpoint (FileSpec *containingModule, const char *func_name, uint32_t func_name_type_mask, bool internal)
Chris Lattner24943d22010-06-08 16:52:24 +0000183{
Greg Clayton12bec712010-06-28 21:30:43 +0000184 BreakpointSP bp_sp;
185 if (func_name)
186 {
187 SearchFilterSP filter_sp(GetSearchFilterForModule (containingModule));
188 BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL, func_name, func_name_type_mask, Breakpoint::Exact));
189 bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal);
190 }
191 return bp_sp;
Chris Lattner24943d22010-06-08 16:52:24 +0000192}
193
194
195SearchFilterSP
196Target::GetSearchFilterForModule (const FileSpec *containingModule)
197{
198 SearchFilterSP filter_sp;
199 lldb::TargetSP target_sp = this->GetSP();
200 if (containingModule != NULL)
201 {
202 // TODO: We should look into sharing module based search filters
203 // across many breakpoints like we do for the simple target based one
204 filter_sp.reset (new SearchFilterByModule (target_sp, *containingModule));
205 }
206 else
207 {
208 if (m_search_filter_sp.get() == NULL)
209 m_search_filter_sp.reset (new SearchFilter (target_sp));
210 filter_sp = m_search_filter_sp;
211 }
212 return filter_sp;
213}
214
215BreakpointSP
216Target::CreateBreakpoint (FileSpec *containingModule, RegularExpression &func_regex, bool internal)
217{
218 SearchFilterSP filter_sp(GetSearchFilterForModule (containingModule));
219 BreakpointResolverSP resolver_sp(new BreakpointResolverName (NULL, func_regex));
220
221 return CreateBreakpoint (filter_sp, resolver_sp, internal);
222}
223
224BreakpointSP
225Target::CreateBreakpoint (SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp, bool internal)
226{
227 BreakpointSP bp_sp;
228 if (filter_sp && resolver_sp)
229 {
230 bp_sp.reset(new Breakpoint (*this, filter_sp, resolver_sp));
231 resolver_sp->SetBreakpoint (bp_sp.get());
232
233 if (internal)
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000234 m_internal_breakpoint_list.Add (bp_sp, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000235 else
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000236 m_breakpoint_list.Add (bp_sp, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000237
238 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
239 if (log)
240 {
241 StreamString s;
242 bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
243 log->Printf ("Target::%s (internal = %s) => break_id = %s\n", __FUNCTION__, internal ? "yes" : "no", s.GetData());
244 }
245
Chris Lattner24943d22010-06-08 16:52:24 +0000246 bp_sp->ResolveBreakpoint();
247 }
248 return bp_sp;
249}
250
251void
252Target::RemoveAllBreakpoints (bool internal_also)
253{
254 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
255 if (log)
256 log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
257
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000258 m_breakpoint_list.RemoveAll (true);
Chris Lattner24943d22010-06-08 16:52:24 +0000259 if (internal_also)
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000260 m_internal_breakpoint_list.RemoveAll (false);
Chris Lattner24943d22010-06-08 16:52:24 +0000261}
262
263void
264Target::DisableAllBreakpoints (bool internal_also)
265{
266 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
267 if (log)
268 log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
269
270 m_breakpoint_list.SetEnabledAll (false);
271 if (internal_also)
272 m_internal_breakpoint_list.SetEnabledAll (false);
273}
274
275void
276Target::EnableAllBreakpoints (bool internal_also)
277{
278 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
279 if (log)
280 log->Printf ("Target::%s (internal_also = %s)\n", __FUNCTION__, internal_also ? "yes" : "no");
281
282 m_breakpoint_list.SetEnabledAll (true);
283 if (internal_also)
284 m_internal_breakpoint_list.SetEnabledAll (true);
285}
286
287bool
288Target::RemoveBreakpointByID (break_id_t break_id)
289{
290 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
291 if (log)
292 log->Printf ("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, break_id, LLDB_BREAK_ID_IS_INTERNAL (break_id) ? "yes" : "no");
293
294 if (DisableBreakpointByID (break_id))
295 {
296 if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000297 m_internal_breakpoint_list.Remove(break_id, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000298 else
Greg Claytonc7f5d5c2010-07-23 23:33:17 +0000299 m_breakpoint_list.Remove(break_id, true);
Chris Lattner24943d22010-06-08 16:52:24 +0000300 return true;
301 }
302 return false;
303}
304
305bool
306Target::DisableBreakpointByID (break_id_t break_id)
307{
308 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
309 if (log)
310 log->Printf ("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, break_id, LLDB_BREAK_ID_IS_INTERNAL (break_id) ? "yes" : "no");
311
312 BreakpointSP bp_sp;
313
314 if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
315 bp_sp = m_internal_breakpoint_list.FindBreakpointByID (break_id);
316 else
317 bp_sp = m_breakpoint_list.FindBreakpointByID (break_id);
318 if (bp_sp)
319 {
320 bp_sp->SetEnabled (false);
321 return true;
322 }
323 return false;
324}
325
326bool
327Target::EnableBreakpointByID (break_id_t break_id)
328{
329 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
330 if (log)
331 log->Printf ("Target::%s (break_id = %i, internal = %s)\n",
332 __FUNCTION__,
333 break_id,
334 LLDB_BREAK_ID_IS_INTERNAL (break_id) ? "yes" : "no");
335
336 BreakpointSP bp_sp;
337
338 if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
339 bp_sp = m_internal_breakpoint_list.FindBreakpointByID (break_id);
340 else
341 bp_sp = m_breakpoint_list.FindBreakpointByID (break_id);
342
343 if (bp_sp)
344 {
345 bp_sp->SetEnabled (true);
346 return true;
347 }
348 return false;
349}
350
351ModuleSP
352Target::GetExecutableModule ()
353{
354 ModuleSP executable_sp;
355 if (m_images.GetSize() > 0)
356 executable_sp = m_images.GetModuleAtIndex(0);
357 return executable_sp;
358}
359
360void
361Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
362{
363 m_images.Clear();
364 m_scratch_ast_context_ap.reset();
365
366 if (executable_sp.get())
367 {
368 Timer scoped_timer (__PRETTY_FUNCTION__,
369 "Target::SetExecutableModule (executable = '%s/%s')",
370 executable_sp->GetFileSpec().GetDirectory().AsCString(),
371 executable_sp->GetFileSpec().GetFilename().AsCString());
372
373 m_images.Append(executable_sp); // The first image is our exectuable file
374
375 ArchSpec exe_arch = executable_sp->GetArchitecture();
376 FileSpecList dependent_files;
377 ObjectFile * executable_objfile = executable_sp->GetObjectFile();
378 if (executable_objfile == NULL)
379 {
380
381 FileSpec bundle_executable(executable_sp->GetFileSpec());
382 if (Host::ResolveExecutableInBundle (&bundle_executable))
383 {
384 ModuleSP bundle_exe_module_sp(GetSharedModule(bundle_executable,
385 exe_arch));
386 SetExecutableModule (bundle_exe_module_sp, get_dependent_files);
387 if (bundle_exe_module_sp->GetObjectFile() != NULL)
388 executable_sp = bundle_exe_module_sp;
389 return;
390 }
391 }
392
393 if (executable_objfile)
394 {
395 executable_objfile->GetDependentModules(dependent_files);
396 for (uint32_t i=0; i<dependent_files.GetSize(); i++)
397 {
398 ModuleSP image_module_sp(GetSharedModule(dependent_files.GetFileSpecPointerAtIndex(i),
399 exe_arch));
400 if (image_module_sp.get())
401 {
402 //image_module_sp->Dump(&s);// REMOVE THIS, DEBUG ONLY
403 ObjectFile *objfile = image_module_sp->GetObjectFile();
404 if (objfile)
405 objfile->GetDependentModules(dependent_files);
406 }
407 }
408 }
409
410 // Now see if we know the target triple, and if so, create our scratch AST context:
411 ConstString target_triple;
412 if (GetTargetTriple(target_triple))
413 {
414 m_scratch_ast_context_ap.reset (new ClangASTContext(target_triple.GetCString()));
415 }
416 }
417}
418
419
420ModuleList&
421Target::GetImages ()
422{
423 return m_images;
424}
425
426ArchSpec
427Target::GetArchitecture () const
428{
429 ArchSpec arch;
430 if (m_images.GetSize() > 0)
431 {
432 Module *exe_module = m_images.GetModulePointerAtIndex(0);
433 if (exe_module)
434 arch = exe_module->GetArchitecture();
435 }
436 return arch;
437}
438
439
440
441bool
442Target::GetTargetTriple(ConstString &triple)
443{
444 triple.Clear();
445
446 if (m_triple)
447 {
448 triple = m_triple;
449 }
450 else
451 {
452 Module *exe_module = GetExecutableModule().get();
453 if (exe_module)
454 {
455 ObjectFile *objfile = exe_module->GetObjectFile();
456 if (objfile)
457 {
458 objfile->GetTargetTriple(m_triple);
459 triple = m_triple;
460 }
461 }
462 }
463 return !triple.IsEmpty();
464}
465
466void
467Target::ModuleAdded (ModuleSP &module_sp)
468{
469 // A module is being added to this target for the first time
470 ModuleList module_list;
471 module_list.Append(module_sp);
472 ModulesDidLoad (module_list);
473}
474
475void
476Target::ModuleUpdated (ModuleSP &old_module_sp, ModuleSP &new_module_sp)
477{
478 // A module is being added to this target for the first time
479 ModuleList module_list;
480 module_list.Append (old_module_sp);
481 ModulesDidUnload (module_list);
482 module_list.Clear ();
483 module_list.Append (new_module_sp);
484 ModulesDidLoad (module_list);
485}
486
487void
488Target::ModulesDidLoad (ModuleList &module_list)
489{
490 m_breakpoint_list.UpdateBreakpoints (module_list, true);
491 // TODO: make event data that packages up the module_list
492 BroadcastEvent (eBroadcastBitModulesLoaded, NULL);
493}
494
495void
496Target::ModulesDidUnload (ModuleList &module_list)
497{
498 m_breakpoint_list.UpdateBreakpoints (module_list, false);
499 // TODO: make event data that packages up the module_list
500 BroadcastEvent (eBroadcastBitModulesUnloaded, NULL);
501}
502
503size_t
Greg Clayton2cf6e9e2010-06-30 23:04:24 +0000504Target::ReadMemory (const Address& addr, void *dst, size_t dst_len, Error &error)
Chris Lattner24943d22010-06-08 16:52:24 +0000505{
Chris Lattner24943d22010-06-08 16:52:24 +0000506 error.Clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000507
Greg Clayton70436352010-06-30 23:03:03 +0000508 bool process_is_valid = m_process_sp && m_process_sp->IsAlive();
509
510 Address resolved_addr(addr);
511 if (!resolved_addr.IsSectionOffset())
512 {
513 if (process_is_valid)
Chris Lattner24943d22010-06-08 16:52:24 +0000514 {
Greg Clayton70436352010-06-30 23:03:03 +0000515 m_process_sp->ResolveLoadAddress (addr.GetOffset(), resolved_addr);
516 }
517 else
518 {
519 m_images.ResolveFileAddress(addr.GetOffset(), resolved_addr);
520 }
521 }
522
523
524 if (process_is_valid)
525 {
526 lldb::addr_t load_addr = resolved_addr.GetLoadAddress(m_process_sp.get());
527 if (load_addr == LLDB_INVALID_ADDRESS)
528 {
529 if (resolved_addr.GetModule() && resolved_addr.GetModule()->GetFileSpec())
530 error.SetErrorStringWithFormat("%s[0x%llx] can't be resolved, %s in not currently loaded.\n",
531 resolved_addr.GetModule()->GetFileSpec().GetFilename().AsCString(),
532 resolved_addr.GetFileAddress());
533 else
534 error.SetErrorStringWithFormat("0x%llx can't be resolved.\n", resolved_addr.GetFileAddress());
535 }
536 else
537 {
538 size_t bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);
Chris Lattner24943d22010-06-08 16:52:24 +0000539 if (bytes_read != dst_len)
540 {
541 if (error.Success())
542 {
543 if (bytes_read == 0)
Greg Clayton70436352010-06-30 23:03:03 +0000544 error.SetErrorStringWithFormat("Read memory from 0x%llx failed.\n", load_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000545 else
Greg Clayton70436352010-06-30 23:03:03 +0000546 error.SetErrorStringWithFormat("Only %zu of %zu bytes were read from memory at 0x%llx.\n", bytes_read, dst_len, load_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000547 }
548 }
Greg Clayton70436352010-06-30 23:03:03 +0000549 if (bytes_read)
550 return bytes_read;
551 // If the address is not section offset we have an address that
552 // doesn't resolve to any address in any currently loaded shared
553 // libaries and we failed to read memory so there isn't anything
554 // more we can do. If it is section offset, we might be able to
555 // read cached memory from the object file.
556 if (!resolved_addr.IsSectionOffset())
557 return 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000558 }
Chris Lattner24943d22010-06-08 16:52:24 +0000559 }
Greg Clayton70436352010-06-30 23:03:03 +0000560
561 const Section *section = resolved_addr.GetSection();
562 if (section && section->GetModule())
563 {
564 ObjectFile *objfile = section->GetModule()->GetObjectFile();
565 return section->ReadSectionDataFromObjectFile (objfile,
566 resolved_addr.GetOffset(),
567 dst,
568 dst_len);
569 }
570 return 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000571}
572
573
574ModuleSP
575Target::GetSharedModule
576(
577 const FileSpec& file_spec,
578 const ArchSpec& arch,
579 const UUID *uuid_ptr,
580 const ConstString *object_name,
581 off_t object_offset,
582 Error *error_ptr
583)
584{
585 // Don't pass in the UUID so we can tell if we have a stale value in our list
586 ModuleSP old_module_sp; // This will get filled in if we have a new version of the library
587 bool did_create_module = false;
588 ModuleSP module_sp;
589
590 // If there are image search path entries, try to use them first to acquire a suitable image.
591
592 Error error;
593
594 if (m_image_search_paths.GetSize())
595 {
596 FileSpec transformed_spec;
597 if (m_image_search_paths.RemapPath (file_spec.GetDirectory(), transformed_spec.GetDirectory()))
598 {
599 transformed_spec.GetFilename() = file_spec.GetFilename();
600 error = ModuleList::GetSharedModule (transformed_spec, arch, uuid_ptr, object_name, object_offset, module_sp, &old_module_sp, &did_create_module);
601 }
602 }
603
604 // If a module hasn't been found yet, use the unmodified path.
605
606 if (!module_sp)
607 {
608 error = (ModuleList::GetSharedModule (file_spec, arch, uuid_ptr, object_name, object_offset, module_sp, &old_module_sp, &did_create_module));
609 }
610
611 if (module_sp)
612 {
613 m_images.Append (module_sp);
614 if (did_create_module)
615 {
616 if (old_module_sp && m_images.GetIndexForModule (old_module_sp.get()) != LLDB_INVALID_INDEX32)
617 ModuleUpdated(old_module_sp, module_sp);
618 else
619 ModuleAdded(module_sp);
620 }
621 }
622 if (error_ptr)
623 *error_ptr = error;
624 return module_sp;
625}
626
627
628Target *
629Target::CalculateTarget ()
630{
631 return this;
632}
633
634Process *
635Target::CalculateProcess ()
636{
637 return NULL;
638}
639
640Thread *
641Target::CalculateThread ()
642{
643 return NULL;
644}
645
646StackFrame *
647Target::CalculateStackFrame ()
648{
649 return NULL;
650}
651
652void
653Target::Calculate (ExecutionContext &exe_ctx)
654{
655 exe_ctx.target = this;
656 exe_ctx.process = NULL; // Do NOT fill in process...
657 exe_ctx.thread = NULL;
658 exe_ctx.frame = NULL;
659}
660
661PathMappingList &
662Target::GetImageSearchPathList ()
663{
664 return m_image_search_paths;
665}
666
667void
668Target::ImageSearchPathsChanged
669(
670 const PathMappingList &path_list,
671 void *baton
672)
673{
674 Target *target = (Target *)baton;
675 if (target->m_images.GetSize() > 1)
676 {
677 ModuleSP exe_module_sp (target->GetExecutableModule());
678 if (exe_module_sp)
679 {
680 target->m_images.Clear();
681 target->SetExecutableModule (exe_module_sp, true);
682 }
683 }
684}
685
686ClangASTContext *
687Target::GetScratchClangASTContext()
688{
689 return m_scratch_ast_context_ap.get();
690}