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