100e305d2STamas Berghammer //===-- PlatformAndroid.cpp -------------------------------------*- C++ -*-===// 200e305d2STamas Berghammer // 300e305d2STamas Berghammer // The LLVM Compiler Infrastructure 400e305d2STamas Berghammer // 500e305d2STamas Berghammer // This file is distributed under the University of Illinois Open Source 600e305d2STamas Berghammer // License. See LICENSE.TXT for details. 700e305d2STamas Berghammer // 800e305d2STamas Berghammer //===----------------------------------------------------------------------===// 900e305d2STamas Berghammer 1000e305d2STamas Berghammer // C Includes 1100e305d2STamas Berghammer // C++ Includes 1200e305d2STamas Berghammer // Other libraries and framework includes 1300e305d2STamas Berghammer #include "lldb/Core/Log.h" 14ec3f92a5STamas Berghammer #include "lldb/Core/Module.h" 1500e305d2STamas Berghammer #include "lldb/Core/PluginManager.h" 163cb132a0STamas Berghammer #include "lldb/Core/Scalar.h" 17ec3f92a5STamas Berghammer #include "lldb/Core/Section.h" 183cb132a0STamas Berghammer #include "lldb/Core/ValueObject.h" 191c6a1ea9STamas Berghammer #include "lldb/Host/HostInfo.h" 201d0d90b9STamas Berghammer #include "lldb/Host/StringConvert.h" 213ea689b3SChaoren Lin #include "Utility/UriParser.h" 2200e305d2STamas Berghammer 2300e305d2STamas Berghammer // Project includes 246f001068SOleksiy Vyalov #include "AdbClient.h" 2500e305d2STamas Berghammer #include "PlatformAndroid.h" 2600e305d2STamas Berghammer #include "PlatformAndroidRemoteGDBServer.h" 2700e305d2STamas Berghammer 2800e305d2STamas Berghammer using namespace lldb; 2900e305d2STamas Berghammer using namespace lldb_private; 30db264a6dSTamas Berghammer using namespace lldb_private::platform_android; 3100e305d2STamas Berghammer 3200e305d2STamas Berghammer static uint32_t g_initialize_count = 0; 33f2991488SPavel Labath static const unsigned int g_android_default_cache_size = 2048; // Fits inside 4k adb packet. 3400e305d2STamas Berghammer 3500e305d2STamas Berghammer void 3600e305d2STamas Berghammer PlatformAndroid::Initialize () 3700e305d2STamas Berghammer { 383c4f89d7STamas Berghammer PlatformLinux::Initialize (); 393c4f89d7STamas Berghammer 4000e305d2STamas Berghammer if (g_initialize_count++ == 0) 4100e305d2STamas Berghammer { 421c6a1ea9STamas Berghammer #if defined(__ANDROID__) 431c6a1ea9STamas Berghammer PlatformSP default_platform_sp (new PlatformAndroid(true)); 441c6a1ea9STamas Berghammer default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); 451c6a1ea9STamas Berghammer Platform::SetHostPlatform (default_platform_sp); 461c6a1ea9STamas Berghammer #endif 471c6a1ea9STamas Berghammer PluginManager::RegisterPlugin (PlatformAndroid::GetPluginNameStatic(false), 481c6a1ea9STamas Berghammer PlatformAndroid::GetPluginDescriptionStatic(false), 4900e305d2STamas Berghammer PlatformAndroid::CreateInstance); 5000e305d2STamas Berghammer } 5100e305d2STamas Berghammer } 5200e305d2STamas Berghammer 5300e305d2STamas Berghammer void 5400e305d2STamas Berghammer PlatformAndroid::Terminate () 5500e305d2STamas Berghammer { 5600e305d2STamas Berghammer if (g_initialize_count > 0) 5700e305d2STamas Berghammer { 5800e305d2STamas Berghammer if (--g_initialize_count == 0) 5900e305d2STamas Berghammer { 6000e305d2STamas Berghammer PluginManager::UnregisterPlugin (PlatformAndroid::CreateInstance); 6100e305d2STamas Berghammer } 6200e305d2STamas Berghammer } 633c4f89d7STamas Berghammer 643c4f89d7STamas Berghammer PlatformLinux::Terminate (); 6500e305d2STamas Berghammer } 6600e305d2STamas Berghammer 6700e305d2STamas Berghammer PlatformSP 6800e305d2STamas Berghammer PlatformAndroid::CreateInstance (bool force, const ArchSpec *arch) 6900e305d2STamas Berghammer { 70db264a6dSTamas Berghammer Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); 7100e305d2STamas Berghammer if (log) 7200e305d2STamas Berghammer { 7300e305d2STamas Berghammer const char *arch_name; 7400e305d2STamas Berghammer if (arch && arch->GetArchitectureName ()) 7500e305d2STamas Berghammer arch_name = arch->GetArchitectureName (); 7600e305d2STamas Berghammer else 7700e305d2STamas Berghammer arch_name = "<null>"; 7800e305d2STamas Berghammer 7900e305d2STamas Berghammer const char *triple_cstr = arch ? arch->GetTriple ().getTriple ().c_str() : "<null>"; 8000e305d2STamas Berghammer 8100e305d2STamas Berghammer log->Printf ("PlatformAndroid::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr); 8200e305d2STamas Berghammer } 8300e305d2STamas Berghammer 8400e305d2STamas Berghammer bool create = force; 8500e305d2STamas Berghammer if (create == false && arch && arch->IsValid()) 8600e305d2STamas Berghammer { 8700e305d2STamas Berghammer const llvm::Triple &triple = arch->GetTriple(); 8800e305d2STamas Berghammer switch (triple.getVendor()) 8900e305d2STamas Berghammer { 9000e305d2STamas Berghammer case llvm::Triple::PC: 9100e305d2STamas Berghammer create = true; 9200e305d2STamas Berghammer break; 9300e305d2STamas Berghammer 9400e305d2STamas Berghammer #if defined(__ANDROID__) 9500e305d2STamas Berghammer // Only accept "unknown" for the vendor if the host is android and 9600e305d2STamas Berghammer // it "unknown" wasn't specified (it was just returned because it 9700e305d2STamas Berghammer // was NOT specified_ 9800e305d2STamas Berghammer case llvm::Triple::VendorType::UnknownVendor: 9900e305d2STamas Berghammer create = !arch->TripleVendorWasSpecified(); 10000e305d2STamas Berghammer break; 10100e305d2STamas Berghammer #endif 10200e305d2STamas Berghammer default: 10300e305d2STamas Berghammer break; 10400e305d2STamas Berghammer } 10500e305d2STamas Berghammer 10600e305d2STamas Berghammer if (create) 10700e305d2STamas Berghammer { 10800e305d2STamas Berghammer switch (triple.getOS()) 10900e305d2STamas Berghammer { 1101c6a1ea9STamas Berghammer case llvm::Triple::Android: 11100e305d2STamas Berghammer break; 11200e305d2STamas Berghammer 11300e305d2STamas Berghammer #if defined(__ANDROID__) 11400e305d2STamas Berghammer // Only accept "unknown" for the OS if the host is android and 11500e305d2STamas Berghammer // it "unknown" wasn't specified (it was just returned because it 11600e305d2STamas Berghammer // was NOT specified) 11700e305d2STamas Berghammer case llvm::Triple::OSType::UnknownOS: 11800e305d2STamas Berghammer create = !arch->TripleOSWasSpecified(); 11900e305d2STamas Berghammer break; 12000e305d2STamas Berghammer #endif 12100e305d2STamas Berghammer default: 12200e305d2STamas Berghammer create = false; 12300e305d2STamas Berghammer break; 12400e305d2STamas Berghammer } 12500e305d2STamas Berghammer } 12600e305d2STamas Berghammer } 12700e305d2STamas Berghammer 12800e305d2STamas Berghammer if (create) 12900e305d2STamas Berghammer { 13000e305d2STamas Berghammer if (log) 13100e305d2STamas Berghammer log->Printf ("PlatformAndroid::%s() creating remote-android platform", __FUNCTION__); 1321c6a1ea9STamas Berghammer return PlatformSP(new PlatformAndroid(false)); 13300e305d2STamas Berghammer } 13400e305d2STamas Berghammer 13500e305d2STamas Berghammer if (log) 13600e305d2STamas Berghammer log->Printf ("PlatformAndroid::%s() aborting creation of remote-android platform", __FUNCTION__); 13700e305d2STamas Berghammer 13800e305d2STamas Berghammer return PlatformSP(); 13900e305d2STamas Berghammer } 14000e305d2STamas Berghammer 1411c6a1ea9STamas Berghammer PlatformAndroid::PlatformAndroid (bool is_host) : 1421d0d90b9STamas Berghammer PlatformLinux(is_host), 1431d0d90b9STamas Berghammer m_sdk_version(0) 14400e305d2STamas Berghammer { 14500e305d2STamas Berghammer } 14600e305d2STamas Berghammer 14700e305d2STamas Berghammer PlatformAndroid::~PlatformAndroid() 14800e305d2STamas Berghammer { 14900e305d2STamas Berghammer } 15000e305d2STamas Berghammer 151db264a6dSTamas Berghammer ConstString 1521c6a1ea9STamas Berghammer PlatformAndroid::GetPluginNameStatic (bool is_host) 1531c6a1ea9STamas Berghammer { 1541c6a1ea9STamas Berghammer if (is_host) 1551c6a1ea9STamas Berghammer { 1561c6a1ea9STamas Berghammer static ConstString g_host_name(Platform::GetHostPlatformName ()); 1571c6a1ea9STamas Berghammer return g_host_name; 1581c6a1ea9STamas Berghammer } 1591c6a1ea9STamas Berghammer else 16000e305d2STamas Berghammer { 16100e305d2STamas Berghammer static ConstString g_remote_name("remote-android"); 16200e305d2STamas Berghammer return g_remote_name; 16300e305d2STamas Berghammer } 1641c6a1ea9STamas Berghammer } 16500e305d2STamas Berghammer 16600e305d2STamas Berghammer const char * 1671c6a1ea9STamas Berghammer PlatformAndroid::GetPluginDescriptionStatic (bool is_host) 16800e305d2STamas Berghammer { 1691c6a1ea9STamas Berghammer if (is_host) 1701c6a1ea9STamas Berghammer return "Local Android user platform plug-in."; 1711c6a1ea9STamas Berghammer else 17200e305d2STamas Berghammer return "Remote Android user platform plug-in."; 17300e305d2STamas Berghammer } 17400e305d2STamas Berghammer 175db264a6dSTamas Berghammer ConstString 17600e305d2STamas Berghammer PlatformAndroid::GetPluginName() 17700e305d2STamas Berghammer { 1781c6a1ea9STamas Berghammer return GetPluginNameStatic(IsHost()); 17900e305d2STamas Berghammer } 18000e305d2STamas Berghammer 18100e305d2STamas Berghammer Error 18200e305d2STamas Berghammer PlatformAndroid::ConnectRemote(Args& args) 18300e305d2STamas Berghammer { 1846f001068SOleksiy Vyalov m_device_id.clear(); 1856f001068SOleksiy Vyalov 1861c6a1ea9STamas Berghammer if (IsHost()) 1871c6a1ea9STamas Berghammer { 1881c6a1ea9STamas Berghammer return Error ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString()); 1891c6a1ea9STamas Berghammer } 1901c6a1ea9STamas Berghammer 19100e305d2STamas Berghammer if (!m_remote_platform_sp) 19200e305d2STamas Berghammer m_remote_platform_sp = PlatformSP(new PlatformAndroidRemoteGDBServer()); 1936f001068SOleksiy Vyalov 1943ea689b3SChaoren Lin int port; 1953ea689b3SChaoren Lin std::string scheme, host, path; 1963ea689b3SChaoren Lin const char *url = args.GetArgumentAtIndex(0); 1973ea689b3SChaoren Lin if (!url) 1983ea689b3SChaoren Lin return Error("URL is null."); 1993ea689b3SChaoren Lin if (!UriParser::Parse(url, scheme, host, port, path)) 2003ea689b3SChaoren Lin return Error("Invalid URL: %s", url); 201a29d6475SOleksiy Vyalov if (host != "localhost") 2023ea689b3SChaoren Lin m_device_id = host; 2033ea689b3SChaoren Lin 2046f001068SOleksiy Vyalov auto error = PlatformLinux::ConnectRemote(args); 2056f001068SOleksiy Vyalov if (error.Success()) 2066f001068SOleksiy Vyalov { 207d6a143fcSOleksiy Vyalov AdbClient adb; 208d6a143fcSOleksiy Vyalov error = AdbClient::CreateByDeviceID(m_device_id, adb); 2096f001068SOleksiy Vyalov if (error.Fail()) 2106f001068SOleksiy Vyalov return error; 2116f001068SOleksiy Vyalov 212d6a143fcSOleksiy Vyalov m_device_id = adb.GetDeviceID(); 2136f001068SOleksiy Vyalov } 2146f001068SOleksiy Vyalov return error; 2156f001068SOleksiy Vyalov } 2166f001068SOleksiy Vyalov 2170b5ebef7SOleksiy Vyalov Error 2180b5ebef7SOleksiy Vyalov PlatformAndroid::GetFile (const FileSpec& source, 2190b5ebef7SOleksiy Vyalov const FileSpec& destination) 2200b5ebef7SOleksiy Vyalov { 221291f59c5SOleksiy Vyalov if (IsHost() || !m_remote_platform_sp) 2220b5ebef7SOleksiy Vyalov return PlatformLinux::GetFile(source, destination); 223291f59c5SOleksiy Vyalov 22432a9da56SOleksiy Vyalov FileSpec source_spec (source.GetPath (false), false, FileSpec::ePathSyntaxPosix); 225372e9067SChaoren Lin if (source_spec.IsRelative()) 22632a9da56SOleksiy Vyalov source_spec = GetRemoteWorkingDirectory ().CopyByAppendingPathComponent (source_spec.GetCString (false)); 227291f59c5SOleksiy Vyalov 228d6a143fcSOleksiy Vyalov Error error; 229d6a143fcSOleksiy Vyalov auto sync_service = GetSyncService (error); 230d6a143fcSOleksiy Vyalov if (error.Fail ()) 231d6a143fcSOleksiy Vyalov return error; 232d6a143fcSOleksiy Vyalov 233c6ac2e1eSOleksiy Vyalov uint32_t mode = 0, size = 0, mtime = 0; 234c6ac2e1eSOleksiy Vyalov error = sync_service->Stat(source_spec, mode, size, mtime); 235c6ac2e1eSOleksiy Vyalov if (error.Fail()) 236c6ac2e1eSOleksiy Vyalov return error; 237c6ac2e1eSOleksiy Vyalov 238c6ac2e1eSOleksiy Vyalov if (mode != 0) 239d6a143fcSOleksiy Vyalov return sync_service->PullFile(source_spec, destination); 240c6ac2e1eSOleksiy Vyalov 241c6ac2e1eSOleksiy Vyalov auto source_file = source_spec.GetCString(false); 242c6ac2e1eSOleksiy Vyalov 243c6ac2e1eSOleksiy Vyalov Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); 244c6ac2e1eSOleksiy Vyalov if (log) 245c6ac2e1eSOleksiy Vyalov log->Printf("Got mode == 0 on '%s': try to get file via 'shell cat'", source_file); 246c6ac2e1eSOleksiy Vyalov 247c6ac2e1eSOleksiy Vyalov if (strchr(source_file, '\'') != nullptr) 248c6ac2e1eSOleksiy Vyalov return Error("Doesn't support single-quotes in filenames"); 249c6ac2e1eSOleksiy Vyalov 250c6ac2e1eSOleksiy Vyalov // mode == 0 can signify that adbd cannot access the file 251c6ac2e1eSOleksiy Vyalov // due security constraints - try "cat ..." as a fallback. 252c6ac2e1eSOleksiy Vyalov AdbClient adb(m_device_id); 253c6ac2e1eSOleksiy Vyalov 254c6ac2e1eSOleksiy Vyalov char cmd[PATH_MAX]; 255c6ac2e1eSOleksiy Vyalov snprintf(cmd, sizeof(cmd), "cat '%s'", source_file); 256c6ac2e1eSOleksiy Vyalov 257c6ac2e1eSOleksiy Vyalov return adb.ShellToFile(cmd, 60000 /* ms */, destination); 2580b5ebef7SOleksiy Vyalov } 2590b5ebef7SOleksiy Vyalov 2600b5ebef7SOleksiy Vyalov Error 2610b5ebef7SOleksiy Vyalov PlatformAndroid::PutFile (const FileSpec& source, 2620b5ebef7SOleksiy Vyalov const FileSpec& destination, 26362efb1f6SRobert Flack uint32_t uid, 26462efb1f6SRobert Flack uint32_t gid) 26562efb1f6SRobert Flack { 26617701b59SOleksiy Vyalov if (IsHost() || !m_remote_platform_sp) 26717701b59SOleksiy Vyalov return PlatformLinux::PutFile (source, destination, uid, gid); 26817701b59SOleksiy Vyalov 26917701b59SOleksiy Vyalov FileSpec destination_spec (destination.GetPath (false), false, FileSpec::ePathSyntaxPosix); 270372e9067SChaoren Lin if (destination_spec.IsRelative()) 27117701b59SOleksiy Vyalov destination_spec = GetRemoteWorkingDirectory ().CopyByAppendingPathComponent (destination_spec.GetCString (false)); 27217701b59SOleksiy Vyalov 27362efb1f6SRobert Flack // TODO: Set correct uid and gid on remote file. 274d6a143fcSOleksiy Vyalov Error error; 275d6a143fcSOleksiy Vyalov auto sync_service = GetSyncService (error); 276d6a143fcSOleksiy Vyalov if (error.Fail ()) 277d6a143fcSOleksiy Vyalov return error; 278d6a143fcSOleksiy Vyalov return sync_service->PushFile(source, destination_spec); 27962efb1f6SRobert Flack } 28062efb1f6SRobert Flack 2816f001068SOleksiy Vyalov const char * 2826f001068SOleksiy Vyalov PlatformAndroid::GetCacheHostname () 2836f001068SOleksiy Vyalov { 2846f001068SOleksiy Vyalov return m_device_id.c_str (); 28500e305d2STamas Berghammer } 28609e9079dSOleksiy Vyalov 28709e9079dSOleksiy Vyalov Error 28809e9079dSOleksiy Vyalov PlatformAndroid::DownloadModuleSlice (const FileSpec &src_file_spec, 28909e9079dSOleksiy Vyalov const uint64_t src_offset, 29009e9079dSOleksiy Vyalov const uint64_t src_size, 29109e9079dSOleksiy Vyalov const FileSpec &dst_file_spec) 29209e9079dSOleksiy Vyalov { 29309e9079dSOleksiy Vyalov if (src_offset != 0) 29409e9079dSOleksiy Vyalov return Error ("Invalid offset - %" PRIu64, src_offset); 29509e9079dSOleksiy Vyalov 2960b5ebef7SOleksiy Vyalov return GetFile (src_file_spec, dst_file_spec); 29709e9079dSOleksiy Vyalov } 2981d0d90b9STamas Berghammer 2991d0d90b9STamas Berghammer Error 3001d0d90b9STamas Berghammer PlatformAndroid::DisconnectRemote() 3011d0d90b9STamas Berghammer { 3021d0d90b9STamas Berghammer Error error = PlatformLinux::DisconnectRemote(); 3031d0d90b9STamas Berghammer if (error.Success()) 3041d0d90b9STamas Berghammer { 3051d0d90b9STamas Berghammer m_device_id.clear(); 3061d0d90b9STamas Berghammer m_sdk_version = 0; 3071d0d90b9STamas Berghammer } 3081d0d90b9STamas Berghammer return error; 3091d0d90b9STamas Berghammer } 3101d0d90b9STamas Berghammer 3111d0d90b9STamas Berghammer uint32_t 312f2991488SPavel Labath PlatformAndroid::GetDefaultMemoryCacheLineSize() 313f2991488SPavel Labath { 314f2991488SPavel Labath return g_android_default_cache_size; 315f2991488SPavel Labath } 316f2991488SPavel Labath 317f2991488SPavel Labath uint32_t 3181d0d90b9STamas Berghammer PlatformAndroid::GetSdkVersion() 3191d0d90b9STamas Berghammer { 3201d0d90b9STamas Berghammer if (!IsConnected()) 3211d0d90b9STamas Berghammer return 0; 3221d0d90b9STamas Berghammer 3231d0d90b9STamas Berghammer if (m_sdk_version != 0) 3241d0d90b9STamas Berghammer return m_sdk_version; 3251d0d90b9STamas Berghammer 3261d0d90b9STamas Berghammer std::string version_string; 327d6a143fcSOleksiy Vyalov AdbClient adb(m_device_id); 328d6a143fcSOleksiy Vyalov Error error = adb.Shell("getprop ro.build.version.sdk", 5000 /* ms */, &version_string); 3293e8947beSTamas Berghammer version_string = llvm::StringRef(version_string).trim().str(); 3303e8947beSTamas Berghammer 3313e8947beSTamas Berghammer if (error.Fail() || version_string.empty()) 3321d0d90b9STamas Berghammer { 3331d0d90b9STamas Berghammer Log* log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM); 3341d0d90b9STamas Berghammer if (log) 3353e8947beSTamas Berghammer log->Printf("Get SDK version failed. (error: %s, output: %s)", 3363e8947beSTamas Berghammer error.AsCString(), version_string.c_str()); 3371d0d90b9STamas Berghammer return 0; 3381d0d90b9STamas Berghammer } 3391d0d90b9STamas Berghammer 3401d0d90b9STamas Berghammer m_sdk_version = StringConvert::ToUInt32(version_string.c_str()); 3411d0d90b9STamas Berghammer return m_sdk_version; 3421d0d90b9STamas Berghammer } 343ec3f92a5STamas Berghammer 344ec3f92a5STamas Berghammer Error 345ec3f92a5STamas Berghammer PlatformAndroid::DownloadSymbolFile (const lldb::ModuleSP& module_sp, 346ec3f92a5STamas Berghammer const FileSpec& dst_file_spec) 347ec3f92a5STamas Berghammer { 348ec3f92a5STamas Berghammer // For oat file we can try to fetch additional debug info from the device 349dba6503aSTamas Berghammer ConstString extension = module_sp->GetFileSpec().GetFileNameExtension(); 350dba6503aSTamas Berghammer if (extension != ConstString("oat") && extension != ConstString("odex")) 351dba6503aSTamas Berghammer return Error("Symbol file downloading only supported for oat and odex files"); 352ec3f92a5STamas Berghammer 353ec3f92a5STamas Berghammer // If we have no information about the platform file we can't execute oatdump 354ec3f92a5STamas Berghammer if (!module_sp->GetPlatformFileSpec()) 355ec3f92a5STamas Berghammer return Error("No platform file specified"); 356ec3f92a5STamas Berghammer 357ec3f92a5STamas Berghammer // Symbolizer isn't available before SDK version 23 358ec3f92a5STamas Berghammer if (GetSdkVersion() < 23) 359ec3f92a5STamas Berghammer return Error("Symbol file generation only supported on SDK 23+"); 360ec3f92a5STamas Berghammer 361ec3f92a5STamas Berghammer // If we already have symtab then we don't have to try and generate one 362ec3f92a5STamas Berghammer if (module_sp->GetSectionList()->FindSectionByName(ConstString(".symtab")) != nullptr) 363ec3f92a5STamas Berghammer return Error("Symtab already available in the module"); 364ec3f92a5STamas Berghammer 365d6a143fcSOleksiy Vyalov AdbClient adb(m_device_id); 3669d8dde8cSTamas Berghammer std::string tmpdir; 367d6a143fcSOleksiy Vyalov Error error = adb.Shell("mktemp --directory --tmpdir /data/local/tmp", 5000 /* ms */, &tmpdir); 3689d8dde8cSTamas Berghammer if (error.Fail() || tmpdir.empty()) 369ec3f92a5STamas Berghammer return Error("Failed to generate temporary directory on the device (%s)", error.AsCString()); 370539cd118STamas Berghammer tmpdir = llvm::StringRef(tmpdir).trim().str(); 371ec3f92a5STamas Berghammer 372ec3f92a5STamas Berghammer // Create file remover for the temporary directory created on the device 373ec3f92a5STamas Berghammer std::unique_ptr<std::string, std::function<void(std::string*)>> tmpdir_remover( 374ec3f92a5STamas Berghammer &tmpdir, 375d6a143fcSOleksiy Vyalov [this, &adb](std::string* s) { 376ec3f92a5STamas Berghammer StreamString command; 377ec3f92a5STamas Berghammer command.Printf("rm -rf %s", s->c_str()); 378d6a143fcSOleksiy Vyalov Error error = adb.Shell(command.GetData(), 5000 /* ms */, nullptr); 379ec3f92a5STamas Berghammer 380ec3f92a5STamas Berghammer Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); 381*dd778ca6SOleksiy Vyalov if (log && error.Fail()) 382ec3f92a5STamas Berghammer log->Printf("Failed to remove temp directory: %s", error.AsCString()); 383ec3f92a5STamas Berghammer } 384ec3f92a5STamas Berghammer ); 385ec3f92a5STamas Berghammer 386ec3f92a5STamas Berghammer FileSpec symfile_platform_filespec(tmpdir.c_str(), false); 387ec3f92a5STamas Berghammer symfile_platform_filespec.AppendPathComponent("symbolized.oat"); 388ec3f92a5STamas Berghammer 389ec3f92a5STamas Berghammer // Execute oatdump on the remote device to generate a file with symtab 3909d8dde8cSTamas Berghammer StreamString command; 391ec3f92a5STamas Berghammer command.Printf("oatdump --symbolize=%s --output=%s", 392ec3f92a5STamas Berghammer module_sp->GetPlatformFileSpec().GetCString(false), 393ec3f92a5STamas Berghammer symfile_platform_filespec.GetCString(false)); 394d6a143fcSOleksiy Vyalov error = adb.Shell(command.GetData(), 60000 /* ms */, nullptr); 3959d8dde8cSTamas Berghammer if (error.Fail()) 396ec3f92a5STamas Berghammer return Error("Oatdump failed: %s", error.AsCString()); 397ec3f92a5STamas Berghammer 398ec3f92a5STamas Berghammer // Download the symbolfile from the remote device 399ec3f92a5STamas Berghammer return GetFile(symfile_platform_filespec, dst_file_spec); 400ec3f92a5STamas Berghammer } 4013c47151dSTamas Berghammer 4023c47151dSTamas Berghammer bool 4033c47151dSTamas Berghammer PlatformAndroid::GetRemoteOSVersion () 4043c47151dSTamas Berghammer { 4053c47151dSTamas Berghammer m_major_os_version = GetSdkVersion(); 4063c47151dSTamas Berghammer m_minor_os_version = 0; 4073c47151dSTamas Berghammer m_update_os_version = 0; 4083c47151dSTamas Berghammer return m_major_os_version != 0; 4093c47151dSTamas Berghammer } 4103cb132a0STamas Berghammer 411fcdde63fSTamas Berghammer const char* 412fcdde63fSTamas Berghammer PlatformAndroid::GetLibdlFunctionDeclarations() const 4133cb132a0STamas Berghammer { 414fcdde63fSTamas Berghammer return R"( 415fcdde63fSTamas Berghammer extern "C" void* dlopen(const char*, int) asm("__dl_dlopen"); 416fcdde63fSTamas Berghammer extern "C" void* dlsym(void*, const char*) asm("__dl_dlsym"); 417fcdde63fSTamas Berghammer extern "C" int dlclose(void*) asm("__dl_dlclose"); 418fcdde63fSTamas Berghammer extern "C" char* dlerror(void) asm("__dl_dlerror"); 4193cb132a0STamas Berghammer )"; 4203cb132a0STamas Berghammer } 421d6a143fcSOleksiy Vyalov 422d6a143fcSOleksiy Vyalov AdbClient::SyncService* 423d6a143fcSOleksiy Vyalov PlatformAndroid::GetSyncService (Error &error) 424d6a143fcSOleksiy Vyalov { 425d6a143fcSOleksiy Vyalov if (m_adb_sync_svc && m_adb_sync_svc->IsConnected ()) 426d6a143fcSOleksiy Vyalov return m_adb_sync_svc.get (); 427d6a143fcSOleksiy Vyalov 428d6a143fcSOleksiy Vyalov AdbClient adb (m_device_id); 429d6a143fcSOleksiy Vyalov m_adb_sync_svc = adb.GetSyncService (error); 430d6a143fcSOleksiy Vyalov return (error.Success ()) ? m_adb_sync_svc.get () : nullptr; 431d6a143fcSOleksiy Vyalov } 432d6a143fcSOleksiy Vyalov 433