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