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 "PlatformDarwin.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 #include "clang/Basic/VersionTuple.h"
16 // Project includes
17 #include "lldb/Breakpoint/BreakpointLocation.h"
18 #include "lldb/Breakpoint/BreakpointSite.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/HostInfo.h"
27 #include "lldb/Host/FileSystem.h"
28 #include "lldb/Host/Symbols.h"
29 #include "lldb/Interpreter/CommandInterpreter.h"
30 #include "lldb/Symbol/ObjectFile.h"
31 #include "lldb/Symbol/SymbolFile.h"
32 #include "lldb/Symbol/SymbolVendor.h"
33 #include "lldb/Target/Target.h"
34 #include "llvm/ADT/STLExtras.h"
35 
36 using namespace lldb;
37 using namespace lldb_private;
38 
39 
40 //------------------------------------------------------------------
41 /// Default Constructor
42 //------------------------------------------------------------------
43 PlatformDarwin::PlatformDarwin (bool is_host) :
44     PlatformPOSIX(is_host),  // This is the local host platform
45     m_developer_directory ()
46 {
47 }
48 
49 //------------------------------------------------------------------
50 /// Destructor.
51 ///
52 /// The destructor is virtual since this class is designed to be
53 /// inherited from by the plug-in instance.
54 //------------------------------------------------------------------
55 PlatformDarwin::~PlatformDarwin()
56 {
57 }
58 
59 FileSpecList
60 PlatformDarwin::LocateExecutableScriptingResources (Target *target,
61                                                     Module &module,
62                                                     Stream* feedback_stream)
63 {
64     FileSpecList file_list;
65     if (target && target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython)
66     {
67         // NB some extensions might be meaningful and should not be stripped - "this.binary.file"
68         // should not lose ".file" but GetFileNameStrippingExtension() will do precisely that.
69         // Ideally, we should have a per-platform list of extensions (".exe", ".app", ".dSYM", ".framework")
70         // which should be stripped while leaving "this.binary.file" as-is.
71         ScriptInterpreter *script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
72 
73         FileSpec module_spec = module.GetFileSpec();
74 
75         if (module_spec)
76         {
77             SymbolVendor *symbols = module.GetSymbolVendor ();
78             if (symbols)
79             {
80                 SymbolFile *symfile = symbols->GetSymbolFile();
81                 if (symfile)
82                 {
83                     ObjectFile *objfile = symfile->GetObjectFile();
84                     if (objfile)
85                     {
86                         FileSpec symfile_spec (objfile->GetFileSpec());
87                         if (symfile_spec && symfile_spec.Exists())
88                         {
89                             while (module_spec.GetFilename())
90                             {
91                                 std::string module_basename (module_spec.GetFilename().GetCString());
92                                 std::string original_module_basename (module_basename);
93 
94                                 bool was_keyword = false;
95 
96                                 // FIXME: for Python, we cannot allow certain characters in module
97                                 // filenames we import. Theoretically, different scripting languages may
98                                 // have different sets of forbidden tokens in filenames, and that should
99                                 // be dealt with by each ScriptInterpreter. For now, we just replace dots
100                                 // with underscores, but if we ever support anything other than Python
101                                 // we will need to rework this
102                                 std::replace(module_basename.begin(), module_basename.end(), '.', '_');
103                                 std::replace(module_basename.begin(), module_basename.end(), ' ', '_');
104                                 std::replace(module_basename.begin(), module_basename.end(), '-', '_');
105                                 if (script_interpreter && script_interpreter->IsReservedWord(module_basename.c_str()))
106                                 {
107                                     module_basename.insert(module_basename.begin(), '_');
108                                     was_keyword = true;
109                                 }
110 
111                                 StreamString path_string;
112                                 StreamString original_path_string;
113                                 // for OSX we are going to be in .dSYM/Contents/Resources/DWARF/<basename>
114                                 // let us go to .dSYM/Contents/Resources/Python/<basename>.py and see if the file exists
115                                 path_string.Printf("%s/../Python/%s.py",symfile_spec.GetDirectory().GetCString(), module_basename.c_str());
116                                 original_path_string.Printf("%s/../Python/%s.py",symfile_spec.GetDirectory().GetCString(), original_module_basename.c_str());
117                                 FileSpec script_fspec(path_string.GetData(), true);
118                                 FileSpec orig_script_fspec(original_path_string.GetData(), true);
119 
120                                 // if we did some replacements of reserved characters, and a file with the untampered name
121                                 // exists, then warn the user that the file as-is shall not be loaded
122                                 if (feedback_stream)
123                                 {
124                                     if (module_basename != original_module_basename
125                                         && orig_script_fspec.Exists())
126                                     {
127                                         const char* reason_for_complaint = was_keyword ? "conflicts with a keyword" : "contains reserved characters";
128                                         if (script_fspec.Exists())
129                                             feedback_stream->Printf("warning: the symbol file '%s' contains a debug script. However, its name"
130                                                                     " '%s' %s and as such cannot be loaded. LLDB will"
131                                                                     " load '%s' instead. Consider removing the file with the malformed name to"
132                                                                     " eliminate this warning.\n",
133                                                                     symfile_spec.GetPath().c_str(),
134                                                                     original_path_string.GetData(),
135                                                                     reason_for_complaint,
136                                                                     path_string.GetData());
137                                         else
138                                             feedback_stream->Printf("warning: the symbol file '%s' contains a debug script. However, its name"
139                                                                     " %s and as such cannot be loaded. If you intend"
140                                                                     " to have this script loaded, please rename '%s' to '%s' and retry.\n",
141                                                                     symfile_spec.GetPath().c_str(),
142                                                                     reason_for_complaint,
143                                                                     original_path_string.GetData(),
144                                                                     path_string.GetData());
145                                     }
146                                 }
147 
148                                 if (script_fspec.Exists())
149                                 {
150                                     file_list.Append (script_fspec);
151                                     break;
152                                 }
153 
154                                 // If we didn't find the python file, then keep
155                                 // stripping the extensions and try again
156                                 ConstString filename_no_extension (module_spec.GetFileNameStrippingExtension());
157                                 if (module_spec.GetFilename() == filename_no_extension)
158                                     break;
159 
160                                 module_spec.GetFilename() = filename_no_extension;
161                             }
162                         }
163                     }
164                 }
165             }
166         }
167     }
168     return file_list;
169 }
170 
171 Error
172 PlatformDarwin::ResolveExecutable (const ModuleSpec &module_spec,
173                                    lldb::ModuleSP &exe_module_sp,
174                                    const FileSpecList *module_search_paths_ptr)
175 {
176     Error error;
177     // Nothing special to do here, just use the actual file and architecture
178 
179     char exe_path[PATH_MAX];
180     ModuleSpec resolved_module_spec(module_spec);
181 
182     if (IsHost())
183     {
184         // If we have "ls" as the exe_file, resolve the executable loation based on
185         // the current path variables
186         if (!resolved_module_spec.GetFileSpec().Exists())
187         {
188             module_spec.GetFileSpec().GetPath (exe_path, sizeof(exe_path));
189             resolved_module_spec.GetFileSpec().SetFile(exe_path, true);
190         }
191 
192         if (!resolved_module_spec.GetFileSpec().Exists())
193             resolved_module_spec.GetFileSpec().ResolveExecutableLocation ();
194 
195         // Resolve any executable within a bundle on MacOSX
196         Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
197 
198         if (resolved_module_spec.GetFileSpec().Exists())
199             error.Clear();
200         else
201         {
202             const uint32_t permissions = resolved_module_spec.GetFileSpec().GetPermissions();
203             if (permissions && (permissions & eFilePermissionsEveryoneR) == 0)
204                 error.SetErrorStringWithFormat ("executable '%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
205             else
206                 error.SetErrorStringWithFormat ("unable to find executable for '%s'", resolved_module_spec.GetFileSpec().GetPath().c_str());
207         }
208     }
209     else
210     {
211         if (m_remote_platform_sp)
212         {
213             error = GetCachedExecutable (resolved_module_spec, exe_module_sp, module_search_paths_ptr, *m_remote_platform_sp);
214         }
215         else
216         {
217             // We may connect to a process and use the provided executable (Don't use local $PATH).
218 
219             // Resolve any executable within a bundle on MacOSX
220             Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
221 
222             if (resolved_module_spec.GetFileSpec().Exists())
223                 error.Clear();
224             else
225                 error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", resolved_module_spec.GetFileSpec().GetFilename().AsCString(""));
226         }
227     }
228 
229 
230     if (error.Success())
231     {
232         if (resolved_module_spec.GetArchitecture().IsValid())
233         {
234             error = ModuleList::GetSharedModule (resolved_module_spec,
235                                                  exe_module_sp,
236                                                  module_search_paths_ptr,
237                                                  NULL,
238                                                  NULL);
239 
240             if (error.Fail() || exe_module_sp.get() == NULL || exe_module_sp->GetObjectFile() == NULL)
241             {
242                 exe_module_sp.reset();
243                 error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
244                                                 resolved_module_spec.GetFileSpec().GetPath().c_str(),
245                                                 resolved_module_spec.GetArchitecture().GetArchitectureName());
246             }
247         }
248         else
249         {
250             // No valid architecture was specified, ask the platform for
251             // the architectures that we should be using (in the correct order)
252             // and see if we can find a match that way
253             StreamString arch_names;
254             for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
255             {
256                 error = GetSharedModule (resolved_module_spec,
257                                          NULL,
258                                          exe_module_sp,
259                                          module_search_paths_ptr,
260                                          NULL,
261                                          NULL);
262                 // Did we find an executable using one of the
263                 if (error.Success())
264                 {
265                     if (exe_module_sp && exe_module_sp->GetObjectFile())
266                         break;
267                     else
268                         error.SetErrorToGenericError();
269                 }
270 
271                 if (idx > 0)
272                     arch_names.PutCString (", ");
273                 arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName());
274             }
275 
276             if (error.Fail() || !exe_module_sp)
277             {
278                 if (resolved_module_spec.GetFileSpec().Readable())
279                 {
280                     error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
281                                                     resolved_module_spec.GetFileSpec().GetPath().c_str(),
282                                                     GetPluginName().GetCString(),
283                                                     arch_names.GetString().c_str());
284                 }
285                 else
286                 {
287                     error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
288                 }
289             }
290         }
291     }
292 
293     return error;
294 }
295 
296 Error
297 PlatformDarwin::ResolveSymbolFile (Target &target,
298                                    const ModuleSpec &sym_spec,
299                                    FileSpec &sym_file)
300 {
301     Error error;
302     sym_file = sym_spec.GetSymbolFileSpec();
303     if (sym_file.Exists())
304     {
305         if (sym_file.GetFileType() == FileSpec::eFileTypeDirectory)
306         {
307             sym_file = Symbols::FindSymbolFileInBundle (sym_file,
308                                                         sym_spec.GetUUIDPtr(),
309                                                         sym_spec.GetArchitecturePtr());
310         }
311     }
312     else
313     {
314         if (sym_spec.GetUUID().IsValid())
315         {
316 
317         }
318     }
319     return error;
320 
321 }
322 
323 static lldb_private::Error
324 MakeCacheFolderForFile (const FileSpec& module_cache_spec)
325 {
326     FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent();
327     return FileSystem::MakeDirectory(module_cache_folder, eFilePermissionsDirectoryDefault);
328 }
329 
330 static lldb_private::Error
331 BringInRemoteFile (Platform* platform,
332                    const lldb_private::ModuleSpec &module_spec,
333                    const FileSpec& module_cache_spec)
334 {
335     MakeCacheFolderForFile(module_cache_spec);
336     Error err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec);
337     return err;
338 }
339 
340 lldb_private::Error
341 PlatformDarwin::GetSharedModuleWithLocalCache (const lldb_private::ModuleSpec &module_spec,
342                                                lldb::ModuleSP &module_sp,
343                                                const lldb_private::FileSpecList *module_search_paths_ptr,
344                                                lldb::ModuleSP *old_module_sp_ptr,
345                                                bool *did_create_ptr)
346 {
347 
348     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
349     if (log)
350         log->Printf("[%s] Trying to find module %s/%s - platform path %s/%s symbol path %s/%s",
351                      (IsHost() ? "host" : "remote"),
352                      module_spec.GetFileSpec().GetDirectory().AsCString(),
353                      module_spec.GetFileSpec().GetFilename().AsCString(),
354                      module_spec.GetPlatformFileSpec().GetDirectory().AsCString(),
355                      module_spec.GetPlatformFileSpec().GetFilename().AsCString(),
356                      module_spec.GetSymbolFileSpec().GetDirectory().AsCString(),
357                      module_spec.GetSymbolFileSpec().GetFilename().AsCString());
358 
359     Error err;
360 
361     err = ModuleList::GetSharedModule(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
362     if (module_sp)
363         return err;
364 
365     if (!IsHost())
366     {
367         std::string cache_path(GetLocalCacheDirectory());
368         // Only search for a locally cached file if we have a valid cache path
369         if (!cache_path.empty())
370         {
371             std::string module_path (module_spec.GetFileSpec().GetPath());
372             cache_path.append(module_path);
373             FileSpec module_cache_spec(cache_path.c_str(),false);
374 
375             // if rsync is supported, always bring in the file - rsync will be very efficient
376             // when files are the same on the local and remote end of the connection
377             if (this->GetSupportsRSync())
378             {
379                 err = BringInRemoteFile (this, module_spec, module_cache_spec);
380                 if (err.Fail())
381                     return err;
382                 if (module_cache_spec.Exists())
383                 {
384                     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
385                     if (log)
386                         log->Printf("[%s] module %s/%s was rsynced and is now there",
387                                      (IsHost() ? "host" : "remote"),
388                                      module_spec.GetFileSpec().GetDirectory().AsCString(),
389                                      module_spec.GetFileSpec().GetFilename().AsCString());
390                     ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
391                     module_sp.reset(new Module(local_spec));
392                     module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
393                     return Error();
394                 }
395             }
396 
397             // try to find the module in the cache
398             if (module_cache_spec.Exists())
399             {
400                 // get the local and remote MD5 and compare
401                 if (m_remote_platform_sp)
402                 {
403                     // when going over the *slow* GDB remote transfer mechanism we first check
404                     // the hashes of the files - and only do the actual transfer if they differ
405                     uint64_t high_local,high_remote,low_local,low_remote;
406                     FileSystem::CalculateMD5(module_cache_spec, low_local, high_local);
407                     m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(), low_remote, high_remote);
408                     if (low_local != low_remote || high_local != high_remote)
409                     {
410                         // bring in the remote file
411                         Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
412                         if (log)
413                             log->Printf("[%s] module %s/%s needs to be replaced from remote copy",
414                                          (IsHost() ? "host" : "remote"),
415                                          module_spec.GetFileSpec().GetDirectory().AsCString(),
416                                          module_spec.GetFileSpec().GetFilename().AsCString());
417                         Error err = BringInRemoteFile (this, module_spec, module_cache_spec);
418                         if (err.Fail())
419                             return err;
420                     }
421                 }
422 
423                 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
424                 module_sp.reset(new Module(local_spec));
425                 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
426                 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
427                     if (log)
428                         log->Printf("[%s] module %s/%s was found in the cache",
429                                      (IsHost() ? "host" : "remote"),
430                                      module_spec.GetFileSpec().GetDirectory().AsCString(),
431                                      module_spec.GetFileSpec().GetFilename().AsCString());
432                 return Error();
433             }
434 
435             // bring in the remote module file
436             if (log)
437                 log->Printf("[%s] module %s/%s needs to come in remotely",
438                              (IsHost() ? "host" : "remote"),
439                              module_spec.GetFileSpec().GetDirectory().AsCString(),
440                              module_spec.GetFileSpec().GetFilename().AsCString());
441             Error err = BringInRemoteFile (this, module_spec, module_cache_spec);
442             if (err.Fail())
443                 return err;
444             if (module_cache_spec.Exists())
445             {
446                 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
447                 if (log)
448                     log->Printf("[%s] module %s/%s is now cached and fine",
449                                  (IsHost() ? "host" : "remote"),
450                                  module_spec.GetFileSpec().GetDirectory().AsCString(),
451                                  module_spec.GetFileSpec().GetFilename().AsCString());
452                 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
453                 module_sp.reset(new Module(local_spec));
454                 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
455                 return Error();
456             }
457             else
458                 return Error("unable to obtain valid module file");
459         }
460         else
461             return Error("no cache path");
462     }
463     else
464         return Error ("unable to resolve module");
465 }
466 
467 Error
468 PlatformDarwin::GetSharedModule (const ModuleSpec &module_spec,
469                                  Process* process,
470                                  ModuleSP &module_sp,
471                                  const FileSpecList *module_search_paths_ptr,
472                                  ModuleSP *old_module_sp_ptr,
473                                  bool *did_create_ptr)
474 {
475     Error error;
476     module_sp.reset();
477 
478     if (IsRemote())
479     {
480         // If we have a remote platform always, let it try and locate
481         // the shared module first.
482         if (m_remote_platform_sp)
483         {
484             error = m_remote_platform_sp->GetSharedModule (module_spec,
485                                                            process,
486                                                            module_sp,
487                                                            module_search_paths_ptr,
488                                                            old_module_sp_ptr,
489                                                            did_create_ptr);
490         }
491     }
492 
493     if (!module_sp)
494     {
495         // Fall back to the local platform and find the file locally
496         error = Platform::GetSharedModule (module_spec,
497                                            process,
498                                            module_sp,
499                                            module_search_paths_ptr,
500                                            old_module_sp_ptr,
501                                            did_create_ptr);
502 
503         const FileSpec &platform_file = module_spec.GetFileSpec();
504         if (!module_sp && module_search_paths_ptr && platform_file)
505         {
506             // We can try to pull off part of the file path up to the bundle
507             // directory level and try any module search paths...
508             FileSpec bundle_directory;
509             if (Host::GetBundleDirectory (platform_file, bundle_directory))
510             {
511                 if (platform_file == bundle_directory)
512                 {
513                     ModuleSpec new_module_spec (module_spec);
514                     new_module_spec.GetFileSpec() = bundle_directory;
515                     if (Host::ResolveExecutableInBundle (new_module_spec.GetFileSpec()))
516                     {
517                         Error new_error (Platform::GetSharedModule (new_module_spec,
518                                                                     process,
519                                                                     module_sp,
520                                                                     NULL,
521                                                                     old_module_sp_ptr,
522                                                                     did_create_ptr));
523 
524                         if (module_sp)
525                             return new_error;
526                     }
527                 }
528                 else
529                 {
530                     char platform_path[PATH_MAX];
531                     char bundle_dir[PATH_MAX];
532                     platform_file.GetPath (platform_path, sizeof(platform_path));
533                     const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir));
534                     char new_path[PATH_MAX];
535                     size_t num_module_search_paths = module_search_paths_ptr->GetSize();
536                     for (size_t i=0; i<num_module_search_paths; ++i)
537                     {
538                         const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path));
539                         if (search_path_len < sizeof(new_path))
540                         {
541                             snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len);
542                             FileSpec new_file_spec (new_path, false);
543                             if (new_file_spec.Exists())
544                             {
545                                 ModuleSpec new_module_spec (module_spec);
546                                 new_module_spec.GetFileSpec() = new_file_spec;
547                                 Error new_error (Platform::GetSharedModule (new_module_spec,
548                                                                             process,
549                                                                             module_sp,
550                                                                             NULL,
551                                                                             old_module_sp_ptr,
552                                                                             did_create_ptr));
553 
554                                 if (module_sp)
555                                 {
556                                     module_sp->SetPlatformFileSpec(new_file_spec);
557                                     return new_error;
558                                 }
559                             }
560                         }
561                     }
562                 }
563             }
564         }
565     }
566     if (module_sp)
567         module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
568     return error;
569 }
570 
571 size_t
572 PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
573 {
574     const uint8_t *trap_opcode = NULL;
575     uint32_t trap_opcode_size = 0;
576     bool bp_is_thumb = false;
577 
578     llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
579     switch (machine)
580     {
581     case llvm::Triple::x86:
582     case llvm::Triple::x86_64:
583         {
584             static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
585             trap_opcode = g_i386_breakpoint_opcode;
586             trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
587         }
588         break;
589 
590     case llvm::Triple::aarch64:
591         {
592             // TODO: fix this with actual darwin breakpoint opcode for arm64.
593             // right now debugging uses the Z packets with GDB remote so this
594             // is not needed, but the size needs to be correct...
595             static const uint8_t g_arm64_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
596             trap_opcode = g_arm64_breakpoint_opcode;
597             trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);
598         }
599         break;
600 
601     case llvm::Triple::thumb:
602         bp_is_thumb = true; // Fall through...
603     case llvm::Triple::arm:
604         {
605             static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
606             static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE };
607 
608             // Auto detect arm/thumb if it wasn't explicitly specified
609             if (!bp_is_thumb)
610             {
611                 lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
612                 if (bp_loc_sp)
613                     bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass () == eAddressClassCodeAlternateISA;
614             }
615             if (bp_is_thumb)
616             {
617                 trap_opcode = g_thumb_breakpooint_opcode;
618                 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode);
619                 break;
620             }
621             trap_opcode = g_arm_breakpoint_opcode;
622             trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
623         }
624         break;
625 
626     case llvm::Triple::ppc:
627     case llvm::Triple::ppc64:
628         {
629             static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 };
630             trap_opcode = g_ppc_breakpoint_opcode;
631             trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
632         }
633         break;
634 
635     default:
636         assert(!"Unhandled architecture in PlatformDarwin::GetSoftwareBreakpointTrapOpcode()");
637         break;
638     }
639 
640     if (trap_opcode && trap_opcode_size)
641     {
642         if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
643             return trap_opcode_size;
644     }
645     return 0;
646 
647 }
648 
649 bool
650 PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
651 {
652     bool sucess = false;
653     if (IsHost())
654     {
655         sucess = Platform::GetProcessInfo (pid, process_info);
656     }
657     else
658     {
659         if (m_remote_platform_sp)
660             sucess = m_remote_platform_sp->GetProcessInfo (pid, process_info);
661     }
662     return sucess;
663 }
664 
665 uint32_t
666 PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info,
667                                ProcessInstanceInfoList &process_infos)
668 {
669     uint32_t match_count = 0;
670     if (IsHost())
671     {
672         // Let the base class figure out the host details
673         match_count = Platform::FindProcesses (match_info, process_infos);
674     }
675     else
676     {
677         // If we are remote, we can only return results if we are connected
678         if (m_remote_platform_sp)
679             match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos);
680     }
681     return match_count;
682 }
683 
684 bool
685 PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp)
686 {
687     if (!module_sp)
688         return false;
689 
690     ObjectFile *obj_file = module_sp->GetObjectFile();
691     if (!obj_file)
692         return false;
693 
694     ObjectFile::Type obj_type = obj_file->GetType();
695     if (obj_type == ObjectFile::eTypeDynamicLinker)
696         return true;
697     else
698         return false;
699 }
700 
701 bool
702 PlatformDarwin::x86GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
703 {
704     ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
705     if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h)
706     {
707         switch (idx)
708         {
709             case 0:
710                 arch = host_arch;
711                 return true;
712 
713             case 1:
714                 arch.SetTriple("x86_64-apple-macosx");
715                 return true;
716 
717             case 2:
718                 arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
719                 return true;
720 
721             default: return false;
722         }
723     }
724     else
725     {
726         if (idx == 0)
727         {
728             arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
729             return arch.IsValid();
730         }
731         else if (idx == 1)
732         {
733             ArchSpec platform_arch(HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
734             ArchSpec platform_arch64(HostInfo::GetArchitecture(HostInfo::eArchKind64));
735             if (platform_arch.IsExactMatch(platform_arch64))
736             {
737                 // This macosx platform supports both 32 and 64 bit. Since we already
738                 // returned the 64 bit arch for idx == 0, return the 32 bit arch
739                 // for idx == 1
740                 arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
741                 return arch.IsValid();
742             }
743         }
744     }
745     return false;
746 }
747 
748 // The architecture selection rules for arm processors
749 // These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f processor.
750 
751 bool
752 PlatformDarwin::ARMGetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
753 {
754     ArchSpec system_arch (GetSystemArchitecture());
755 
756     const ArchSpec::Core system_core = system_arch.GetCore();
757     switch (system_core)
758     {
759     default:
760         switch (idx)
761         {
762             case  0: arch.SetTriple ("arm64-apple-ios");    return true;
763             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
764             case  2: arch.SetTriple ("armv7f-apple-ios");   return true;
765             case  3: arch.SetTriple ("armv7k-apple-ios");   return true;
766             case  4: arch.SetTriple ("armv7s-apple-ios");   return true;
767             case  5: arch.SetTriple ("armv7m-apple-ios");   return true;
768             case  6: arch.SetTriple ("armv7em-apple-ios");  return true;
769             case  7: arch.SetTriple ("armv6m-apple-ios");   return true;
770             case  8: arch.SetTriple ("armv6-apple-ios");    return true;
771             case  9: arch.SetTriple ("armv5-apple-ios");    return true;
772             case 10: arch.SetTriple ("armv4-apple-ios");    return true;
773             case 11: arch.SetTriple ("arm-apple-ios");      return true;
774             case 12: arch.SetTriple ("thumbv7-apple-ios");  return true;
775             case 13: arch.SetTriple ("thumbv7f-apple-ios"); return true;
776             case 14: arch.SetTriple ("thumbv7k-apple-ios"); return true;
777             case 15: arch.SetTriple ("thumbv7s-apple-ios"); return true;
778             case 16: arch.SetTriple ("thumbv7m-apple-ios"); return true;
779             case 17: arch.SetTriple ("thumbv7em-apple-ios"); return true;
780             case 18: arch.SetTriple ("thumbv6m-apple-ios"); return true;
781             case 19: arch.SetTriple ("thumbv6-apple-ios");  return true;
782             case 20: arch.SetTriple ("thumbv5-apple-ios");  return true;
783             case 21: arch.SetTriple ("thumbv4t-apple-ios"); return true;
784             case 22: arch.SetTriple ("thumb-apple-ios");    return true;
785             default: break;
786         }
787         break;
788 
789     case ArchSpec::eCore_arm_arm64:
790         switch (idx)
791         {
792             case  0: arch.SetTriple ("arm64-apple-ios");   return true;
793             case  1: arch.SetTriple ("armv7s-apple-ios");   return true;
794             case  2: arch.SetTriple ("armv7f-apple-ios");   return true;
795             case  3: arch.SetTriple ("armv7m-apple-ios");   return true;
796             case  4: arch.SetTriple ("armv7em-apple-ios");  return true;
797             case  5: arch.SetTriple ("armv7-apple-ios");    return true;
798             case  6: arch.SetTriple ("armv6m-apple-ios");   return true;
799             case  7: arch.SetTriple ("armv6-apple-ios");    return true;
800             case  8: arch.SetTriple ("armv5-apple-ios");    return true;
801             case  9: arch.SetTriple ("armv4-apple-ios");    return true;
802             case 10: arch.SetTriple ("arm-apple-ios");      return true;
803             case 11: arch.SetTriple ("thumbv7-apple-ios");  return true;
804             case 12: arch.SetTriple ("thumbv7f-apple-ios"); return true;
805             case 13: arch.SetTriple ("thumbv7k-apple-ios"); return true;
806             case 14: arch.SetTriple ("thumbv7s-apple-ios"); return true;
807             case 15: arch.SetTriple ("thumbv7m-apple-ios"); return true;
808             case 16: arch.SetTriple ("thumbv7em-apple-ios"); return true;
809             case 17: arch.SetTriple ("thumbv6m-apple-ios"); return true;
810             case 18: arch.SetTriple ("thumbv6-apple-ios");  return true;
811             case 19: arch.SetTriple ("thumbv5-apple-ios");  return true;
812             case 20: arch.SetTriple ("thumbv4t-apple-ios"); return true;
813             case 21: arch.SetTriple ("thumb-apple-ios");    return true;
814         default: break;
815         }
816         break;
817 
818     case ArchSpec::eCore_arm_armv7f:
819         switch (idx)
820         {
821             case  0: arch.SetTriple ("armv7f-apple-ios");   return true;
822             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
823             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
824             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
825             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
826             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
827             case  6: arch.SetTriple ("arm-apple-ios");      return true;
828             case  7: arch.SetTriple ("thumbv7f-apple-ios"); return true;
829             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
830             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
831             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
832             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
833             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
834             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
835             default: break;
836         }
837         break;
838 
839     case ArchSpec::eCore_arm_armv7k:
840         switch (idx)
841         {
842             case  0: arch.SetTriple ("armv7k-apple-ios");   return true;
843             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
844             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
845             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
846             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
847             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
848             case  6: arch.SetTriple ("arm-apple-ios");      return true;
849             case  7: arch.SetTriple ("thumbv7k-apple-ios"); return true;
850             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
851             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
852             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
853             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
854             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
855             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
856             default: break;
857         }
858         break;
859 
860     case ArchSpec::eCore_arm_armv7s:
861         switch (idx)
862         {
863             case  0: arch.SetTriple ("armv7s-apple-ios");   return true;
864             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
865             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
866             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
867             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
868             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
869             case  6: arch.SetTriple ("arm-apple-ios");      return true;
870             case  7: arch.SetTriple ("thumbv7s-apple-ios"); return true;
871             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
872             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
873             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
874             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
875             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
876             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
877             default: break;
878         }
879         break;
880 
881     case ArchSpec::eCore_arm_armv7m:
882         switch (idx)
883         {
884             case  0: arch.SetTriple ("armv7m-apple-ios");   return true;
885             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
886             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
887             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
888             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
889             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
890             case  6: arch.SetTriple ("arm-apple-ios");      return true;
891             case  7: arch.SetTriple ("thumbv7m-apple-ios"); return true;
892             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
893             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
894             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
895             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
896             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
897             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
898             default: break;
899         }
900         break;
901 
902     case ArchSpec::eCore_arm_armv7em:
903         switch (idx)
904         {
905             case  0: arch.SetTriple ("armv7em-apple-ios");  return true;
906             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
907             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
908             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
909             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
910             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
911             case  6: arch.SetTriple ("arm-apple-ios");      return true;
912             case  7: arch.SetTriple ("thumbv7em-apple-ios"); return true;
913             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
914             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
915             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
916             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
917             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
918             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
919             default: break;
920         }
921         break;
922 
923     case ArchSpec::eCore_arm_armv7:
924         switch (idx)
925         {
926             case  0: arch.SetTriple ("armv7-apple-ios");    return true;
927             case  1: arch.SetTriple ("armv6m-apple-ios");   return true;
928             case  2: arch.SetTriple ("armv6-apple-ios");    return true;
929             case  3: arch.SetTriple ("armv5-apple-ios");    return true;
930             case  4: arch.SetTriple ("armv4-apple-ios");    return true;
931             case  5: arch.SetTriple ("arm-apple-ios");      return true;
932             case  6: arch.SetTriple ("thumbv7-apple-ios");  return true;
933             case  7: arch.SetTriple ("thumbv6m-apple-ios"); return true;
934             case  8: arch.SetTriple ("thumbv6-apple-ios");  return true;
935             case  9: arch.SetTriple ("thumbv5-apple-ios");  return true;
936             case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
937             case 11: arch.SetTriple ("thumb-apple-ios");    return true;
938             default: break;
939         }
940         break;
941 
942     case ArchSpec::eCore_arm_armv6m:
943         switch (idx)
944         {
945             case 0: arch.SetTriple ("armv6m-apple-ios");   return true;
946             case 1: arch.SetTriple ("armv6-apple-ios");    return true;
947             case 2: arch.SetTriple ("armv5-apple-ios");    return true;
948             case 3: arch.SetTriple ("armv4-apple-ios");    return true;
949             case 4: arch.SetTriple ("arm-apple-ios");      return true;
950             case 5: arch.SetTriple ("thumbv6m-apple-ios"); return true;
951             case 6: arch.SetTriple ("thumbv6-apple-ios");  return true;
952             case 7: arch.SetTriple ("thumbv5-apple-ios");  return true;
953             case 8: arch.SetTriple ("thumbv4t-apple-ios"); return true;
954             case 9: arch.SetTriple ("thumb-apple-ios");    return true;
955             default: break;
956         }
957         break;
958 
959     case ArchSpec::eCore_arm_armv6:
960         switch (idx)
961         {
962             case 0: arch.SetTriple ("armv6-apple-ios");    return true;
963             case 1: arch.SetTriple ("armv5-apple-ios");    return true;
964             case 2: arch.SetTriple ("armv4-apple-ios");    return true;
965             case 3: arch.SetTriple ("arm-apple-ios");      return true;
966             case 4: arch.SetTriple ("thumbv6-apple-ios");  return true;
967             case 5: arch.SetTriple ("thumbv5-apple-ios");  return true;
968             case 6: arch.SetTriple ("thumbv4t-apple-ios"); return true;
969             case 7: arch.SetTriple ("thumb-apple-ios");    return true;
970             default: break;
971         }
972         break;
973 
974     case ArchSpec::eCore_arm_armv5:
975         switch (idx)
976         {
977             case 0: arch.SetTriple ("armv5-apple-ios");    return true;
978             case 1: arch.SetTriple ("armv4-apple-ios");    return true;
979             case 2: arch.SetTriple ("arm-apple-ios");      return true;
980             case 3: arch.SetTriple ("thumbv5-apple-ios");  return true;
981             case 4: arch.SetTriple ("thumbv4t-apple-ios"); return true;
982             case 5: arch.SetTriple ("thumb-apple-ios");    return true;
983             default: break;
984         }
985         break;
986 
987     case ArchSpec::eCore_arm_armv4:
988         switch (idx)
989         {
990             case 0: arch.SetTriple ("armv4-apple-ios");    return true;
991             case 1: arch.SetTriple ("arm-apple-ios");      return true;
992             case 2: arch.SetTriple ("thumbv4t-apple-ios"); return true;
993             case 3: arch.SetTriple ("thumb-apple-ios");    return true;
994             default: break;
995         }
996         break;
997     }
998     arch.Clear();
999     return false;
1000 }
1001 
1002 
1003 const char *
1004 PlatformDarwin::GetDeveloperDirectory()
1005 {
1006     Mutex::Locker locker (m_mutex);
1007     if (m_developer_directory.empty())
1008     {
1009         bool developer_dir_path_valid = false;
1010         char developer_dir_path[PATH_MAX];
1011         FileSpec temp_file_spec;
1012         if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, temp_file_spec))
1013         {
1014             if (temp_file_spec.GetPath (developer_dir_path, sizeof(developer_dir_path)))
1015             {
1016                 char *shared_frameworks = strstr (developer_dir_path, "/SharedFrameworks/LLDB.framework");
1017                 if (shared_frameworks)
1018                 {
1019                     ::snprintf (shared_frameworks,
1020                                 sizeof(developer_dir_path) - (shared_frameworks - developer_dir_path),
1021                                 "/Developer");
1022                     developer_dir_path_valid = true;
1023                 }
1024                 else
1025                 {
1026                     char *lib_priv_frameworks = strstr (developer_dir_path, "/Library/PrivateFrameworks/LLDB.framework");
1027                     if (lib_priv_frameworks)
1028                     {
1029                         *lib_priv_frameworks = '\0';
1030                         developer_dir_path_valid = true;
1031                     }
1032                 }
1033             }
1034         }
1035 
1036         if (!developer_dir_path_valid)
1037         {
1038             std::string xcode_dir_path;
1039             const char *xcode_select_prefix_dir = getenv ("XCODE_SELECT_PREFIX_DIR");
1040             if (xcode_select_prefix_dir)
1041                 xcode_dir_path.append (xcode_select_prefix_dir);
1042             xcode_dir_path.append ("/usr/share/xcode-select/xcode_dir_path");
1043             temp_file_spec.SetFile(xcode_dir_path.c_str(), false);
1044             size_t bytes_read = temp_file_spec.ReadFileContents(0, developer_dir_path, sizeof(developer_dir_path), NULL);
1045             if (bytes_read > 0)
1046             {
1047                 developer_dir_path[bytes_read] = '\0';
1048                 while (developer_dir_path[bytes_read-1] == '\r' ||
1049                        developer_dir_path[bytes_read-1] == '\n')
1050                     developer_dir_path[--bytes_read] = '\0';
1051                 developer_dir_path_valid = true;
1052             }
1053         }
1054 
1055         if (!developer_dir_path_valid)
1056         {
1057             FileSpec xcode_select_cmd ("/usr/bin/xcode-select", false);
1058             if (xcode_select_cmd.Exists())
1059             {
1060                 int exit_status = -1;
1061                 int signo = -1;
1062                 std::string command_output;
1063                 Error error = Host::RunShellCommand ("/usr/bin/xcode-select --print-path",
1064                                                      NULL,                                 // current working directory
1065                                                      &exit_status,
1066                                                      &signo,
1067                                                      &command_output,
1068                                                      2,                                     // short timeout
1069                                                      false);                                // don't run in a shell
1070                 if (error.Success() && exit_status == 0 && !command_output.empty())
1071                 {
1072                     const char *cmd_output_ptr = command_output.c_str();
1073                     developer_dir_path[sizeof (developer_dir_path) - 1] = '\0';
1074                     size_t i;
1075                     for (i = 0; i < sizeof (developer_dir_path) - 1; i++)
1076                     {
1077                         if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' || cmd_output_ptr[i] == '\0')
1078                             break;
1079                         developer_dir_path[i] = cmd_output_ptr[i];
1080                     }
1081                     developer_dir_path[i] = '\0';
1082 
1083                     FileSpec devel_dir (developer_dir_path, false);
1084                     if (devel_dir.Exists() && devel_dir.IsDirectory())
1085                     {
1086                         developer_dir_path_valid = true;
1087                     }
1088                 }
1089             }
1090         }
1091 
1092         if (developer_dir_path_valid)
1093         {
1094             temp_file_spec.SetFile (developer_dir_path, false);
1095             if (temp_file_spec.Exists())
1096             {
1097                 m_developer_directory.assign (developer_dir_path);
1098                 return m_developer_directory.c_str();
1099             }
1100         }
1101         // Assign a single NULL character so we know we tried to find the device
1102         // support directory and we don't keep trying to find it over and over.
1103         m_developer_directory.assign (1, '\0');
1104     }
1105 
1106     // We should have put a single NULL character into m_developer_directory
1107     // or it should have a valid path if the code gets here
1108     assert (m_developer_directory.empty() == false);
1109     if (m_developer_directory[0])
1110         return m_developer_directory.c_str();
1111     return NULL;
1112 }
1113 
1114 
1115 BreakpointSP
1116 PlatformDarwin::SetThreadCreationBreakpoint (Target &target)
1117 {
1118     BreakpointSP bp_sp;
1119     static const char *g_bp_names[] =
1120     {
1121         "start_wqthread",
1122         "_pthread_wqthread",
1123         "_pthread_start",
1124     };
1125 
1126     static const char *g_bp_modules[] =
1127     {
1128         "libsystem_c.dylib",
1129         "libSystem.B.dylib"
1130     };
1131 
1132     FileSpecList bp_modules;
1133     for (size_t i = 0; i < llvm::array_lengthof(g_bp_modules); i++)
1134     {
1135         const char *bp_module = g_bp_modules[i];
1136         bp_modules.Append(FileSpec(bp_module, false));
1137     }
1138 
1139     bool internal = true;
1140     bool hardware = false;
1141     LazyBool skip_prologue = eLazyBoolNo;
1142     bp_sp = target.CreateBreakpoint (&bp_modules,
1143                                      NULL,
1144                                      g_bp_names,
1145                                      llvm::array_lengthof(g_bp_names),
1146                                      eFunctionNameTypeFull,
1147                                      skip_prologue,
1148                                      internal,
1149                                      hardware);
1150     bp_sp->SetBreakpointKind("thread-creation");
1151 
1152     return bp_sp;
1153 }
1154 
1155 
1156 int32_t
1157 PlatformDarwin::GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info)
1158 {
1159     const FileSpec &shell = launch_info.GetShell();
1160     if (!shell)
1161         return 1;
1162 
1163     std::string shell_string = shell.GetPath();
1164     const char *shell_name = strrchr (shell_string.c_str(), '/');
1165     if (shell_name == NULL)
1166         shell_name = shell_string.c_str();
1167     else
1168         shell_name++;
1169 
1170     if (strcmp (shell_name, "sh") == 0)
1171     {
1172         // /bin/sh re-exec's itself as /bin/bash requiring another resume.
1173         // But it only does this if the COMMAND_MODE environment variable
1174         // is set to "legacy".
1175         const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector();
1176         if (envp != NULL)
1177         {
1178             for (int i = 0; envp[i] != NULL; i++)
1179             {
1180                 if (strcmp (envp[i], "COMMAND_MODE=legacy" ) == 0)
1181                     return 2;
1182             }
1183         }
1184         return 1;
1185     }
1186     else if (strcmp (shell_name, "csh") == 0
1187             || strcmp (shell_name, "tcsh") == 0
1188             || strcmp (shell_name, "zsh") == 0)
1189     {
1190         // csh and tcsh always seem to re-exec themselves.
1191         return 2;
1192     }
1193     else
1194         return 1;
1195 }
1196 
1197 void
1198 PlatformDarwin::CalculateTrapHandlerSymbolNames ()
1199 {
1200     m_trap_handlers.push_back (ConstString ("_sigtramp"));
1201 }
1202 
1203 
1204 static const char *const sdk_strings[] = {
1205     "MacOSX",
1206     "iPhoneSimulator",
1207     "iPhoneOS",
1208 };
1209 
1210 static FileSpec
1211 GetXcodeContentsPath ()
1212 {
1213     const char substr[] = ".app/Contents/";
1214 
1215     // First, try based on the current shlib's location
1216 
1217     {
1218         FileSpec fspec;
1219 
1220         if (HostInfo::GetLLDBPath (lldb::ePathTypeLLDBShlibDir, fspec))
1221         {
1222             std::string path_to_shlib = fspec.GetPath();
1223             size_t pos = path_to_shlib.rfind(substr);
1224             if (pos != std::string::npos)
1225             {
1226                 path_to_shlib.erase(pos + strlen(substr));
1227                 return FileSpec(path_to_shlib.c_str(), false);
1228             }
1229         }
1230     }
1231 
1232     // Fall back to using xcrun
1233 
1234     {
1235         int status = 0;
1236         int signo = 0;
1237         std::string output;
1238         const char *command = "xcrun -sdk macosx --show-sdk-path";
1239         lldb_private::Error error = Host::RunShellCommand (command,   // shell command to run
1240                                                            NULL,      // current working directory
1241                                                            &status,   // Put the exit status of the process in here
1242                                                            &signo,    // Put the signal that caused the process to exit in here
1243                                                            &output,   // Get the output from the command and place it in this string
1244                                                            3);        // Timeout in seconds to wait for shell program to finish
1245         if (status == 0 && !output.empty())
1246         {
1247             size_t first_non_newline = output.find_last_not_of("\r\n");
1248             if (first_non_newline != std::string::npos)
1249             {
1250                 output.erase(first_non_newline+1);
1251             }
1252 
1253             size_t pos = output.rfind(substr);
1254             if (pos != std::string::npos)
1255             {
1256                 output.erase(pos + strlen(substr));
1257                 return FileSpec(output.c_str(), false);
1258             }
1259         }
1260     }
1261 
1262     return FileSpec();
1263 }
1264 
1265 bool
1266 PlatformDarwin::SDKSupportsModules (SDKType sdk_type, uint32_t major, uint32_t minor, uint32_t micro)
1267 {
1268     switch (sdk_type)
1269     {
1270         case SDKType::MacOSX:
1271             if (major > 10 || (major == 10 && minor >= 10))
1272                 return true;
1273             break;
1274         case SDKType::iPhoneOS:
1275         case SDKType::iPhoneSimulator:
1276             if (major >= 8)
1277                 return true;
1278             break;
1279     }
1280 
1281     return false;
1282 }
1283 
1284 bool
1285 PlatformDarwin::SDKSupportsModules (SDKType desired_type, const FileSpec &sdk_path)
1286 {
1287     ConstString last_path_component = sdk_path.GetLastPathComponent();
1288 
1289     if (last_path_component)
1290     {
1291         const llvm::StringRef sdk_name = last_path_component.GetStringRef();
1292 
1293         llvm::StringRef version_part;
1294 
1295         if (sdk_name.startswith(sdk_strings[(int)desired_type]))
1296         {
1297             version_part = sdk_name.drop_front(strlen(sdk_strings[(int)desired_type]));
1298         }
1299         else
1300         {
1301             return false;
1302         }
1303 
1304         const size_t major_dot_offset = version_part.find('.');
1305         if (major_dot_offset == llvm::StringRef::npos)
1306             return false;
1307 
1308         const llvm::StringRef major_version = version_part.slice(0, major_dot_offset);
1309         const llvm::StringRef minor_part = version_part.drop_front(major_dot_offset + 1);
1310 
1311         const size_t minor_dot_offset = minor_part.find('.');
1312         if (minor_dot_offset == llvm::StringRef::npos)
1313             return false;
1314 
1315         const llvm::StringRef minor_version = minor_part.slice(0, minor_dot_offset);
1316 
1317         unsigned int major = 0;
1318         unsigned int minor = 0;
1319         unsigned int micro = 0;
1320 
1321         if (major_version.getAsInteger(10, major))
1322             return false;
1323 
1324         if (minor_version.getAsInteger(10, minor))
1325             return false;
1326 
1327         return SDKSupportsModules(desired_type, major, minor, micro);
1328     }
1329 
1330     return false;
1331 }
1332 
1333 FileSpec::EnumerateDirectoryResult
1334 PlatformDarwin::DirectoryEnumerator(void *baton,
1335                                     FileSpec::FileType file_type,
1336                                     const FileSpec &spec)
1337 {
1338     SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo*>(baton);
1339 
1340     if (SDKSupportsModules(enumerator_info->sdk_type, spec))
1341     {
1342         enumerator_info->found_path = spec;
1343         return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
1344     }
1345 
1346     return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;
1347 }
1348 
1349 FileSpec
1350 PlatformDarwin::FindSDKInXcodeForModules (SDKType sdk_type,
1351                                           const FileSpec &sdks_spec)
1352 {
1353     // Look inside Xcode for the required installed iOS SDK version
1354 
1355     if (!sdks_spec.IsDirectory())
1356         return FileSpec();
1357 
1358     const bool find_directories = true;
1359     const bool find_files = false;
1360     const bool find_other = true; // include symlinks
1361 
1362     SDKEnumeratorInfo enumerator_info;
1363 
1364     enumerator_info.sdk_type = sdk_type;
1365 
1366     FileSpec::EnumerateDirectory(sdks_spec.GetPath().c_str(),
1367                                  find_directories,
1368                                  find_files,
1369                                  find_other,
1370                                  DirectoryEnumerator,
1371                                  &enumerator_info);
1372 
1373     if (enumerator_info.found_path.IsDirectory())
1374         return enumerator_info.found_path;
1375     else
1376         return FileSpec();
1377 }
1378 
1379 FileSpec
1380 PlatformDarwin::GetSDKDirectoryForModules (SDKType sdk_type)
1381 {
1382     switch (sdk_type)
1383     {
1384         case SDKType::MacOSX:
1385         case SDKType::iPhoneSimulator:
1386         case SDKType::iPhoneOS:
1387             break;
1388     }
1389 
1390     FileSpec sdks_spec = GetXcodeContentsPath();
1391     sdks_spec.AppendPathComponent("Developer");
1392     sdks_spec.AppendPathComponent("Platforms");
1393 
1394     switch (sdk_type)
1395     {
1396         case SDKType::MacOSX:
1397             sdks_spec.AppendPathComponent("MacOSX.platform");
1398             break;
1399         case SDKType::iPhoneSimulator:
1400             sdks_spec.AppendPathComponent("iPhoneSimulator.platform");
1401             break;
1402         case SDKType::iPhoneOS:
1403             sdks_spec.AppendPathComponent("iPhoneOS.platform");
1404             break;
1405     }
1406 
1407     sdks_spec.AppendPathComponent("Developer");
1408     sdks_spec.AppendPathComponent("SDKs");
1409 
1410     if (sdk_type == SDKType::MacOSX)
1411     {
1412         uint32_t major = 0;
1413         uint32_t minor = 0;
1414         uint32_t micro = 0;
1415 
1416         if (HostInfo::GetOSVersion(major, minor, micro))
1417         {
1418             if (SDKSupportsModules(SDKType::MacOSX, major, minor, micro))
1419             {
1420                 // We slightly prefer the exact SDK for this machine.  See if it is there.
1421 
1422                 FileSpec native_sdk_spec = sdks_spec;
1423                 StreamString native_sdk_name;
1424                 native_sdk_name.Printf("MacOSX%u.%u.sdk", major, minor);
1425                 native_sdk_spec.AppendPathComponent(native_sdk_name.GetString().c_str());
1426 
1427                 if (native_sdk_spec.Exists())
1428                 {
1429                     return native_sdk_spec;
1430                 }
1431             }
1432         }
1433     }
1434 
1435     return FindSDKInXcodeForModules(sdk_type, sdks_spec);
1436 }
1437 
1438 void
1439 PlatformDarwin::AddClangModuleCompilationOptionsForSDKType (Target *target, std::vector<std::string> &options, SDKType sdk_type)
1440 {
1441     const std::vector<std::string> apple_arguments =
1442     {
1443         "-x", "objective-c++",
1444         "-fobjc-arc",
1445         "-fblocks",
1446         "-D_ISO646_H",
1447         "-D__ISO646_H"
1448     };
1449 
1450     options.insert(options.end(),
1451                    apple_arguments.begin(),
1452                    apple_arguments.end());
1453 
1454     StreamString minimum_version_option;
1455     uint32_t versions[3] = { 0, 0, 0 };
1456     bool use_current_os_version = false;
1457     switch (sdk_type)
1458     {
1459         case SDKType::iPhoneOS:
1460 #if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
1461             use_current_os_version = true;
1462 #else
1463             use_current_os_version = false;
1464 #endif
1465             break;
1466 
1467         case SDKType::iPhoneSimulator:
1468             use_current_os_version = false;
1469             break;
1470 
1471         case SDKType::MacOSX:
1472 #if defined (__i386__) || defined (__x86_64__)
1473             use_current_os_version = true;
1474 #else
1475             use_current_os_version = false;
1476 #endif
1477             break;
1478     }
1479 
1480     bool versions_valid = false;
1481     if (use_current_os_version)
1482         versions_valid = GetOSVersion(versions[0], versions[1], versions[2]);
1483     else if (target)
1484     {
1485         // Our OS doesn't match our executable so we need to get the min OS version from the object file
1486         ModuleSP exe_module_sp = target->GetExecutableModule();
1487         if (exe_module_sp)
1488         {
1489             ObjectFile *object_file = exe_module_sp->GetObjectFile();
1490             if (object_file)
1491                 versions_valid = object_file->GetMinimumOSVersion(versions, 3) > 0;
1492         }
1493     }
1494     // Only add the version-min options if we got a version from somewhere
1495     if (versions_valid && versions[0] != UINT32_MAX)
1496     {
1497         // Make any invalid versions be zero if needed
1498         if (versions[1] == UINT32_MAX)
1499             versions[1] = 0;
1500         if (versions[2] == UINT32_MAX)
1501             versions[2] = 0;
1502 
1503         switch (sdk_type)
1504         {
1505         case SDKType::iPhoneOS:
1506             minimum_version_option.PutCString("-mios-version-min=");
1507             minimum_version_option.PutCString(clang::VersionTuple(versions[0], versions[1], versions[2]).getAsString().c_str());
1508             break;
1509         case SDKType::iPhoneSimulator:
1510             minimum_version_option.PutCString("-mios-simulator-version-min=");
1511             minimum_version_option.PutCString(clang::VersionTuple(versions[0], versions[1], versions[2]).getAsString().c_str());
1512             break;
1513         case SDKType::MacOSX:
1514             minimum_version_option.PutCString("-mmacosx-version-min=");
1515             minimum_version_option.PutCString(clang::VersionTuple(versions[0], versions[1], versions[2]).getAsString().c_str());
1516         }
1517         options.push_back(minimum_version_option.GetString());
1518     }
1519 
1520     FileSpec sysroot_spec;
1521     // Scope for mutex locker below
1522     {
1523         Mutex::Locker locker (m_mutex);
1524         sysroot_spec = GetSDKDirectoryForModules(sdk_type);
1525     }
1526 
1527     if (sysroot_spec.IsDirectory())
1528     {
1529         options.push_back("-isysroot");
1530         options.push_back(sysroot_spec.GetPath());
1531     }
1532 }
1533