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/Log.h"
22 #include "lldb/Core/Module.h"
23 #include "lldb/Core/ModuleSpec.h"
24 #include "lldb/Core/Timer.h"
25 #include "lldb/Host/Host.h"
26 #include "lldb/Host/Symbols.h"
27 #include "lldb/Symbol/ObjectFile.h"
28 #include "lldb/Symbol/SymbolFile.h"
29 #include "lldb/Symbol/SymbolVendor.h"
30 #include "lldb/Target/Target.h"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 
36 //------------------------------------------------------------------
37 /// Default Constructor
38 //------------------------------------------------------------------
39 PlatformDarwin::PlatformDarwin (bool is_host) :
40     PlatformPOSIX(is_host),  // This is the local host platform
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 //------------------------------------------------------------------
51 PlatformDarwin::~PlatformDarwin()
52 {
53 }
54 
55 FileSpecList
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
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 = 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
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 static lldb_private::Error
272 MakeCacheFolderForFile (const FileSpec& module_cache_spec)
273 {
274     FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent();
275     return Host::MakeDirectory(module_cache_folder.GetPath().c_str(), eFilePermissionsDirectoryDefault);
276 }
277 
278 static lldb_private::Error
279 BringInRemoteFile (Platform* platform,
280                    const lldb_private::ModuleSpec &module_spec,
281                    const FileSpec& module_cache_spec)
282 {
283     MakeCacheFolderForFile(module_cache_spec);
284     Error err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec);
285     return err;
286 }
287 
288 lldb_private::Error
289 PlatformDarwin::GetSharedModuleWithLocalCache (const lldb_private::ModuleSpec &module_spec,
290                                                lldb::ModuleSP &module_sp,
291                                                const lldb_private::FileSpecList *module_search_paths_ptr,
292                                                lldb::ModuleSP *old_module_sp_ptr,
293                                                bool *did_create_ptr)
294 {
295 
296     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
297     if (log)
298         log->Printf("[%s] Trying to find module %s/%s - platform path %s/%s symbol path %s/%s",
299                      (IsHost() ? "host" : "remote"),
300                      module_spec.GetFileSpec().GetDirectory().AsCString(),
301                      module_spec.GetFileSpec().GetFilename().AsCString(),
302                      module_spec.GetPlatformFileSpec().GetDirectory().AsCString(),
303                      module_spec.GetPlatformFileSpec().GetFilename().AsCString(),
304                      module_spec.GetSymbolFileSpec().GetDirectory().AsCString(),
305                      module_spec.GetSymbolFileSpec().GetFilename().AsCString());
306 
307     Error err;
308 
309     err = ModuleList::GetSharedModule(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
310     if (module_sp)
311         return err;
312 
313     if (!IsHost())
314     {
315         std::string cache_path(GetLocalCacheDirectory());
316         // Only search for a locally cached file if we have a valid cache path
317         if (!cache_path.empty())
318         {
319             std::string module_path (module_spec.GetFileSpec().GetPath());
320             cache_path.append(module_path);
321             FileSpec module_cache_spec(cache_path.c_str(),false);
322 
323             // if rsync is supported, always bring in the file - rsync will be very efficient
324             // when files are the same on the local and remote end of the connection
325             if (this->GetSupportsRSync())
326             {
327                 err = BringInRemoteFile (this, module_spec, module_cache_spec);
328                 if (err.Fail())
329                     return err;
330                 if (module_cache_spec.Exists())
331                 {
332                     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
333                     if (log)
334                         log->Printf("[%s] module %s/%s was rsynced and is now there",
335                                      (IsHost() ? "host" : "remote"),
336                                      module_spec.GetFileSpec().GetDirectory().AsCString(),
337                                      module_spec.GetFileSpec().GetFilename().AsCString());
338                     ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
339                     module_sp.reset(new Module(local_spec));
340                     module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
341                     return Error();
342                 }
343             }
344 
345             // try to find the module in the cache
346             if (module_cache_spec.Exists())
347             {
348                 // get the local and remote MD5 and compare
349                 if (m_remote_platform_sp)
350                 {
351                     // when going over the *slow* GDB remote transfer mechanism we first check
352                     // the hashes of the files - and only do the actual transfer if they differ
353                     uint64_t high_local,high_remote,low_local,low_remote;
354                     Host::CalculateMD5 (module_cache_spec, low_local, high_local);
355                     m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(), low_remote, high_remote);
356                     if (low_local != low_remote || high_local != high_remote)
357                     {
358                         // bring in the remote file
359                         Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
360                         if (log)
361                             log->Printf("[%s] module %s/%s needs to be replaced from remote copy",
362                                          (IsHost() ? "host" : "remote"),
363                                          module_spec.GetFileSpec().GetDirectory().AsCString(),
364                                          module_spec.GetFileSpec().GetFilename().AsCString());
365                         Error err = BringInRemoteFile (this, module_spec, module_cache_spec);
366                         if (err.Fail())
367                             return err;
368                     }
369                 }
370 
371                 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
372                 module_sp.reset(new Module(local_spec));
373                 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
374                 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
375                     if (log)
376                         log->Printf("[%s] module %s/%s was found in the cache",
377                                      (IsHost() ? "host" : "remote"),
378                                      module_spec.GetFileSpec().GetDirectory().AsCString(),
379                                      module_spec.GetFileSpec().GetFilename().AsCString());
380                 return Error();
381             }
382 
383             // bring in the remote module file
384             if (log)
385                 log->Printf("[%s] module %s/%s needs to come in remotely",
386                              (IsHost() ? "host" : "remote"),
387                              module_spec.GetFileSpec().GetDirectory().AsCString(),
388                              module_spec.GetFileSpec().GetFilename().AsCString());
389             Error err = BringInRemoteFile (this, module_spec, module_cache_spec);
390             if (err.Fail())
391                 return err;
392             if (module_cache_spec.Exists())
393             {
394                 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
395                 if (log)
396                     log->Printf("[%s] module %s/%s is now cached and fine",
397                                  (IsHost() ? "host" : "remote"),
398                                  module_spec.GetFileSpec().GetDirectory().AsCString(),
399                                  module_spec.GetFileSpec().GetFilename().AsCString());
400                 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
401                 module_sp.reset(new Module(local_spec));
402                 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
403                 return Error();
404             }
405             else
406                 return Error("unable to obtain valid module file");
407         }
408         else
409             return Error("no cache path");
410     }
411     else
412         return Error ("unable to resolve module");
413 }
414 
415 Error
416 PlatformDarwin::GetSharedModule (const ModuleSpec &module_spec,
417                                  ModuleSP &module_sp,
418                                  const FileSpecList *module_search_paths_ptr,
419                                  ModuleSP *old_module_sp_ptr,
420                                  bool *did_create_ptr)
421 {
422     Error error;
423     module_sp.reset();
424 
425     if (IsRemote())
426     {
427         // If we have a remote platform always, let it try and locate
428         // the shared module first.
429         if (m_remote_platform_sp)
430         {
431             error = m_remote_platform_sp->GetSharedModule (module_spec,
432                                                            module_sp,
433                                                            module_search_paths_ptr,
434                                                            old_module_sp_ptr,
435                                                            did_create_ptr);
436         }
437     }
438 
439     if (!module_sp)
440     {
441         // Fall back to the local platform and find the file locally
442         error = Platform::GetSharedModule (module_spec,
443                                            module_sp,
444                                            module_search_paths_ptr,
445                                            old_module_sp_ptr,
446                                            did_create_ptr);
447 
448         const FileSpec &platform_file = module_spec.GetFileSpec();
449         if (!module_sp && module_search_paths_ptr && platform_file)
450         {
451             // We can try to pull off part of the file path up to the bundle
452             // directory level and try any module search paths...
453             FileSpec bundle_directory;
454             if (Host::GetBundleDirectory (platform_file, bundle_directory))
455             {
456                 if (platform_file == bundle_directory)
457                 {
458                     ModuleSpec new_module_spec (module_spec);
459                     new_module_spec.GetFileSpec() = bundle_directory;
460                     if (Host::ResolveExecutableInBundle (new_module_spec.GetFileSpec()))
461                     {
462                         Error new_error (Platform::GetSharedModule (new_module_spec,
463                                                                     module_sp,
464                                                                     NULL,
465                                                                     old_module_sp_ptr,
466                                                                     did_create_ptr));
467 
468                         if (module_sp)
469                             return new_error;
470                     }
471                 }
472                 else
473                 {
474                     char platform_path[PATH_MAX];
475                     char bundle_dir[PATH_MAX];
476                     platform_file.GetPath (platform_path, sizeof(platform_path));
477                     const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir));
478                     char new_path[PATH_MAX];
479                     size_t num_module_search_paths = module_search_paths_ptr->GetSize();
480                     for (size_t i=0; i<num_module_search_paths; ++i)
481                     {
482                         const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path));
483                         if (search_path_len < sizeof(new_path))
484                         {
485                             snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len);
486                             FileSpec new_file_spec (new_path, false);
487                             if (new_file_spec.Exists())
488                             {
489                                 ModuleSpec new_module_spec (module_spec);
490                                 new_module_spec.GetFileSpec() = new_file_spec;
491                                 Error new_error (Platform::GetSharedModule (new_module_spec,
492                                                                             module_sp,
493                                                                             NULL,
494                                                                             old_module_sp_ptr,
495                                                                             did_create_ptr));
496 
497                                 if (module_sp)
498                                 {
499                                     module_sp->SetPlatformFileSpec(new_file_spec);
500                                     return new_error;
501                                 }
502                             }
503                         }
504                     }
505                 }
506             }
507         }
508     }
509     if (module_sp)
510         module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
511     return error;
512 }
513 
514 size_t
515 PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
516 {
517     const uint8_t *trap_opcode = NULL;
518     uint32_t trap_opcode_size = 0;
519     bool bp_is_thumb = false;
520 
521     llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
522     switch (machine)
523     {
524     case llvm::Triple::x86:
525     case llvm::Triple::x86_64:
526         {
527             static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
528             trap_opcode = g_i386_breakpoint_opcode;
529             trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
530         }
531         break;
532 
533     case llvm::Triple::arm64:
534         {
535             // TODO: fix this with actual darwin breakpoint opcode for arm64.
536             // right now debugging uses the Z packets with GDB remote so this
537             // is not needed, but the size needs to be correct...
538             static const uint8_t g_arm64_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
539             trap_opcode = g_arm64_breakpoint_opcode;
540             trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);
541         }
542         break;
543 
544     case llvm::Triple::thumb:
545         bp_is_thumb = true; // Fall through...
546     case llvm::Triple::arm:
547         {
548             static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
549             static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE };
550 
551             // Auto detect arm/thumb if it wasn't explicitly specified
552             if (!bp_is_thumb)
553             {
554                 lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
555                 if (bp_loc_sp)
556                     bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass () == eAddressClassCodeAlternateISA;
557             }
558             if (bp_is_thumb)
559             {
560                 trap_opcode = g_thumb_breakpooint_opcode;
561                 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode);
562                 break;
563             }
564             trap_opcode = g_arm_breakpoint_opcode;
565             trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
566         }
567         break;
568 
569     case llvm::Triple::ppc:
570     case llvm::Triple::ppc64:
571         {
572             static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 };
573             trap_opcode = g_ppc_breakpoint_opcode;
574             trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
575         }
576         break;
577 
578     default:
579         assert(!"Unhandled architecture in PlatformDarwin::GetSoftwareBreakpointTrapOpcode()");
580         break;
581     }
582 
583     if (trap_opcode && trap_opcode_size)
584     {
585         if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
586             return trap_opcode_size;
587     }
588     return 0;
589 
590 }
591 
592 bool
593 PlatformDarwin::GetRemoteOSVersion ()
594 {
595     if (m_remote_platform_sp)
596         return m_remote_platform_sp->GetOSVersion (m_major_os_version,
597                                                    m_minor_os_version,
598                                                    m_update_os_version);
599     return false;
600 }
601 
602 bool
603 PlatformDarwin::GetRemoteOSBuildString (std::string &s)
604 {
605     if (m_remote_platform_sp)
606         return m_remote_platform_sp->GetRemoteOSBuildString (s);
607     s.clear();
608     return false;
609 }
610 
611 bool
612 PlatformDarwin::GetRemoteOSKernelDescription (std::string &s)
613 {
614     if (m_remote_platform_sp)
615         return m_remote_platform_sp->GetRemoteOSKernelDescription (s);
616     s.clear();
617     return false;
618 }
619 
620 // Remote Platform subclasses need to override this function
621 ArchSpec
622 PlatformDarwin::GetRemoteSystemArchitecture ()
623 {
624     if (m_remote_platform_sp)
625         return m_remote_platform_sp->GetRemoteSystemArchitecture ();
626     return ArchSpec();
627 }
628 
629 
630 const char *
631 PlatformDarwin::GetHostname ()
632 {
633     if (IsHost())
634         return Platform::GetHostname();
635 
636     if (m_remote_platform_sp)
637         return m_remote_platform_sp->GetHostname ();
638     return NULL;
639 }
640 
641 bool
642 PlatformDarwin::IsConnected () const
643 {
644     if (IsHost())
645         return true;
646     else if (m_remote_platform_sp)
647         return m_remote_platform_sp->IsConnected();
648     return false;
649 }
650 
651 Error
652 PlatformDarwin::ConnectRemote (Args& args)
653 {
654     Error error;
655     if (IsHost())
656     {
657         error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString());
658     }
659     else
660     {
661         if (!m_remote_platform_sp)
662             m_remote_platform_sp = Platform::Create ("remote-gdb-server", error);
663 
664         if (m_remote_platform_sp && error.Success())
665             error = m_remote_platform_sp->ConnectRemote (args);
666         else
667             error.SetErrorString ("failed to create a 'remote-gdb-server' platform");
668 
669         if (error.Fail())
670             m_remote_platform_sp.reset();
671     }
672 
673     if (error.Success() && m_remote_platform_sp)
674     {
675         if (m_options.get())
676         {
677             OptionGroupOptions* options = m_options.get();
678             OptionGroupPlatformRSync* m_rsync_options = (OptionGroupPlatformRSync*)options->GetGroupWithOption('r');
679             OptionGroupPlatformSSH* m_ssh_options = (OptionGroupPlatformSSH*)options->GetGroupWithOption('s');
680             OptionGroupPlatformCaching* m_cache_options = (OptionGroupPlatformCaching*)options->GetGroupWithOption('c');
681 
682             if (m_rsync_options->m_rsync)
683             {
684                 SetSupportsRSync(true);
685                 SetRSyncOpts(m_rsync_options->m_rsync_opts.c_str());
686                 SetRSyncPrefix(m_rsync_options->m_rsync_prefix.c_str());
687                 SetIgnoresRemoteHostname(m_rsync_options->m_ignores_remote_hostname);
688             }
689             if (m_ssh_options->m_ssh)
690             {
691                 SetSupportsSSH(true);
692                 SetSSHOpts(m_ssh_options->m_ssh_opts.c_str());
693             }
694             SetLocalCacheDirectory(m_cache_options->m_cache_dir.c_str());
695         }
696     }
697 
698     return error;
699 }
700 
701 Error
702 PlatformDarwin::DisconnectRemote ()
703 {
704     Error error;
705 
706     if (IsHost())
707     {
708         error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString());
709     }
710     else
711     {
712         if (m_remote_platform_sp)
713             error = m_remote_platform_sp->DisconnectRemote ();
714         else
715             error.SetErrorString ("the platform is not currently connected");
716     }
717     return error;
718 }
719 
720 
721 bool
722 PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
723 {
724     bool sucess = false;
725     if (IsHost())
726     {
727         sucess = Platform::GetProcessInfo (pid, process_info);
728     }
729     else
730     {
731         if (m_remote_platform_sp)
732             sucess = m_remote_platform_sp->GetProcessInfo (pid, process_info);
733     }
734     return sucess;
735 }
736 
737 
738 
739 uint32_t
740 PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info,
741                                ProcessInstanceInfoList &process_infos)
742 {
743     uint32_t match_count = 0;
744     if (IsHost())
745     {
746         // Let the base class figure out the host details
747         match_count = Platform::FindProcesses (match_info, process_infos);
748     }
749     else
750     {
751         // If we are remote, we can only return results if we are connected
752         if (m_remote_platform_sp)
753             match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos);
754     }
755     return match_count;
756 }
757 
758 Error
759 PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info)
760 {
761     Error error;
762 
763     if (IsHost())
764     {
765         error = Platform::LaunchProcess (launch_info);
766     }
767     else
768     {
769         if (m_remote_platform_sp)
770             error = m_remote_platform_sp->LaunchProcess (launch_info);
771         else
772             error.SetErrorString ("the platform is not currently connected");
773     }
774     return error;
775 }
776 
777 lldb::ProcessSP
778 PlatformDarwin::DebugProcess (ProcessLaunchInfo &launch_info,
779                               Debugger &debugger,
780                               Target *target,       // Can be NULL, if NULL create a new target, else use existing one
781                               Listener &listener,
782                               Error &error)
783 {
784     ProcessSP process_sp;
785 
786     if (IsHost())
787     {
788         // We are going to hand this process off to debugserver which will monitor the process itself.
789         // So don't also monitor it from lldb or we set up a race between debugserver & us for who will find out
790         // about the debugged process's death.
791         launch_info.GetFlags().Set(eLaunchFlagsDontMonitorProcess);
792         process_sp = Platform::DebugProcess (launch_info, debugger, target, listener, error);
793     }
794     else
795     {
796         if (m_remote_platform_sp)
797             process_sp = m_remote_platform_sp->DebugProcess (launch_info, debugger, target, listener, error);
798         else
799             error.SetErrorString ("the platform is not currently connected");
800     }
801     return process_sp;
802 
803 }
804 
805 
806 lldb::ProcessSP
807 PlatformDarwin::Attach (ProcessAttachInfo &attach_info,
808                         Debugger &debugger,
809                         Target *target,
810                         Listener &listener,
811                         Error &error)
812 {
813     lldb::ProcessSP process_sp;
814 
815     if (IsHost())
816     {
817         if (target == NULL)
818         {
819             TargetSP new_target_sp;
820 
821             error = debugger.GetTargetList().CreateTarget (debugger,
822                                                            NULL,
823                                                            NULL,
824                                                            false,
825                                                            NULL,
826                                                            new_target_sp);
827             target = new_target_sp.get();
828         }
829         else
830             error.Clear();
831 
832         if (target && error.Success())
833         {
834             debugger.GetTargetList().SetSelectedTarget(target);
835 
836             process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName(), NULL);
837 
838             if (process_sp)
839             {
840                 ListenerSP listener_sp (new Listener("lldb.PlatformDarwin.attach.hijack"));
841                 attach_info.SetHijackListener(listener_sp);
842                 process_sp->HijackProcessEvents(listener_sp.get());
843                 error = process_sp->Attach (attach_info);
844             }
845         }
846     }
847     else
848     {
849         if (m_remote_platform_sp)
850             process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error);
851         else
852             error.SetErrorString ("the platform is not currently connected");
853     }
854     return process_sp;
855 }
856 
857 const char *
858 PlatformDarwin::GetUserName (uint32_t uid)
859 {
860     // Check the cache in Platform in case we have already looked this uid up
861     const char *user_name = Platform::GetUserName(uid);
862     if (user_name)
863         return user_name;
864 
865     if (IsRemote() && m_remote_platform_sp)
866         return m_remote_platform_sp->GetUserName(uid);
867     return NULL;
868 }
869 
870 const char *
871 PlatformDarwin::GetGroupName (uint32_t gid)
872 {
873     const char *group_name = Platform::GetGroupName(gid);
874     if (group_name)
875         return group_name;
876 
877     if (IsRemote() && m_remote_platform_sp)
878         return m_remote_platform_sp->GetGroupName(gid);
879     return NULL;
880 }
881 
882 bool
883 PlatformDarwin::ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp)
884 {
885     if (!module_sp)
886         return false;
887 
888     ObjectFile *obj_file = module_sp->GetObjectFile();
889     if (!obj_file)
890         return false;
891 
892     ObjectFile::Type obj_type = obj_file->GetType();
893     if (obj_type == ObjectFile::eTypeDynamicLinker)
894         return true;
895     else
896         return false;
897 }
898 
899 bool
900 PlatformDarwin::x86GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
901 {
902     ArchSpec host_arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
903     if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h)
904     {
905         switch (idx)
906         {
907             case 0:
908                 arch = host_arch;
909                 return true;
910 
911             case 1:
912                 arch.SetTriple("x86_64-apple-macosx");
913                 return true;
914 
915             case 2:
916                 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32);
917                 return true;
918 
919             default: return false;
920         }
921     }
922     else
923     {
924         if (idx == 0)
925         {
926             arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
927             return arch.IsValid();
928         }
929         else if (idx == 1)
930         {
931             ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture));
932             ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64));
933             if (platform_arch.IsExactMatch(platform_arch64))
934             {
935                 // This macosx platform supports both 32 and 64 bit. Since we already
936                 // returned the 64 bit arch for idx == 0, return the 32 bit arch
937                 // for idx == 1
938                 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32);
939                 return arch.IsValid();
940             }
941         }
942     }
943     return false;
944 }
945 
946 // The architecture selection rules for arm processors
947 // These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f processor.
948 
949 bool
950 PlatformDarwin::ARMGetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
951 {
952     ArchSpec system_arch (GetSystemArchitecture());
953 
954     const ArchSpec::Core system_core = system_arch.GetCore();
955     switch (system_core)
956     {
957     default:
958         switch (idx)
959         {
960             case  0: arch.SetTriple ("arm64-apple-ios");    return true;
961             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
962             case  2: arch.SetTriple ("armv7f-apple-ios");   return true;
963             case  3: arch.SetTriple ("armv7k-apple-ios");   return true;
964             case  4: arch.SetTriple ("armv7s-apple-ios");   return true;
965             case  5: arch.SetTriple ("armv7m-apple-ios");   return true;
966             case  6: arch.SetTriple ("armv7em-apple-ios");  return true;
967             case  7: arch.SetTriple ("armv6m-apple-ios");   return true;
968             case  8: arch.SetTriple ("armv6-apple-ios");    return true;
969             case  9: arch.SetTriple ("armv5-apple-ios");    return true;
970             case 10: arch.SetTriple ("armv4-apple-ios");    return true;
971             case 11: arch.SetTriple ("arm-apple-ios");      return true;
972             case 12: arch.SetTriple ("thumbv7-apple-ios");  return true;
973             case 13: arch.SetTriple ("thumbv7f-apple-ios"); return true;
974             case 14: arch.SetTriple ("thumbv7k-apple-ios"); return true;
975             case 15: arch.SetTriple ("thumbv7s-apple-ios"); return true;
976             case 16: arch.SetTriple ("thumbv7m-apple-ios"); return true;
977             case 17: arch.SetTriple ("thumbv7em-apple-ios"); return true;
978             case 18: arch.SetTriple ("thumbv6m-apple-ios"); return true;
979             case 19: arch.SetTriple ("thumbv6-apple-ios");  return true;
980             case 20: arch.SetTriple ("thumbv5-apple-ios");  return true;
981             case 21: arch.SetTriple ("thumbv4t-apple-ios"); return true;
982             case 22: arch.SetTriple ("thumb-apple-ios");    return true;
983             default: break;
984         }
985         break;
986 
987     case ArchSpec::eCore_arm_arm64:
988         switch (idx)
989         {
990             case  0: arch.SetTriple ("arm64-apple-ios");   return true;
991             case  1: arch.SetTriple ("armv7s-apple-ios");   return true;
992             case  2: arch.SetTriple ("armv7f-apple-ios");   return true;
993             case  3: arch.SetTriple ("armv7m-apple-ios");   return true;
994             case  4: arch.SetTriple ("armv7em-apple-ios");  return true;
995             case  5: arch.SetTriple ("armv7-apple-ios");    return true;
996             case  6: arch.SetTriple ("armv6m-apple-ios");   return true;
997             case  7: arch.SetTriple ("armv6-apple-ios");    return true;
998             case  8: arch.SetTriple ("armv5-apple-ios");    return true;
999             case  9: arch.SetTriple ("armv4-apple-ios");    return true;
1000             case 10: arch.SetTriple ("arm-apple-ios");      return true;
1001             case 11: arch.SetTriple ("thumbv7-apple-ios");  return true;
1002             case 12: arch.SetTriple ("thumbv7f-apple-ios"); return true;
1003             case 13: arch.SetTriple ("thumbv7k-apple-ios"); return true;
1004             case 14: arch.SetTriple ("thumbv7s-apple-ios"); return true;
1005             case 15: arch.SetTriple ("thumbv7m-apple-ios"); return true;
1006             case 16: arch.SetTriple ("thumbv7em-apple-ios"); return true;
1007             case 17: arch.SetTriple ("thumbv6m-apple-ios"); return true;
1008             case 18: arch.SetTriple ("thumbv6-apple-ios");  return true;
1009             case 19: arch.SetTriple ("thumbv5-apple-ios");  return true;
1010             case 20: arch.SetTriple ("thumbv4t-apple-ios"); return true;
1011             case 21: arch.SetTriple ("thumb-apple-ios");    return true;
1012         default: break;
1013         }
1014         break;
1015 
1016     case ArchSpec::eCore_arm_armv7f:
1017         switch (idx)
1018         {
1019             case  0: arch.SetTriple ("armv7f-apple-ios");   return true;
1020             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
1021             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
1022             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
1023             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
1024             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
1025             case  6: arch.SetTriple ("arm-apple-ios");      return true;
1026             case  7: arch.SetTriple ("thumbv7f-apple-ios"); return true;
1027             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
1028             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
1029             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
1030             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
1031             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
1032             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
1033             default: break;
1034         }
1035         break;
1036 
1037     case ArchSpec::eCore_arm_armv7k:
1038         switch (idx)
1039         {
1040             case  0: arch.SetTriple ("armv7k-apple-ios");   return true;
1041             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
1042             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
1043             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
1044             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
1045             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
1046             case  6: arch.SetTriple ("arm-apple-ios");      return true;
1047             case  7: arch.SetTriple ("thumbv7k-apple-ios"); return true;
1048             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
1049             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
1050             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
1051             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
1052             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
1053             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
1054             default: break;
1055         }
1056         break;
1057 
1058     case ArchSpec::eCore_arm_armv7s:
1059         switch (idx)
1060         {
1061             case  0: arch.SetTriple ("armv7s-apple-ios");   return true;
1062             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
1063             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
1064             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
1065             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
1066             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
1067             case  6: arch.SetTriple ("arm-apple-ios");      return true;
1068             case  7: arch.SetTriple ("thumbv7s-apple-ios"); return true;
1069             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
1070             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
1071             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
1072             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
1073             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
1074             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
1075             default: break;
1076         }
1077         break;
1078 
1079     case ArchSpec::eCore_arm_armv7m:
1080         switch (idx)
1081         {
1082             case  0: arch.SetTriple ("armv7m-apple-ios");   return true;
1083             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
1084             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
1085             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
1086             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
1087             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
1088             case  6: arch.SetTriple ("arm-apple-ios");      return true;
1089             case  7: arch.SetTriple ("thumbv7m-apple-ios"); return true;
1090             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
1091             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
1092             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
1093             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
1094             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
1095             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
1096             default: break;
1097         }
1098         break;
1099 
1100     case ArchSpec::eCore_arm_armv7em:
1101         switch (idx)
1102         {
1103             case  0: arch.SetTriple ("armv7em-apple-ios");  return true;
1104             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
1105             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
1106             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
1107             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
1108             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
1109             case  6: arch.SetTriple ("arm-apple-ios");      return true;
1110             case  7: arch.SetTriple ("thumbv7em-apple-ios"); return true;
1111             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
1112             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
1113             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
1114             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
1115             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
1116             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
1117             default: break;
1118         }
1119         break;
1120 
1121     case ArchSpec::eCore_arm_armv7:
1122         switch (idx)
1123         {
1124             case  0: arch.SetTriple ("armv7-apple-ios");    return true;
1125             case  1: arch.SetTriple ("armv6m-apple-ios");   return true;
1126             case  2: arch.SetTriple ("armv6-apple-ios");    return true;
1127             case  3: arch.SetTriple ("armv5-apple-ios");    return true;
1128             case  4: arch.SetTriple ("armv4-apple-ios");    return true;
1129             case  5: arch.SetTriple ("arm-apple-ios");      return true;
1130             case  6: arch.SetTriple ("thumbv7-apple-ios");  return true;
1131             case  7: arch.SetTriple ("thumbv6m-apple-ios"); return true;
1132             case  8: arch.SetTriple ("thumbv6-apple-ios");  return true;
1133             case  9: arch.SetTriple ("thumbv5-apple-ios");  return true;
1134             case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
1135             case 11: arch.SetTriple ("thumb-apple-ios");    return true;
1136             default: break;
1137         }
1138         break;
1139 
1140     case ArchSpec::eCore_arm_armv6m:
1141         switch (idx)
1142         {
1143             case 0: arch.SetTriple ("armv6m-apple-ios");   return true;
1144             case 1: arch.SetTriple ("armv6-apple-ios");    return true;
1145             case 2: arch.SetTriple ("armv5-apple-ios");    return true;
1146             case 3: arch.SetTriple ("armv4-apple-ios");    return true;
1147             case 4: arch.SetTriple ("arm-apple-ios");      return true;
1148             case 5: arch.SetTriple ("thumbv6m-apple-ios"); return true;
1149             case 6: arch.SetTriple ("thumbv6-apple-ios");  return true;
1150             case 7: arch.SetTriple ("thumbv5-apple-ios");  return true;
1151             case 8: arch.SetTriple ("thumbv4t-apple-ios"); return true;
1152             case 9: arch.SetTriple ("thumb-apple-ios");    return true;
1153             default: break;
1154         }
1155         break;
1156 
1157     case ArchSpec::eCore_arm_armv6:
1158         switch (idx)
1159         {
1160             case 0: arch.SetTriple ("armv6-apple-ios");    return true;
1161             case 1: arch.SetTriple ("armv5-apple-ios");    return true;
1162             case 2: arch.SetTriple ("armv4-apple-ios");    return true;
1163             case 3: arch.SetTriple ("arm-apple-ios");      return true;
1164             case 4: arch.SetTriple ("thumbv6-apple-ios");  return true;
1165             case 5: arch.SetTriple ("thumbv5-apple-ios");  return true;
1166             case 6: arch.SetTriple ("thumbv4t-apple-ios"); return true;
1167             case 7: arch.SetTriple ("thumb-apple-ios");    return true;
1168             default: break;
1169         }
1170         break;
1171 
1172     case ArchSpec::eCore_arm_armv5:
1173         switch (idx)
1174         {
1175             case 0: arch.SetTriple ("armv5-apple-ios");    return true;
1176             case 1: arch.SetTriple ("armv4-apple-ios");    return true;
1177             case 2: arch.SetTriple ("arm-apple-ios");      return true;
1178             case 3: arch.SetTriple ("thumbv5-apple-ios");  return true;
1179             case 4: arch.SetTriple ("thumbv4t-apple-ios"); return true;
1180             case 5: arch.SetTriple ("thumb-apple-ios");    return true;
1181             default: break;
1182         }
1183         break;
1184 
1185     case ArchSpec::eCore_arm_armv4:
1186         switch (idx)
1187         {
1188             case 0: arch.SetTriple ("armv4-apple-ios");    return true;
1189             case 1: arch.SetTriple ("arm-apple-ios");      return true;
1190             case 2: arch.SetTriple ("thumbv4t-apple-ios"); return true;
1191             case 3: arch.SetTriple ("thumb-apple-ios");    return true;
1192             default: break;
1193         }
1194         break;
1195     }
1196     arch.Clear();
1197     return false;
1198 }
1199 
1200 
1201 const char *
1202 PlatformDarwin::GetDeveloperDirectory()
1203 {
1204     if (m_developer_directory.empty())
1205     {
1206         bool developer_dir_path_valid = false;
1207         char developer_dir_path[PATH_MAX];
1208         FileSpec temp_file_spec;
1209         if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, temp_file_spec))
1210         {
1211             if (temp_file_spec.GetPath (developer_dir_path, sizeof(developer_dir_path)))
1212             {
1213                 char *shared_frameworks = strstr (developer_dir_path, "/SharedFrameworks/LLDB.framework");
1214                 if (shared_frameworks)
1215                 {
1216                     ::snprintf (shared_frameworks,
1217                                 sizeof(developer_dir_path) - (shared_frameworks - developer_dir_path),
1218                                 "/Developer");
1219                     developer_dir_path_valid = true;
1220                 }
1221                 else
1222                 {
1223                     char *lib_priv_frameworks = strstr (developer_dir_path, "/Library/PrivateFrameworks/LLDB.framework");
1224                     if (lib_priv_frameworks)
1225                     {
1226                         *lib_priv_frameworks = '\0';
1227                         developer_dir_path_valid = true;
1228                     }
1229                 }
1230             }
1231         }
1232 
1233         if (!developer_dir_path_valid)
1234         {
1235             std::string xcode_dir_path;
1236             const char *xcode_select_prefix_dir = getenv ("XCODE_SELECT_PREFIX_DIR");
1237             if (xcode_select_prefix_dir)
1238                 xcode_dir_path.append (xcode_select_prefix_dir);
1239             xcode_dir_path.append ("/usr/share/xcode-select/xcode_dir_path");
1240             temp_file_spec.SetFile(xcode_dir_path.c_str(), false);
1241             size_t bytes_read = temp_file_spec.ReadFileContents(0, developer_dir_path, sizeof(developer_dir_path), NULL);
1242             if (bytes_read > 0)
1243             {
1244                 developer_dir_path[bytes_read] = '\0';
1245                 while (developer_dir_path[bytes_read-1] == '\r' ||
1246                        developer_dir_path[bytes_read-1] == '\n')
1247                     developer_dir_path[--bytes_read] = '\0';
1248                 developer_dir_path_valid = true;
1249             }
1250         }
1251 
1252         if (!developer_dir_path_valid)
1253         {
1254             FileSpec xcode_select_cmd ("/usr/bin/xcode-select", false);
1255             if (xcode_select_cmd.Exists())
1256             {
1257                 int exit_status = -1;
1258                 int signo = -1;
1259                 std::string command_output;
1260                 Error error = Host::RunShellCommand ("/usr/bin/xcode-select --print-path",
1261                                                      NULL,                                 // current working directory
1262                                                      &exit_status,
1263                                                      &signo,
1264                                                      &command_output,
1265                                                      2,                                     // short timeout
1266                                                      NULL);                                 // don't run in a shell
1267                 if (error.Success() && exit_status == 0 && !command_output.empty())
1268                 {
1269                     const char *cmd_output_ptr = command_output.c_str();
1270                     developer_dir_path[sizeof (developer_dir_path) - 1] = '\0';
1271                     size_t i;
1272                     for (i = 0; i < sizeof (developer_dir_path) - 1; i++)
1273                     {
1274                         if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' || cmd_output_ptr[i] == '\0')
1275                             break;
1276                         developer_dir_path[i] = cmd_output_ptr[i];
1277                     }
1278                     developer_dir_path[i] = '\0';
1279 
1280                     FileSpec devel_dir (developer_dir_path, false);
1281                     if (devel_dir.Exists() && devel_dir.IsDirectory())
1282                     {
1283                         developer_dir_path_valid = true;
1284                     }
1285                 }
1286             }
1287         }
1288 
1289         if (developer_dir_path_valid)
1290         {
1291             temp_file_spec.SetFile (developer_dir_path, false);
1292             if (temp_file_spec.Exists())
1293             {
1294                 m_developer_directory.assign (developer_dir_path);
1295                 return m_developer_directory.c_str();
1296             }
1297         }
1298         // Assign a single NULL character so we know we tried to find the device
1299         // support directory and we don't keep trying to find it over and over.
1300         m_developer_directory.assign (1, '\0');
1301     }
1302 
1303     // We should have put a single NULL character into m_developer_directory
1304     // or it should have a valid path if the code gets here
1305     assert (m_developer_directory.empty() == false);
1306     if (m_developer_directory[0])
1307         return m_developer_directory.c_str();
1308     return NULL;
1309 }
1310 
1311 
1312 BreakpointSP
1313 PlatformDarwin::SetThreadCreationBreakpoint (Target &target)
1314 {
1315     BreakpointSP bp_sp;
1316     static const char *g_bp_names[] =
1317     {
1318         "start_wqthread",
1319         "_pthread_wqthread",
1320         "_pthread_start",
1321     };
1322 
1323     static const char *g_bp_modules[] =
1324     {
1325         "libsystem_c.dylib",
1326         "libSystem.B.dylib"
1327     };
1328 
1329     FileSpecList bp_modules;
1330     for (size_t i = 0; i < sizeof(g_bp_modules)/sizeof(const char *); i++)
1331     {
1332         const char *bp_module = g_bp_modules[i];
1333         bp_modules.Append(FileSpec(bp_module, false));
1334     }
1335 
1336     bool internal = true;
1337     bool hardware = false;
1338     LazyBool skip_prologue = eLazyBoolNo;
1339     bp_sp = target.CreateBreakpoint (&bp_modules,
1340                                      NULL,
1341                                      g_bp_names,
1342                                      sizeof(g_bp_names)/sizeof(const char *),
1343                                      eFunctionNameTypeFull,
1344                                      skip_prologue,
1345                                      internal,
1346                                      hardware);
1347     bp_sp->SetBreakpointKind("thread-creation");
1348 
1349     return bp_sp;
1350 }
1351 
1352 size_t
1353 PlatformDarwin::GetEnvironment (StringList &env)
1354 {
1355     if (IsRemote())
1356     {
1357         if (m_remote_platform_sp)
1358             return m_remote_platform_sp->GetEnvironment(env);
1359         return 0;
1360     }
1361     return Host::GetEnvironment(env);
1362 }
1363 
1364 int32_t
1365 PlatformDarwin::GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info)
1366 {
1367     const char *shell = launch_info.GetShell();
1368     if (shell == NULL)
1369         return 1;
1370 
1371     const char *shell_name = strrchr (shell, '/');
1372     if (shell_name == NULL)
1373         shell_name = shell;
1374     else
1375         shell_name++;
1376 
1377     if (strcmp (shell_name, "sh") == 0)
1378     {
1379         // /bin/sh re-exec's itself as /bin/bash requiring another resume.
1380         // But it only does this if the COMMAND_MODE environment variable
1381         // is set to "legacy".
1382         char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector();
1383         if (envp != NULL)
1384         {
1385             for (int i = 0; envp[i] != NULL; i++)
1386             {
1387                 if (strcmp (envp[i], "COMMAND_MODE=legacy" ) == 0)
1388                     return 2;
1389             }
1390         }
1391         return 1;
1392     }
1393     else if (strcmp (shell_name, "csh") == 0
1394             || strcmp (shell_name, "tcsh") == 0
1395             || strcmp (shell_name, "zsh") == 0)
1396     {
1397         // csh and tcsh always seem to re-exec themselves.
1398         return 2;
1399     }
1400     else
1401         return 1;
1402 }
1403 
1404 void
1405 PlatformDarwin::CalculateTrapHandlerSymbolNames ()
1406 {
1407     m_trap_handlers.push_back (ConstString ("_sigtramp"));
1408 }
1409