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