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