diff options
Diffstat (limited to 'lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp')
| -rw-r--r-- | lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp index d3440c4ce51..dbad21aa52c 100644 --- a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp +++ b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -13,7 +13,9 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/Scalar.h" #include "lldb/Core/Section.h" +#include "lldb/Core/ValueObject.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/StringConvert.h" #include "Utility/UriParser.h" @@ -374,3 +376,91 @@ PlatformAndroid::GetRemoteOSVersion () m_update_os_version = 0; return m_major_os_version != 0; } + +uint32_t +PlatformAndroid::LoadImage(lldb_private::Process* process, const FileSpec& image_spec, Error& error) +{ + char path[PATH_MAX]; + image_spec.GetPath(path, sizeof(path)); + + StreamString expr; + expr.Printf(R"( + struct __lldb_dlopen_result { void *image_ptr; const char *error_str; } the_result; + the_result.image_ptr = __dl_dlopen ("%s", 2); + if (the_result.image_ptr == (void*)0x0) + the_result.error_str = __dl_dlerror(); + else + the_result.error_str = (const char*)0x0; + the_result; + )", + path); + const char *prefix = R"( + extern "C" void* __dl_dlopen(const char* path, int mode); + extern "C" const char *__dl_dlerror(void); + )"; + lldb::ValueObjectSP result_valobj_sp; + error = EvaluateLibdlExpression(process, expr.GetData(), prefix, result_valobj_sp); + if (error.Fail()) + return LLDB_INVALID_IMAGE_TOKEN; + + error = result_valobj_sp->GetError(); + if (error.Fail()) + return LLDB_INVALID_IMAGE_TOKEN; + + Scalar scalar; + ValueObjectSP image_ptr_sp = result_valobj_sp->GetChildAtIndex(0, true); + if (!image_ptr_sp || !image_ptr_sp->ResolveValue(scalar)) + { + error.SetErrorStringWithFormat("unable to load '%s'", path); + return LLDB_INVALID_IMAGE_TOKEN; + } + + addr_t image_ptr = scalar.ULongLong(LLDB_INVALID_ADDRESS); + if (image_ptr != 0 && image_ptr != LLDB_INVALID_ADDRESS) + return process->AddImageToken(image_ptr); + + if (image_ptr == 0) + { + ValueObjectSP error_str_sp = result_valobj_sp->GetChildAtIndex(1, true); + if (error_str_sp && error_str_sp->IsCStringContainer(true)) + { + DataBufferSP buffer_sp(new DataBufferHeap(10240,0)); + size_t num_chars = error_str_sp->ReadPointedString (buffer_sp, error, 10240).first; + if (error.Success() && num_chars > 0) + error.SetErrorStringWithFormat("dlopen error: %s", buffer_sp->GetBytes()); + else + error.SetErrorStringWithFormat("dlopen failed for unknown reasons."); + return LLDB_INVALID_IMAGE_TOKEN; + } + } + error.SetErrorStringWithFormat("unable to load '%s'", path); + return LLDB_INVALID_IMAGE_TOKEN; +} + +Error +PlatformAndroid::UnloadImage (lldb_private::Process* process, uint32_t image_token) +{ + const addr_t image_addr = process->GetImagePtrFromToken(image_token); + if (image_addr == LLDB_INVALID_ADDRESS) + return Error("Invalid image token"); + + StreamString expr; + expr.Printf("__dl_dlclose((void*)0x%" PRIx64 ")", image_addr); + const char *prefix = "extern \"C\" int __dl_dlclose(void* handle);\n"; + lldb::ValueObjectSP result_valobj_sp; + Error error = EvaluateLibdlExpression(process, expr.GetData(), prefix, result_valobj_sp); + if (error.Fail()) + return error; + + if (result_valobj_sp->GetError().Fail()) + return result_valobj_sp->GetError(); + + Scalar scalar; + if (result_valobj_sp->ResolveValue(scalar)) + { + if (scalar.UInt(1)) + return Error("expression failed: \"%s\"", expr.GetData()); + process->ResetImageToken(image_token); + } + return Error(); +} |

