1 //===-- PlatformAndroid.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 // C Includes 11 // C++ Includes 12 // Other libraries and framework includes 13 #include "lldb/Core/Log.h" 14 #include "lldb/Core/PluginManager.h" 15 #include "lldb/Host/HostInfo.h" 16 17 // Project includes 18 #include "AdbClient.h" 19 #include "PlatformAndroid.h" 20 #include "PlatformAndroidRemoteGDBServer.h" 21 22 using namespace lldb; 23 using namespace lldb_private; 24 using namespace lldb_private::platform_android; 25 26 static uint32_t g_initialize_count = 0; 27 28 void 29 PlatformAndroid::Initialize () 30 { 31 PlatformLinux::Initialize (); 32 33 if (g_initialize_count++ == 0) 34 { 35 #if defined(__ANDROID__) 36 PlatformSP default_platform_sp (new PlatformAndroid(true)); 37 default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); 38 Platform::SetHostPlatform (default_platform_sp); 39 #endif 40 PluginManager::RegisterPlugin (PlatformAndroid::GetPluginNameStatic(false), 41 PlatformAndroid::GetPluginDescriptionStatic(false), 42 PlatformAndroid::CreateInstance); 43 } 44 } 45 46 void 47 PlatformAndroid::Terminate () 48 { 49 if (g_initialize_count > 0) 50 { 51 if (--g_initialize_count == 0) 52 { 53 PluginManager::UnregisterPlugin (PlatformAndroid::CreateInstance); 54 } 55 } 56 57 PlatformLinux::Terminate (); 58 } 59 60 PlatformSP 61 PlatformAndroid::CreateInstance (bool force, const ArchSpec *arch) 62 { 63 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); 64 if (log) 65 { 66 const char *arch_name; 67 if (arch && arch->GetArchitectureName ()) 68 arch_name = arch->GetArchitectureName (); 69 else 70 arch_name = "<null>"; 71 72 const char *triple_cstr = arch ? arch->GetTriple ().getTriple ().c_str() : "<null>"; 73 74 log->Printf ("PlatformAndroid::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr); 75 } 76 77 bool create = force; 78 if (create == false && arch && arch->IsValid()) 79 { 80 const llvm::Triple &triple = arch->GetTriple(); 81 switch (triple.getVendor()) 82 { 83 case llvm::Triple::PC: 84 create = true; 85 break; 86 87 #if defined(__ANDROID__) 88 // Only accept "unknown" for the vendor if the host is android and 89 // it "unknown" wasn't specified (it was just returned because it 90 // was NOT specified_ 91 case llvm::Triple::VendorType::UnknownVendor: 92 create = !arch->TripleVendorWasSpecified(); 93 break; 94 #endif 95 default: 96 break; 97 } 98 99 if (create) 100 { 101 switch (triple.getOS()) 102 { 103 case llvm::Triple::Android: 104 break; 105 106 #if defined(__ANDROID__) 107 // Only accept "unknown" for the OS if the host is android and 108 // it "unknown" wasn't specified (it was just returned because it 109 // was NOT specified) 110 case llvm::Triple::OSType::UnknownOS: 111 create = !arch->TripleOSWasSpecified(); 112 break; 113 #endif 114 default: 115 create = false; 116 break; 117 } 118 } 119 } 120 121 if (create) 122 { 123 if (log) 124 log->Printf ("PlatformAndroid::%s() creating remote-android platform", __FUNCTION__); 125 return PlatformSP(new PlatformAndroid(false)); 126 } 127 128 if (log) 129 log->Printf ("PlatformAndroid::%s() aborting creation of remote-android platform", __FUNCTION__); 130 131 return PlatformSP(); 132 } 133 134 PlatformAndroid::PlatformAndroid (bool is_host) : 135 PlatformLinux(is_host) 136 { 137 } 138 139 PlatformAndroid::~PlatformAndroid() 140 { 141 } 142 143 ConstString 144 PlatformAndroid::GetPluginNameStatic (bool is_host) 145 { 146 if (is_host) 147 { 148 static ConstString g_host_name(Platform::GetHostPlatformName ()); 149 return g_host_name; 150 } 151 else 152 { 153 static ConstString g_remote_name("remote-android"); 154 return g_remote_name; 155 } 156 } 157 158 const char * 159 PlatformAndroid::GetPluginDescriptionStatic (bool is_host) 160 { 161 if (is_host) 162 return "Local Android user platform plug-in."; 163 else 164 return "Remote Android user platform plug-in."; 165 } 166 167 ConstString 168 PlatformAndroid::GetPluginName() 169 { 170 return GetPluginNameStatic(IsHost()); 171 } 172 173 Error 174 PlatformAndroid::ConnectRemote (Args& args) 175 { 176 m_device_id.clear (); 177 178 if (IsHost()) 179 { 180 return Error ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString()); 181 } 182 183 if (!m_remote_platform_sp) 184 m_remote_platform_sp = PlatformSP(new PlatformAndroidRemoteGDBServer()); 185 186 auto error = PlatformLinux::ConnectRemote (args); 187 if (error.Success ()) 188 { 189 // Fetch the device list from ADB and if only 1 device found then use that device 190 // TODO: Handle the case when more device is available 191 AdbClient adb; 192 error = AdbClient::CreateByDeviceID (nullptr, adb); 193 if (error.Fail ()) 194 return error; 195 196 m_device_id = adb.GetDeviceID (); 197 } 198 return error; 199 } 200 201 const char * 202 PlatformAndroid::GetCacheHostname () 203 { 204 return m_device_id.c_str (); 205 } 206