1 //===-- PlatformMacOSX.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 "PlatformMacOSX.h" 11 #include "lldb/Host/Config.h" 12 13 // C Includes 14 #ifndef LLDB_DISABLE_POSIX 15 #include <sys/stat.h> 16 #include <sys/sysctl.h> 17 #endif 18 19 // C++ Includes 20 21 #include <sstream> 22 23 // Other libraries and framework includes 24 // Project includes 25 #include "lldb/Core/Error.h" 26 #include "lldb/Breakpoint/BreakpointLocation.h" 27 #include "lldb/Core/DataBufferHeap.h" 28 #include "lldb/Core/Module.h" 29 #include "lldb/Core/ModuleList.h" 30 #include "lldb/Core/PluginManager.h" 31 #include "lldb/Core/StreamString.h" 32 #include "lldb/Host/FileSpec.h" 33 #include "lldb/Host/Host.h" 34 #include "lldb/Target/Process.h" 35 #include "lldb/Target/Target.h" 36 37 using namespace lldb; 38 using namespace lldb_private; 39 40 static uint32_t g_initialize_count = 0; 41 42 void 43 PlatformMacOSX::Initialize () 44 { 45 if (g_initialize_count++ == 0) 46 { 47 #if defined (__APPLE__) 48 PlatformSP default_platform_sp (new PlatformMacOSX(true)); 49 default_platform_sp->SetSystemArchitecture (Host::GetArchitecture()); 50 Platform::SetDefaultPlatform (default_platform_sp); 51 #endif 52 PluginManager::RegisterPlugin (PlatformMacOSX::GetPluginNameStatic(false), 53 PlatformMacOSX::GetDescriptionStatic(false), 54 PlatformMacOSX::CreateInstance); 55 } 56 57 } 58 59 void 60 PlatformMacOSX::Terminate () 61 { 62 if (g_initialize_count > 0) 63 { 64 if (--g_initialize_count == 0) 65 { 66 PluginManager::UnregisterPlugin (PlatformMacOSX::CreateInstance); 67 } 68 } 69 } 70 71 Platform* 72 PlatformMacOSX::CreateInstance (bool force, const ArchSpec *arch) 73 { 74 // The only time we create an instance is when we are creating a remote 75 // macosx platform 76 const bool is_host = false; 77 78 bool create = force; 79 if (create == false && arch && arch->IsValid()) 80 { 81 const llvm::Triple &triple = arch->GetTriple(); 82 switch (triple.getVendor()) 83 { 84 case llvm::Triple::Apple: 85 create = true; 86 break; 87 88 #if defined(__APPLE__) 89 // Only accept "unknown" for vendor if the host is Apple and 90 // it "unknown" wasn't specified (it was just returned becasue it 91 // was NOT specified) 92 case llvm::Triple::UnknownArch: 93 create = !arch->TripleVendorWasSpecified(); 94 break; 95 #endif 96 default: 97 break; 98 } 99 100 if (create) 101 { 102 switch (triple.getOS()) 103 { 104 case llvm::Triple::Darwin: // Deprecated, but still support Darwin for historical reasons 105 case llvm::Triple::MacOSX: 106 break; 107 #if defined(__APPLE__) 108 // Only accept "vendor" for vendor if the host is Apple and 109 // it "unknown" wasn't specified (it was just returned becasue it 110 // was NOT specified) 111 case llvm::Triple::UnknownOS: 112 create = !arch->TripleOSWasSpecified(); 113 break; 114 #endif 115 default: 116 create = false; 117 break; 118 } 119 } 120 } 121 if (create) 122 return new PlatformMacOSX (is_host); 123 return NULL; 124 } 125 126 lldb_private::ConstString 127 PlatformMacOSX::GetPluginNameStatic (bool is_host) 128 { 129 if (is_host) 130 { 131 static ConstString g_host_name(Platform::GetHostPlatformName ()); 132 return g_host_name; 133 } 134 else 135 { 136 static ConstString g_remote_name("remote-macosx"); 137 return g_remote_name; 138 } 139 } 140 141 const char * 142 PlatformMacOSX::GetDescriptionStatic (bool is_host) 143 { 144 if (is_host) 145 return "Local Mac OS X user platform plug-in."; 146 else 147 return "Remote Mac OS X user platform plug-in."; 148 } 149 150 //------------------------------------------------------------------ 151 /// Default Constructor 152 //------------------------------------------------------------------ 153 PlatformMacOSX::PlatformMacOSX (bool is_host) : 154 PlatformDarwin (is_host) 155 { 156 } 157 158 //------------------------------------------------------------------ 159 /// Destructor. 160 /// 161 /// The destructor is virtual since this class is designed to be 162 /// inherited from by the plug-in instance. 163 //------------------------------------------------------------------ 164 PlatformMacOSX::~PlatformMacOSX() 165 { 166 } 167 168 Error 169 PlatformMacOSX::GetSymbolFile (const FileSpec &platform_file, 170 const UUID *uuid_ptr, 171 FileSpec &local_file) 172 { 173 if (IsRemote()) 174 { 175 if (m_remote_platform_sp) 176 return m_remote_platform_sp->GetFile (platform_file, uuid_ptr, local_file); 177 } 178 179 // Default to the local case 180 local_file = platform_file; 181 return Error(); 182 } 183 184 lldb_private::Error 185 PlatformMacOSX::GetFile (const lldb_private::FileSpec &platform_file, 186 const lldb_private::UUID *uuid_ptr, 187 lldb_private::FileSpec &local_file) 188 { 189 if (IsRemote() && m_remote_platform_sp) 190 { 191 std::string local_os_build; 192 Host::GetOSBuildString(local_os_build); 193 std::string remote_os_build; 194 m_remote_platform_sp->GetOSBuildString(remote_os_build); 195 if (local_os_build.compare(remote_os_build) == 0) 196 { 197 // same OS version: the local file is good enough 198 local_file = platform_file; 199 return Error(); 200 } 201 else 202 { 203 // try to find the file in the cache 204 std::string cache_path(GetLocalCacheDirectory()); 205 std::string module_path (platform_file.GetPath()); 206 cache_path.append(module_path); 207 FileSpec module_cache_spec(cache_path.c_str(),false); 208 if (module_cache_spec.Exists()) 209 { 210 local_file = module_cache_spec; 211 return Error(); 212 } 213 // bring in the remote module file 214 FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent(); 215 StreamString mkdir_folder_cmd; 216 // try to make the local directory first 217 mkdir_folder_cmd.Printf("mkdir -p %s/%s", module_cache_folder.GetDirectory().AsCString(), module_cache_folder.GetFilename().AsCString()); 218 Host::RunShellCommand(mkdir_folder_cmd.GetData(), 219 NULL, 220 NULL, 221 NULL, 222 NULL, 223 60); 224 Error err = GetFile(platform_file, module_cache_spec); 225 if (err.Fail()) 226 return err; 227 if (module_cache_spec.Exists()) 228 { 229 local_file = module_cache_spec; 230 return Error(); 231 } 232 else 233 return Error("unable to obtain valid module file"); 234 } 235 } 236 local_file = platform_file; 237 return Error(); 238 } 239 240 bool 241 PlatformMacOSX::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 242 { 243 #if defined (__arm__) 244 return ARMGetSupportedArchitectureAtIndex (idx, arch); 245 #else 246 return x86GetSupportedArchitectureAtIndex (idx, arch); 247 #endif 248 } 249 250 lldb_private::Error 251 PlatformMacOSX::GetSharedModule (const lldb_private::ModuleSpec &module_spec, 252 lldb::ModuleSP &module_sp, 253 const lldb_private::FileSpecList *module_search_paths_ptr, 254 lldb::ModuleSP *old_module_sp_ptr, 255 bool *did_create_ptr) 256 { 257 return GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); 258 } 259