1 //===-- PlatformDarwin.cpp --------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/lldb-python.h"
11 
12 #include "PlatformDarwin.h"
13 
14 // C Includes
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/Breakpoint/BreakpointLocation.h"
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/Core/Error.h"
21 #include "lldb/Core/Log.h"
22 #include "lldb/Core/Module.h"
23 #include "lldb/Core/ModuleSpec.h"
24 #include "lldb/Core/Timer.h"
25 #include "lldb/Host/Host.h"
26 #include "lldb/Host/Symbols.h"
27 #include "lldb/Symbol/ObjectFile.h"
28 #include "lldb/Symbol/SymbolFile.h"
29 #include "lldb/Symbol/SymbolVendor.h"
30 #include "lldb/Target/Target.h"
31 #include "llvm/ADT/STLExtras.h"
32 
33 using namespace lldb;
34 using namespace lldb_private;
35 
36 
37 //------------------------------------------------------------------
38 /// Default Constructor
39 //------------------------------------------------------------------
40 PlatformDarwin::PlatformDarwin (bool is_host) :
41     PlatformPOSIX(is_host),  // This is the local host platform
42     m_developer_directory ()
43 {
44 }
45 
46 //------------------------------------------------------------------
47 /// Destructor.
48 ///
49 /// The destructor is virtual since this class is designed to be
50 /// inherited from by the plug-in instance.
51 //------------------------------------------------------------------
52 PlatformDarwin::~PlatformDarwin()
53 {
54 }
55 
56 FileSpecList
57 PlatformDarwin::LocateExecutableScriptingResources (Target *target,
58                                                     Module &module)
59 {
60     FileSpecList file_list;
61     if (target && target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython)
62     {
63         // NB some extensions might be meaningful and should not be stripped - "this.binary.file"
64         // should not lose ".file" but GetFileNameStrippingExtension() will do precisely that.
65         // Ideally, we should have a per-platform list of extensions (".exe", ".app", ".dSYM", ".framework")
66         // which should be stripped while leaving "this.binary.file" as-is.
67         FileSpec module_spec = module.GetFileSpec();
68 
69         if (module_spec)
70         {
71             SymbolVendor *symbols = module.GetSymbolVendor ();
72             if (symbols)
73             {
74                 SymbolFile *symfile = symbols->GetSymbolFile();
75                 if (symfile)
76                 {
77                     ObjectFile *objfile = symfile->GetObjectFile();
78                     if (objfile)
79                     {
80                         FileSpec symfile_spec (objfile->GetFileSpec());
81                         if (symfile_spec && symfile_spec.Exists())
82                         {
83                             while (module_spec.GetFilename())
84                             {
85                                 std::string module_basename (module_spec.GetFilename().GetCString());
86 
87                                 // FIXME: for Python, we cannot allow certain characters in module
88                                 // filenames we import. Theoretically, different scripting languages may
89                                 // have different sets of forbidden tokens in filenames, and that should
90                                 // be dealt with by each ScriptInterpreter. For now, we just replace dots
91                                 // with underscores, but if we ever support anything other than Python
92                                 // we will need to rework this
93                                 std::replace(module_basename.begin(), module_basename.end(), '.', '_');
94                                 std::replace(module_basename.begin(), module_basename.end(), ' ', '_');
95                                 std::replace(module_basename.begin(), module_basename.end(), '-', '_');
96 
97 
98                                 StreamString path_string;
99                                 // for OSX we are going to be in .dSYM/Contents/Resources/DWARF/<basename>
100                                 // let us go to .dSYM/Contents/Resources/Python/<basename>.py and see if the file exists
101                                 path_string.Printf("%s/../Python/%s.py",symfile_spec.GetDirectory().GetCString(), module_basename.c_str());
102                                 FileSpec script_fspec(path_string.GetData(), true);
103                                 if (script_fspec.Exists())
104                                 {
105                                     file_list.Append (script_fspec);
106                                     break;
107                                 }
108 
109                                 // If we didn't find the python file, then keep
110                                 // stripping the extensions and try again
111                                 ConstString filename_no_extension (module_spec.GetFileNameStrippingExtension());
112                                 if (module_spec.GetFilename() == filename_no_extension)
113                                     break;
114 
115                                 module_spec.GetFilename() = filename_no_extension;
116                             }
117                         }
118                     }
119                 }
120             }
121         }
122     }
123     return file_list;
124 }
125 
126 Error
127 PlatformDarwin::ResolveExecutable (const FileSpec &exe_file,
128                                    const ArchSpec &exe_arch,
129                                    lldb::ModuleSP &exe_module_sp,
130                                    const FileSpecList *module_search_paths_ptr)
131 {
132     Error error;
133     // Nothing special to do here, just use the actual file and architecture
134 
135     char exe_path[PATH_MAX];
136     FileSpec resolved_exe_file (exe_file);
137 
138     if (IsHost())
139     {
140         // If we have "ls" as the exe_file, resolve the executable loation based on
141         // the current path variables
142         if (!resolved_exe_file.Exists())
143         {
144             exe_file.GetPath (exe_path, sizeof(exe_path));
145             resolved_exe_file.SetFile(exe_path, true);
146         }
147 
148         if (!resolved_exe_file.Exists())
149             resolved_exe_file.ResolveExecutableLocation ();
150 
151         // Resolve any executable within a bundle on MacOSX
152         Host::ResolveExecutableInBundle (resolved_exe_file);
153 
154         if (resolved_exe_file.Exists())
155             error.Clear();
156         else
157         {
158             exe_file.GetPath (exe_path, sizeof(exe_path));
159             error.SetErrorStringWithFormat ("unable to find executable for '%s'", exe_path);
160         }
161     }
162     else
163     {
164         if (m_remote_platform_sp)
165         {
166             error = m_remote_platform_sp->ResolveExecutable (exe_file,
167                                                              exe_arch,
168                                                              exe_module_sp,
169                                                              module_search_paths_ptr);
170         }
171         else
172         {
173             // We may connect to a process and use the provided executable (Don't use local $PATH).
174 
175             // Resolve any executable within a bundle on MacOSX
176             Host::ResolveExecutableInBundle (resolved_exe_file);
177 
178             if (resolved_exe_file.Exists())
179                 error.Clear();
180             else
181                 error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", resolved_exe_file.GetFilename().AsCString(""));
182         }
183     }
184 
185 
186     if (error.Success())
187     {
188         ModuleSpec module_spec (resolved_exe_file, exe_arch);
189         if (module_spec.GetArchitecture().IsValid())
190         {
191             error = ModuleList::GetSharedModule (module_spec,
192                                                  exe_module_sp,
193                                                  module_search_paths_ptr,
194                                                  NULL,
195                                                  NULL);
196 
197             if (error.Fail() || exe_module_sp.get() == NULL || exe_module_sp->GetObjectFile() == NULL)
198             {
199                 exe_module_sp.reset();
200                 error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s",
201                                                 exe_file.GetPath().c_str(),
202                                                 exe_arch.GetArchitectureName());
203             }
204         }
205         else
206         {
207             // No valid architecture was specified, ask the platform for
208             // the architectures that we should be using (in the correct order)
209             // and see if we can find a match that way
210             StreamString arch_names;
211             for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx)
212             {
213                 error = GetSharedModule (module_spec,
214                                          exe_module_sp,
215                                          module_search_paths_ptr,
216                                          NULL,
217                                          NULL);
218                 // Did we find an executable using one of the
219                 if (error.Success())
220                 {
221                     if (exe_module_sp && exe_module_sp->GetObjectFile())
222                         break;
223                     else
224                         error.SetErrorToGenericError();
225                 }
226 
227                 if (idx > 0)
228                     arch_names.PutCString (", ");
229                 arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName());
230             }
231 
232             if (error.Fail() || !exe_module_sp)
233             {
234                 error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
235                                                 exe_file.GetPath().c_str(),
236                                                 GetPluginName().GetCString(),
237                                                 arch_names.GetString().c_str());
238             }
239         }
240     }
241 
242     return error;
243 }
244 
245 Error
246 PlatformDarwin::ResolveSymbolFile (Target &target,
247                                    const ModuleSpec &sym_spec,
248                                    FileSpec &sym_file)
249 {
250     Error error;
251     sym_file = sym_spec.GetSymbolFileSpec();
252     if (sym_file.Exists())
253     {
254         if (sym_file.GetFileType() == FileSpec::eFileTypeDirectory)
255         {
256             sym_file = Symbols::FindSymbolFileInBundle (sym_file,
257                                                         sym_spec.GetUUIDPtr(),
258                                                         sym_spec.GetArchitecturePtr());
259         }
260     }
261     else
262     {
263         if (sym_spec.GetUUID().IsValid())
264         {
265 
266         }
267     }
268     return error;
269 
270 }
271 
272 static lldb_private::Error
273 MakeCacheFolderForFile (const FileSpec& module_cache_spec)
274 {
275     FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent();
276     return Host::MakeDirectory(module_cache_folder.GetPath().c_str(), eFilePermissionsDirectoryDefault);
277 }
278 
279 static lldb_private::Error
280 BringInRemoteFile (Platform* platform,
281                    const lldb_private::ModuleSpec &module_spec,
282                    const FileSpec& module_cache_spec)
283 {
284     MakeCacheFolderForFile(module_cache_spec);
285     Error err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec);
286     return err;
287 }
288 
289 lldb_private::Error
290 PlatformDarwin::GetSharedModuleWithLocalCache (const lldb_private::ModuleSpec &module_spec,
291                                                lldb::ModuleSP &module_sp,
292                                                const lldb_private::FileSpecList *module_search_paths_ptr,
293                                                lldb::ModuleSP *old_module_sp_ptr,
294                                                bool *did_create_ptr)
295 {
296 
297     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
298     if (log)
299         log->Printf("[%s] Trying to find module %s/%s - platform path %s/%s symbol path %s/%s",
300                      (IsHost() ? "host" : "remote"),
301                      module_spec.GetFileSpec().GetDirectory().AsCString(),
302                      module_spec.GetFileSpec().GetFilename().AsCString(),
303                      module_spec.GetPlatformFileSpec().GetDirectory().AsCString(),
304                      module_spec.GetPlatformFileSpec().GetFilename().AsCString(),
305                      module_spec.GetSymbolFileSpec().GetDirectory().AsCString(),
306                      module_spec.GetSymbolFileSpec().GetFilename().AsCString());
307 
308     Error err;
309 
310     err = ModuleList::GetSharedModule(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
311     if (module_sp)
312         return err;
313 
314     if (!IsHost())
315     {
316         std::string cache_path(GetLocalCacheDirectory());
317         // Only search for a locally cached file if we have a valid cache path
318         if (!cache_path.empty())
319         {
320             std::string module_path (module_spec.GetFileSpec().GetPath());
321             cache_path.append(module_path);
322             FileSpec module_cache_spec(cache_path.c_str(),false);
323 
324             // if rsync is supported, always bring in the file - rsync will be very efficient
325             // when files are the same on the local and remote end of the connection
326             if (this->GetSupportsRSync())
327             {
328                 err = BringInRemoteFile (this, module_spec, module_cache_spec);
329                 if (err.Fail())
330                     return err;
331                 if (module_cache_spec.Exists())
332                 {
333                     Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
334                     if (log)
335                         log->Printf("[%s] module %s/%s was rsynced and is now there",
336                                      (IsHost() ? "host" : "remote"),
337                                      module_spec.GetFileSpec().GetDirectory().AsCString(),
338                                      module_spec.GetFileSpec().GetFilename().AsCString());
339                     ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
340                     module_sp.reset(new Module(local_spec));
341                     module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
342                     return Error();
343                 }
344             }
345 
346             // try to find the module in the cache
347             if (module_cache_spec.Exists())
348             {
349                 // get the local and remote MD5 and compare
350                 if (m_remote_platform_sp)
351                 {
352                     // when going over the *slow* GDB remote transfer mechanism we first check
353                     // the hashes of the files - and only do the actual transfer if they differ
354                     uint64_t high_local,high_remote,low_local,low_remote;
355                     Host::CalculateMD5 (module_cache_spec, low_local, high_local);
356                     m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(), low_remote, high_remote);
357                     if (low_local != low_remote || high_local != high_remote)
358                     {
359                         // bring in the remote file
360                         Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
361                         if (log)
362                             log->Printf("[%s] module %s/%s needs to be replaced from remote copy",
363                                          (IsHost() ? "host" : "remote"),
364                                          module_spec.GetFileSpec().GetDirectory().AsCString(),
365                                          module_spec.GetFileSpec().GetFilename().AsCString());
366                         Error err = BringInRemoteFile (this, module_spec, module_cache_spec);
367                         if (err.Fail())
368                             return err;
369                     }
370                 }
371 
372                 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
373                 module_sp.reset(new Module(local_spec));
374                 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
375                 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
376                     if (log)
377                         log->Printf("[%s] module %s/%s was found in the cache",
378                                      (IsHost() ? "host" : "remote"),
379                                      module_spec.GetFileSpec().GetDirectory().AsCString(),
380                                      module_spec.GetFileSpec().GetFilename().AsCString());
381                 return Error();
382             }
383 
384             // bring in the remote module file
385             if (log)
386                 log->Printf("[%s] module %s/%s needs to come in remotely",
387                              (IsHost() ? "host" : "remote"),
388                              module_spec.GetFileSpec().GetDirectory().AsCString(),
389                              module_spec.GetFileSpec().GetFilename().AsCString());
390             Error err = BringInRemoteFile (this, module_spec, module_cache_spec);
391             if (err.Fail())
392                 return err;
393             if (module_cache_spec.Exists())
394             {
395                 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
396                 if (log)
397                     log->Printf("[%s] module %s/%s is now cached and fine",
398                                  (IsHost() ? "host" : "remote"),
399                                  module_spec.GetFileSpec().GetDirectory().AsCString(),
400                                  module_spec.GetFileSpec().GetFilename().AsCString());
401                 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture());
402                 module_sp.reset(new Module(local_spec));
403                 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
404                 return Error();
405             }
406             else
407                 return Error("unable to obtain valid module file");
408         }
409         else
410             return Error("no cache path");
411     }
412     else
413         return Error ("unable to resolve module");
414 }
415 
416 Error
417 PlatformDarwin::GetSharedModule (const ModuleSpec &module_spec,
418                                  ModuleSP &module_sp,
419                                  const FileSpecList *module_search_paths_ptr,
420                                  ModuleSP *old_module_sp_ptr,
421                                  bool *did_create_ptr)
422 {
423     Error error;
424     module_sp.reset();
425 
426     if (IsRemote())
427     {
428         // If we have a remote platform always, let it try and locate
429         // the shared module first.
430         if (m_remote_platform_sp)
431         {
432             error = m_remote_platform_sp->GetSharedModule (module_spec,
433                                                            module_sp,
434                                                            module_search_paths_ptr,
435                                                            old_module_sp_ptr,
436                                                            did_create_ptr);
437         }
438     }
439 
440     if (!module_sp)
441     {
442         // Fall back to the local platform and find the file locally
443         error = Platform::GetSharedModule (module_spec,
444                                            module_sp,
445                                            module_search_paths_ptr,
446                                            old_module_sp_ptr,
447                                            did_create_ptr);
448 
449         const FileSpec &platform_file = module_spec.GetFileSpec();
450         if (!module_sp && module_search_paths_ptr && platform_file)
451         {
452             // We can try to pull off part of the file path up to the bundle
453             // directory level and try any module search paths...
454             FileSpec bundle_directory;
455             if (Host::GetBundleDirectory (platform_file, bundle_directory))
456             {
457                 if (platform_file == bundle_directory)
458                 {
459                     ModuleSpec new_module_spec (module_spec);
460                     new_module_spec.GetFileSpec() = bundle_directory;
461                     if (Host::ResolveExecutableInBundle (new_module_spec.GetFileSpec()))
462                     {
463                         Error new_error (Platform::GetSharedModule (new_module_spec,
464                                                                     module_sp,
465                                                                     NULL,
466                                                                     old_module_sp_ptr,
467                                                                     did_create_ptr));
468 
469                         if (module_sp)
470                             return new_error;
471                     }
472                 }
473                 else
474                 {
475                     char platform_path[PATH_MAX];
476                     char bundle_dir[PATH_MAX];
477                     platform_file.GetPath (platform_path, sizeof(platform_path));
478                     const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir));
479                     char new_path[PATH_MAX];
480                     size_t num_module_search_paths = module_search_paths_ptr->GetSize();
481                     for (size_t i=0; i<num_module_search_paths; ++i)
482                     {
483                         const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path));
484                         if (search_path_len < sizeof(new_path))
485                         {
486                             snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len);
487                             FileSpec new_file_spec (new_path, false);
488                             if (new_file_spec.Exists())
489                             {
490                                 ModuleSpec new_module_spec (module_spec);
491                                 new_module_spec.GetFileSpec() = new_file_spec;
492                                 Error new_error (Platform::GetSharedModule (new_module_spec,
493                                                                             module_sp,
494                                                                             NULL,
495                                                                             old_module_sp_ptr,
496                                                                             did_create_ptr));
497 
498                                 if (module_sp)
499                                 {
500                                     module_sp->SetPlatformFileSpec(new_file_spec);
501                                     return new_error;
502                                 }
503                             }
504                         }
505                     }
506                 }
507             }
508         }
509     }
510     if (module_sp)
511         module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());
512     return error;
513 }
514 
515 size_t
516 PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
517 {
518     const uint8_t *trap_opcode = NULL;
519     uint32_t trap_opcode_size = 0;
520     bool bp_is_thumb = false;
521 
522     llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
523     switch (machine)
524     {
525     case llvm::Triple::x86:
526     case llvm::Triple::x86_64:
527         {
528             static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC };
529             trap_opcode = g_i386_breakpoint_opcode;
530             trap_opcode_size = sizeof(g_i386_breakpoint_opcode);
531         }
532         break;
533 
534     case llvm::Triple::aarch64:
535         {
536             // TODO: fix this with actual darwin breakpoint opcode for arm64.
537             // right now debugging uses the Z packets with GDB remote so this
538             // is not needed, but the size needs to be correct...
539             static const uint8_t g_arm64_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
540             trap_opcode = g_arm64_breakpoint_opcode;
541             trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);
542         }
543         break;
544 
545     case llvm::Triple::thumb:
546         bp_is_thumb = true; // Fall through...
547     case llvm::Triple::arm:
548         {
549             static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
550             static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE };
551 
552             // Auto detect arm/thumb if it wasn't explicitly specified
553             if (!bp_is_thumb)
554             {
555                 lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0));
556                 if (bp_loc_sp)
557                     bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass () == eAddressClassCodeAlternateISA;
558             }
559             if (bp_is_thumb)
560             {
561                 trap_opcode = g_thumb_breakpooint_opcode;
562                 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode);
563                 break;
564             }
565             trap_opcode = g_arm_breakpoint_opcode;
566             trap_opcode_size = sizeof(g_arm_breakpoint_opcode);
567         }
568         break;
569 
570     case llvm::Triple::ppc:
571     case llvm::Triple::ppc64:
572         {
573             static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 };
574             trap_opcode = g_ppc_breakpoint_opcode;
575             trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);
576         }
577         break;
578 
579     default:
580         assert(!"Unhandled architecture in PlatformDarwin::GetSoftwareBreakpointTrapOpcode()");
581         break;
582     }
583 
584     if (trap_opcode && trap_opcode_size)
585     {
586         if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))
587             return trap_opcode_size;
588     }
589     return 0;
590 
591 }
592 
593 bool
594 PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info)
595 {
596     bool sucess = false;
597     if (IsHost())
598     {
599         sucess = Platform::GetProcessInfo (pid, process_info);
600     }
601     else
602     {
603         if (m_remote_platform_sp)
604             sucess = m_remote_platform_sp->GetProcessInfo (pid, process_info);
605     }
606     return sucess;
607 }
608 
609 uint32_t
610 PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info,
611                                ProcessInstanceInfoList &process_infos)
612 {
613     uint32_t match_count = 0;
614     if (IsHost())
615     {
616         // Let the base class figure out the host details
617         match_count = Platform::FindProcesses (match_info, process_infos);
618     }
619     else
620     {
621         // If we are remote, we can only return results if we are connected
622         if (m_remote_platform_sp)
623             match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos);
624     }
625     return match_count;
626 }
627 
628 Error
629 PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info)
630 {
631     Error error;
632 
633     if (IsHost())
634     {
635         error = Platform::LaunchProcess (launch_info);
636     }
637     else
638     {
639         if (m_remote_platform_sp)
640             error = m_remote_platform_sp->LaunchProcess (launch_info);
641         else
642             error.SetErrorString ("the platform is not currently connected");
643     }
644     return error;
645 }
646 
647 lldb::ProcessSP
648 PlatformDarwin::Attach (ProcessAttachInfo &attach_info,
649                         Debugger &debugger,
650                         Target *target,
651                         Listener &listener,
652                         Error &error)
653 {
654     lldb::ProcessSP process_sp;
655 
656     if (IsHost())
657     {
658         if (target == NULL)
659         {
660             TargetSP new_target_sp;
661 
662             error = debugger.GetTargetList().CreateTarget (debugger,
663                                                            NULL,
664                                                            NULL,
665                                                            false,
666                                                            NULL,
667                                                            new_target_sp);
668             target = new_target_sp.get();
669         }
670         else
671             error.Clear();
672 
673         if (target && error.Success())
674         {
675             debugger.GetTargetList().SetSelectedTarget(target);
676 
677             process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName(), NULL);
678 
679             if (process_sp)
680             {
681                 ListenerSP listener_sp (new Listener("lldb.PlatformDarwin.attach.hijack"));
682                 attach_info.SetHijackListener(listener_sp);
683                 process_sp->HijackProcessEvents(listener_sp.get());
684                 error = process_sp->Attach (attach_info);
685             }
686         }
687     }
688     else
689     {
690         if (m_remote_platform_sp)
691             process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error);
692         else
693             error.SetErrorString ("the platform is not currently connected");
694     }
695     return process_sp;
696 }
697 
698 bool
699 PlatformDarwin::ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp)
700 {
701     if (!module_sp)
702         return false;
703 
704     ObjectFile *obj_file = module_sp->GetObjectFile();
705     if (!obj_file)
706         return false;
707 
708     ObjectFile::Type obj_type = obj_file->GetType();
709     if (obj_type == ObjectFile::eTypeDynamicLinker)
710         return true;
711     else
712         return false;
713 }
714 
715 bool
716 PlatformDarwin::x86GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
717 {
718     ArchSpec host_arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
719     if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h)
720     {
721         switch (idx)
722         {
723             case 0:
724                 arch = host_arch;
725                 return true;
726 
727             case 1:
728                 arch.SetTriple("x86_64-apple-macosx");
729                 return true;
730 
731             case 2:
732                 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32);
733                 return true;
734 
735             default: return false;
736         }
737     }
738     else
739     {
740         if (idx == 0)
741         {
742             arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture);
743             return arch.IsValid();
744         }
745         else if (idx == 1)
746         {
747             ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture));
748             ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64));
749             if (platform_arch.IsExactMatch(platform_arch64))
750             {
751                 // This macosx platform supports both 32 and 64 bit. Since we already
752                 // returned the 64 bit arch for idx == 0, return the 32 bit arch
753                 // for idx == 1
754                 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32);
755                 return arch.IsValid();
756             }
757         }
758     }
759     return false;
760 }
761 
762 // The architecture selection rules for arm processors
763 // These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f processor.
764 
765 bool
766 PlatformDarwin::ARMGetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
767 {
768     ArchSpec system_arch (GetSystemArchitecture());
769 
770     const ArchSpec::Core system_core = system_arch.GetCore();
771     switch (system_core)
772     {
773     default:
774         switch (idx)
775         {
776             case  0: arch.SetTriple ("arm64-apple-ios");    return true;
777             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
778             case  2: arch.SetTriple ("armv7f-apple-ios");   return true;
779             case  3: arch.SetTriple ("armv7k-apple-ios");   return true;
780             case  4: arch.SetTriple ("armv7s-apple-ios");   return true;
781             case  5: arch.SetTriple ("armv7m-apple-ios");   return true;
782             case  6: arch.SetTriple ("armv7em-apple-ios");  return true;
783             case  7: arch.SetTriple ("armv6m-apple-ios");   return true;
784             case  8: arch.SetTriple ("armv6-apple-ios");    return true;
785             case  9: arch.SetTriple ("armv5-apple-ios");    return true;
786             case 10: arch.SetTriple ("armv4-apple-ios");    return true;
787             case 11: arch.SetTriple ("arm-apple-ios");      return true;
788             case 12: arch.SetTriple ("thumbv7-apple-ios");  return true;
789             case 13: arch.SetTriple ("thumbv7f-apple-ios"); return true;
790             case 14: arch.SetTriple ("thumbv7k-apple-ios"); return true;
791             case 15: arch.SetTriple ("thumbv7s-apple-ios"); return true;
792             case 16: arch.SetTriple ("thumbv7m-apple-ios"); return true;
793             case 17: arch.SetTriple ("thumbv7em-apple-ios"); return true;
794             case 18: arch.SetTriple ("thumbv6m-apple-ios"); return true;
795             case 19: arch.SetTriple ("thumbv6-apple-ios");  return true;
796             case 20: arch.SetTriple ("thumbv5-apple-ios");  return true;
797             case 21: arch.SetTriple ("thumbv4t-apple-ios"); return true;
798             case 22: arch.SetTriple ("thumb-apple-ios");    return true;
799             default: break;
800         }
801         break;
802 
803     case ArchSpec::eCore_arm_arm64:
804         switch (idx)
805         {
806             case  0: arch.SetTriple ("arm64-apple-ios");   return true;
807             case  1: arch.SetTriple ("armv7s-apple-ios");   return true;
808             case  2: arch.SetTriple ("armv7f-apple-ios");   return true;
809             case  3: arch.SetTriple ("armv7m-apple-ios");   return true;
810             case  4: arch.SetTriple ("armv7em-apple-ios");  return true;
811             case  5: arch.SetTriple ("armv7-apple-ios");    return true;
812             case  6: arch.SetTriple ("armv6m-apple-ios");   return true;
813             case  7: arch.SetTriple ("armv6-apple-ios");    return true;
814             case  8: arch.SetTriple ("armv5-apple-ios");    return true;
815             case  9: arch.SetTriple ("armv4-apple-ios");    return true;
816             case 10: arch.SetTriple ("arm-apple-ios");      return true;
817             case 11: arch.SetTriple ("thumbv7-apple-ios");  return true;
818             case 12: arch.SetTriple ("thumbv7f-apple-ios"); return true;
819             case 13: arch.SetTriple ("thumbv7k-apple-ios"); return true;
820             case 14: arch.SetTriple ("thumbv7s-apple-ios"); return true;
821             case 15: arch.SetTriple ("thumbv7m-apple-ios"); return true;
822             case 16: arch.SetTriple ("thumbv7em-apple-ios"); return true;
823             case 17: arch.SetTriple ("thumbv6m-apple-ios"); return true;
824             case 18: arch.SetTriple ("thumbv6-apple-ios");  return true;
825             case 19: arch.SetTriple ("thumbv5-apple-ios");  return true;
826             case 20: arch.SetTriple ("thumbv4t-apple-ios"); return true;
827             case 21: arch.SetTriple ("thumb-apple-ios");    return true;
828         default: break;
829         }
830         break;
831 
832     case ArchSpec::eCore_arm_armv7f:
833         switch (idx)
834         {
835             case  0: arch.SetTriple ("armv7f-apple-ios");   return true;
836             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
837             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
838             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
839             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
840             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
841             case  6: arch.SetTriple ("arm-apple-ios");      return true;
842             case  7: arch.SetTriple ("thumbv7f-apple-ios"); return true;
843             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
844             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
845             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
846             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
847             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
848             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
849             default: break;
850         }
851         break;
852 
853     case ArchSpec::eCore_arm_armv7k:
854         switch (idx)
855         {
856             case  0: arch.SetTriple ("armv7k-apple-ios");   return true;
857             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
858             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
859             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
860             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
861             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
862             case  6: arch.SetTriple ("arm-apple-ios");      return true;
863             case  7: arch.SetTriple ("thumbv7k-apple-ios"); return true;
864             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
865             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
866             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
867             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
868             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
869             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
870             default: break;
871         }
872         break;
873 
874     case ArchSpec::eCore_arm_armv7s:
875         switch (idx)
876         {
877             case  0: arch.SetTriple ("armv7s-apple-ios");   return true;
878             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
879             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
880             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
881             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
882             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
883             case  6: arch.SetTriple ("arm-apple-ios");      return true;
884             case  7: arch.SetTriple ("thumbv7s-apple-ios"); return true;
885             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
886             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
887             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
888             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
889             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
890             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
891             default: break;
892         }
893         break;
894 
895     case ArchSpec::eCore_arm_armv7m:
896         switch (idx)
897         {
898             case  0: arch.SetTriple ("armv7m-apple-ios");   return true;
899             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
900             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
901             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
902             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
903             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
904             case  6: arch.SetTriple ("arm-apple-ios");      return true;
905             case  7: arch.SetTriple ("thumbv7m-apple-ios"); return true;
906             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
907             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
908             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
909             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
910             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
911             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
912             default: break;
913         }
914         break;
915 
916     case ArchSpec::eCore_arm_armv7em:
917         switch (idx)
918         {
919             case  0: arch.SetTriple ("armv7em-apple-ios");  return true;
920             case  1: arch.SetTriple ("armv7-apple-ios");    return true;
921             case  2: arch.SetTriple ("armv6m-apple-ios");   return true;
922             case  3: arch.SetTriple ("armv6-apple-ios");    return true;
923             case  4: arch.SetTriple ("armv5-apple-ios");    return true;
924             case  5: arch.SetTriple ("armv4-apple-ios");    return true;
925             case  6: arch.SetTriple ("arm-apple-ios");      return true;
926             case  7: arch.SetTriple ("thumbv7em-apple-ios"); return true;
927             case  8: arch.SetTriple ("thumbv7-apple-ios");  return true;
928             case  9: arch.SetTriple ("thumbv6m-apple-ios"); return true;
929             case 10: arch.SetTriple ("thumbv6-apple-ios");  return true;
930             case 11: arch.SetTriple ("thumbv5-apple-ios");  return true;
931             case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true;
932             case 13: arch.SetTriple ("thumb-apple-ios");    return true;
933             default: break;
934         }
935         break;
936 
937     case ArchSpec::eCore_arm_armv7:
938         switch (idx)
939         {
940             case  0: arch.SetTriple ("armv7-apple-ios");    return true;
941             case  1: arch.SetTriple ("armv6m-apple-ios");   return true;
942             case  2: arch.SetTriple ("armv6-apple-ios");    return true;
943             case  3: arch.SetTriple ("armv5-apple-ios");    return true;
944             case  4: arch.SetTriple ("armv4-apple-ios");    return true;
945             case  5: arch.SetTriple ("arm-apple-ios");      return true;
946             case  6: arch.SetTriple ("thumbv7-apple-ios");  return true;
947             case  7: arch.SetTriple ("thumbv6m-apple-ios"); return true;
948             case  8: arch.SetTriple ("thumbv6-apple-ios");  return true;
949             case  9: arch.SetTriple ("thumbv5-apple-ios");  return true;
950             case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
951             case 11: arch.SetTriple ("thumb-apple-ios");    return true;
952             default: break;
953         }
954         break;
955 
956     case ArchSpec::eCore_arm_armv6m:
957         switch (idx)
958         {
959             case 0: arch.SetTriple ("armv6m-apple-ios");   return true;
960             case 1: arch.SetTriple ("armv6-apple-ios");    return true;
961             case 2: arch.SetTriple ("armv5-apple-ios");    return true;
962             case 3: arch.SetTriple ("armv4-apple-ios");    return true;
963             case 4: arch.SetTriple ("arm-apple-ios");      return true;
964             case 5: arch.SetTriple ("thumbv6m-apple-ios"); return true;
965             case 6: arch.SetTriple ("thumbv6-apple-ios");  return true;
966             case 7: arch.SetTriple ("thumbv5-apple-ios");  return true;
967             case 8: arch.SetTriple ("thumbv4t-apple-ios"); return true;
968             case 9: arch.SetTriple ("thumb-apple-ios");    return true;
969             default: break;
970         }
971         break;
972 
973     case ArchSpec::eCore_arm_armv6:
974         switch (idx)
975         {
976             case 0: arch.SetTriple ("armv6-apple-ios");    return true;
977             case 1: arch.SetTriple ("armv5-apple-ios");    return true;
978             case 2: arch.SetTriple ("armv4-apple-ios");    return true;
979             case 3: arch.SetTriple ("arm-apple-ios");      return true;
980             case 4: arch.SetTriple ("thumbv6-apple-ios");  return true;
981             case 5: arch.SetTriple ("thumbv5-apple-ios");  return true;
982             case 6: arch.SetTriple ("thumbv4t-apple-ios"); return true;
983             case 7: arch.SetTriple ("thumb-apple-ios");    return true;
984             default: break;
985         }
986         break;
987 
988     case ArchSpec::eCore_arm_armv5:
989         switch (idx)
990         {
991             case 0: arch.SetTriple ("armv5-apple-ios");    return true;
992             case 1: arch.SetTriple ("armv4-apple-ios");    return true;
993             case 2: arch.SetTriple ("arm-apple-ios");      return true;
994             case 3: arch.SetTriple ("thumbv5-apple-ios");  return true;
995             case 4: arch.SetTriple ("thumbv4t-apple-ios"); return true;
996             case 5: arch.SetTriple ("thumb-apple-ios");    return true;
997             default: break;
998         }
999         break;
1000 
1001     case ArchSpec::eCore_arm_armv4:
1002         switch (idx)
1003         {
1004             case 0: arch.SetTriple ("armv4-apple-ios");    return true;
1005             case 1: arch.SetTriple ("arm-apple-ios");      return true;
1006             case 2: arch.SetTriple ("thumbv4t-apple-ios"); return true;
1007             case 3: arch.SetTriple ("thumb-apple-ios");    return true;
1008             default: break;
1009         }
1010         break;
1011     }
1012     arch.Clear();
1013     return false;
1014 }
1015 
1016 
1017 const char *
1018 PlatformDarwin::GetDeveloperDirectory()
1019 {
1020     if (m_developer_directory.empty())
1021     {
1022         bool developer_dir_path_valid = false;
1023         char developer_dir_path[PATH_MAX];
1024         FileSpec temp_file_spec;
1025         if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, temp_file_spec))
1026         {
1027             if (temp_file_spec.GetPath (developer_dir_path, sizeof(developer_dir_path)))
1028             {
1029                 char *shared_frameworks = strstr (developer_dir_path, "/SharedFrameworks/LLDB.framework");
1030                 if (shared_frameworks)
1031                 {
1032                     ::snprintf (shared_frameworks,
1033                                 sizeof(developer_dir_path) - (shared_frameworks - developer_dir_path),
1034                                 "/Developer");
1035                     developer_dir_path_valid = true;
1036                 }
1037                 else
1038                 {
1039                     char *lib_priv_frameworks = strstr (developer_dir_path, "/Library/PrivateFrameworks/LLDB.framework");
1040                     if (lib_priv_frameworks)
1041                     {
1042                         *lib_priv_frameworks = '\0';
1043                         developer_dir_path_valid = true;
1044                     }
1045                 }
1046             }
1047         }
1048 
1049         if (!developer_dir_path_valid)
1050         {
1051             std::string xcode_dir_path;
1052             const char *xcode_select_prefix_dir = getenv ("XCODE_SELECT_PREFIX_DIR");
1053             if (xcode_select_prefix_dir)
1054                 xcode_dir_path.append (xcode_select_prefix_dir);
1055             xcode_dir_path.append ("/usr/share/xcode-select/xcode_dir_path");
1056             temp_file_spec.SetFile(xcode_dir_path.c_str(), false);
1057             size_t bytes_read = temp_file_spec.ReadFileContents(0, developer_dir_path, sizeof(developer_dir_path), NULL);
1058             if (bytes_read > 0)
1059             {
1060                 developer_dir_path[bytes_read] = '\0';
1061                 while (developer_dir_path[bytes_read-1] == '\r' ||
1062                        developer_dir_path[bytes_read-1] == '\n')
1063                     developer_dir_path[--bytes_read] = '\0';
1064                 developer_dir_path_valid = true;
1065             }
1066         }
1067 
1068         if (!developer_dir_path_valid)
1069         {
1070             FileSpec xcode_select_cmd ("/usr/bin/xcode-select", false);
1071             if (xcode_select_cmd.Exists())
1072             {
1073                 int exit_status = -1;
1074                 int signo = -1;
1075                 std::string command_output;
1076                 Error error = Host::RunShellCommand ("/usr/bin/xcode-select --print-path",
1077                                                      NULL,                                 // current working directory
1078                                                      &exit_status,
1079                                                      &signo,
1080                                                      &command_output,
1081                                                      2,                                     // short timeout
1082                                                      NULL);                                 // don't run in a shell
1083                 if (error.Success() && exit_status == 0 && !command_output.empty())
1084                 {
1085                     const char *cmd_output_ptr = command_output.c_str();
1086                     developer_dir_path[sizeof (developer_dir_path) - 1] = '\0';
1087                     size_t i;
1088                     for (i = 0; i < sizeof (developer_dir_path) - 1; i++)
1089                     {
1090                         if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' || cmd_output_ptr[i] == '\0')
1091                             break;
1092                         developer_dir_path[i] = cmd_output_ptr[i];
1093                     }
1094                     developer_dir_path[i] = '\0';
1095 
1096                     FileSpec devel_dir (developer_dir_path, false);
1097                     if (devel_dir.Exists() && devel_dir.IsDirectory())
1098                     {
1099                         developer_dir_path_valid = true;
1100                     }
1101                 }
1102             }
1103         }
1104 
1105         if (developer_dir_path_valid)
1106         {
1107             temp_file_spec.SetFile (developer_dir_path, false);
1108             if (temp_file_spec.Exists())
1109             {
1110                 m_developer_directory.assign (developer_dir_path);
1111                 return m_developer_directory.c_str();
1112             }
1113         }
1114         // Assign a single NULL character so we know we tried to find the device
1115         // support directory and we don't keep trying to find it over and over.
1116         m_developer_directory.assign (1, '\0');
1117     }
1118 
1119     // We should have put a single NULL character into m_developer_directory
1120     // or it should have a valid path if the code gets here
1121     assert (m_developer_directory.empty() == false);
1122     if (m_developer_directory[0])
1123         return m_developer_directory.c_str();
1124     return NULL;
1125 }
1126 
1127 
1128 BreakpointSP
1129 PlatformDarwin::SetThreadCreationBreakpoint (Target &target)
1130 {
1131     BreakpointSP bp_sp;
1132     static const char *g_bp_names[] =
1133     {
1134         "start_wqthread",
1135         "_pthread_wqthread",
1136         "_pthread_start",
1137     };
1138 
1139     static const char *g_bp_modules[] =
1140     {
1141         "libsystem_c.dylib",
1142         "libSystem.B.dylib"
1143     };
1144 
1145     FileSpecList bp_modules;
1146     for (size_t i = 0; i < llvm::array_lengthof(g_bp_modules); i++)
1147     {
1148         const char *bp_module = g_bp_modules[i];
1149         bp_modules.Append(FileSpec(bp_module, false));
1150     }
1151 
1152     bool internal = true;
1153     bool hardware = false;
1154     LazyBool skip_prologue = eLazyBoolNo;
1155     bp_sp = target.CreateBreakpoint (&bp_modules,
1156                                      NULL,
1157                                      g_bp_names,
1158                                      llvm::array_lengthof(g_bp_names),
1159                                      eFunctionNameTypeFull,
1160                                      skip_prologue,
1161                                      internal,
1162                                      hardware);
1163     bp_sp->SetBreakpointKind("thread-creation");
1164 
1165     return bp_sp;
1166 }
1167 
1168 size_t
1169 PlatformDarwin::GetEnvironment (StringList &env)
1170 {
1171     if (IsRemote())
1172     {
1173         if (m_remote_platform_sp)
1174             return m_remote_platform_sp->GetEnvironment(env);
1175         return 0;
1176     }
1177     return Host::GetEnvironment(env);
1178 }
1179 
1180 int32_t
1181 PlatformDarwin::GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info)
1182 {
1183     const char *shell = launch_info.GetShell();
1184     if (shell == NULL)
1185         return 1;
1186 
1187     const char *shell_name = strrchr (shell, '/');
1188     if (shell_name == NULL)
1189         shell_name = shell;
1190     else
1191         shell_name++;
1192 
1193     if (strcmp (shell_name, "sh") == 0)
1194     {
1195         // /bin/sh re-exec's itself as /bin/bash requiring another resume.
1196         // But it only does this if the COMMAND_MODE environment variable
1197         // is set to "legacy".
1198         char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector();
1199         if (envp != NULL)
1200         {
1201             for (int i = 0; envp[i] != NULL; i++)
1202             {
1203                 if (strcmp (envp[i], "COMMAND_MODE=legacy" ) == 0)
1204                     return 2;
1205             }
1206         }
1207         return 1;
1208     }
1209     else if (strcmp (shell_name, "csh") == 0
1210             || strcmp (shell_name, "tcsh") == 0
1211             || strcmp (shell_name, "zsh") == 0)
1212     {
1213         // csh and tcsh always seem to re-exec themselves.
1214         return 2;
1215     }
1216     else
1217         return 1;
1218 }
1219 
1220 void
1221 PlatformDarwin::CalculateTrapHandlerSymbolNames ()
1222 {
1223     m_trap_handlers.push_back (ConstString ("_sigtramp"));
1224 }
1225