18#include "llvm/ADT/DenseMap.h"
29using namespace std::chrono;
35#define LLDB_PROPERTIES_android
36#include "PlatformAndroidProperties.inc"
39#define LLDB_PROPERTIES_android
40#include "PlatformAndroidPropertiesEnum.inc"
46 m_collection_sp = std::make_shared<OptionValueProperties>(
48 m_collection_sp->Initialize(g_android_properties);
53 static PluginProperties g_settings;
58const unsigned int g_android_default_cache_size =
64 PlatformLinux::Initialize();
67#if defined(__ANDROID__)
69 default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
86 PlatformLinux::Terminate();
92 const char *arch_name;
98 const char *triple_cstr =
99 arch ? arch->
GetTriple().getTriple().c_str() :
"<null>";
101 LLDB_LOGF(log,
"PlatformAndroid::%s(force=%s, arch={%s,%s})", __FUNCTION__,
102 force ?
"true" :
"false", arch_name, triple_cstr);
106 if (!create && arch && arch->
IsValid()) {
107 const llvm::Triple &triple = arch->
GetTriple();
108 switch (triple.getVendor()) {
109 case llvm::Triple::PC:
113#if defined(__ANDROID__)
117 case llvm::Triple::VendorType::UnknownVendor:
126 switch (triple.getEnvironment()) {
127 case llvm::Triple::Android:
130#if defined(__ANDROID__)
134 case llvm::Triple::EnvironmentType::UnknownEnvironment:
146 LLDB_LOGF(log,
"PlatformAndroid::%s() creating remote-android platform",
152 log,
"PlatformAndroid::%s() aborting creation of remote-android platform",
163 "Properties for the Android platform plugin.",
173 return "Local Android user platform plug-in.";
174 return "Remote Android user platform plug-in.";
182 "can't connect to the host platform, always connected");
190 std::optional<URI> parsed_url =
URI::Parse(url);
193 if (parsed_url->hostname !=
"localhost")
196 auto error = PlatformLinux::ConnectRemote(args);
197 if (
error.Success()) {
199 if (!resolved_device_id_or_error)
209 return PlatformLinux::GetFile(source, destination);
220 if (
error.Success() && sync_service) {
221 uint32_t mode = 0, size = 0, mtime = 0;
222 error = sync_service->Stat(source_spec, mode, size, mtime);
223 if (
error.Success()) {
225 return sync_service->PullFile(source_spec, destination);
230 LLDB_LOGF(log,
"Got mode == 0 on '%s': try to get file via 'shell cat'",
231 source_spec.
GetPath(
false).c_str());
236 std::string source_file = source_spec.
GetPath(
false);
239 LLDB_LOGF(log,
"Using shell cat fallback for '%s'", source_file.c_str());
241 if (strchr(source_file.c_str(),
'\'') !=
nullptr)
243 "Doesn't support single-quotes in filenames");
250 snprintf(cmd,
sizeof(cmd),
"%scat '%s'",
GetRunAs().c_str(),
251 source_file.c_str());
253 return adb->ShellToFile(cmd, minutes(1), destination);
257 const FileSpec &destination, uint32_t uid,
260 return PlatformLinux::PutFile(source, destination, uid, gid);
262 FileSpec destination_spec(destination.
GetPath(
false), FileSpec::Style::posix);
265 destination_spec.
GetPath(
false));
272 return sync_service->PushFile(source, destination_spec);
278 const uint64_t src_offset,
279 const uint64_t src_size,
281 std::string source_file = src_file_spec.
GetPath(
false);
282 if (source_file.empty())
285 std::string destination_file = dst_file_spec.
GetPath(
false);
286 if (destination_file.empty())
292 return GetFile(src_file_spec, dst_file_spec);
294 if (source_file.find(
'\'') != std::string::npos)
296 "Doesn't support single-quotes in filenames");
300 static constexpr llvm::StringLiteral k_zip_separator(
"!/");
301 size_t pos = source_file.find(k_zip_separator);
302 if (pos != std::string::npos)
303 source_file.resize(pos);
312 snprintf(cmd,
sizeof(cmd),
313 "%sdd if='%s' iflag=skip_bytes,count_bytes "
314 "skip=%" PRIu64
" count=%" PRIu64
" status=none",
315 GetRunAs().c_str(), source_file.c_str(), src_offset, src_size);
317 return adb->ShellToFile(cmd, minutes(1), dst_file_spec);
322 if (
error.Success()) {
330 return g_android_default_cache_size;
340 std::string version_string;
346 adb->Shell(
"getprop ro.build.version.sdk", seconds(5), &version_string);
347 version_string = llvm::StringRef(version_string).trim().str();
349 if (
error.Fail() || version_string.empty()) {
351 LLDB_LOGF(log,
"Get SDK version failed. (error: %s, output: %s)",
352 error.AsCString(), version_string.c_str());
364 llvm::StringRef extension = module_sp->GetFileSpec().GetFileNameExtension();
365 if (extension !=
".oat" && extension !=
".odex")
367 "Symbol file downloading only supported for oat and odex files");
370 if (!module_sp->GetPlatformFileSpec())
376 "Symbol file generation only supported on SDK 23+");
379 if (module_sp->GetSectionList()->FindSectionByName(
ConstString(
".symtab")) !=
388 error = adb->Shell(
"mktemp --directory --tmpdir /data/local/tmp", seconds(5),
390 if (
error.Fail() || tmpdir.empty())
392 "Failed to generate temporary directory on the device (%s)",
394 tmpdir = llvm::StringRef(tmpdir).trim().str();
397 std::unique_ptr<std::string, std::function<void(std::string *)>>
398 tmpdir_remover(&tmpdir, [&adb](std::string *s) {
400 command.
Printf(
"rm -rf %s", s->c_str());
404 if (log &&
error.Fail())
405 LLDB_LOGF(log,
"Failed to remove temp directory: %s",
409 FileSpec symfile_platform_filespec(tmpdir);
410 symfile_platform_filespec.AppendPathComponent(
"symbolized.oat");
414 command.
Printf(
"oatdump --symbolize=%s --output=%s",
415 module_sp->GetPlatformFileSpec().GetPath(
false).c_str(),
416 symfile_platform_filespec.GetPath(
false).c_str());
417 error = adb->Shell(command.
GetData(), minutes(1),
nullptr);
423 return GetFile(symfile_platform_filespec, dst_file_spec);
434 std::vector<const char *> dl_open_names = {
"__dl_dlopen",
"dlopen"};
435 const char *dl_open_name =
nullptr;
437 for (
auto *name : dl_open_names) {
439 ConstString(name), eFunctionNameTypeFull, matching_symbols);
440 if (matching_symbols.
GetSize()) {
446 if (dl_open_name == dl_open_names[0])
448 extern "C" void* dlopen(const char*, int) asm("__dl_dlopen");
449 extern "C" void* dlsym(void*, const char*) asm("__dl_dlsym");
450 extern "C" int dlclose(void*) asm("__dl_dlclose");
451 extern "C" char* dlerror(void) asm("__dl_dlerror");
459 error = adb->Connect();
465 ePropertyPlatformPackageName,
"");
470 if (!run_as.empty()) {
479 return std::string(
"run-as '") + run_as.str() +
"' ";
485 llvm::StringRef name =
487 return name.contains(
"app_process") || name.contains(
"zygote");
494 if (proc_infos.empty())
497 llvm::DenseMap<lldb::pid_t, ProcessInstanceInfo *> pid_map;
498 std::string pid_list;
499 for (
auto &proc_info : proc_infos) {
502 pid_map[pid] = &proc_info;
503 if (!pid_list.empty())
505 pid_list += std::to_string(pid);
509 if (pid_list.empty())
517 "echo '%s' | xargs -n 1 -P 8 sh -c "
518 "'echo \"$1:$(cat /proc/$1/cmdline 2>/dev/null | tr \"\\0\" \" \")\"' sh",
521 std::string cmdline_output;
524 if (
error.Fail() || cmdline_output.empty())
527 llvm::SmallVector<llvm::StringRef, 256> lines;
528 llvm::StringRef(cmdline_output).split(lines,
'\n', -1,
false);
530 for (llvm::StringRef line : lines) {
532 auto [pid_str, cmdline] = line.split(
':');
533 if (pid_str.empty() || cmdline.empty())
536 cmdline = cmdline.trim();
539 if (!llvm::to_integer(pid_str, pid) || cmdline.empty())
542 auto it = pid_map.find(pid);
543 if (it == pid_map.end())
546 ProcessInstanceInfo *proc_info = it->second;
547 llvm::SmallVector<llvm::StringRef, 16> args;
548 cmdline.split(args,
' ', -1,
false);
553 if (args.size() > 1) {
555 for (
size_t i = 1; i < args.size(); ++i) {
556 if (!args[i].empty())
563 "PlatformAndroid::%s supplemented PID %llu with cmdline: %s",
564 __FUNCTION__,
static_cast<unsigned long long>(pid),
565 cmdline.str().c_str());
576 return PlatformLinux::FindProcesses(match_info, proc_infos);
601 for (
auto &proc_info : all_procs) {
602 if (match_info.
Matches(proc_info))
603 proc_infos.push_back(proc_info);
607 return proc_infos.size();
611 auto sync_service = std::make_unique<AdbSyncService>(
m_device_id);
612 error = sync_service->SetupSyncConnection();
static llvm::raw_ostream & error(Stream &strm)
static DynamicLoaderDarwinKernelProperties & GetGlobalProperties()
#define LLDB_LOGF(log,...)
#define LLDB_PLUGIN_DEFINE(PluginName)
An architecture specification class.
bool IsValid() const
Tests if this ArchSpec is valid.
llvm::Triple & GetTriple()
Architecture triple accessor.
bool TripleEnvironmentWasSpecified() const
bool TripleVendorWasSpecified() const
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
A command line argument class.
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
A uniqued constant string class.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
A class to manage flag bits.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const
bool IsRelative() const
Returns true if the filespec represents a relative path.
const ConstString & GetFilename() const
Filename string const get accessor.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
ConstString GetPathAsConstString(bool denormalize=true) const
Get the full path as a ConstString.
void FindFunctionSymbols(ConstString name, lldb::FunctionNameType name_type_mask, SymbolContextList &sc_list)
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static lldb::OptionValuePropertiesSP GetSettingForPlatformPlugin(Debugger &debugger, llvm::StringRef setting_name)
static bool CreateSettingForPlatformPlugin(Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, llvm::StringRef description, bool is_global_property)
static bool UnregisterPlugin(ABICreateInstance create_callback)
lldb::pid_t GetProcessID() const
void SetArguments(const Args &args, bool first_arg_is_executable)
FileSpec & GetExecutableFile()
bool Matches(const ProcessInstanceInfo &proc_info) const
void SetNameMatchType(NameMatch name_match_type)
A plug-in interface definition class for debugging a process.
Target & GetTarget()
Get the target object pointer for this module.
T GetPropertyAtIndexAs(uint32_t idx, T default_value, const ExecutionContext *exe_ctx=nullptr) const
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
const char * GetData() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
const ModuleList & GetImages() const
Get accessor for the images for this process.
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
std::shared_ptr< lldb_private::Platform > PlatformSP
std::shared_ptr< lldb_private::Module > ModuleSP
static std::optional< URI > Parse(llvm::StringRef uri)