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