1 //===-- PlatformDarwin.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/lldb-python.h"
11
12 #include "PlatformDarwin.h"
13
14 // C Includes
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/Breakpoint/BreakpointLocation.h"
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Core/Error.h"
21 #include "lldb/Core/Module.h"
22 #include "lldb/Core/ModuleSpec.h"
23 #include "lldb/Core/Timer.h"
24 #include "lldb/Host/Host.h"
25 #include "lldb/Host/Symbols.h"
26 #include "lldb/Symbol/ObjectFile.h"
27 #include "lldb/Symbol/SymbolFile.h"
28 #include "lldb/Symbol/SymbolVendor.h"
29 #include "lldb/Target/Target.h"
30
31 using namespace lldb;
32 using namespace lldb_private;
33
34
35 //------------------------------------------------------------------
36 /// Default Constructor
37 //------------------------------------------------------------------
PlatformDarwin(bool is_host)38 PlatformDarwin::PlatformDarwin (bool is_host) :
39 Platform(is_host), // This is the local host platform
40 m_remote_platform_sp (),
41 m_developer_directory ()
42 {
43 }
44
45 //------------------------------------------------------------------
46 /// Destructor.
47 ///
48 /// The destructor is virtual since this class is designed to be
49 /// inherited from by the plug-in instance.
50 //------------------------------------------------------------------
~PlatformDarwin()51 PlatformDarwin::~PlatformDarwin()
52 {
53 }
54
55 FileSpecList
LocateExecutableScriptingResources(Target * target,Module & module)56 PlatformDarwin::LocateExecutableScriptingResources (Target *target,
57 Module &module)
58 {
59 FileSpecList file_list;
60 if (target && target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython)
61 {
62 // NB some extensions might be meaningful and should not be stripped - "this.binary.file"
63 // should not lose ".file" but GetFileNameStrippingExtension() will do precisely that.
64 // Ideally, we should have a per-platform list of extensions (".exe", ".app", ".dSYM", ".framework")
65 // which should be stripped while leaving "this.binary.file" as-is.
66 FileSpec module_spec = module.GetFileSpec();
67
68 if (module_spec)
69 {
70 SymbolVendor *symbols = module.GetSymbolVendor ();
71 if (symbols)
72 {
73 SymbolFile *symfile = symbols->GetSymbolFile();
74 if (symfile)
75 {
76 ObjectFile *objfile = symfile->GetObjectFile();
77 if (objfile)
78 {
79 FileSpec symfile_spec (objfile->GetFileSpec());
80 if (symfile_spec && symfile_spec.Exists())
81 {
82 while (module_spec.GetFilename())
83 {
84 std::string module_basename (module_spec.GetFilename().GetCString());
85
86 // FIXME: for Python, we cannot allow certain characters in module
87 // filenames we import. Theoretically, different scripting languages may
88 // have different sets of forbidden tokens in filenames, and that should
89 // be dealt with by each ScriptInterpreter. For now, we just replace dots
90 // with underscores, but if we ever support anything other than Python
91 // we will need to rework this
92 std::replace(module_basename.begin(), module_basename.end(), '.', '_');
93 std::replace(module_basename.begin(), module_basename.end(), ' ', '_');
94 std::replace(module_basename.begin(), module_basename.end(), '-', '_');
95
96
97 StreamString path_string;
98 // for OSX we are going to be in .dSYM/Contents/Resources/DWARF/<basename>
99 // let us go to .dSYM/Contents/Resources/Python/<basename>.py and see if the file exists
100 path_string.Printf("%s/../Python/%s.py",symfile_spec.GetDirectory().GetCString(), module_basename.c_str());
101 FileSpec script_fspec(path_string.GetData(), true);
102 if (script_fspec.Exists())
103 {
104 file_list.Append (script_fspec);
105 break;
106 }
107
108 // If we didn't find the python file, then keep
109 // stripping the extensions and try again
110 ConstString filename_no_extension (module_spec.GetFileNameStrippingExtension());
111 if (module_spec.GetFilename() == filename_no_extension)
112 break;
113
114 module_spec.GetFilename() = filename_no_extension;
115 }
116 }
117 }
118 }
119 }
120 }
121 }
122 return file_list;
123 }
124
125 Error
ResolveExecutable(const FileSpec & exe_file,const ArchSpec & exe_arch,lldb::ModuleSP & exe_module_sp,const FileSpecList * module_search_paths_ptr)126 PlatformDarwin::ResolveExecutable (const FileSpec &exe_file,
127 const ArchSpec &exe_arch,
128 lldb::ModuleSP &exe_module_sp,
129 const FileSpecList *module_search_paths_ptr)
130 {
131 Error error;
132 // Nothing special to do here, just use the actual file and architecture
133
134 char exe_path[PATH_MAX];
135 FileSpec resolved_exe_file (exe_file);
136
137 if (IsHost())
138 {
139 // If we have "ls" as the exe_file, resolve the executable loation based on
140 // the current path variables
141 if (!resolved_exe_file.Exists())
142 {
143 exe_file.GetPath (exe_path, sizeof(exe_path));
144 resolved_exe_file.SetFile(exe_path, true);
145 }
146
147 if (!resolved_exe_file.Exists())
148 resolved_exe_file.ResolveExecutableLocation ();
149
150 // Resolve any executable within a bundle on MacOSX
151 Host::ResolveExecutableInBundle (resolved_exe_file);
152
153 if (resolved_exe_file.Exists())
154 error.Clear();
155 else
156 {
157 exe_file.GetPath (exe_path, sizeof(exe_path));
158 error.SetErrorStringWithFormat ("unable to find executable for '%s'", exe_path);
159 }
160 }
161 else
162 {
163 if (m_remote_platform_sp)
164 {
165 error = m_remote_platform_sp->ResolveExecutable (exe_file,
166 exe_arch,
167 exe_module_sp,
168 module_search_paths_ptr);
169 }
170 else
171 {
172 // We may connect to a process and use the provided executable (Don't use local $PATH).
173
174 // Resolve any executable within a bundle on MacOSX
175 Host::ResolveExecutableInBundle (resolved_exe_file);
176
177 if (resolved_exe_file.Exists())
178 error.Clear();
179 else
180 error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", resolved_exe_file.GetFilename().AsCString(""));
181 }
182 }
183
184
185 if (error.Success())
186 {
187 ModuleSpec module_spec (resolved_exe_file, exe_arch);
188 if (module_spec.GetArchitecture().IsValid())
189 {
190 error = ModuleList::GetSharedModule (module_spec,
191 exe_module_sp,
192 module_search_paths_ptr,
193 NULL,
194 NULL);
195
196 if (error.Fail() || exe_module_sp.get() == NULL || exe_module_sp->GetObjectFile() == NULL)
197 {
198 exe_module_sp.reset();
199 error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
200 exe_file.GetPath().c_str(),
201 exe_arch.GetArchitectureName());
202 }
203 }
204 else
205 {
206 // No valid architecture was specified, ask the platform for
207 // the architectures that we should be using (in the correct order)
208 // and see if we can find a match that way
209 StreamString arch_names;
210 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
211 {
212 error = ModuleList::GetSharedModule (module_spec,
213 exe_module_sp,
214 module_search_paths_ptr,
215 NULL,
216 NULL);
217 // Did we find an executable using one of the
218 if (error.Success())
219 {
220 if (exe_module_sp && exe_module_sp->GetObjectFile())
221 break;
222 else
223 error.SetErrorToGenericError();
224 }
225
226 if (idx > 0)
227 arch_names.PutCString (", ");
228 arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName());
229 }
230
231 if (error.Fail() || !exe_module_sp)
232 {
233 error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
234 exe_file.GetPath().c_str(),
235 GetPluginName().GetCString(),
236 arch_names.GetString().c_str());
237 }
238 }
239 }
240
241 return error;
242 }
243
244 Error
ResolveSymbolFile(Target & target,const ModuleSpec & sym_spec,FileSpec & sym_file)245 PlatformDarwin::ResolveSymbolFile (Target &target,
246 const ModuleSpec &sym_spec,
247 FileSpec &sym_file)
248 {
249 Error error;
250 sym_file = sym_spec.GetSymbolFileSpec();
251 if (sym_file.Exists())
252 {
253 if (sym_file.GetFileType() == FileSpec::eFileTypeDirectory)
254 {
255 sym_file = Symbols::FindSymbolFileInBundle (sym_file,
256 sym_spec.GetUUIDPtr(),
257 sym_spec.GetArchitecturePtr());
258 }
259 }
260 else
261 {
262 if (sym_spec.GetUUID().IsValid())
263 {
264
265 }
266 }
267 return error;
268
269 }
270
271
272
273 Error
GetSharedModule(const ModuleSpec & module_spec,ModuleSP & module_sp,const FileSpecList * module_search_paths_ptr,ModuleSP * old_module_sp_ptr,bool * did_create_ptr)274 PlatformDarwin::GetSharedModule (const ModuleSpec &module_spec,
275 ModuleSP &module_sp,
276 const FileSpecList *module_search_paths_ptr,
277 ModuleSP *old_module_sp_ptr,
278 bool *did_create_ptr)
279 {
280 Error error;
281 module_sp.reset();
282
283 if (IsRemote())
284 {
285 // If we have a remote platform always, let it try and locate
286 // the shared module first.
287 if (m_remote_platform_sp)
288 {
289 error = m_remote_platform_sp->GetSharedModule (module_spec,
290 module_sp,
291 module_search_paths_ptr,
292 old_module_sp_ptr,
293 did_create_ptr);
294 }
295 }
296
297 if (!module_sp)
298 {
299 // Fall back to the local platform and find the file locally
300 error = Platform::GetSharedModule (module_spec,
301 module_sp,
302 module_search_paths_ptr,
303 old_module_sp_ptr,
304 did_create_ptr);
305
306 const FileSpec &platform_file = module_spec.GetFileSpec();
307 if (!module_sp && module_search_paths_ptr && platform_file)
308 {
309 // We can try to pull off part of the file path up to the bundle
310 // directory level and try any module search paths...
311 FileSpec bundle_directory;
312 if (Host::GetBundleDirectory (platform_file, bundle_directory))
313 {
314 if (platform_file == bundle_directory)
315 {
316 ModuleSpec new_module_spec (module_spec);
317 new_module_spec.GetFileSpec() = bundle_directory;
318 if (Host::ResolveExecutableInBundle (new_module_spec.GetFileSpec()))
319 {
320 Error new_error (Platform::GetSharedModule (new_module_spec,
321 module_sp,
322 NULL,
323 old_module_sp_ptr,
324 did_create_ptr));
325
326 if (module_sp)
327 return new_error;
328 }
329 }
330 else
331 {
332 char platform_path[PATH_MAX];
333 char bundle_dir[PATH_MAX];
334 platform_file.GetPath (platform_path, sizeof(platform_path));
335 const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir));
336 char new_path[PATH_MAX];
337 size_t num_module_search_paths = module_search_paths_ptr->GetSize();
338 for (size_t i=0; i<num_module_search_paths; ++i)
339 {
340 const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path));
341 if (search_path_len < sizeof(new_path))
342 {
343 snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len);
344 FileSpec new_file_spec (new_path, false);
345 if (new_file_spec.Exists())
346 {
347 ModuleSpec new_module_spec (module_spec);
348 new_module_spec.GetFileSpec() = new_file_spec;
349 Error new_error (Platform::GetSharedModule (new_module_spec,
350 module_sp,
351 NULL,
352 old_module_sp_ptr,
353 did_create_ptr));
354
355 if (module_sp)
356 {
357 module_sp->SetPlatformFileSpec(new_file_spec);
358 return new_error;
359 }
360 }
361 }
362 }
363 }
364 }
365 }
366 }
367 if (module_sp)
368 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
369 return error;
370 }
371
372 size_t
GetSoftwareBreakpointTrapOpcode(Target & target,BreakpointSite * bp_site)373 PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
374 {
375 const uint8_t *trap_opcode = NULL;
376 uint32_t trap_opcode_size = 0;
377 bool bp_is_thumb = false;
378
379 llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
380 switch (machine)
381 {
382 case llvm::Triple::x86:
383 case llvm::Triple::x86_64:
384 {
385 static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
386 trap_opcode = g_i386_breakpoint_opcode;
387 trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
388 }
389 break;
390
391 case llvm::Triple::thumb:
392 bp_is_thumb = true; // Fall through...
393 case llvm::Triple::arm:
394 {
395 static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
396 static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE };
397
398 // Auto detect arm/thumb if it wasn't explicitly specified
399 if (!bp_is_thumb)
400 {
401 lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
402 if (bp_loc_sp)
403 bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass () == eAddressClassCodeAlternateISA;
404 }
405 if (bp_is_thumb)
406 {
407 trap_opcode = g_thumb_breakpooint_opcode;
408 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode);
409 break;
410 }
411 trap_opcode = g_arm_breakpoint_opcode;
412 trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
413 }
414 break;
415
416 case llvm::Triple::ppc:
417 case llvm::Triple::ppc64:
418 {
419 static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 };
420 trap_opcode = g_ppc_breakpoint_opcode;
421 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
422 }
423 break;
424
425 default:
426 assert(!"Unhandled architecture in PlatformDarwin::GetSoftwareBreakpointTrapOpcode()");
427 break;
428 }
429
430 if (trap_opcode && trap_opcode_size)
431 {
432 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
433 return trap_opcode_size;
434 }
435 return 0;
436
437 }
438
439 bool
GetRemoteOSVersion()440 PlatformDarwin::GetRemoteOSVersion ()
441 {
442 if (m_remote_platform_sp)
443 return m_remote_platform_sp->GetOSVersion (m_major_os_version,
444 m_minor_os_version,
445 m_update_os_version);
446 return false;
447 }
448
449 bool
GetRemoteOSBuildString(std::string & s)450 PlatformDarwin::GetRemoteOSBuildString (std::string &s)
451 {
452 if (m_remote_platform_sp)
453 return m_remote_platform_sp->GetRemoteOSBuildString (s);
454 s.clear();
455 return false;
456 }
457
458 bool
GetRemoteOSKernelDescription(std::string & s)459 PlatformDarwin::GetRemoteOSKernelDescription (std::string &s)
460 {
461 if (m_remote_platform_sp)
462 return m_remote_platform_sp->GetRemoteOSKernelDescription (s);
463 s.clear();
464 return false;
465 }
466
467 // Remote Platform subclasses need to override this function
468 ArchSpec
GetRemoteSystemArchitecture()469 PlatformDarwin::GetRemoteSystemArchitecture ()
470 {
471 if (m_remote_platform_sp)
472 return m_remote_platform_sp->GetRemoteSystemArchitecture ();
473 return ArchSpec();
474 }
475
476
477 const char *
GetHostname()478 PlatformDarwin::GetHostname ()
479 {
480 if (IsHost())
481 return Platform::GetHostname();
482
483 if (m_remote_platform_sp)
484 return m_remote_platform_sp->GetHostname ();
485 return NULL;
486 }
487
488 bool
IsConnected() const489 PlatformDarwin::IsConnected () const
490 {
491 if (IsHost())
492 return true;
493 else if (m_remote_platform_sp)
494 return m_remote_platform_sp->IsConnected();
495 return false;
496 }
497
498 Error
ConnectRemote(Args & args)499 PlatformDarwin::ConnectRemote (Args& args)
500 {
501 Error error;
502 if (IsHost())
503 {
504 error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString());
505 }
506 else
507 {
508 if (!m_remote_platform_sp)
509 m_remote_platform_sp = Platform::Create ("remote-gdb-server", error);
510
511 if (m_remote_platform_sp)
512 {
513 if (error.Success())
514 {
515 if (m_remote_platform_sp)
516 {
517 error = m_remote_platform_sp->ConnectRemote (args);
518 }
519 else
520 {
521 error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>");
522 }
523 }
524 }
525 else
526 error.SetErrorString ("failed to create a 'remote-gdb-server' platform");
527
528 if (error.Fail())
529 m_remote_platform_sp.reset();
530 }
531
532 return error;
533 }
534
535 Error
DisconnectRemote()536 PlatformDarwin::DisconnectRemote ()
537 {
538 Error error;
539
540 if (IsHost())
541 {
542 error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString());
543 }
544 else
545 {
546 if (m_remote_platform_sp)
547 error = m_remote_platform_sp->DisconnectRemote ();
548 else
549 error.SetErrorString ("the platform is not currently connected");
550 }
551 return error;
552 }
553
554
555 bool
GetProcessInfo(lldb::pid_t pid,ProcessInstanceInfo & process_info)556 PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
557 {
558 bool sucess = false;
559 if (IsHost())
560 {
561 sucess = Platform::GetProcessInfo (pid, process_info);
562 }
563 else
564 {
565 if (m_remote_platform_sp)
566 sucess = m_remote_platform_sp->GetProcessInfo (pid, process_info);
567 }
568 return sucess;
569 }
570
571
572
573 uint32_t
FindProcesses(const ProcessInstanceInfoMatch & match_info,ProcessInstanceInfoList & process_infos)574 PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info,
575 ProcessInstanceInfoList &process_infos)
576 {
577 uint32_t match_count = 0;
578 if (IsHost())
579 {
580 // Let the base class figure out the host details
581 match_count = Platform::FindProcesses (match_info, process_infos);
582 }
583 else
584 {
585 // If we are remote, we can only return results if we are connected
586 if (m_remote_platform_sp)
587 match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos);
588 }
589 return match_count;
590 }
591
592 Error
LaunchProcess(ProcessLaunchInfo & launch_info)593 PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info)
594 {
595 Error error;
596
597 if (IsHost())
598 {
599 error = Platform::LaunchProcess (launch_info);
600 }
601 else
602 {
603 if (m_remote_platform_sp)
604 error = m_remote_platform_sp->LaunchProcess (launch_info);
605 else
606 error.SetErrorString ("the platform is not currently connected");
607 }
608 return error;
609 }
610
611 lldb::ProcessSP
Attach(ProcessAttachInfo & attach_info,Debugger & debugger,Target * target,Listener & listener,Error & error)612 PlatformDarwin::Attach (ProcessAttachInfo &attach_info,
613 Debugger &debugger,
614 Target *target,
615 Listener &listener,
616 Error &error)
617 {
618 lldb::ProcessSP process_sp;
619
620 if (IsHost())
621 {
622 if (target == NULL)
623 {
624 TargetSP new_target_sp;
625
626 error = debugger.GetTargetList().CreateTarget (debugger,
627 NULL,
628 NULL,
629 false,
630 NULL,
631 new_target_sp);
632 target = new_target_sp.get();
633 }
634 else
635 error.Clear();
636
637 if (target && error.Success())
638 {
639 debugger.GetTargetList().SetSelectedTarget(target);
640
641 process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName(), NULL);
642
643 if (process_sp)
644 error = process_sp->Attach (attach_info);
645 }
646 }
647 else
648 {
649 if (m_remote_platform_sp)
650 process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error);
651 else
652 error.SetErrorString ("the platform is not currently connected");
653 }
654 return process_sp;
655 }
656
657 const char *
GetUserName(uint32_t uid)658 PlatformDarwin::GetUserName (uint32_t uid)
659 {
660 // Check the cache in Platform in case we have already looked this uid up
661 const char *user_name = Platform::GetUserName(uid);
662 if (user_name)
663 return user_name;
664
665 if (IsRemote() && m_remote_platform_sp)
666 return m_remote_platform_sp->GetUserName(uid);
667 return NULL;
668 }
669
670 const char *
GetGroupName(uint32_t gid)671 PlatformDarwin::GetGroupName (uint32_t gid)
672 {
673 const char *group_name = Platform::GetGroupName(gid);
674 if (group_name)
675 return group_name;
676
677 if (IsRemote() && m_remote_platform_sp)
678 return m_remote_platform_sp->GetGroupName(gid);
679 return NULL;
680 }
681
682 bool
ModuleIsExcludedForNonModuleSpecificSearches(lldb_private::Target & target,const lldb::ModuleSP & module_sp)683 PlatformDarwin::ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp)
684 {
685 if (!module_sp)
686 return false;
687
688 ObjectFile *obj_file = module_sp->GetObjectFile();
689 if (!obj_file)
690 return false;
691
692 ObjectFile::Type obj_type = obj_file->GetType();
693 if (obj_type == ObjectFile::eTypeDynamicLinker)
694 return true;
695 else
696 return false;
697 }
698
699
700 bool
x86GetSupportedArchitectureAtIndex(uint32_t idx,ArchSpec & arch)701 PlatformDarwin::x86GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
702 {
703 if (idx == 0)
704 {
705 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
706 return arch.IsValid();
707 }
708 else if (idx == 1)
709 {
710 ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture));
711 ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64));
712 if (platform_arch.IsExactMatch(platform_arch64))
713 {
714 // This macosx platform supports both 32 and 64 bit. Since we already
715 // returned the 64 bit arch for idx == 0, return the 32 bit arch
716 // for idx == 1
717 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32);
718 return arch.IsValid();
719 }
720 }
721 return false;
722 }
723
724 // The architecture selection rules for arm processors
725 // These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f processor.
726
727 bool
ARMGetSupportedArchitectureAtIndex(uint32_t idx,ArchSpec & arch)728 PlatformDarwin::ARMGetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
729 {
730 ArchSpec system_arch (GetSystemArchitecture());
731 const ArchSpec::Core system_core = system_arch.GetCore();
732 switch (system_core)
733 {
734 default:
735 switch (idx)
736 {
737 case 0: arch.SetTriple ("armv7-apple-ios"); return true;
738 case 1: arch.SetTriple ("armv7f-apple-ios"); return true;
739 case 2: arch.SetTriple ("armv7k-apple-ios"); return true;
740 case 3: arch.SetTriple ("armv7s-apple-ios"); return true;
741 case 4: arch.SetTriple ("armv7m-apple-ios"); return true;
742 case 5: arch.SetTriple ("armv7em-apple-ios"); return true;
743 case 6: arch.SetTriple ("armv6-apple-ios"); return true;
744 case 7: arch.SetTriple ("armv5-apple-ios"); return true;
745 case 8: arch.SetTriple ("armv4-apple-ios"); return true;
746 case 9: arch.SetTriple ("arm-apple-ios"); return true;
747 case 10: arch.SetTriple ("thumbv7-apple-ios"); return true;
748 case 11: arch.SetTriple ("thumbv7f-apple-ios"); return true;
749 case 12: arch.SetTriple ("thumbv7k-apple-ios"); return true;
750 case 13: arch.SetTriple ("thumbv7s-apple-ios"); return true;
751 case 14: arch.SetTriple ("thumbv7m-apple-ios"); return true;
752 case 15: arch.SetTriple ("thumbv7em-apple-ios"); return true;
753 case 16: arch.SetTriple ("thumbv6-apple-ios"); return true;
754 case 17: arch.SetTriple ("thumbv5-apple-ios"); return true;
755 case 18: arch.SetTriple ("thumbv4t-apple-ios"); return true;
756 case 19: arch.SetTriple ("thumb-apple-ios"); return true;
757 default: break;
758 }
759 break;
760
761 case ArchSpec::eCore_arm_armv7f:
762 switch (idx)
763 {
764 case 0: arch.SetTriple ("armv7f-apple-ios"); return true;
765 case 1: arch.SetTriple ("armv7-apple-ios"); return true;
766 case 2: arch.SetTriple ("armv6-apple-ios"); return true;
767 case 3: arch.SetTriple ("armv5-apple-ios"); return true;
768 case 4: arch.SetTriple ("armv4-apple-ios"); return true;
769 case 5: arch.SetTriple ("arm-apple-ios"); return true;
770 case 6: arch.SetTriple ("thumbv7f-apple-ios"); return true;
771 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true;
772 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true;
773 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true;
774 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
775 case 11: arch.SetTriple ("thumb-apple-ios"); return true;
776 default: break;
777 }
778 break;
779
780 case ArchSpec::eCore_arm_armv7k:
781 switch (idx)
782 {
783 case 0: arch.SetTriple ("armv7k-apple-ios"); return true;
784 case 1: arch.SetTriple ("armv7-apple-ios"); return true;
785 case 2: arch.SetTriple ("armv6-apple-ios"); return true;
786 case 3: arch.SetTriple ("armv5-apple-ios"); return true;
787 case 4: arch.SetTriple ("armv4-apple-ios"); return true;
788 case 5: arch.SetTriple ("arm-apple-ios"); return true;
789 case 6: arch.SetTriple ("thumbv7k-apple-ios"); return true;
790 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true;
791 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true;
792 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true;
793 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
794 case 11: arch.SetTriple ("thumb-apple-ios"); return true;
795 default: break;
796 }
797 break;
798
799 case ArchSpec::eCore_arm_armv7s:
800 switch (idx)
801 {
802 case 0: arch.SetTriple ("armv7s-apple-ios"); return true;
803 case 1: arch.SetTriple ("armv7-apple-ios"); return true;
804 case 2: arch.SetTriple ("armv6-apple-ios"); return true;
805 case 3: arch.SetTriple ("armv5-apple-ios"); return true;
806 case 4: arch.SetTriple ("armv4-apple-ios"); return true;
807 case 5: arch.SetTriple ("arm-apple-ios"); return true;
808 case 6: arch.SetTriple ("thumbv7s-apple-ios"); return true;
809 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true;
810 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true;
811 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true;
812 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
813 case 11: arch.SetTriple ("thumb-apple-ios"); return true;
814 default: break;
815 }
816 break;
817
818 case ArchSpec::eCore_arm_armv7m:
819 switch (idx)
820 {
821 case 0: arch.SetTriple ("armv7m-apple-ios"); return true;
822 case 1: arch.SetTriple ("armv7-apple-ios"); return true;
823 case 2: arch.SetTriple ("armv6-apple-ios"); return true;
824 case 3: arch.SetTriple ("armv5-apple-ios"); return true;
825 case 4: arch.SetTriple ("armv4-apple-ios"); return true;
826 case 5: arch.SetTriple ("arm-apple-ios"); return true;
827 case 6: arch.SetTriple ("thumbv7m-apple-ios"); return true;
828 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true;
829 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true;
830 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true;
831 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
832 case 11: arch.SetTriple ("thumb-apple-ios"); return true;
833 default: break;
834 }
835 break;
836
837 case ArchSpec::eCore_arm_armv7em:
838 switch (idx)
839 {
840 case 0: arch.SetTriple ("armv7em-apple-ios"); return true;
841 case 1: arch.SetTriple ("armv7-apple-ios"); return true;
842 case 2: arch.SetTriple ("armv6-apple-ios"); return true;
843 case 3: arch.SetTriple ("armv5-apple-ios"); return true;
844 case 4: arch.SetTriple ("armv4-apple-ios"); return true;
845 case 5: arch.SetTriple ("arm-apple-ios"); return true;
846 case 6: arch.SetTriple ("thumbv7em-apple-ios"); return true;
847 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true;
848 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true;
849 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true;
850 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
851 case 11: arch.SetTriple ("thumb-apple-ios"); return true;
852 default: break;
853 }
854 break;
855
856 case ArchSpec::eCore_arm_armv7:
857 switch (idx)
858 {
859 case 0: arch.SetTriple ("armv7-apple-ios"); return true;
860 case 1: arch.SetTriple ("armv6-apple-ios"); return true;
861 case 2: arch.SetTriple ("armv5-apple-ios"); return true;
862 case 3: arch.SetTriple ("armv4-apple-ios"); return true;
863 case 4: arch.SetTriple ("arm-apple-ios"); return true;
864 case 5: arch.SetTriple ("thumbv7-apple-ios"); return true;
865 case 6: arch.SetTriple ("thumbv6-apple-ios"); return true;
866 case 7: arch.SetTriple ("thumbv5-apple-ios"); return true;
867 case 8: arch.SetTriple ("thumbv4t-apple-ios"); return true;
868 case 9: arch.SetTriple ("thumb-apple-ios"); return true;
869 default: break;
870 }
871 break;
872
873 case ArchSpec::eCore_arm_armv6:
874 switch (idx)
875 {
876 case 0: arch.SetTriple ("armv6-apple-ios"); return true;
877 case 1: arch.SetTriple ("armv5-apple-ios"); return true;
878 case 2: arch.SetTriple ("armv4-apple-ios"); return true;
879 case 3: arch.SetTriple ("arm-apple-ios"); return true;
880 case 4: arch.SetTriple ("thumbv6-apple-ios"); return true;
881 case 5: arch.SetTriple ("thumbv5-apple-ios"); return true;
882 case 6: arch.SetTriple ("thumbv4t-apple-ios"); return true;
883 case 7: arch.SetTriple ("thumb-apple-ios"); return true;
884 default: break;
885 }
886 break;
887
888 case ArchSpec::eCore_arm_armv5:
889 switch (idx)
890 {
891 case 0: arch.SetTriple ("armv5-apple-ios"); return true;
892 case 1: arch.SetTriple ("armv4-apple-ios"); return true;
893 case 2: arch.SetTriple ("arm-apple-ios"); return true;
894 case 3: arch.SetTriple ("thumbv5-apple-ios"); return true;
895 case 4: arch.SetTriple ("thumbv4t-apple-ios"); return true;
896 case 5: arch.SetTriple ("thumb-apple-ios"); return true;
897 default: break;
898 }
899 break;
900
901 case ArchSpec::eCore_arm_armv4:
902 switch (idx)
903 {
904 case 0: arch.SetTriple ("armv4-apple-ios"); return true;
905 case 1: arch.SetTriple ("arm-apple-ios"); return true;
906 case 2: arch.SetTriple ("thumbv4t-apple-ios"); return true;
907 case 3: arch.SetTriple ("thumb-apple-ios"); return true;
908 default: break;
909 }
910 break;
911 }
912 arch.Clear();
913 return false;
914 }
915
916
917 const char *
GetDeveloperDirectory()918 PlatformDarwin::GetDeveloperDirectory()
919 {
920 if (m_developer_directory.empty())
921 {
922 bool developer_dir_path_valid = false;
923 char developer_dir_path[PATH_MAX];
924 FileSpec temp_file_spec;
925 if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, temp_file_spec))
926 {
927 if (temp_file_spec.GetPath (developer_dir_path, sizeof(developer_dir_path)))
928 {
929 char *shared_frameworks = strstr (developer_dir_path, "/SharedFrameworks/LLDB.framework");
930 if (shared_frameworks)
931 {
932 ::snprintf (shared_frameworks,
933 sizeof(developer_dir_path) - (shared_frameworks - developer_dir_path),
934 "/Developer");
935 developer_dir_path_valid = true;
936 }
937 else
938 {
939 char *lib_priv_frameworks = strstr (developer_dir_path, "/Library/PrivateFrameworks/LLDB.framework");
940 if (lib_priv_frameworks)
941 {
942 *lib_priv_frameworks = '\0';
943 developer_dir_path_valid = true;
944 }
945 }
946 }
947 }
948
949 if (!developer_dir_path_valid)
950 {
951 std::string xcode_dir_path;
952 const char *xcode_select_prefix_dir = getenv ("XCODE_SELECT_PREFIX_DIR");
953 if (xcode_select_prefix_dir)
954 xcode_dir_path.append (xcode_select_prefix_dir);
955 xcode_dir_path.append ("/usr/share/xcode-select/xcode_dir_path");
956 temp_file_spec.SetFile(xcode_dir_path.c_str(), false);
957 size_t bytes_read = temp_file_spec.ReadFileContents(0, developer_dir_path, sizeof(developer_dir_path), NULL);
958 if (bytes_read > 0)
959 {
960 developer_dir_path[bytes_read] = '\0';
961 while (developer_dir_path[bytes_read-1] == '\r' ||
962 developer_dir_path[bytes_read-1] == '\n')
963 developer_dir_path[--bytes_read] = '\0';
964 developer_dir_path_valid = true;
965 }
966 }
967
968 if (!developer_dir_path_valid)
969 {
970 FileSpec xcode_select_cmd ("/usr/bin/xcode-select", false);
971 if (xcode_select_cmd.Exists())
972 {
973 int exit_status = -1;
974 int signo = -1;
975 std::string command_output;
976 Error error = Host::RunShellCommand ("/usr/bin/xcode-select --print-path",
977 NULL, // current working directory
978 &exit_status,
979 &signo,
980 &command_output,
981 2, // short timeout
982 NULL); // don't run in a shell
983 if (error.Success() && exit_status == 0 && !command_output.empty())
984 {
985 const char *cmd_output_ptr = command_output.c_str();
986 developer_dir_path[sizeof (developer_dir_path) - 1] = '\0';
987 size_t i;
988 for (i = 0; i < sizeof (developer_dir_path) - 1; i++)
989 {
990 if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' || cmd_output_ptr[i] == '\0')
991 break;
992 developer_dir_path[i] = cmd_output_ptr[i];
993 }
994 developer_dir_path[i] = '\0';
995
996 FileSpec devel_dir (developer_dir_path, false);
997 if (devel_dir.Exists() && devel_dir.IsDirectory())
998 {
999 developer_dir_path_valid = true;
1000 }
1001 }
1002 }
1003 }
1004
1005 if (developer_dir_path_valid)
1006 {
1007 temp_file_spec.SetFile (developer_dir_path, false);
1008 if (temp_file_spec.Exists())
1009 {
1010 m_developer_directory.assign (developer_dir_path);
1011 return m_developer_directory.c_str();
1012 }
1013 }
1014 // Assign a single NULL character so we know we tried to find the device
1015 // support directory and we don't keep trying to find it over and over.
1016 m_developer_directory.assign (1, '\0');
1017 }
1018
1019 // We should have put a single NULL character into m_developer_directory
1020 // or it should have a valid path if the code gets here
1021 assert (m_developer_directory.empty() == false);
1022 if (m_developer_directory[0])
1023 return m_developer_directory.c_str();
1024 return NULL;
1025 }
1026
1027
1028 BreakpointSP
SetThreadCreationBreakpoint(Target & target)1029 PlatformDarwin::SetThreadCreationBreakpoint (Target &target)
1030 {
1031 BreakpointSP bp_sp;
1032 static const char *g_bp_names[] =
1033 {
1034 "start_wqthread",
1035 "_pthread_wqthread",
1036 "_pthread_start",
1037 };
1038
1039 static const char *g_bp_modules[] =
1040 {
1041 "libsystem_c.dylib",
1042 "libSystem.B.dylib"
1043 };
1044
1045 FileSpecList bp_modules;
1046 for (size_t i = 0; i < sizeof(g_bp_modules)/sizeof(const char *); i++)
1047 {
1048 const char *bp_module = g_bp_modules[i];
1049 bp_modules.Append(FileSpec(bp_module, false));
1050 }
1051
1052 bool internal = true;
1053 LazyBool skip_prologue = eLazyBoolNo;
1054 bp_sp = target.CreateBreakpoint (&bp_modules,
1055 NULL,
1056 g_bp_names,
1057 sizeof(g_bp_names)/sizeof(const char *),
1058 eFunctionNameTypeFull,
1059 skip_prologue,
1060 internal);
1061 bp_sp->SetBreakpointKind("thread-creation");
1062
1063 return bp_sp;
1064 }
1065
1066 size_t
GetEnvironment(StringList & env)1067 PlatformDarwin::GetEnvironment (StringList &env)
1068 {
1069 if (IsRemote())
1070 {
1071 if (m_remote_platform_sp)
1072 return m_remote_platform_sp->GetEnvironment(env);
1073 return 0;
1074 }
1075 return Host::GetEnvironment(env);
1076 }
1077