15ec532a9SColin Riley //===-- RenderScriptRuntime.cpp ---------------------------------*- C++ -*-===// 25ec532a9SColin Riley // 35ec532a9SColin Riley // The LLVM Compiler Infrastructure 45ec532a9SColin Riley // 55ec532a9SColin Riley // This file is distributed under the University of Illinois Open Source 65ec532a9SColin Riley // License. See LICENSE.TXT for details. 75ec532a9SColin Riley // 85ec532a9SColin Riley //===----------------------------------------------------------------------===// 95ec532a9SColin Riley 105ec532a9SColin Riley #include "RenderScriptRuntime.h" 115ec532a9SColin Riley 125ec532a9SColin Riley #include "lldb/Core/ConstString.h" 135ec532a9SColin Riley #include "lldb/Core/Debugger.h" 145ec532a9SColin Riley #include "lldb/Core/Error.h" 155ec532a9SColin Riley #include "lldb/Core/Log.h" 165ec532a9SColin Riley #include "lldb/Core/PluginManager.h" 17a0f08674SEwan Crawford #include "lldb/Host/StringConvert.h" 185ec532a9SColin Riley #include "lldb/Symbol/Symbol.h" 194640cde1SColin Riley #include "lldb/Symbol/Type.h" 205ec532a9SColin Riley #include "lldb/Target/Process.h" 215ec532a9SColin Riley #include "lldb/Target/Target.h" 225ec532a9SColin Riley #include "lldb/Interpreter/Args.h" 235ec532a9SColin Riley #include "lldb/Interpreter/Options.h" 245ec532a9SColin Riley #include "lldb/Interpreter/CommandInterpreter.h" 255ec532a9SColin Riley #include "lldb/Interpreter/CommandReturnObject.h" 265ec532a9SColin Riley #include "lldb/Interpreter/CommandObjectMultiword.h" 274640cde1SColin Riley #include "lldb/Breakpoint/StoppointCallbackContext.h" 284640cde1SColin Riley #include "lldb/Target/RegisterContext.h" 2915f2bd95SEwan Crawford #include "lldb/Expression/UserExpression.h" 304640cde1SColin Riley #include "lldb/Symbol/VariableList.h" 315ec532a9SColin Riley 325ec532a9SColin Riley using namespace lldb; 335ec532a9SColin Riley using namespace lldb_private; 3498156583SEwan Crawford using namespace lldb_renderscript; 355ec532a9SColin Riley 3678f339d1SEwan Crawford namespace { 3778f339d1SEwan Crawford 3878f339d1SEwan Crawford // The empirical_type adds a basic level of validation to arbitrary data 3978f339d1SEwan Crawford // allowing us to track if data has been discovered and stored or not. 4078f339d1SEwan Crawford // An empirical_type will be marked as valid only if it has been explicitly assigned to. 4178f339d1SEwan Crawford template <typename type_t> 4278f339d1SEwan Crawford class empirical_type 4378f339d1SEwan Crawford { 4478f339d1SEwan Crawford public: 4578f339d1SEwan Crawford // Ctor. Contents is invalid when constructed. 4678f339d1SEwan Crawford empirical_type() 4778f339d1SEwan Crawford : valid(false) 4878f339d1SEwan Crawford {} 4978f339d1SEwan Crawford 5078f339d1SEwan Crawford // Return true and copy contents to out if valid, else return false. 5178f339d1SEwan Crawford bool get(type_t& out) const 5278f339d1SEwan Crawford { 5378f339d1SEwan Crawford if (valid) 5478f339d1SEwan Crawford out = data; 5578f339d1SEwan Crawford return valid; 5678f339d1SEwan Crawford } 5778f339d1SEwan Crawford 5878f339d1SEwan Crawford // Return a pointer to the contents or nullptr if it was not valid. 5978f339d1SEwan Crawford const type_t* get() const 6078f339d1SEwan Crawford { 6178f339d1SEwan Crawford return valid ? &data : nullptr; 6278f339d1SEwan Crawford } 6378f339d1SEwan Crawford 6478f339d1SEwan Crawford // Assign data explicitly. 6578f339d1SEwan Crawford void set(const type_t in) 6678f339d1SEwan Crawford { 6778f339d1SEwan Crawford data = in; 6878f339d1SEwan Crawford valid = true; 6978f339d1SEwan Crawford } 7078f339d1SEwan Crawford 7178f339d1SEwan Crawford // Mark contents as invalid. 7278f339d1SEwan Crawford void invalidate() 7378f339d1SEwan Crawford { 7478f339d1SEwan Crawford valid = false; 7578f339d1SEwan Crawford } 7678f339d1SEwan Crawford 7778f339d1SEwan Crawford // Returns true if this type contains valid data. 7878f339d1SEwan Crawford bool isValid() const 7978f339d1SEwan Crawford { 8078f339d1SEwan Crawford return valid; 8178f339d1SEwan Crawford } 8278f339d1SEwan Crawford 8378f339d1SEwan Crawford // Assignment operator. 8478f339d1SEwan Crawford empirical_type<type_t>& operator = (const type_t in) 8578f339d1SEwan Crawford { 8678f339d1SEwan Crawford set(in); 8778f339d1SEwan Crawford return *this; 8878f339d1SEwan Crawford } 8978f339d1SEwan Crawford 9078f339d1SEwan Crawford // Dereference operator returns contents. 9178f339d1SEwan Crawford // Warning: Will assert if not valid so use only when you know data is valid. 9278f339d1SEwan Crawford const type_t& operator * () const 9378f339d1SEwan Crawford { 9478f339d1SEwan Crawford assert(valid); 9578f339d1SEwan Crawford return data; 9678f339d1SEwan Crawford } 9778f339d1SEwan Crawford 9878f339d1SEwan Crawford protected: 9978f339d1SEwan Crawford bool valid; 10078f339d1SEwan Crawford type_t data; 10178f339d1SEwan Crawford }; 10278f339d1SEwan Crawford 10378f339d1SEwan Crawford } // namespace {} 10478f339d1SEwan Crawford 10578f339d1SEwan Crawford // The ScriptDetails class collects data associated with a single script instance. 10678f339d1SEwan Crawford struct RenderScriptRuntime::ScriptDetails 10778f339d1SEwan Crawford { 10878f339d1SEwan Crawford ~ScriptDetails() {}; 10978f339d1SEwan Crawford 11078f339d1SEwan Crawford enum ScriptType 11178f339d1SEwan Crawford { 11278f339d1SEwan Crawford eScript, 11378f339d1SEwan Crawford eScriptC 11478f339d1SEwan Crawford }; 11578f339d1SEwan Crawford 11678f339d1SEwan Crawford // The derived type of the script. 11778f339d1SEwan Crawford empirical_type<ScriptType> type; 11878f339d1SEwan Crawford // The name of the original source file. 11978f339d1SEwan Crawford empirical_type<std::string> resName; 12078f339d1SEwan Crawford // Path to script .so file on the device. 12178f339d1SEwan Crawford empirical_type<std::string> scriptDyLib; 12278f339d1SEwan Crawford // Directory where kernel objects are cached on device. 12378f339d1SEwan Crawford empirical_type<std::string> cacheDir; 12478f339d1SEwan Crawford // Pointer to the context which owns this script. 12578f339d1SEwan Crawford empirical_type<lldb::addr_t> context; 12678f339d1SEwan Crawford // Pointer to the script object itself. 12778f339d1SEwan Crawford empirical_type<lldb::addr_t> script; 12878f339d1SEwan Crawford }; 12978f339d1SEwan Crawford 13078f339d1SEwan Crawford // This AllocationDetails class collects data associated with a single 13178f339d1SEwan Crawford // allocation instance. 13278f339d1SEwan Crawford struct RenderScriptRuntime::AllocationDetails 13378f339d1SEwan Crawford { 13415f2bd95SEwan Crawford // Taken from rsDefines.h 13515f2bd95SEwan Crawford enum DataKind 13615f2bd95SEwan Crawford { 13715f2bd95SEwan Crawford RS_KIND_USER, 13815f2bd95SEwan Crawford RS_KIND_PIXEL_L = 7, 13915f2bd95SEwan Crawford RS_KIND_PIXEL_A, 14015f2bd95SEwan Crawford RS_KIND_PIXEL_LA, 14115f2bd95SEwan Crawford RS_KIND_PIXEL_RGB, 14215f2bd95SEwan Crawford RS_KIND_PIXEL_RGBA, 14315f2bd95SEwan Crawford RS_KIND_PIXEL_DEPTH, 14415f2bd95SEwan Crawford RS_KIND_PIXEL_YUV, 14515f2bd95SEwan Crawford RS_KIND_INVALID = 100 14615f2bd95SEwan Crawford }; 14778f339d1SEwan Crawford 14815f2bd95SEwan Crawford // Taken from rsDefines.h 14978f339d1SEwan Crawford enum DataType 15078f339d1SEwan Crawford { 15115f2bd95SEwan Crawford RS_TYPE_NONE = 0, 15215f2bd95SEwan Crawford RS_TYPE_FLOAT_16, 15315f2bd95SEwan Crawford RS_TYPE_FLOAT_32, 15415f2bd95SEwan Crawford RS_TYPE_FLOAT_64, 15515f2bd95SEwan Crawford RS_TYPE_SIGNED_8, 15615f2bd95SEwan Crawford RS_TYPE_SIGNED_16, 15715f2bd95SEwan Crawford RS_TYPE_SIGNED_32, 15815f2bd95SEwan Crawford RS_TYPE_SIGNED_64, 15915f2bd95SEwan Crawford RS_TYPE_UNSIGNED_8, 16015f2bd95SEwan Crawford RS_TYPE_UNSIGNED_16, 16115f2bd95SEwan Crawford RS_TYPE_UNSIGNED_32, 16215f2bd95SEwan Crawford RS_TYPE_UNSIGNED_64, 16315f2bd95SEwan Crawford RS_TYPE_BOOLEAN 16478f339d1SEwan Crawford }; 16578f339d1SEwan Crawford 16615f2bd95SEwan Crawford struct Dimension 16778f339d1SEwan Crawford { 16815f2bd95SEwan Crawford uint32_t dim_1; 16915f2bd95SEwan Crawford uint32_t dim_2; 17015f2bd95SEwan Crawford uint32_t dim_3; 17115f2bd95SEwan Crawford uint32_t cubeMap; 17215f2bd95SEwan Crawford 17315f2bd95SEwan Crawford Dimension() 17415f2bd95SEwan Crawford { 17515f2bd95SEwan Crawford dim_1 = 0; 17615f2bd95SEwan Crawford dim_2 = 0; 17715f2bd95SEwan Crawford dim_3 = 0; 17815f2bd95SEwan Crawford cubeMap = 0; 17915f2bd95SEwan Crawford } 18078f339d1SEwan Crawford }; 18178f339d1SEwan Crawford 182*55232f09SEwan Crawford // Header for reading and writing allocation contents 183*55232f09SEwan Crawford // to a binary file. 184*55232f09SEwan Crawford struct FileHeader 185*55232f09SEwan Crawford { 186*55232f09SEwan Crawford uint8_t ident[4]; // ASCII 'RSAD' identifying the file 187*55232f09SEwan Crawford uint16_t hdr_size; // Header size in bytes, for backwards compatability 188*55232f09SEwan Crawford uint16_t type; // DataType enum 189*55232f09SEwan Crawford uint32_t kind; // DataKind enum 190*55232f09SEwan Crawford uint32_t dims[3]; // Dimensions 191*55232f09SEwan Crawford uint32_t element_size; // Size of a single element, including padding 192*55232f09SEwan Crawford }; 193*55232f09SEwan Crawford 19415f2bd95SEwan Crawford // Monotonically increasing from 1 19515f2bd95SEwan Crawford static unsigned int ID; 19615f2bd95SEwan Crawford 19715f2bd95SEwan Crawford // Maps Allocation DataType enum and vector size to printable strings 19815f2bd95SEwan Crawford // using mapping from RenderScript numerical types summary documentation 19915f2bd95SEwan Crawford static const char* RsDataTypeToString[][4]; 20015f2bd95SEwan Crawford 20115f2bd95SEwan Crawford // Maps Allocation DataKind enum to printable strings 20215f2bd95SEwan Crawford static const char* RsDataKindToString[]; 20315f2bd95SEwan Crawford 204a0f08674SEwan Crawford // Maps allocation types to format sizes for printing. 205a0f08674SEwan Crawford static const unsigned int RSTypeToFormat[][3]; 206a0f08674SEwan Crawford 20715f2bd95SEwan Crawford // Give each allocation an ID as a way 20815f2bd95SEwan Crawford // for commands to reference it. 20915f2bd95SEwan Crawford const unsigned int id; 21015f2bd95SEwan Crawford 21115f2bd95SEwan Crawford empirical_type<DataType> type; // Type of each data pointer stored by the allocation 21215f2bd95SEwan Crawford empirical_type<DataKind> type_kind; // Defines pixel type if Allocation is created from an image 21315f2bd95SEwan Crawford empirical_type<uint32_t> type_vec_size; // Vector size of each data point, e.g '4' for uchar4 21415f2bd95SEwan Crawford empirical_type<Dimension> dimension; // Dimensions of the Allocation 21515f2bd95SEwan Crawford empirical_type<lldb::addr_t> address; // Pointer to address of the RS Allocation 21615f2bd95SEwan Crawford empirical_type<lldb::addr_t> data_ptr; // Pointer to the data held by the Allocation 21715f2bd95SEwan Crawford empirical_type<lldb::addr_t> type_ptr; // Pointer to the RS Type of the Allocation 21815f2bd95SEwan Crawford empirical_type<lldb::addr_t> element_ptr; // Pointer to the RS Element of the Type 21915f2bd95SEwan Crawford empirical_type<lldb::addr_t> context; // Pointer to the RS Context of the Allocation 220a0f08674SEwan Crawford empirical_type<uint32_t> size; // Size of the allocation 221a0f08674SEwan Crawford empirical_type<uint32_t> stride; // Stride between rows of the allocation 22215f2bd95SEwan Crawford 22315f2bd95SEwan Crawford // Give each allocation an id, so we can reference it in user commands. 22415f2bd95SEwan Crawford AllocationDetails(): id(ID++) 22515f2bd95SEwan Crawford { 22615f2bd95SEwan Crawford } 22715f2bd95SEwan Crawford 22815f2bd95SEwan Crawford }; 22915f2bd95SEwan Crawford 23015f2bd95SEwan Crawford unsigned int RenderScriptRuntime::AllocationDetails::ID = 1; 23115f2bd95SEwan Crawford 23215f2bd95SEwan Crawford const char* RenderScriptRuntime::AllocationDetails::RsDataKindToString[] = 23315f2bd95SEwan Crawford { 23415f2bd95SEwan Crawford "User", 23515f2bd95SEwan Crawford "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7 23615f2bd95SEwan Crawford "Undefined", "Undefined", "Undefined", 23715f2bd95SEwan Crawford "L Pixel", 23815f2bd95SEwan Crawford "A Pixel", 23915f2bd95SEwan Crawford "LA Pixel", 24015f2bd95SEwan Crawford "RGB Pixel", 24115f2bd95SEwan Crawford "RGBA Pixel", 24215f2bd95SEwan Crawford "Pixel Depth", 24315f2bd95SEwan Crawford "YUV Pixel" 24415f2bd95SEwan Crawford }; 24515f2bd95SEwan Crawford 24615f2bd95SEwan Crawford const char* RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] = 24715f2bd95SEwan Crawford { 24815f2bd95SEwan Crawford {"None", "None", "None", "None"}, 24915f2bd95SEwan Crawford {"half", "half2", "half3", "half4"}, 25015f2bd95SEwan Crawford {"float", "float2", "float3", "float4"}, 25115f2bd95SEwan Crawford {"double", "double2", "double3", "double4"}, 25215f2bd95SEwan Crawford {"char", "char2", "char3", "char4"}, 25315f2bd95SEwan Crawford {"short", "short2", "short3", "short4"}, 25415f2bd95SEwan Crawford {"int", "int2", "int3", "int4"}, 25515f2bd95SEwan Crawford {"long", "long2", "long3", "long4"}, 25615f2bd95SEwan Crawford {"uchar", "uchar2", "uchar3", "uchar4"}, 25715f2bd95SEwan Crawford {"ushort", "ushort2", "ushort3", "ushort4"}, 25815f2bd95SEwan Crawford {"uint", "uint2", "uint3", "uint4"}, 25915f2bd95SEwan Crawford {"ulong", "ulong2", "ulong3", "ulong4"}, 26015f2bd95SEwan Crawford {"bool", "bool2", "bool3", "bool4"} 26178f339d1SEwan Crawford }; 26278f339d1SEwan Crawford 263a0f08674SEwan Crawford // Used as an index into the RSTypeToFormat array elements 264a0f08674SEwan Crawford enum TypeToFormatIndex { 265a0f08674SEwan Crawford eFormatSingle = 0, 266a0f08674SEwan Crawford eFormatVector, 267a0f08674SEwan Crawford eElementSize 268a0f08674SEwan Crawford }; 269a0f08674SEwan Crawford 270a0f08674SEwan Crawford // { format enum of single element, format enum of element vector, size of element} 271a0f08674SEwan Crawford const unsigned int RenderScriptRuntime::AllocationDetails::RSTypeToFormat[][3] = 272a0f08674SEwan Crawford { 273a0f08674SEwan Crawford {eFormatHex, eFormatHex, 1}, // RS_TYPE_NONE 274a0f08674SEwan Crawford {eFormatFloat, eFormatVectorOfFloat16, 2}, // RS_TYPE_FLOAT_16 275a0f08674SEwan Crawford {eFormatFloat, eFormatVectorOfFloat32, sizeof(float)}, // RS_TYPE_FLOAT_32 276a0f08674SEwan Crawford {eFormatFloat, eFormatVectorOfFloat64, sizeof(double)}, // RS_TYPE_FLOAT_64 277a0f08674SEwan Crawford {eFormatDecimal, eFormatVectorOfSInt8, sizeof(int8_t)}, // RS_TYPE_SIGNED_8 278a0f08674SEwan Crawford {eFormatDecimal, eFormatVectorOfSInt16, sizeof(int16_t)}, // RS_TYPE_SIGNED_16 279a0f08674SEwan Crawford {eFormatDecimal, eFormatVectorOfSInt32, sizeof(int32_t)}, // RS_TYPE_SIGNED_32 280a0f08674SEwan Crawford {eFormatDecimal, eFormatVectorOfSInt64, sizeof(int64_t)}, // RS_TYPE_SIGNED_64 281a0f08674SEwan Crawford {eFormatDecimal, eFormatVectorOfUInt8, sizeof(uint8_t)}, // RS_TYPE_UNSIGNED_8 282a0f08674SEwan Crawford {eFormatDecimal, eFormatVectorOfUInt16, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_16 283a0f08674SEwan Crawford {eFormatDecimal, eFormatVectorOfUInt32, sizeof(uint32_t)}, // RS_TYPE_UNSIGNED_32 284a0f08674SEwan Crawford {eFormatDecimal, eFormatVectorOfUInt64, sizeof(uint64_t)}, // RS_TYPE_UNSIGNED_64 285a0f08674SEwan Crawford {eFormatBoolean, eFormatBoolean, sizeof(bool)} // RS_TYPE_BOOL 286a0f08674SEwan Crawford }; 287a0f08674SEwan Crawford 2885ec532a9SColin Riley //------------------------------------------------------------------ 2895ec532a9SColin Riley // Static Functions 2905ec532a9SColin Riley //------------------------------------------------------------------ 2915ec532a9SColin Riley LanguageRuntime * 2925ec532a9SColin Riley RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language) 2935ec532a9SColin Riley { 2945ec532a9SColin Riley 2955ec532a9SColin Riley if (language == eLanguageTypeExtRenderScript) 2965ec532a9SColin Riley return new RenderScriptRuntime(process); 2975ec532a9SColin Riley else 2985ec532a9SColin Riley return NULL; 2995ec532a9SColin Riley } 3005ec532a9SColin Riley 30198156583SEwan Crawford // Callback with a module to search for matching symbols. 30298156583SEwan Crawford // We first check that the module contains RS kernels. 30398156583SEwan Crawford // Then look for a symbol which matches our kernel name. 30498156583SEwan Crawford // The breakpoint address is finally set using the address of this symbol. 30598156583SEwan Crawford Searcher::CallbackReturn 30698156583SEwan Crawford RSBreakpointResolver::SearchCallback(SearchFilter &filter, 30798156583SEwan Crawford SymbolContext &context, 30898156583SEwan Crawford Address*, 30998156583SEwan Crawford bool) 31098156583SEwan Crawford { 31198156583SEwan Crawford ModuleSP module = context.module_sp; 31298156583SEwan Crawford 31398156583SEwan Crawford if (!module) 31498156583SEwan Crawford return Searcher::eCallbackReturnContinue; 31598156583SEwan Crawford 31698156583SEwan Crawford // Is this a module containing renderscript kernels? 31798156583SEwan Crawford if (nullptr == module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData)) 31898156583SEwan Crawford return Searcher::eCallbackReturnContinue; 31998156583SEwan Crawford 32098156583SEwan Crawford // Attempt to set a breakpoint on the kernel name symbol within the module library. 32198156583SEwan Crawford // If it's not found, it's likely debug info is unavailable - try to set a 32298156583SEwan Crawford // breakpoint on <name>.expand. 32398156583SEwan Crawford 32498156583SEwan Crawford const Symbol* kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode); 32598156583SEwan Crawford if (!kernel_sym) 32698156583SEwan Crawford { 32798156583SEwan Crawford std::string kernel_name_expanded(m_kernel_name.AsCString()); 32898156583SEwan Crawford kernel_name_expanded.append(".expand"); 32998156583SEwan Crawford kernel_sym = module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode); 33098156583SEwan Crawford } 33198156583SEwan Crawford 33298156583SEwan Crawford if (kernel_sym) 33398156583SEwan Crawford { 33498156583SEwan Crawford Address bp_addr = kernel_sym->GetAddress(); 33598156583SEwan Crawford if (filter.AddressPasses(bp_addr)) 33698156583SEwan Crawford m_breakpoint->AddLocation(bp_addr); 33798156583SEwan Crawford } 33898156583SEwan Crawford 33998156583SEwan Crawford return Searcher::eCallbackReturnContinue; 34098156583SEwan Crawford } 34198156583SEwan Crawford 3425ec532a9SColin Riley void 3435ec532a9SColin Riley RenderScriptRuntime::Initialize() 3445ec532a9SColin Riley { 3454640cde1SColin Riley PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject); 3465ec532a9SColin Riley } 3475ec532a9SColin Riley 3485ec532a9SColin Riley void 3495ec532a9SColin Riley RenderScriptRuntime::Terminate() 3505ec532a9SColin Riley { 3515ec532a9SColin Riley PluginManager::UnregisterPlugin(CreateInstance); 3525ec532a9SColin Riley } 3535ec532a9SColin Riley 3545ec532a9SColin Riley lldb_private::ConstString 3555ec532a9SColin Riley RenderScriptRuntime::GetPluginNameStatic() 3565ec532a9SColin Riley { 3575ec532a9SColin Riley static ConstString g_name("renderscript"); 3585ec532a9SColin Riley return g_name; 3595ec532a9SColin Riley } 3605ec532a9SColin Riley 361ef20b08fSColin Riley RenderScriptRuntime::ModuleKind 362ef20b08fSColin Riley RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp) 363ef20b08fSColin Riley { 364ef20b08fSColin Riley if (module_sp) 365ef20b08fSColin Riley { 366ef20b08fSColin Riley // Is this a module containing renderscript kernels? 367ef20b08fSColin Riley const Symbol *info_sym = module_sp->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData); 368ef20b08fSColin Riley if (info_sym) 369ef20b08fSColin Riley { 370ef20b08fSColin Riley return eModuleKindKernelObj; 371ef20b08fSColin Riley } 3724640cde1SColin Riley 3734640cde1SColin Riley // Is this the main RS runtime library 3744640cde1SColin Riley const ConstString rs_lib("libRS.so"); 3754640cde1SColin Riley if (module_sp->GetFileSpec().GetFilename() == rs_lib) 3764640cde1SColin Riley { 3774640cde1SColin Riley return eModuleKindLibRS; 3784640cde1SColin Riley } 3794640cde1SColin Riley 3804640cde1SColin Riley const ConstString rs_driverlib("libRSDriver.so"); 3814640cde1SColin Riley if (module_sp->GetFileSpec().GetFilename() == rs_driverlib) 3824640cde1SColin Riley { 3834640cde1SColin Riley return eModuleKindDriver; 3844640cde1SColin Riley } 3854640cde1SColin Riley 38615f2bd95SEwan Crawford const ConstString rs_cpureflib("libRSCpuRef.so"); 3874640cde1SColin Riley if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib) 3884640cde1SColin Riley { 3894640cde1SColin Riley return eModuleKindImpl; 3904640cde1SColin Riley } 3914640cde1SColin Riley 392ef20b08fSColin Riley } 393ef20b08fSColin Riley return eModuleKindIgnored; 394ef20b08fSColin Riley } 395ef20b08fSColin Riley 396ef20b08fSColin Riley bool 397ef20b08fSColin Riley RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp) 398ef20b08fSColin Riley { 399ef20b08fSColin Riley return GetModuleKind(module_sp) != eModuleKindIgnored; 400ef20b08fSColin Riley } 401ef20b08fSColin Riley 402ef20b08fSColin Riley 403ef20b08fSColin Riley void 404ef20b08fSColin Riley RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list ) 405ef20b08fSColin Riley { 406ef20b08fSColin Riley Mutex::Locker locker (module_list.GetMutex ()); 407ef20b08fSColin Riley 408ef20b08fSColin Riley size_t num_modules = module_list.GetSize(); 409ef20b08fSColin Riley for (size_t i = 0; i < num_modules; i++) 410ef20b08fSColin Riley { 411ef20b08fSColin Riley auto mod = module_list.GetModuleAtIndex (i); 412ef20b08fSColin Riley if (IsRenderScriptModule (mod)) 413ef20b08fSColin Riley { 414ef20b08fSColin Riley LoadModule(mod); 415ef20b08fSColin Riley } 416ef20b08fSColin Riley } 417ef20b08fSColin Riley } 418ef20b08fSColin Riley 419ef20b08fSColin Riley 4205ec532a9SColin Riley //------------------------------------------------------------------ 4215ec532a9SColin Riley // PluginInterface protocol 4225ec532a9SColin Riley //------------------------------------------------------------------ 4235ec532a9SColin Riley lldb_private::ConstString 4245ec532a9SColin Riley RenderScriptRuntime::GetPluginName() 4255ec532a9SColin Riley { 4265ec532a9SColin Riley return GetPluginNameStatic(); 4275ec532a9SColin Riley } 4285ec532a9SColin Riley 4295ec532a9SColin Riley uint32_t 4305ec532a9SColin Riley RenderScriptRuntime::GetPluginVersion() 4315ec532a9SColin Riley { 4325ec532a9SColin Riley return 1; 4335ec532a9SColin Riley } 4345ec532a9SColin Riley 4355ec532a9SColin Riley bool 4365ec532a9SColin Riley RenderScriptRuntime::IsVTableName(const char *name) 4375ec532a9SColin Riley { 4385ec532a9SColin Riley return false; 4395ec532a9SColin Riley } 4405ec532a9SColin Riley 4415ec532a9SColin Riley bool 4425ec532a9SColin Riley RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, 4430b6003f3SEnrico Granata TypeAndOrName &class_type_or_name, Address &address, 4440b6003f3SEnrico Granata Value::ValueType &value_type) 4455ec532a9SColin Riley { 4465ec532a9SColin Riley return false; 4475ec532a9SColin Riley } 4485ec532a9SColin Riley 449c74275bcSEnrico Granata TypeAndOrName 450c74275bcSEnrico Granata RenderScriptRuntime::FixUpDynamicType (const TypeAndOrName& type_and_or_name, 4517eed4877SEnrico Granata ValueObject& static_value) 452c74275bcSEnrico Granata { 453c74275bcSEnrico Granata return type_and_or_name; 454c74275bcSEnrico Granata } 455c74275bcSEnrico Granata 4565ec532a9SColin Riley bool 4575ec532a9SColin Riley RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value) 4585ec532a9SColin Riley { 4595ec532a9SColin Riley return false; 4605ec532a9SColin Riley } 4615ec532a9SColin Riley 4625ec532a9SColin Riley lldb::BreakpointResolverSP 4635ec532a9SColin Riley RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) 4645ec532a9SColin Riley { 4655ec532a9SColin Riley BreakpointResolverSP resolver_sp; 4665ec532a9SColin Riley return resolver_sp; 4675ec532a9SColin Riley } 4685ec532a9SColin Riley 4694640cde1SColin Riley 4704640cde1SColin Riley const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] = 4714640cde1SColin Riley { 4724640cde1SColin Riley //rsdScript 47382780287SAidan Dodds { 47482780287SAidan Dodds "rsdScriptInit", //name 47582780287SAidan Dodds "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", // symbol name 32 bit 47682780287SAidan Dodds "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj", // symbol name 64 bit 47782780287SAidan Dodds 0, // version 47882780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 47982780287SAidan Dodds &lldb_private::RenderScriptRuntime::CaptureScriptInit1 // handler 48082780287SAidan Dodds }, 48182780287SAidan Dodds { 48282780287SAidan Dodds "rsdScriptInvokeForEach", // name 48382780287SAidan Dodds "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvjPK12RsScriptCall", // symbol name 32bit 48482780287SAidan Dodds "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvmPK12RsScriptCall", // symbol name 64bit 48582780287SAidan Dodds 0, // version 48682780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 48782780287SAidan Dodds nullptr // handler 48882780287SAidan Dodds }, 48982780287SAidan Dodds { 49082780287SAidan Dodds "rsdScriptInvokeForEachMulti", // name 49182780287SAidan Dodds "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", // symbol name 32bit 49282780287SAidan Dodds "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall", // symbol name 64bit 49382780287SAidan Dodds 0, // version 49482780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 49582780287SAidan Dodds nullptr // handler 49682780287SAidan Dodds }, 49782780287SAidan Dodds { 49882780287SAidan Dodds "rsdScriptInvokeFunction", // name 49982780287SAidan Dodds "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvj", // symbol name 32bit 50082780287SAidan Dodds "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvm", // symbol name 64bit 50182780287SAidan Dodds 0, // version 50282780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 50382780287SAidan Dodds nullptr // handler 50482780287SAidan Dodds }, 50582780287SAidan Dodds { 50682780287SAidan Dodds "rsdScriptSetGlobalVar", // name 50782780287SAidan Dodds "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", // symbol name 32bit 50882780287SAidan Dodds "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm", // symbol name 64bit 50982780287SAidan Dodds 0, // version 51082780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 51182780287SAidan Dodds &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1 // handler 51282780287SAidan Dodds }, 5134640cde1SColin Riley 5144640cde1SColin Riley //rsdAllocation 51582780287SAidan Dodds { 51682780287SAidan Dodds "rsdAllocationInit", // name 51782780287SAidan Dodds "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 32bit 51882780287SAidan Dodds "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 64bit 51982780287SAidan Dodds 0, // version 52082780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 52182780287SAidan Dodds &lldb_private::RenderScriptRuntime::CaptureAllocationInit1 // handler 52282780287SAidan Dodds }, 52382780287SAidan Dodds { 52482780287SAidan Dodds "rsdAllocationRead2D", //name 52582780287SAidan Dodds "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", // symbol name 32bit 52682780287SAidan Dodds "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm", // symbol name 64bit 52782780287SAidan Dodds 0, // version 52882780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 52982780287SAidan Dodds nullptr // handler 53082780287SAidan Dodds }, 5314640cde1SColin Riley }; 5324640cde1SColin Riley const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]); 5334640cde1SColin Riley 5344640cde1SColin Riley 5354640cde1SColin Riley bool 5364640cde1SColin Riley RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id) 5374640cde1SColin Riley { 5384640cde1SColin Riley RuntimeHook* hook_info = (RuntimeHook*)baton; 5394640cde1SColin Riley ExecutionContext context(ctx->exe_ctx_ref); 5404640cde1SColin Riley 5414640cde1SColin Riley RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 5424640cde1SColin Riley 5434640cde1SColin Riley lang_rt->HookCallback(hook_info, context); 5444640cde1SColin Riley 5454640cde1SColin Riley return false; 5464640cde1SColin Riley } 5474640cde1SColin Riley 5484640cde1SColin Riley 5494640cde1SColin Riley void 5504640cde1SColin Riley RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context) 5514640cde1SColin Riley { 5524640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 5534640cde1SColin Riley 5544640cde1SColin Riley if (log) 5554640cde1SColin Riley log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name); 5564640cde1SColin Riley 5574640cde1SColin Riley if (hook_info->defn->grabber) 5584640cde1SColin Riley { 5594640cde1SColin Riley (this->*(hook_info->defn->grabber))(hook_info, context); 5604640cde1SColin Riley } 5614640cde1SColin Riley } 5624640cde1SColin Riley 5634640cde1SColin Riley 5644640cde1SColin Riley bool 56582780287SAidan Dodds RenderScriptRuntime::GetArgSimple(ExecutionContext &context, uint32_t arg, uint64_t *data) 5664640cde1SColin Riley { 5674640cde1SColin Riley if (!data) 5684640cde1SColin Riley return false; 5694640cde1SColin Riley 57082780287SAidan Dodds Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 5714640cde1SColin Riley Error error; 5724640cde1SColin Riley RegisterContext* reg_ctx = context.GetRegisterContext(); 5734640cde1SColin Riley Process* process = context.GetProcessPtr(); 57482780287SAidan Dodds bool success = false; // return value 5754640cde1SColin Riley 57682780287SAidan Dodds if (!context.GetTargetPtr()) 57782780287SAidan Dodds { 57882780287SAidan Dodds if (log) 57982780287SAidan Dodds log->Printf("RenderScriptRuntime::GetArgSimple - Invalid target"); 58082780287SAidan Dodds 58182780287SAidan Dodds return false; 58282780287SAidan Dodds } 58382780287SAidan Dodds 58482780287SAidan Dodds switch (context.GetTargetPtr()->GetArchitecture().GetMachine()) 58582780287SAidan Dodds { 58682780287SAidan Dodds case llvm::Triple::ArchType::x86: 5874640cde1SColin Riley { 5884640cde1SColin Riley uint64_t sp = reg_ctx->GetSP(); 5894640cde1SColin Riley uint32_t offset = (1 + arg) * sizeof(uint32_t); 59082780287SAidan Dodds uint32_t result = 0; 59182780287SAidan Dodds process->ReadMemory(sp + offset, &result, sizeof(uint32_t), error); 5924640cde1SColin Riley if (error.Fail()) 5934640cde1SColin Riley { 5944640cde1SColin Riley if (log) 59582780287SAidan Dodds log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading X86 stack: %s.", error.AsCString()); 5964640cde1SColin Riley } 59782780287SAidan Dodds else 5984640cde1SColin Riley { 59982780287SAidan Dodds *data = result; 60082780287SAidan Dodds success = true; 60182780287SAidan Dodds } 60282780287SAidan Dodds 60382780287SAidan Dodds break; 60482780287SAidan Dodds } 60582780287SAidan Dodds case llvm::Triple::ArchType::arm: 60682780287SAidan Dodds { 60782780287SAidan Dodds // arm 32 bit 6084640cde1SColin Riley if (arg < 4) 6094640cde1SColin Riley { 6104640cde1SColin Riley const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg); 6114640cde1SColin Riley RegisterValue rVal; 6124640cde1SColin Riley reg_ctx->ReadRegister(rArg, rVal); 6134640cde1SColin Riley (*data) = rVal.GetAsUInt32(); 61482780287SAidan Dodds success = true; 6154640cde1SColin Riley } 6164640cde1SColin Riley else 6174640cde1SColin Riley { 6184640cde1SColin Riley uint64_t sp = reg_ctx->GetSP(); 6194640cde1SColin Riley { 6204640cde1SColin Riley uint32_t offset = (arg-4) * sizeof(uint32_t); 6214640cde1SColin Riley process->ReadMemory(sp + offset, &data, sizeof(uint32_t), error); 6224640cde1SColin Riley if (error.Fail()) 6234640cde1SColin Riley { 6244640cde1SColin Riley if (log) 62582780287SAidan Dodds log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading ARM stack: %s.", error.AsCString()); 62682780287SAidan Dodds } 62782780287SAidan Dodds else 62882780287SAidan Dodds { 62982780287SAidan Dodds success = true; 6304640cde1SColin Riley } 6314640cde1SColin Riley } 6324640cde1SColin Riley } 63382780287SAidan Dodds 63482780287SAidan Dodds break; 6354640cde1SColin Riley } 63682780287SAidan Dodds case llvm::Triple::ArchType::aarch64: 63782780287SAidan Dodds { 63882780287SAidan Dodds // arm 64 bit 63982780287SAidan Dodds // first 8 arguments are in the registers 64082780287SAidan Dodds if (arg < 8) 64182780287SAidan Dodds { 64282780287SAidan Dodds const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg); 64382780287SAidan Dodds RegisterValue rVal; 64482780287SAidan Dodds success = reg_ctx->ReadRegister(rArg, rVal); 64582780287SAidan Dodds if (success) 64682780287SAidan Dodds { 64782780287SAidan Dodds *data = rVal.GetAsUInt64(); 64882780287SAidan Dodds } 64982780287SAidan Dodds else 65082780287SAidan Dodds { 65182780287SAidan Dodds if (log) 65282780287SAidan Dodds log->Printf("RenderScriptRuntime::GetArgSimple() - AARCH64 - Error while reading the argument #%d", arg); 65382780287SAidan Dodds } 65482780287SAidan Dodds } 65582780287SAidan Dodds else 65682780287SAidan Dodds { 65782780287SAidan Dodds // @TODO: need to find the argument in the stack 65882780287SAidan Dodds if (log) 65982780287SAidan Dodds log->Printf("RenderScriptRuntime::GetArgSimple - AARCH64 - FOR #ARG >= 8 NOT IMPLEMENTED YET. Argument number: %d", arg); 66082780287SAidan Dodds } 66182780287SAidan Dodds break; 66282780287SAidan Dodds } 66382780287SAidan Dodds default: 66482780287SAidan Dodds { 66582780287SAidan Dodds // invalid architecture 66682780287SAidan Dodds if (log) 66782780287SAidan Dodds log->Printf("RenderScriptRuntime::GetArgSimple - Architecture not supported"); 66882780287SAidan Dodds 66982780287SAidan Dodds } 67082780287SAidan Dodds } 67182780287SAidan Dodds 67282780287SAidan Dodds 67382780287SAidan Dodds return success; 6744640cde1SColin Riley } 6754640cde1SColin Riley 6764640cde1SColin Riley void 6774640cde1SColin Riley RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context) 6784640cde1SColin Riley { 6794640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 6804640cde1SColin Riley 6814640cde1SColin Riley //Context, Script, int, data, length 6824640cde1SColin Riley 68382780287SAidan Dodds uint64_t rs_context_u64 = 0U; 68482780287SAidan Dodds uint64_t rs_script_u64 = 0U; 68582780287SAidan Dodds uint64_t rs_id_u64 = 0U; 68682780287SAidan Dodds uint64_t rs_data_u64 = 0U; 68782780287SAidan Dodds uint64_t rs_length_u64 = 0U; 6884640cde1SColin Riley 68982780287SAidan Dodds bool success = 69082780287SAidan Dodds GetArgSimple(context, 0, &rs_context_u64) && 69182780287SAidan Dodds GetArgSimple(context, 1, &rs_script_u64) && 69282780287SAidan Dodds GetArgSimple(context, 2, &rs_id_u64) && 69382780287SAidan Dodds GetArgSimple(context, 3, &rs_data_u64) && 69482780287SAidan Dodds GetArgSimple(context, 4, &rs_length_u64); 6954640cde1SColin Riley 69682780287SAidan Dodds if (!success) 69782780287SAidan Dodds { 69882780287SAidan Dodds if (log) 69982780287SAidan Dodds log->Printf("RenderScriptRuntime::CaptureSetGlobalVar1 - Error while reading the function parameters"); 70082780287SAidan Dodds return; 70182780287SAidan Dodds } 7024640cde1SColin Riley 7034640cde1SColin Riley if (log) 7044640cde1SColin Riley { 7054640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.", 70682780287SAidan Dodds rs_context_u64, rs_script_u64, rs_id_u64, rs_data_u64, rs_length_u64); 7074640cde1SColin Riley 70882780287SAidan Dodds addr_t script_addr = (addr_t)rs_script_u64; 7094640cde1SColin Riley if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end()) 7104640cde1SColin Riley { 7114640cde1SColin Riley auto rsm = m_scriptMappings[script_addr]; 71282780287SAidan Dodds if (rs_id_u64 < rsm->m_globals.size()) 7134640cde1SColin Riley { 71482780287SAidan Dodds auto rsg = rsm->m_globals[rs_id_u64]; 7154640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(), 7164640cde1SColin Riley rsm->m_module->GetFileSpec().GetFilename().AsCString()); 7174640cde1SColin Riley } 7184640cde1SColin Riley } 7194640cde1SColin Riley } 7204640cde1SColin Riley } 7214640cde1SColin Riley 7224640cde1SColin Riley void 7234640cde1SColin Riley RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context) 7244640cde1SColin Riley { 7254640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 7264640cde1SColin Riley 7274640cde1SColin Riley //Context, Alloc, bool 7284640cde1SColin Riley 72982780287SAidan Dodds uint64_t rs_context_u64 = 0U; 73082780287SAidan Dodds uint64_t rs_alloc_u64 = 0U; 73182780287SAidan Dodds uint64_t rs_forceZero_u64 = 0U; 7324640cde1SColin Riley 73382780287SAidan Dodds bool success = 73482780287SAidan Dodds GetArgSimple(context, 0, &rs_context_u64) && 73582780287SAidan Dodds GetArgSimple(context, 1, &rs_alloc_u64) && 73682780287SAidan Dodds GetArgSimple(context, 2, &rs_forceZero_u64); 73782780287SAidan Dodds if (!success) // error case 73882780287SAidan Dodds { 73982780287SAidan Dodds if (log) 74082780287SAidan Dodds log->Printf("RenderScriptRuntime::CaptureAllocationInit1 - Error while reading the function parameters"); 74182780287SAidan Dodds return; // abort 74282780287SAidan Dodds } 7434640cde1SColin Riley 7444640cde1SColin Riley if (log) 7454640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .", 74682780287SAidan Dodds rs_context_u64, rs_alloc_u64, rs_forceZero_u64); 74778f339d1SEwan Crawford 74878f339d1SEwan Crawford AllocationDetails* alloc = LookUpAllocation(rs_alloc_u64, true); 74978f339d1SEwan Crawford if (alloc) 75078f339d1SEwan Crawford alloc->context = rs_context_u64; 7514640cde1SColin Riley } 7524640cde1SColin Riley 7534640cde1SColin Riley void 7544640cde1SColin Riley RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context) 7554640cde1SColin Riley { 7564640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 7574640cde1SColin Riley 7584640cde1SColin Riley //Context, Script, resname Str, cachedir Str 7594640cde1SColin Riley Error error; 7604640cde1SColin Riley Process* process = context.GetProcessPtr(); 7614640cde1SColin Riley 76282780287SAidan Dodds uint64_t rs_context_u64 = 0U; 76382780287SAidan Dodds uint64_t rs_script_u64 = 0U; 76482780287SAidan Dodds uint64_t rs_resnameptr_u64 = 0U; 76582780287SAidan Dodds uint64_t rs_cachedirptr_u64 = 0U; 7664640cde1SColin Riley 7674640cde1SColin Riley std::string resname; 7684640cde1SColin Riley std::string cachedir; 7694640cde1SColin Riley 77082780287SAidan Dodds // read the function parameters 77182780287SAidan Dodds bool success = 77282780287SAidan Dodds GetArgSimple(context, 0, &rs_context_u64) && 77382780287SAidan Dodds GetArgSimple(context, 1, &rs_script_u64) && 77482780287SAidan Dodds GetArgSimple(context, 2, &rs_resnameptr_u64) && 77582780287SAidan Dodds GetArgSimple(context, 3, &rs_cachedirptr_u64); 7764640cde1SColin Riley 77782780287SAidan Dodds if (!success) 77882780287SAidan Dodds { 77982780287SAidan Dodds if (log) 78082780287SAidan Dodds log->Printf("RenderScriptRuntime::CaptureScriptInit1 - Error while reading the function parameters"); 78182780287SAidan Dodds return; 78282780287SAidan Dodds } 78382780287SAidan Dodds 78482780287SAidan Dodds process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u64, resname, error); 7854640cde1SColin Riley if (error.Fail()) 7864640cde1SColin Riley { 7874640cde1SColin Riley if (log) 7884640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString()); 7894640cde1SColin Riley 7904640cde1SColin Riley } 7914640cde1SColin Riley 79282780287SAidan Dodds process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u64, cachedir, error); 7934640cde1SColin Riley if (error.Fail()) 7944640cde1SColin Riley { 7954640cde1SColin Riley if (log) 7964640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString()); 7974640cde1SColin Riley } 7984640cde1SColin Riley 7994640cde1SColin Riley if (log) 8004640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .", 80182780287SAidan Dodds rs_context_u64, rs_script_u64, resname.c_str(), cachedir.c_str()); 8024640cde1SColin Riley 8034640cde1SColin Riley if (resname.size() > 0) 8044640cde1SColin Riley { 8054640cde1SColin Riley StreamString strm; 8064640cde1SColin Riley strm.Printf("librs.%s.so", resname.c_str()); 8074640cde1SColin Riley 80878f339d1SEwan Crawford ScriptDetails* script = LookUpScript(rs_script_u64, true); 80978f339d1SEwan Crawford if (script) 81078f339d1SEwan Crawford { 81178f339d1SEwan Crawford script->type = ScriptDetails::eScriptC; 81278f339d1SEwan Crawford script->cacheDir = cachedir; 81378f339d1SEwan Crawford script->resName = resname; 81478f339d1SEwan Crawford script->scriptDyLib = strm.GetData(); 81578f339d1SEwan Crawford script->context = addr_t(rs_context_u64); 81678f339d1SEwan Crawford } 8174640cde1SColin Riley 8184640cde1SColin Riley if (log) 8194640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".", 82082780287SAidan Dodds strm.GetData(), rs_context_u64, rs_script_u64); 8214640cde1SColin Riley } 8224640cde1SColin Riley else if (log) 8234640cde1SColin Riley { 8244640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged"); 8254640cde1SColin Riley } 8264640cde1SColin Riley 8274640cde1SColin Riley } 8284640cde1SColin Riley 8294640cde1SColin Riley void 8304640cde1SColin Riley RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind) 8314640cde1SColin Riley { 8324640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 8334640cde1SColin Riley 8344640cde1SColin Riley if (!module) 8354640cde1SColin Riley { 8364640cde1SColin Riley return; 8374640cde1SColin Riley } 8384640cde1SColin Riley 83982780287SAidan Dodds Target &target = GetProcess()->GetTarget(); 84082780287SAidan Dodds llvm::Triple::ArchType targetArchType = target.GetArchitecture().GetMachine(); 84182780287SAidan Dodds 84282780287SAidan Dodds if (targetArchType != llvm::Triple::ArchType::x86 84382780287SAidan Dodds && targetArchType != llvm::Triple::ArchType::arm 84482780287SAidan Dodds && targetArchType != llvm::Triple::ArchType::aarch64) 8454640cde1SColin Riley { 8464640cde1SColin Riley if (log) 8474640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM supported currently."); 8484640cde1SColin Riley 8494640cde1SColin Riley return; 8504640cde1SColin Riley } 8514640cde1SColin Riley 85282780287SAidan Dodds uint32_t archByteSize = target.GetArchitecture().GetAddressByteSize(); 8534640cde1SColin Riley 8544640cde1SColin Riley for (size_t idx = 0; idx < s_runtimeHookCount; idx++) 8554640cde1SColin Riley { 8564640cde1SColin Riley const HookDefn* hook_defn = &s_runtimeHookDefns[idx]; 8574640cde1SColin Riley if (hook_defn->kind != kind) { 8584640cde1SColin Riley continue; 8594640cde1SColin Riley } 8604640cde1SColin Riley 86182780287SAidan Dodds const char* symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64; 86282780287SAidan Dodds 86382780287SAidan Dodds const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(symbol_name), eSymbolTypeCode); 86482780287SAidan Dodds if (!sym){ 86582780287SAidan Dodds if (log){ 86682780287SAidan Dodds log->Printf("RenderScriptRuntime::LoadRuntimeHooks - ERROR: Symbol '%s' related to the function %s not found", symbol_name, hook_defn->name); 86782780287SAidan Dodds } 86882780287SAidan Dodds continue; 86982780287SAidan Dodds } 8704640cde1SColin Riley 871358cf1eaSGreg Clayton addr_t addr = sym->GetLoadAddress(&target); 8724640cde1SColin Riley if (addr == LLDB_INVALID_ADDRESS) 8734640cde1SColin Riley { 8744640cde1SColin Riley if (log) 8754640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.", 87682780287SAidan Dodds hook_defn->name, symbol_name); 8774640cde1SColin Riley continue; 8784640cde1SColin Riley } 87982780287SAidan Dodds else 88082780287SAidan Dodds { 88182780287SAidan Dodds if (log) 88282780287SAidan Dodds log->Printf("RenderScriptRuntime::LoadRuntimeHooks - Function %s, address resolved at 0x%" PRIx64, hook_defn->name, addr); 88382780287SAidan Dodds } 8844640cde1SColin Riley 8854640cde1SColin Riley RuntimeHookSP hook(new RuntimeHook()); 8864640cde1SColin Riley hook->address = addr; 8874640cde1SColin Riley hook->defn = hook_defn; 8884640cde1SColin Riley hook->bp_sp = target.CreateBreakpoint(addr, true, false); 8894640cde1SColin Riley hook->bp_sp->SetCallback(HookCallback, hook.get(), true); 8904640cde1SColin Riley m_runtimeHooks[addr] = hook; 8914640cde1SColin Riley if (log) 8924640cde1SColin Riley { 8934640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".", 8944640cde1SColin Riley hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr); 8954640cde1SColin Riley } 8964640cde1SColin Riley } 8974640cde1SColin Riley } 8984640cde1SColin Riley 8994640cde1SColin Riley void 9004640cde1SColin Riley RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) 9014640cde1SColin Riley { 9024640cde1SColin Riley if (!rsmodule_sp) 9034640cde1SColin Riley return; 9044640cde1SColin Riley 9054640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 9064640cde1SColin Riley 9074640cde1SColin Riley const ModuleSP module = rsmodule_sp->m_module; 9084640cde1SColin Riley const FileSpec& file = module->GetPlatformFileSpec(); 9094640cde1SColin Riley 91078f339d1SEwan Crawford // Iterate over all of the scripts that we currently know of. 91178f339d1SEwan Crawford // Note: We cant push or pop to m_scripts here or it may invalidate rs_script. 9124640cde1SColin Riley for (const auto & rs_script : m_scripts) 9134640cde1SColin Riley { 91478f339d1SEwan Crawford // Extract the expected .so file path for this script. 91578f339d1SEwan Crawford std::string dylib; 91678f339d1SEwan Crawford if (!rs_script->scriptDyLib.get(dylib)) 91778f339d1SEwan Crawford continue; 91878f339d1SEwan Crawford 91978f339d1SEwan Crawford // Only proceed if the module that has loaded corresponds to this script. 92078f339d1SEwan Crawford if (file.GetFilename() != ConstString(dylib.c_str())) 92178f339d1SEwan Crawford continue; 92278f339d1SEwan Crawford 92378f339d1SEwan Crawford // Obtain the script address which we use as a key. 92478f339d1SEwan Crawford lldb::addr_t script; 92578f339d1SEwan Crawford if (!rs_script->script.get(script)) 92678f339d1SEwan Crawford continue; 92778f339d1SEwan Crawford 92878f339d1SEwan Crawford // If we have a script mapping for the current script. 92978f339d1SEwan Crawford if (m_scriptMappings.find(script) != m_scriptMappings.end()) 9304640cde1SColin Riley { 93178f339d1SEwan Crawford // if the module we have stored is different to the one we just received. 93278f339d1SEwan Crawford if (m_scriptMappings[script] != rsmodule_sp) 9334640cde1SColin Riley { 9344640cde1SColin Riley if (log) 9354640cde1SColin Riley log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.", 93678f339d1SEwan Crawford (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); 9374640cde1SColin Riley } 9384640cde1SColin Riley } 93978f339d1SEwan Crawford // We don't have a script mapping for the current script. 9404640cde1SColin Riley else 9414640cde1SColin Riley { 94278f339d1SEwan Crawford // Obtain the script resource name. 94378f339d1SEwan Crawford std::string resName; 94478f339d1SEwan Crawford if (rs_script->resName.get(resName)) 94578f339d1SEwan Crawford // Set the modules resource name. 94678f339d1SEwan Crawford rsmodule_sp->m_resname = resName; 94778f339d1SEwan Crawford // Add Script/Module pair to map. 94878f339d1SEwan Crawford m_scriptMappings[script] = rsmodule_sp; 9494640cde1SColin Riley if (log) 9504640cde1SColin Riley log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.", 95178f339d1SEwan Crawford (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); 9524640cde1SColin Riley } 9534640cde1SColin Riley } 9544640cde1SColin Riley } 9554640cde1SColin Riley 95615f2bd95SEwan Crawford // Uses the Target API to evaluate the expression passed as a parameter to the function 95715f2bd95SEwan Crawford // The result of that expression is returned an unsigned 64 bit int, via the result* paramter. 95815f2bd95SEwan Crawford // Function returns true on success, and false on failure 95915f2bd95SEwan Crawford bool 96015f2bd95SEwan Crawford RenderScriptRuntime::EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result) 96115f2bd95SEwan Crawford { 96215f2bd95SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 96315f2bd95SEwan Crawford if (log) 96415f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::EvalRSExpression(%s)", expression); 96515f2bd95SEwan Crawford 96615f2bd95SEwan Crawford ValueObjectSP expr_result; 96715f2bd95SEwan Crawford // Perform the actual expression evaluation 96815f2bd95SEwan Crawford GetProcess()->GetTarget().EvaluateExpression(expression, frame_ptr, expr_result); 96915f2bd95SEwan Crawford 97015f2bd95SEwan Crawford if (!expr_result) 97115f2bd95SEwan Crawford { 97215f2bd95SEwan Crawford if (log) 97315f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::EvalRSExpression - Error: Couldn't evaluate expression"); 97415f2bd95SEwan Crawford return false; 97515f2bd95SEwan Crawford } 97615f2bd95SEwan Crawford 97715f2bd95SEwan Crawford // The result of the expression is invalid 97815f2bd95SEwan Crawford if (!expr_result->GetError().Success()) 97915f2bd95SEwan Crawford { 98015f2bd95SEwan Crawford Error err = expr_result->GetError(); 98115f2bd95SEwan Crawford if (err.GetError() == UserExpression::kNoResult) // Expression returned void, so this is actually a success 98215f2bd95SEwan Crawford { 98315f2bd95SEwan Crawford if (log) 98415f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::EvalRSExpression - Expression returned void"); 98515f2bd95SEwan Crawford 98615f2bd95SEwan Crawford result = nullptr; 98715f2bd95SEwan Crawford return true; 98815f2bd95SEwan Crawford } 98915f2bd95SEwan Crawford 99015f2bd95SEwan Crawford if (log) 99115f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::EvalRSExpression - Error evaluating expression result: %s", err.AsCString()); 99215f2bd95SEwan Crawford return false; 99315f2bd95SEwan Crawford } 99415f2bd95SEwan Crawford 99515f2bd95SEwan Crawford bool success = false; 99615f2bd95SEwan Crawford *result = expr_result->GetValueAsUnsigned(0, &success); // We only read the result as an unsigned int. 99715f2bd95SEwan Crawford 99815f2bd95SEwan Crawford if (!success) 99915f2bd95SEwan Crawford { 100015f2bd95SEwan Crawford if (log) 100115f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::EvalRSExpression - Error: Couldn't convert expression result to unsigned int"); 100215f2bd95SEwan Crawford return false; 100315f2bd95SEwan Crawford } 100415f2bd95SEwan Crawford 100515f2bd95SEwan Crawford return true; 100615f2bd95SEwan Crawford } 100715f2bd95SEwan Crawford 100815f2bd95SEwan Crawford // Used to index expression format strings 100915f2bd95SEwan Crawford enum ExpressionStrings 101015f2bd95SEwan Crawford { 101115f2bd95SEwan Crawford eExprGetOffsetPtr = 0, 101215f2bd95SEwan Crawford eExprAllocGetType, 101315f2bd95SEwan Crawford eExprTypeDimX, 101415f2bd95SEwan Crawford eExprTypeDimY, 101515f2bd95SEwan Crawford eExprTypeDimZ, 101615f2bd95SEwan Crawford eExprTypeElemPtr, 101715f2bd95SEwan Crawford eExprElementType, 101815f2bd95SEwan Crawford eExprElementKind, 101915f2bd95SEwan Crawford eExprElementVec 102015f2bd95SEwan Crawford }; 102115f2bd95SEwan Crawford 102215f2bd95SEwan Crawford // Format strings containing the expressions we may need to evaluate. 102315f2bd95SEwan Crawford const char runtimeExpressions[][256] = 102415f2bd95SEwan Crawford { 102515f2bd95SEwan Crawford // Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap) 102615f2bd95SEwan Crawford "(int*)_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace(0x%lx, %u, %u, %u, 0, 0)", 102715f2bd95SEwan Crawford 102815f2bd95SEwan Crawford // Type* rsaAllocationGetType(Context*, Allocation*) 102915f2bd95SEwan Crawford "(void*)rsaAllocationGetType(0x%lx, 0x%lx)", 103015f2bd95SEwan Crawford 103115f2bd95SEwan Crawford // rsaTypeGetNativeData(Context*, Type*, void* typeData, size) 103215f2bd95SEwan Crawford // Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ; 103315f2bd95SEwan Crawford // mHal.state.lodCount; mHal.state.faces; mElement; into typeData 103415f2bd95SEwan Crawford // Need to specify 32 or 64 bit for uint_t since this differs between devices 103515f2bd95SEwan Crawford "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[0]", // X dim 103615f2bd95SEwan Crawford "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[1]", // Y dim 103715f2bd95SEwan Crawford "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[2]", // Z dim 103815f2bd95SEwan Crawford "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[5]", // Element ptr 103915f2bd95SEwan Crawford 104015f2bd95SEwan Crawford // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size) 104115f2bd95SEwan Crawford // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData 104215f2bd95SEwan Crawford "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[0]", // Type 104315f2bd95SEwan Crawford "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[1]", // Kind 104415f2bd95SEwan Crawford "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[3]" // Vector Size 104515f2bd95SEwan Crawford }; 104615f2bd95SEwan Crawford 104715f2bd95SEwan Crawford // JITs the RS runtime for the internal data pointer of an allocation. 104815f2bd95SEwan Crawford // Is passed x,y,z coordinates for the pointer to a specific element. 104915f2bd95SEwan Crawford // Then sets the data_ptr member in Allocation with the result. 105015f2bd95SEwan Crawford // Returns true on success, false otherwise 105115f2bd95SEwan Crawford bool 105215f2bd95SEwan Crawford RenderScriptRuntime::JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr, 105315f2bd95SEwan Crawford unsigned int x, unsigned int y, unsigned int z) 105415f2bd95SEwan Crawford { 105515f2bd95SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 105615f2bd95SEwan Crawford 105715f2bd95SEwan Crawford if (!allocation->address.isValid()) 105815f2bd95SEwan Crawford { 105915f2bd95SEwan Crawford if (log) 106015f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITDataPointer - Failed to find allocation details"); 106115f2bd95SEwan Crawford return false; 106215f2bd95SEwan Crawford } 106315f2bd95SEwan Crawford 106415f2bd95SEwan Crawford const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr]; 106515f2bd95SEwan Crawford const int max_expr_size = 512; // Max expression size 106615f2bd95SEwan Crawford char buffer[max_expr_size]; 106715f2bd95SEwan Crawford 106815f2bd95SEwan Crawford int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->address.get(), x, y, z); 106915f2bd95SEwan Crawford if (chars_written < 0) 107015f2bd95SEwan Crawford { 107115f2bd95SEwan Crawford if (log) 107215f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()"); 107315f2bd95SEwan Crawford return false; 107415f2bd95SEwan Crawford } 107515f2bd95SEwan Crawford else if (chars_written >= max_expr_size) 107615f2bd95SEwan Crawford { 107715f2bd95SEwan Crawford if (log) 107815f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITDataPointer - Expression too long"); 107915f2bd95SEwan Crawford return false; 108015f2bd95SEwan Crawford } 108115f2bd95SEwan Crawford 108215f2bd95SEwan Crawford uint64_t result = 0; 108315f2bd95SEwan Crawford if (!EvalRSExpression(buffer, frame_ptr, &result)) 108415f2bd95SEwan Crawford return false; 108515f2bd95SEwan Crawford 108615f2bd95SEwan Crawford addr_t mem_ptr = static_cast<lldb::addr_t>(result); 108715f2bd95SEwan Crawford allocation->data_ptr = mem_ptr; 108815f2bd95SEwan Crawford 108915f2bd95SEwan Crawford return true; 109015f2bd95SEwan Crawford } 109115f2bd95SEwan Crawford 109215f2bd95SEwan Crawford // JITs the RS runtime for the internal pointer to the RS Type of an allocation 109315f2bd95SEwan Crawford // Then sets the type_ptr member in Allocation with the result. 109415f2bd95SEwan Crawford // Returns true on success, false otherwise 109515f2bd95SEwan Crawford bool 109615f2bd95SEwan Crawford RenderScriptRuntime::JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr) 109715f2bd95SEwan Crawford { 109815f2bd95SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 109915f2bd95SEwan Crawford 110015f2bd95SEwan Crawford if (!allocation->address.isValid() || !allocation->context.isValid()) 110115f2bd95SEwan Crawford { 110215f2bd95SEwan Crawford if (log) 110315f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITTypePointer - Failed to find allocation details"); 110415f2bd95SEwan Crawford return false; 110515f2bd95SEwan Crawford } 110615f2bd95SEwan Crawford 110715f2bd95SEwan Crawford const char* expr_cstr = runtimeExpressions[eExprAllocGetType]; 110815f2bd95SEwan Crawford const int max_expr_size = 512; // Max expression size 110915f2bd95SEwan Crawford char buffer[max_expr_size]; 111015f2bd95SEwan Crawford 111115f2bd95SEwan Crawford int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->context.get(), *allocation->address.get()); 111215f2bd95SEwan Crawford if (chars_written < 0) 111315f2bd95SEwan Crawford { 111415f2bd95SEwan Crawford if (log) 111515f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()"); 111615f2bd95SEwan Crawford return false; 111715f2bd95SEwan Crawford } 111815f2bd95SEwan Crawford else if (chars_written >= max_expr_size) 111915f2bd95SEwan Crawford { 112015f2bd95SEwan Crawford if (log) 112115f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITTypePointer - Expression too long"); 112215f2bd95SEwan Crawford return false; 112315f2bd95SEwan Crawford } 112415f2bd95SEwan Crawford 112515f2bd95SEwan Crawford uint64_t result = 0; 112615f2bd95SEwan Crawford if (!EvalRSExpression(buffer, frame_ptr, &result)) 112715f2bd95SEwan Crawford return false; 112815f2bd95SEwan Crawford 112915f2bd95SEwan Crawford addr_t type_ptr = static_cast<lldb::addr_t>(result); 113015f2bd95SEwan Crawford allocation->type_ptr = type_ptr; 113115f2bd95SEwan Crawford 113215f2bd95SEwan Crawford return true; 113315f2bd95SEwan Crawford } 113415f2bd95SEwan Crawford 113515f2bd95SEwan Crawford // JITs the RS runtime for information about the dimensions and type of an allocation 113615f2bd95SEwan Crawford // Then sets dimension and element_ptr members in Allocation with the result. 113715f2bd95SEwan Crawford // Returns true on success, false otherwise 113815f2bd95SEwan Crawford bool 113915f2bd95SEwan Crawford RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr) 114015f2bd95SEwan Crawford { 114115f2bd95SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 114215f2bd95SEwan Crawford 114315f2bd95SEwan Crawford if (!allocation->type_ptr.isValid() || !allocation->context.isValid()) 114415f2bd95SEwan Crawford { 114515f2bd95SEwan Crawford if (log) 114615f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITTypePacked - Failed to find allocation details"); 114715f2bd95SEwan Crawford return false; 114815f2bd95SEwan Crawford } 114915f2bd95SEwan Crawford 115015f2bd95SEwan Crawford // Expression is different depending on if device is 32 or 64 bit 115115f2bd95SEwan Crawford uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize(); 115215f2bd95SEwan Crawford const unsigned int bits = archByteSize == 4 ? 32 : 64; 115315f2bd95SEwan Crawford 115415f2bd95SEwan Crawford // We want 4 elements from packed data 115515f2bd95SEwan Crawford const unsigned int num_exprs = 4; 115615f2bd95SEwan Crawford assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1) && "Invalid number of expressions"); 115715f2bd95SEwan Crawford 115815f2bd95SEwan Crawford const int max_expr_size = 512; // Max expression size 115915f2bd95SEwan Crawford char buffer[num_exprs][max_expr_size]; 116015f2bd95SEwan Crawford uint64_t results[num_exprs]; 116115f2bd95SEwan Crawford 116215f2bd95SEwan Crawford for (unsigned int i = 0; i < num_exprs; ++i) 116315f2bd95SEwan Crawford { 116415f2bd95SEwan Crawford int chars_written = snprintf(buffer[i], max_expr_size, runtimeExpressions[eExprTypeDimX + i], bits, 116515f2bd95SEwan Crawford *allocation->context.get(), *allocation->type_ptr.get()); 116615f2bd95SEwan Crawford if (chars_written < 0) 116715f2bd95SEwan Crawford { 116815f2bd95SEwan Crawford if (log) 116915f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()"); 117015f2bd95SEwan Crawford return false; 117115f2bd95SEwan Crawford } 117215f2bd95SEwan Crawford else if (chars_written >= max_expr_size) 117315f2bd95SEwan Crawford { 117415f2bd95SEwan Crawford if (log) 117515f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITTypePacked - Expression too long"); 117615f2bd95SEwan Crawford return false; 117715f2bd95SEwan Crawford } 117815f2bd95SEwan Crawford 117915f2bd95SEwan Crawford // Perform expression evaluation 118015f2bd95SEwan Crawford if (!EvalRSExpression(buffer[i], frame_ptr, &results[i])) 118115f2bd95SEwan Crawford return false; 118215f2bd95SEwan Crawford } 118315f2bd95SEwan Crawford 118415f2bd95SEwan Crawford // Assign results to allocation members 118515f2bd95SEwan Crawford AllocationDetails::Dimension dims; 118615f2bd95SEwan Crawford dims.dim_1 = static_cast<uint32_t>(results[0]); 118715f2bd95SEwan Crawford dims.dim_2 = static_cast<uint32_t>(results[1]); 118815f2bd95SEwan Crawford dims.dim_3 = static_cast<uint32_t>(results[2]); 118915f2bd95SEwan Crawford allocation->dimension = dims; 119015f2bd95SEwan Crawford 119115f2bd95SEwan Crawford addr_t elem_ptr = static_cast<lldb::addr_t>(results[3]); 119215f2bd95SEwan Crawford allocation->element_ptr = elem_ptr; 119315f2bd95SEwan Crawford 119415f2bd95SEwan Crawford if (log) 119515f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITTypePacked - dims (%u, %u, %u) Element*: 0x%" PRIx64, 119615f2bd95SEwan Crawford dims.dim_1, dims.dim_2, dims.dim_3, elem_ptr); 119715f2bd95SEwan Crawford 119815f2bd95SEwan Crawford return true; 119915f2bd95SEwan Crawford } 120015f2bd95SEwan Crawford 120115f2bd95SEwan Crawford // JITs the RS runtime for information about the Element of an allocation 120215f2bd95SEwan Crawford // Then sets type, type_vec_size, and type_kind members in Allocation with the result. 120315f2bd95SEwan Crawford // Returns true on success, false otherwise 120415f2bd95SEwan Crawford bool 120515f2bd95SEwan Crawford RenderScriptRuntime::JITElementPacked(AllocationDetails* allocation, StackFrame* frame_ptr) 120615f2bd95SEwan Crawford { 120715f2bd95SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 120815f2bd95SEwan Crawford 120915f2bd95SEwan Crawford if (!allocation->element_ptr.isValid() || !allocation->context.isValid()) 121015f2bd95SEwan Crawford { 121115f2bd95SEwan Crawford if (log) 121215f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITElementPacked - Failed to find allocation details"); 121315f2bd95SEwan Crawford return false; 121415f2bd95SEwan Crawford } 121515f2bd95SEwan Crawford 121615f2bd95SEwan Crawford // We want 3 elements from packed data 121715f2bd95SEwan Crawford const unsigned int num_exprs = 3; 121815f2bd95SEwan Crawford assert(num_exprs == (eExprElementVec - eExprElementType + 1) && "Invalid number of expressions"); 121915f2bd95SEwan Crawford 122015f2bd95SEwan Crawford const int max_expr_size = 512; // Max expression size 122115f2bd95SEwan Crawford char buffer[num_exprs][max_expr_size]; 122215f2bd95SEwan Crawford uint64_t results[num_exprs]; 122315f2bd95SEwan Crawford 122415f2bd95SEwan Crawford for (unsigned int i = 0; i < num_exprs; i++) 122515f2bd95SEwan Crawford { 122615f2bd95SEwan Crawford int chars_written = snprintf(buffer[i], max_expr_size, runtimeExpressions[eExprElementType + i], *allocation->context.get(), *allocation->element_ptr.get()); 122715f2bd95SEwan Crawford if (chars_written < 0) 122815f2bd95SEwan Crawford { 122915f2bd95SEwan Crawford if (log) 123015f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()"); 123115f2bd95SEwan Crawford return false; 123215f2bd95SEwan Crawford } 123315f2bd95SEwan Crawford else if (chars_written >= max_expr_size) 123415f2bd95SEwan Crawford { 123515f2bd95SEwan Crawford if (log) 123615f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITElementPacked - Expression too long"); 123715f2bd95SEwan Crawford return false; 123815f2bd95SEwan Crawford } 123915f2bd95SEwan Crawford 124015f2bd95SEwan Crawford // Perform expression evaluation 124115f2bd95SEwan Crawford if (!EvalRSExpression(buffer[i], frame_ptr, &results[i])) 124215f2bd95SEwan Crawford return false; 124315f2bd95SEwan Crawford } 124415f2bd95SEwan Crawford 124515f2bd95SEwan Crawford // Assign results to allocation members 124615f2bd95SEwan Crawford allocation->type = static_cast<RenderScriptRuntime::AllocationDetails::DataType>(results[0]); 124715f2bd95SEwan Crawford allocation->type_kind = static_cast<RenderScriptRuntime::AllocationDetails::DataKind>(results[1]); 124815f2bd95SEwan Crawford allocation->type_vec_size = static_cast<uint32_t>(results[2]); 124915f2bd95SEwan Crawford 125015f2bd95SEwan Crawford if (log) 125115f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITElementPacked - data type %u, pixel type %u, vector size %u", 125215f2bd95SEwan Crawford *allocation->type.get(), *allocation->type_kind.get(), *allocation->type_vec_size.get()); 125315f2bd95SEwan Crawford 125415f2bd95SEwan Crawford return true; 125515f2bd95SEwan Crawford } 125615f2bd95SEwan Crawford 1257a0f08674SEwan Crawford // JITs the RS runtime for the address of the last element in the allocation. 1258a0f08674SEwan Crawford // The `elem_size` paramter represents the size of a single element, including padding. 1259a0f08674SEwan Crawford // Which is needed as an offset from the last element pointer. 1260a0f08674SEwan Crawford // Using this offset minus the starting address we can calculate the size of the allocation. 1261a0f08674SEwan Crawford // Returns true on success, false otherwise 1262a0f08674SEwan Crawford bool 1263a0f08674SEwan Crawford RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame* frame_ptr, 1264a0f08674SEwan Crawford const uint32_t elem_size) 1265a0f08674SEwan Crawford { 1266a0f08674SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1267a0f08674SEwan Crawford 1268a0f08674SEwan Crawford if (!allocation->address.isValid() || !allocation->dimension.isValid() 1269a0f08674SEwan Crawford || !allocation->data_ptr.isValid()) 1270a0f08674SEwan Crawford { 1271a0f08674SEwan Crawford if (log) 1272a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::JITAllocationSize - Failed to find allocation details"); 1273a0f08674SEwan Crawford return false; 1274a0f08674SEwan Crawford } 1275a0f08674SEwan Crawford 1276a0f08674SEwan Crawford const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr]; 1277a0f08674SEwan Crawford const int max_expr_size = 512; // Max expression size 1278a0f08674SEwan Crawford char buffer[max_expr_size]; 1279a0f08674SEwan Crawford 1280a0f08674SEwan Crawford // Find dimensions 1281a0f08674SEwan Crawford unsigned int dim_x = allocation->dimension.get()->dim_1; 1282a0f08674SEwan Crawford unsigned int dim_y = allocation->dimension.get()->dim_2; 1283a0f08674SEwan Crawford unsigned int dim_z = allocation->dimension.get()->dim_3; 1284a0f08674SEwan Crawford 1285a0f08674SEwan Crawford // Calculate last element 1286a0f08674SEwan Crawford dim_x = dim_x == 0 ? 0 : dim_x - 1; 1287a0f08674SEwan Crawford dim_y = dim_y == 0 ? 0 : dim_y - 1; 1288a0f08674SEwan Crawford dim_z = dim_z == 0 ? 0 : dim_z - 1; 1289a0f08674SEwan Crawford 1290a0f08674SEwan Crawford int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->address.get(), 1291a0f08674SEwan Crawford dim_x, dim_y, dim_z); 1292a0f08674SEwan Crawford if (chars_written < 0) 1293a0f08674SEwan Crawford { 1294a0f08674SEwan Crawford if (log) 1295a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::JITAllocationSize - Encoding error in snprintf()"); 1296a0f08674SEwan Crawford return false; 1297a0f08674SEwan Crawford } 1298a0f08674SEwan Crawford else if (chars_written >= max_expr_size) 1299a0f08674SEwan Crawford { 1300a0f08674SEwan Crawford if (log) 1301a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::JITAllocationSize - Expression too long"); 1302a0f08674SEwan Crawford return false; 1303a0f08674SEwan Crawford } 1304a0f08674SEwan Crawford 1305a0f08674SEwan Crawford uint64_t result = 0; 1306a0f08674SEwan Crawford if (!EvalRSExpression(buffer, frame_ptr, &result)) 1307a0f08674SEwan Crawford return false; 1308a0f08674SEwan Crawford 1309a0f08674SEwan Crawford addr_t mem_ptr = static_cast<lldb::addr_t>(result); 1310a0f08674SEwan Crawford // Find pointer to last element and add on size of an element 1311a0f08674SEwan Crawford allocation->size = static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get()) + elem_size; 1312a0f08674SEwan Crawford 1313a0f08674SEwan Crawford return true; 1314a0f08674SEwan Crawford } 1315a0f08674SEwan Crawford 1316a0f08674SEwan Crawford // JITs the RS runtime for information about the stride between rows in the allocation. 1317a0f08674SEwan Crawford // This is done to detect padding, since allocated memory is 16-byte aligned. 1318a0f08674SEwan Crawford // Returns true on success, false otherwise 1319a0f08674SEwan Crawford bool 1320a0f08674SEwan Crawford RenderScriptRuntime::JITAllocationStride(AllocationDetails* allocation, StackFrame* frame_ptr) 1321a0f08674SEwan Crawford { 1322a0f08674SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1323a0f08674SEwan Crawford 1324a0f08674SEwan Crawford if (!allocation->address.isValid() || !allocation->data_ptr.isValid()) 1325a0f08674SEwan Crawford { 1326a0f08674SEwan Crawford if (log) 1327a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::JITAllocationStride - Failed to find allocation details"); 1328a0f08674SEwan Crawford return false; 1329a0f08674SEwan Crawford } 1330a0f08674SEwan Crawford 1331a0f08674SEwan Crawford const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr]; 1332a0f08674SEwan Crawford const int max_expr_size = 512; // Max expression size 1333a0f08674SEwan Crawford char buffer[max_expr_size]; 1334a0f08674SEwan Crawford 1335a0f08674SEwan Crawford int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->address.get(), 1336a0f08674SEwan Crawford 0, 1, 0); 1337a0f08674SEwan Crawford if (chars_written < 0) 1338a0f08674SEwan Crawford { 1339a0f08674SEwan Crawford if (log) 1340a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::JITAllocationStride - Encoding error in snprintf()"); 1341a0f08674SEwan Crawford return false; 1342a0f08674SEwan Crawford } 1343a0f08674SEwan Crawford else if (chars_written >= max_expr_size) 1344a0f08674SEwan Crawford { 1345a0f08674SEwan Crawford if (log) 1346a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::JITAllocationStride - Expression too long"); 1347a0f08674SEwan Crawford return false; 1348a0f08674SEwan Crawford } 1349a0f08674SEwan Crawford 1350a0f08674SEwan Crawford uint64_t result = 0; 1351a0f08674SEwan Crawford if (!EvalRSExpression(buffer, frame_ptr, &result)) 1352a0f08674SEwan Crawford return false; 1353a0f08674SEwan Crawford 1354a0f08674SEwan Crawford addr_t mem_ptr = static_cast<lldb::addr_t>(result); 1355a0f08674SEwan Crawford allocation->stride = static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get()); 1356a0f08674SEwan Crawford 1357a0f08674SEwan Crawford return true; 1358a0f08674SEwan Crawford } 1359a0f08674SEwan Crawford 136015f2bd95SEwan Crawford // JIT all the current runtime info regarding an allocation 136115f2bd95SEwan Crawford bool 136215f2bd95SEwan Crawford RenderScriptRuntime::RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr) 136315f2bd95SEwan Crawford { 136415f2bd95SEwan Crawford // GetOffsetPointer() 136515f2bd95SEwan Crawford if (!JITDataPointer(allocation, frame_ptr)) 136615f2bd95SEwan Crawford return false; 136715f2bd95SEwan Crawford 136815f2bd95SEwan Crawford // rsaAllocationGetType() 136915f2bd95SEwan Crawford if (!JITTypePointer(allocation, frame_ptr)) 137015f2bd95SEwan Crawford return false; 137115f2bd95SEwan Crawford 137215f2bd95SEwan Crawford // rsaTypeGetNativeData() 137315f2bd95SEwan Crawford if (!JITTypePacked(allocation, frame_ptr)) 137415f2bd95SEwan Crawford return false; 137515f2bd95SEwan Crawford 137615f2bd95SEwan Crawford // rsaElementGetNativeData() 137715f2bd95SEwan Crawford if (!JITElementPacked(allocation, frame_ptr)) 137815f2bd95SEwan Crawford return false; 137915f2bd95SEwan Crawford 1380*55232f09SEwan Crawford // Use GetOffsetPointer() to infer size of the allocation 1381*55232f09SEwan Crawford const unsigned int element_size = GetElementSize(allocation); 1382*55232f09SEwan Crawford if (!JITAllocationSize(allocation, frame_ptr, element_size)) 1383*55232f09SEwan Crawford return false; 1384*55232f09SEwan Crawford 1385*55232f09SEwan Crawford return true; 1386*55232f09SEwan Crawford } 1387*55232f09SEwan Crawford 1388*55232f09SEwan Crawford // Returns the size of a single allocation element including padding. 1389*55232f09SEwan Crawford // Assumes the relevant allocation information has already been jitted. 1390*55232f09SEwan Crawford unsigned int 1391*55232f09SEwan Crawford RenderScriptRuntime::GetElementSize(const AllocationDetails* allocation) 1392*55232f09SEwan Crawford { 1393*55232f09SEwan Crawford const AllocationDetails::DataType type = *allocation->type.get(); 1394*55232f09SEwan Crawford assert(type >= AllocationDetails::RS_TYPE_NONE && type <= AllocationDetails::RS_TYPE_BOOLEAN 1395*55232f09SEwan Crawford && "Invalid allocation type"); 1396*55232f09SEwan Crawford 1397*55232f09SEwan Crawford const unsigned int vec_size = *allocation->type_vec_size.get(); 1398*55232f09SEwan Crawford const unsigned int data_size = vec_size * AllocationDetails::RSTypeToFormat[type][eElementSize]; 1399*55232f09SEwan Crawford const unsigned int padding = vec_size == 3 ? AllocationDetails::RSTypeToFormat[type][eElementSize] : 0; 1400*55232f09SEwan Crawford 1401*55232f09SEwan Crawford return data_size + padding; 1402*55232f09SEwan Crawford } 1403*55232f09SEwan Crawford 1404*55232f09SEwan Crawford // Given an allocation, this function copies the allocation contents from device into a buffer on the heap. 1405*55232f09SEwan Crawford // Returning a shared pointer to the buffer containing the data. 1406*55232f09SEwan Crawford std::shared_ptr<uint8_t> 1407*55232f09SEwan Crawford RenderScriptRuntime::GetAllocationData(AllocationDetails* allocation, StackFrame* frame_ptr) 1408*55232f09SEwan Crawford { 1409*55232f09SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1410*55232f09SEwan Crawford 1411*55232f09SEwan Crawford // JIT all the allocation details 1412*55232f09SEwan Crawford if (!allocation->data_ptr.isValid() || !allocation->type.isValid() || !allocation->type_vec_size.isValid() 1413*55232f09SEwan Crawford || !allocation->size.isValid()) 1414*55232f09SEwan Crawford { 1415*55232f09SEwan Crawford if (log) 1416*55232f09SEwan Crawford log->Printf("RenderScriptRuntime::GetAllocationData - Allocation details not calculated yet, jitting info"); 1417*55232f09SEwan Crawford 1418*55232f09SEwan Crawford if (!RefreshAllocation(allocation, frame_ptr)) 1419*55232f09SEwan Crawford { 1420*55232f09SEwan Crawford if (log) 1421*55232f09SEwan Crawford log->Printf("RenderScriptRuntime::GetAllocationData - Couldn't JIT allocation details"); 1422*55232f09SEwan Crawford return nullptr; 1423*55232f09SEwan Crawford } 1424*55232f09SEwan Crawford } 1425*55232f09SEwan Crawford 1426*55232f09SEwan Crawford assert(allocation->data_ptr.isValid() && allocation->type.isValid() && allocation->type_vec_size.isValid() 1427*55232f09SEwan Crawford && allocation->size.isValid() && "Allocation information not available"); 1428*55232f09SEwan Crawford 1429*55232f09SEwan Crawford // Allocate a buffer to copy data into 1430*55232f09SEwan Crawford const unsigned int size = *allocation->size.get(); 1431*55232f09SEwan Crawford std::shared_ptr<uint8_t> buffer(new uint8_t[size]); 1432*55232f09SEwan Crawford if (!buffer) 1433*55232f09SEwan Crawford { 1434*55232f09SEwan Crawford if (log) 1435*55232f09SEwan Crawford log->Printf("RenderScriptRuntime::GetAllocationData - Couldn't allocate a %u byte buffer", size); 1436*55232f09SEwan Crawford return nullptr; 1437*55232f09SEwan Crawford } 1438*55232f09SEwan Crawford 1439*55232f09SEwan Crawford // Read the inferior memory 1440*55232f09SEwan Crawford Error error; 1441*55232f09SEwan Crawford lldb::addr_t data_ptr = *allocation->data_ptr.get(); 1442*55232f09SEwan Crawford GetProcess()->ReadMemory(data_ptr, buffer.get(), size, error); 1443*55232f09SEwan Crawford if (error.Fail()) 1444*55232f09SEwan Crawford { 1445*55232f09SEwan Crawford if (log) 1446*55232f09SEwan Crawford log->Printf("RenderScriptRuntime::GetAllocationData - '%s' Couldn't read %u bytes of allocation data from 0x%" PRIx64, 1447*55232f09SEwan Crawford error.AsCString(), size, data_ptr); 1448*55232f09SEwan Crawford return nullptr; 1449*55232f09SEwan Crawford } 1450*55232f09SEwan Crawford 1451*55232f09SEwan Crawford return buffer; 1452*55232f09SEwan Crawford } 1453*55232f09SEwan Crawford 1454*55232f09SEwan Crawford // Function copies data from a binary file into an allocation. 1455*55232f09SEwan Crawford // There is a header at the start of the file, FileHeader, before the data content itself. 1456*55232f09SEwan Crawford // Information from this header is used to display warnings to the user about incompatabilities 1457*55232f09SEwan Crawford bool 1458*55232f09SEwan Crawford RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr) 1459*55232f09SEwan Crawford { 1460*55232f09SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1461*55232f09SEwan Crawford 1462*55232f09SEwan Crawford // Find allocation with the given id 1463*55232f09SEwan Crawford AllocationDetails* alloc = FindAllocByID(strm, alloc_id); 1464*55232f09SEwan Crawford if (!alloc) 1465*55232f09SEwan Crawford return false; 1466*55232f09SEwan Crawford 1467*55232f09SEwan Crawford if (log) 1468*55232f09SEwan Crawford log->Printf("RenderScriptRuntime::LoadAllocation - Found allocation 0x%" PRIx64, *alloc->address.get()); 1469*55232f09SEwan Crawford 1470*55232f09SEwan Crawford // JIT all the allocation details 1471*55232f09SEwan Crawford if (!alloc->data_ptr.isValid() || !alloc->type.isValid() || !alloc->type_vec_size.isValid() || !alloc->size.isValid()) 1472*55232f09SEwan Crawford { 1473*55232f09SEwan Crawford if (log) 1474*55232f09SEwan Crawford log->Printf("RenderScriptRuntime::LoadAllocation - Allocation details not calculated yet, jitting info"); 1475*55232f09SEwan Crawford 1476*55232f09SEwan Crawford if (!RefreshAllocation(alloc, frame_ptr)) 1477*55232f09SEwan Crawford { 1478*55232f09SEwan Crawford if (log) 1479*55232f09SEwan Crawford log->Printf("RenderScriptRuntime::LoadAllocation - Couldn't JIT allocation details"); 1480*55232f09SEwan Crawford return nullptr; 1481*55232f09SEwan Crawford } 1482*55232f09SEwan Crawford } 1483*55232f09SEwan Crawford 1484*55232f09SEwan Crawford assert(alloc->data_ptr.isValid() && alloc->type.isValid() && alloc->type_vec_size.isValid() && alloc->size.isValid() 1485*55232f09SEwan Crawford && "Allocation information not available"); 1486*55232f09SEwan Crawford 1487*55232f09SEwan Crawford // Check we can read from file 1488*55232f09SEwan Crawford FileSpec file(filename, true); 1489*55232f09SEwan Crawford if (!file.Exists()) 1490*55232f09SEwan Crawford { 1491*55232f09SEwan Crawford strm.Printf("Error: File %s does not exist", filename); 1492*55232f09SEwan Crawford strm.EOL(); 1493*55232f09SEwan Crawford return false; 1494*55232f09SEwan Crawford } 1495*55232f09SEwan Crawford 1496*55232f09SEwan Crawford if (!file.Readable()) 1497*55232f09SEwan Crawford { 1498*55232f09SEwan Crawford strm.Printf("Error: File %s does not have readable permissions", filename); 1499*55232f09SEwan Crawford strm.EOL(); 1500*55232f09SEwan Crawford return false; 1501*55232f09SEwan Crawford } 1502*55232f09SEwan Crawford 1503*55232f09SEwan Crawford // Read file into data buffer 1504*55232f09SEwan Crawford DataBufferSP data_sp(file.ReadFileContents()); 1505*55232f09SEwan Crawford 1506*55232f09SEwan Crawford // Cast start of buffer to FileHeader and use pointer to read metadata 1507*55232f09SEwan Crawford void* file_buffer = data_sp->GetBytes(); 1508*55232f09SEwan Crawford const AllocationDetails::FileHeader* head = static_cast<AllocationDetails::FileHeader*>(file_buffer); 1509*55232f09SEwan Crawford 1510*55232f09SEwan Crawford // Advance buffer past header 1511*55232f09SEwan Crawford file_buffer = static_cast<uint8_t*>(file_buffer) + head->hdr_size; 1512*55232f09SEwan Crawford 1513*55232f09SEwan Crawford if (log) 1514*55232f09SEwan Crawford log->Printf("RenderScriptRuntime::LoadAllocation - header type %u, element size %u", 1515*55232f09SEwan Crawford head->type, head->element_size); 1516*55232f09SEwan Crawford 1517*55232f09SEwan Crawford // Check if the target allocation and file both have the same number of bytes for an Element 1518*55232f09SEwan Crawford const unsigned int elem_size = GetElementSize(alloc); 1519*55232f09SEwan Crawford if (elem_size != head->element_size) 1520*55232f09SEwan Crawford { 1521*55232f09SEwan Crawford strm.Printf("Warning: Mismatched Element sizes - file %u bytes, allocation %u bytes", 1522*55232f09SEwan Crawford head->element_size, elem_size); 1523*55232f09SEwan Crawford strm.EOL(); 1524*55232f09SEwan Crawford } 1525*55232f09SEwan Crawford 1526*55232f09SEwan Crawford // Check if the target allocation and file both have the same integral type 1527*55232f09SEwan Crawford const unsigned int type = static_cast<unsigned int>(*alloc->type.get()); 1528*55232f09SEwan Crawford if (type != head->type) 1529*55232f09SEwan Crawford { 1530*55232f09SEwan Crawford const char* file_type_cstr = AllocationDetails::RsDataTypeToString[head->type][0]; 1531*55232f09SEwan Crawford const char* alloc_type_cstr = AllocationDetails::RsDataTypeToString[type][0]; 1532*55232f09SEwan Crawford 1533*55232f09SEwan Crawford strm.Printf("Warning: Mismatched Types - file '%s' type, allocation '%s' type", 1534*55232f09SEwan Crawford file_type_cstr, alloc_type_cstr); 1535*55232f09SEwan Crawford strm.EOL(); 1536*55232f09SEwan Crawford } 1537*55232f09SEwan Crawford 1538*55232f09SEwan Crawford // Calculate size of allocation data in file 1539*55232f09SEwan Crawford size_t length = data_sp->GetByteSize() - head->hdr_size; 1540*55232f09SEwan Crawford 1541*55232f09SEwan Crawford // Check if the target allocation and file both have the same total data size. 1542*55232f09SEwan Crawford const unsigned int alloc_size = *alloc->size.get(); 1543*55232f09SEwan Crawford if (alloc_size != length) 1544*55232f09SEwan Crawford { 1545*55232f09SEwan Crawford strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64 " bytes, allocation 0x%x bytes", 1546*55232f09SEwan Crawford length, alloc_size); 1547*55232f09SEwan Crawford strm.EOL(); 1548*55232f09SEwan Crawford length = alloc_size < length ? alloc_size : length; // Set length to copy to minimum 1549*55232f09SEwan Crawford } 1550*55232f09SEwan Crawford 1551*55232f09SEwan Crawford // Copy file data from our buffer into the target allocation. 1552*55232f09SEwan Crawford lldb::addr_t alloc_data = *alloc->data_ptr.get(); 1553*55232f09SEwan Crawford Error error; 1554*55232f09SEwan Crawford size_t bytes_written = GetProcess()->WriteMemory(alloc_data, file_buffer, length, error); 1555*55232f09SEwan Crawford if (!error.Success() || bytes_written != length) 1556*55232f09SEwan Crawford { 1557*55232f09SEwan Crawford strm.Printf("Error: Couldn't write data to allocation %s", error.AsCString()); 1558*55232f09SEwan Crawford strm.EOL(); 1559*55232f09SEwan Crawford return false; 1560*55232f09SEwan Crawford } 1561*55232f09SEwan Crawford 1562*55232f09SEwan Crawford strm.Printf("Contents of file '%s' read into allocation %u", filename, alloc->id); 1563*55232f09SEwan Crawford strm.EOL(); 1564*55232f09SEwan Crawford 1565*55232f09SEwan Crawford return true; 1566*55232f09SEwan Crawford } 1567*55232f09SEwan Crawford 1568*55232f09SEwan Crawford // Function copies allocation contents into a binary file. 1569*55232f09SEwan Crawford // This file can then be loaded later into a different allocation. 1570*55232f09SEwan Crawford // There is a header, FileHeader, before the allocation data containing meta-data. 1571*55232f09SEwan Crawford bool 1572*55232f09SEwan Crawford RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr) 1573*55232f09SEwan Crawford { 1574*55232f09SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1575*55232f09SEwan Crawford 1576*55232f09SEwan Crawford // Find allocation with the given id 1577*55232f09SEwan Crawford AllocationDetails* alloc = FindAllocByID(strm, alloc_id); 1578*55232f09SEwan Crawford if (!alloc) 1579*55232f09SEwan Crawford return false; 1580*55232f09SEwan Crawford 1581*55232f09SEwan Crawford if (log) 1582*55232f09SEwan Crawford log->Printf("RenderScriptRuntime::SaveAllocation - Found allocation 0x%" PRIx64, *alloc->address.get()); 1583*55232f09SEwan Crawford 1584*55232f09SEwan Crawford // JIT all the allocation details 1585*55232f09SEwan Crawford if (!alloc->data_ptr.isValid() || !alloc->type.isValid() || !alloc->type_vec_size.isValid() 1586*55232f09SEwan Crawford || !alloc->type_kind.isValid() || !alloc->dimension.isValid()) 1587*55232f09SEwan Crawford { 1588*55232f09SEwan Crawford if (log) 1589*55232f09SEwan Crawford log->Printf("RenderScriptRuntime::SaveAllocation - Allocation details not calculated yet, jitting info"); 1590*55232f09SEwan Crawford 1591*55232f09SEwan Crawford if (!RefreshAllocation(alloc, frame_ptr)) 1592*55232f09SEwan Crawford { 1593*55232f09SEwan Crawford if (log) 1594*55232f09SEwan Crawford log->Printf("RenderScriptRuntime::SaveAllocation - Couldn't JIT allocation details"); 1595*55232f09SEwan Crawford return nullptr; 1596*55232f09SEwan Crawford } 1597*55232f09SEwan Crawford } 1598*55232f09SEwan Crawford 1599*55232f09SEwan Crawford assert(alloc->data_ptr.isValid() && alloc->type.isValid() && alloc->type_vec_size.isValid() && alloc->type_kind.isValid() 1600*55232f09SEwan Crawford && alloc->dimension.isValid() && "Allocation information not available"); 1601*55232f09SEwan Crawford 1602*55232f09SEwan Crawford // Check we can create writable file 1603*55232f09SEwan Crawford FileSpec file_spec(filename, true); 1604*55232f09SEwan Crawford File file(file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionTruncate); 1605*55232f09SEwan Crawford if (!file) 1606*55232f09SEwan Crawford { 1607*55232f09SEwan Crawford strm.Printf("Error: Failed to open '%s' for writing", filename); 1608*55232f09SEwan Crawford strm.EOL(); 1609*55232f09SEwan Crawford return false; 1610*55232f09SEwan Crawford } 1611*55232f09SEwan Crawford 1612*55232f09SEwan Crawford // Read allocation into buffer of heap memory 1613*55232f09SEwan Crawford const std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr); 1614*55232f09SEwan Crawford if (!buffer) 1615*55232f09SEwan Crawford { 1616*55232f09SEwan Crawford strm.Printf("Error: Couldn't read allocation data into buffer"); 1617*55232f09SEwan Crawford strm.EOL(); 1618*55232f09SEwan Crawford return false; 1619*55232f09SEwan Crawford } 1620*55232f09SEwan Crawford 1621*55232f09SEwan Crawford // Create the file header 1622*55232f09SEwan Crawford AllocationDetails::FileHeader head; 1623*55232f09SEwan Crawford head.ident[0] = 'R'; head.ident[1] = 'S'; head.ident[2] = 'A'; head.ident[3] = 'D'; 1624*55232f09SEwan Crawford head.hdr_size = static_cast<uint16_t>(sizeof(AllocationDetails::FileHeader)); 1625*55232f09SEwan Crawford head.type = static_cast<uint16_t>(*alloc->type.get()); 1626*55232f09SEwan Crawford head.kind = static_cast<uint32_t>(*alloc->type_kind.get()); 1627*55232f09SEwan Crawford head.dims[1] = static_cast<uint32_t>(alloc->dimension.get()->dim_1); 1628*55232f09SEwan Crawford head.dims[2] = static_cast<uint32_t>(alloc->dimension.get()->dim_2); 1629*55232f09SEwan Crawford head.dims[3] = static_cast<uint32_t>(alloc->dimension.get()->dim_3); 1630*55232f09SEwan Crawford head.element_size = static_cast<uint32_t>(GetElementSize(alloc)); 1631*55232f09SEwan Crawford 1632*55232f09SEwan Crawford // Write the file header 1633*55232f09SEwan Crawford size_t num_bytes = sizeof(AllocationDetails::FileHeader); 1634*55232f09SEwan Crawford Error err = file.Write(static_cast<const void*>(&head), num_bytes); 1635*55232f09SEwan Crawford if (!err.Success()) 1636*55232f09SEwan Crawford { 1637*55232f09SEwan Crawford strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), filename); 1638*55232f09SEwan Crawford strm.EOL(); 1639*55232f09SEwan Crawford return false; 1640*55232f09SEwan Crawford } 1641*55232f09SEwan Crawford 1642*55232f09SEwan Crawford // Write allocation data to file 1643*55232f09SEwan Crawford num_bytes = static_cast<size_t>(*alloc->size.get()); 1644*55232f09SEwan Crawford if (log) 1645*55232f09SEwan Crawford log->Printf("RenderScriptRuntime::SaveAllocation - Writing %" PRIx64 "bytes from %p", num_bytes, buffer.get()); 1646*55232f09SEwan Crawford 1647*55232f09SEwan Crawford err = file.Write(buffer.get(), num_bytes); 1648*55232f09SEwan Crawford if (!err.Success()) 1649*55232f09SEwan Crawford { 1650*55232f09SEwan Crawford strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), filename); 1651*55232f09SEwan Crawford strm.EOL(); 1652*55232f09SEwan Crawford return false; 1653*55232f09SEwan Crawford } 1654*55232f09SEwan Crawford 1655*55232f09SEwan Crawford strm.Printf("Allocation written to file '%s'", filename); 1656*55232f09SEwan Crawford strm.EOL(); 165715f2bd95SEwan Crawford return true; 165815f2bd95SEwan Crawford } 165915f2bd95SEwan Crawford 16605ec532a9SColin Riley bool 16615ec532a9SColin Riley RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) 16625ec532a9SColin Riley { 16634640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 16644640cde1SColin Riley 16655ec532a9SColin Riley if (module_sp) 16665ec532a9SColin Riley { 16675ec532a9SColin Riley for (const auto &rs_module : m_rsmodules) 16685ec532a9SColin Riley { 16694640cde1SColin Riley if (rs_module->m_module == module_sp) 16707dc7771cSEwan Crawford { 16717dc7771cSEwan Crawford // Check if the user has enabled automatically breaking on 16727dc7771cSEwan Crawford // all RS kernels. 16737dc7771cSEwan Crawford if (m_breakAllKernels) 16747dc7771cSEwan Crawford BreakOnModuleKernels(rs_module); 16757dc7771cSEwan Crawford 16765ec532a9SColin Riley return false; 16775ec532a9SColin Riley } 16787dc7771cSEwan Crawford } 1679ef20b08fSColin Riley bool module_loaded = false; 1680ef20b08fSColin Riley switch (GetModuleKind(module_sp)) 1681ef20b08fSColin Riley { 1682ef20b08fSColin Riley case eModuleKindKernelObj: 1683ef20b08fSColin Riley { 16844640cde1SColin Riley RSModuleDescriptorSP module_desc; 16854640cde1SColin Riley module_desc.reset(new RSModuleDescriptor(module_sp)); 16864640cde1SColin Riley if (module_desc->ParseRSInfo()) 16875ec532a9SColin Riley { 16885ec532a9SColin Riley m_rsmodules.push_back(module_desc); 1689ef20b08fSColin Riley module_loaded = true; 16905ec532a9SColin Riley } 16914640cde1SColin Riley if (module_loaded) 16924640cde1SColin Riley { 16934640cde1SColin Riley FixupScriptDetails(module_desc); 16944640cde1SColin Riley } 1695ef20b08fSColin Riley break; 1696ef20b08fSColin Riley } 1697ef20b08fSColin Riley case eModuleKindDriver: 16984640cde1SColin Riley { 16994640cde1SColin Riley if (!m_libRSDriver) 17004640cde1SColin Riley { 17014640cde1SColin Riley m_libRSDriver = module_sp; 17024640cde1SColin Riley LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver); 17034640cde1SColin Riley } 17044640cde1SColin Riley break; 17054640cde1SColin Riley } 1706ef20b08fSColin Riley case eModuleKindImpl: 17074640cde1SColin Riley { 17084640cde1SColin Riley m_libRSCpuRef = module_sp; 17094640cde1SColin Riley break; 17104640cde1SColin Riley } 1711ef20b08fSColin Riley case eModuleKindLibRS: 17124640cde1SColin Riley { 17134640cde1SColin Riley if (!m_libRS) 17144640cde1SColin Riley { 17154640cde1SColin Riley m_libRS = module_sp; 17164640cde1SColin Riley static ConstString gDbgPresentStr("gDebuggerPresent"); 17174640cde1SColin Riley const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData); 17184640cde1SColin Riley if (debug_present) 17194640cde1SColin Riley { 17204640cde1SColin Riley Error error; 17214640cde1SColin Riley uint32_t flag = 0x00000001U; 17224640cde1SColin Riley Target &target = GetProcess()->GetTarget(); 1723358cf1eaSGreg Clayton addr_t addr = debug_present->GetLoadAddress(&target); 17244640cde1SColin Riley GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error); 17254640cde1SColin Riley if(error.Success()) 17264640cde1SColin Riley { 17274640cde1SColin Riley if (log) 17284640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee"); 17294640cde1SColin Riley 17304640cde1SColin Riley m_debuggerPresentFlagged = true; 17314640cde1SColin Riley } 17324640cde1SColin Riley else if (log) 17334640cde1SColin Riley { 17344640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString()); 17354640cde1SColin Riley } 17364640cde1SColin Riley } 17374640cde1SColin Riley else if (log) 17384640cde1SColin Riley { 17394640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found"); 17404640cde1SColin Riley } 17414640cde1SColin Riley } 17424640cde1SColin Riley break; 17434640cde1SColin Riley } 1744ef20b08fSColin Riley default: 1745ef20b08fSColin Riley break; 1746ef20b08fSColin Riley } 1747ef20b08fSColin Riley if (module_loaded) 1748ef20b08fSColin Riley Update(); 1749ef20b08fSColin Riley return module_loaded; 17505ec532a9SColin Riley } 17515ec532a9SColin Riley return false; 17525ec532a9SColin Riley } 17535ec532a9SColin Riley 1754ef20b08fSColin Riley void 1755ef20b08fSColin Riley RenderScriptRuntime::Update() 1756ef20b08fSColin Riley { 1757ef20b08fSColin Riley if (m_rsmodules.size() > 0) 1758ef20b08fSColin Riley { 1759ef20b08fSColin Riley if (!m_initiated) 1760ef20b08fSColin Riley { 1761ef20b08fSColin Riley Initiate(); 1762ef20b08fSColin Riley } 1763ef20b08fSColin Riley } 1764ef20b08fSColin Riley } 1765ef20b08fSColin Riley 1766ef20b08fSColin Riley 17675ec532a9SColin Riley // The maximum line length of an .rs.info packet 17685ec532a9SColin Riley #define MAXLINE 500 17695ec532a9SColin Riley 17705ec532a9SColin Riley // The .rs.info symbol in renderscript modules contains a string which needs to be parsed. 17715ec532a9SColin Riley // The string is basic and is parsed on a line by line basis. 17725ec532a9SColin Riley bool 17735ec532a9SColin Riley RSModuleDescriptor::ParseRSInfo() 17745ec532a9SColin Riley { 17755ec532a9SColin Riley const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData); 17765ec532a9SColin Riley if (info_sym) 17775ec532a9SColin Riley { 1778358cf1eaSGreg Clayton const addr_t addr = info_sym->GetAddressRef().GetFileAddress(); 17795ec532a9SColin Riley const addr_t size = info_sym->GetByteSize(); 17805ec532a9SColin Riley const FileSpec fs = m_module->GetFileSpec(); 17815ec532a9SColin Riley 17825ec532a9SColin Riley DataBufferSP buffer = fs.ReadFileContents(addr, size); 17835ec532a9SColin Riley 17845ec532a9SColin Riley if (!buffer) 17855ec532a9SColin Riley return false; 17865ec532a9SColin Riley 17875ec532a9SColin Riley std::string info((const char *)buffer->GetBytes()); 17885ec532a9SColin Riley 17895ec532a9SColin Riley std::vector<std::string> info_lines; 1790e8433cc1SBruce Mitchener size_t lpos = info.find('\n'); 17915ec532a9SColin Riley while (lpos != std::string::npos) 17925ec532a9SColin Riley { 17935ec532a9SColin Riley info_lines.push_back(info.substr(0, lpos)); 17945ec532a9SColin Riley info = info.substr(lpos + 1); 1795e8433cc1SBruce Mitchener lpos = info.find('\n'); 17965ec532a9SColin Riley } 17975ec532a9SColin Riley size_t offset = 0; 17985ec532a9SColin Riley while (offset < info_lines.size()) 17995ec532a9SColin Riley { 18005ec532a9SColin Riley std::string line = info_lines[offset]; 18015ec532a9SColin Riley // Parse directives 18025ec532a9SColin Riley uint32_t numDefns = 0; 18035ec532a9SColin Riley if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1) 18045ec532a9SColin Riley { 18055ec532a9SColin Riley while (numDefns--) 18064640cde1SColin Riley m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str())); 18075ec532a9SColin Riley } 18085ec532a9SColin Riley else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1) 18095ec532a9SColin Riley { 18105ec532a9SColin Riley } 18115ec532a9SColin Riley else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1) 18125ec532a9SColin Riley { 18135ec532a9SColin Riley char name[MAXLINE]; 18145ec532a9SColin Riley while (numDefns--) 18155ec532a9SColin Riley { 18165ec532a9SColin Riley uint32_t slot = 0; 18175ec532a9SColin Riley name[0] = '\0'; 18185ec532a9SColin Riley if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2) 18195ec532a9SColin Riley { 18204640cde1SColin Riley m_kernels.push_back(RSKernelDescriptor(this, name, slot)); 18214640cde1SColin Riley } 18224640cde1SColin Riley } 18234640cde1SColin Riley } 18244640cde1SColin Riley else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1) 18254640cde1SColin Riley { 18264640cde1SColin Riley char name[MAXLINE]; 18274640cde1SColin Riley char value[MAXLINE]; 18284640cde1SColin Riley while (numDefns--) 18294640cde1SColin Riley { 18304640cde1SColin Riley name[0] = '\0'; 18314640cde1SColin Riley value[0] = '\0'; 18324640cde1SColin Riley if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0 18334640cde1SColin Riley && (name[0] != '\0')) 18344640cde1SColin Riley { 18354640cde1SColin Riley m_pragmas[std::string(name)] = value; 18365ec532a9SColin Riley } 18375ec532a9SColin Riley } 18385ec532a9SColin Riley } 18395ec532a9SColin Riley else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1) 18405ec532a9SColin Riley { 18415ec532a9SColin Riley } 18425ec532a9SColin Riley 18435ec532a9SColin Riley offset++; 18445ec532a9SColin Riley } 18455ec532a9SColin Riley return m_kernels.size() > 0; 18465ec532a9SColin Riley } 18475ec532a9SColin Riley return false; 18485ec532a9SColin Riley } 18495ec532a9SColin Riley 18505ec532a9SColin Riley bool 18515ec532a9SColin Riley RenderScriptRuntime::ProbeModules(const ModuleList module_list) 18525ec532a9SColin Riley { 18535ec532a9SColin Riley bool rs_found = false; 18545ec532a9SColin Riley size_t num_modules = module_list.GetSize(); 18555ec532a9SColin Riley for (size_t i = 0; i < num_modules; i++) 18565ec532a9SColin Riley { 18575ec532a9SColin Riley auto module = module_list.GetModuleAtIndex(i); 18585ec532a9SColin Riley rs_found |= LoadModule(module); 18595ec532a9SColin Riley } 18605ec532a9SColin Riley return rs_found; 18615ec532a9SColin Riley } 18625ec532a9SColin Riley 18635ec532a9SColin Riley void 18644640cde1SColin Riley RenderScriptRuntime::Status(Stream &strm) const 18654640cde1SColin Riley { 18664640cde1SColin Riley if (m_libRS) 18674640cde1SColin Riley { 18684640cde1SColin Riley strm.Printf("Runtime Library discovered."); 18694640cde1SColin Riley strm.EOL(); 18704640cde1SColin Riley } 18714640cde1SColin Riley if (m_libRSDriver) 18724640cde1SColin Riley { 18734640cde1SColin Riley strm.Printf("Runtime Driver discovered."); 18744640cde1SColin Riley strm.EOL(); 18754640cde1SColin Riley } 18764640cde1SColin Riley if (m_libRSCpuRef) 18774640cde1SColin Riley { 18784640cde1SColin Riley strm.Printf("CPU Reference Implementation discovered."); 18794640cde1SColin Riley strm.EOL(); 18804640cde1SColin Riley } 18814640cde1SColin Riley 18824640cde1SColin Riley if (m_runtimeHooks.size()) 18834640cde1SColin Riley { 18844640cde1SColin Riley strm.Printf("Runtime functions hooked:"); 18854640cde1SColin Riley strm.EOL(); 18864640cde1SColin Riley for (auto b : m_runtimeHooks) 18874640cde1SColin Riley { 18884640cde1SColin Riley strm.Indent(b.second->defn->name); 18894640cde1SColin Riley strm.EOL(); 18904640cde1SColin Riley } 18914640cde1SColin Riley strm.EOL(); 18924640cde1SColin Riley } 18934640cde1SColin Riley else 18944640cde1SColin Riley { 18954640cde1SColin Riley strm.Printf("Runtime is not hooked."); 18964640cde1SColin Riley strm.EOL(); 18974640cde1SColin Riley } 18984640cde1SColin Riley } 18994640cde1SColin Riley 19004640cde1SColin Riley void 19014640cde1SColin Riley RenderScriptRuntime::DumpContexts(Stream &strm) const 19024640cde1SColin Riley { 19034640cde1SColin Riley strm.Printf("Inferred RenderScript Contexts:"); 19044640cde1SColin Riley strm.EOL(); 19054640cde1SColin Riley strm.IndentMore(); 19064640cde1SColin Riley 19074640cde1SColin Riley std::map<addr_t, uint64_t> contextReferences; 19084640cde1SColin Riley 190978f339d1SEwan Crawford // Iterate over all of the currently discovered scripts. 191078f339d1SEwan Crawford // Note: We cant push or pop from m_scripts inside this loop or it may invalidate script. 19114640cde1SColin Riley for (const auto & script : m_scripts) 19124640cde1SColin Riley { 191378f339d1SEwan Crawford if (!script->context.isValid()) 191478f339d1SEwan Crawford continue; 191578f339d1SEwan Crawford lldb::addr_t context = *script->context; 191678f339d1SEwan Crawford 191778f339d1SEwan Crawford if (contextReferences.find(context) != contextReferences.end()) 19184640cde1SColin Riley { 191978f339d1SEwan Crawford contextReferences[context]++; 19204640cde1SColin Riley } 19214640cde1SColin Riley else 19224640cde1SColin Riley { 192378f339d1SEwan Crawford contextReferences[context] = 1; 19244640cde1SColin Riley } 19254640cde1SColin Riley } 19264640cde1SColin Riley 19274640cde1SColin Riley for (const auto& cRef : contextReferences) 19284640cde1SColin Riley { 19294640cde1SColin Riley strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second); 19304640cde1SColin Riley strm.EOL(); 19314640cde1SColin Riley } 19324640cde1SColin Riley strm.IndentLess(); 19334640cde1SColin Riley } 19344640cde1SColin Riley 19354640cde1SColin Riley void 19364640cde1SColin Riley RenderScriptRuntime::DumpKernels(Stream &strm) const 19374640cde1SColin Riley { 19384640cde1SColin Riley strm.Printf("RenderScript Kernels:"); 19394640cde1SColin Riley strm.EOL(); 19404640cde1SColin Riley strm.IndentMore(); 19414640cde1SColin Riley for (const auto &module : m_rsmodules) 19424640cde1SColin Riley { 19434640cde1SColin Riley strm.Printf("Resource '%s':",module->m_resname.c_str()); 19444640cde1SColin Riley strm.EOL(); 19454640cde1SColin Riley for (const auto &kernel : module->m_kernels) 19464640cde1SColin Riley { 19474640cde1SColin Riley strm.Indent(kernel.m_name.AsCString()); 19484640cde1SColin Riley strm.EOL(); 19494640cde1SColin Riley } 19504640cde1SColin Riley } 19514640cde1SColin Riley strm.IndentLess(); 19524640cde1SColin Riley } 19534640cde1SColin Riley 1954a0f08674SEwan Crawford RenderScriptRuntime::AllocationDetails* 1955a0f08674SEwan Crawford RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id) 1956a0f08674SEwan Crawford { 1957a0f08674SEwan Crawford AllocationDetails* alloc = nullptr; 1958a0f08674SEwan Crawford 1959a0f08674SEwan Crawford // See if we can find allocation using id as an index; 1960a0f08674SEwan Crawford if (alloc_id <= m_allocations.size() && alloc_id != 0 1961a0f08674SEwan Crawford && m_allocations[alloc_id-1]->id == alloc_id) 1962a0f08674SEwan Crawford { 1963a0f08674SEwan Crawford alloc = m_allocations[alloc_id-1].get(); 1964a0f08674SEwan Crawford return alloc; 1965a0f08674SEwan Crawford } 1966a0f08674SEwan Crawford 1967a0f08674SEwan Crawford // Fallback to searching 1968a0f08674SEwan Crawford for (const auto & a : m_allocations) 1969a0f08674SEwan Crawford { 1970a0f08674SEwan Crawford if (a->id == alloc_id) 1971a0f08674SEwan Crawford { 1972a0f08674SEwan Crawford alloc = a.get(); 1973a0f08674SEwan Crawford break; 1974a0f08674SEwan Crawford } 1975a0f08674SEwan Crawford } 1976a0f08674SEwan Crawford 1977a0f08674SEwan Crawford if (alloc == nullptr) 1978a0f08674SEwan Crawford { 1979a0f08674SEwan Crawford strm.Printf("Error: Couldn't find allocation with id matching %u", alloc_id); 1980a0f08674SEwan Crawford strm.EOL(); 1981a0f08674SEwan Crawford } 1982a0f08674SEwan Crawford 1983a0f08674SEwan Crawford return alloc; 1984a0f08674SEwan Crawford } 1985a0f08674SEwan Crawford 1986a0f08674SEwan Crawford // Prints the contents of an allocation to the output stream, which may be a file 1987a0f08674SEwan Crawford bool 1988a0f08674SEwan Crawford RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const uint32_t id) 1989a0f08674SEwan Crawford { 1990a0f08674SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1991a0f08674SEwan Crawford 1992a0f08674SEwan Crawford // Check we can find the desired allocation 1993a0f08674SEwan Crawford AllocationDetails* alloc = FindAllocByID(strm, id); 1994a0f08674SEwan Crawford if (!alloc) 1995a0f08674SEwan Crawford return false; // FindAllocByID() will print error message for us here 1996a0f08674SEwan Crawford 1997a0f08674SEwan Crawford if (log) 1998a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::DumpAllocation - Found allocation 0x%" PRIx64, *alloc->address.get()); 1999a0f08674SEwan Crawford 2000a0f08674SEwan Crawford // Check we have information about the allocation, if not calculate it 2001a0f08674SEwan Crawford if (!alloc->data_ptr.isValid() || !alloc->type.isValid() || 2002a0f08674SEwan Crawford !alloc->type_vec_size.isValid() || !alloc->dimension.isValid()) 2003a0f08674SEwan Crawford { 2004a0f08674SEwan Crawford if (log) 2005a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::DumpAllocation - Allocation details not calculated yet, jitting info"); 2006a0f08674SEwan Crawford 2007a0f08674SEwan Crawford // JIT all the allocation information 2008a0f08674SEwan Crawford if (!RefreshAllocation(alloc, frame_ptr)) 2009a0f08674SEwan Crawford { 2010a0f08674SEwan Crawford strm.Printf("Error: Couldn't JIT allocation details"); 2011a0f08674SEwan Crawford strm.EOL(); 2012a0f08674SEwan Crawford return false; 2013a0f08674SEwan Crawford } 2014a0f08674SEwan Crawford } 2015a0f08674SEwan Crawford 2016a0f08674SEwan Crawford // Establish format and size of each data element 2017a0f08674SEwan Crawford const unsigned int vec_size = *alloc->type_vec_size.get(); 2018a0f08674SEwan Crawford const AllocationDetails::DataType type = *alloc->type.get(); 2019a0f08674SEwan Crawford 2020a0f08674SEwan Crawford assert(type >= AllocationDetails::RS_TYPE_NONE && type <= AllocationDetails::RS_TYPE_BOOLEAN 2021a0f08674SEwan Crawford && "Invalid allocation type"); 2022a0f08674SEwan Crawford 2023a0f08674SEwan Crawford lldb::Format format = vec_size == 1 ? static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatSingle]) 2024a0f08674SEwan Crawford : static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatVector]); 2025a0f08674SEwan Crawford 2026a0f08674SEwan Crawford const unsigned int data_size = vec_size * AllocationDetails::RSTypeToFormat[type][eElementSize]; 2027a0f08674SEwan Crawford // Renderscript pads vector 3 elements to vector 4 2028a0f08674SEwan Crawford const unsigned int elem_padding = vec_size == 3 ? AllocationDetails::RSTypeToFormat[type][eElementSize] : 0; 2029a0f08674SEwan Crawford 2030a0f08674SEwan Crawford if (log) 2031a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::DumpAllocation - Element size %u bytes, element padding %u bytes", 2032a0f08674SEwan Crawford data_size, elem_padding); 2033a0f08674SEwan Crawford 2034*55232f09SEwan Crawford // Allocate a buffer to copy data into 2035*55232f09SEwan Crawford std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr); 2036*55232f09SEwan Crawford if (!buffer) 2037*55232f09SEwan Crawford { 2038*55232f09SEwan Crawford strm.Printf("Error: Couldn't allocate a read allocation data into memory"); 2039*55232f09SEwan Crawford strm.EOL(); 2040*55232f09SEwan Crawford return false; 2041*55232f09SEwan Crawford } 2042*55232f09SEwan Crawford 2043a0f08674SEwan Crawford // Calculate stride between rows as there may be padding at end of rows since 2044a0f08674SEwan Crawford // allocated memory is 16-byte aligned 2045a0f08674SEwan Crawford if (!alloc->stride.isValid()) 2046a0f08674SEwan Crawford { 2047a0f08674SEwan Crawford if (alloc->dimension.get()->dim_2 == 0) // We only have one dimension 2048a0f08674SEwan Crawford alloc->stride = 0; 2049a0f08674SEwan Crawford else if (!JITAllocationStride(alloc, frame_ptr)) 2050a0f08674SEwan Crawford { 2051a0f08674SEwan Crawford strm.Printf("Error: Couldn't calculate allocation row stride"); 2052a0f08674SEwan Crawford strm.EOL(); 2053a0f08674SEwan Crawford return false; 2054a0f08674SEwan Crawford } 2055a0f08674SEwan Crawford } 2056a0f08674SEwan Crawford const unsigned int stride = *alloc->stride.get(); 2057a0f08674SEwan Crawford const unsigned int size = *alloc->size.get(); //size of last element 2058a0f08674SEwan Crawford 2059a0f08674SEwan Crawford if (log) 2060a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::DumpAllocation - stride %u bytes, size %u bytes", stride, size); 2061a0f08674SEwan Crawford 2062a0f08674SEwan Crawford // Find dimensions used to index loops, so need to be non-zero 2063a0f08674SEwan Crawford unsigned int dim_x = alloc->dimension.get()->dim_1; 2064a0f08674SEwan Crawford dim_x = dim_x == 0 ? 1 : dim_x; 2065a0f08674SEwan Crawford 2066a0f08674SEwan Crawford unsigned int dim_y = alloc->dimension.get()->dim_2; 2067a0f08674SEwan Crawford dim_y = dim_y == 0 ? 1 : dim_y; 2068a0f08674SEwan Crawford 2069a0f08674SEwan Crawford unsigned int dim_z = alloc->dimension.get()->dim_3; 2070a0f08674SEwan Crawford dim_z = dim_z == 0 ? 1 : dim_z; 2071a0f08674SEwan Crawford 2072*55232f09SEwan Crawford // Use data extractor to format output 2073*55232f09SEwan Crawford const uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize(); 2074*55232f09SEwan Crawford DataExtractor alloc_data(buffer.get(), size, GetProcess()->GetByteOrder(), archByteSize); 2075*55232f09SEwan Crawford 2076a0f08674SEwan Crawford unsigned int offset = 0; // Offset in buffer to next element to be printed 2077a0f08674SEwan Crawford unsigned int prev_row = 0; // Offset to the start of the previous row 2078a0f08674SEwan Crawford 2079a0f08674SEwan Crawford // Iterate over allocation dimensions, printing results to user 2080a0f08674SEwan Crawford strm.Printf("Data (X, Y, Z):"); 2081a0f08674SEwan Crawford for (unsigned int z = 0; z < dim_z; ++z) 2082a0f08674SEwan Crawford { 2083a0f08674SEwan Crawford for (unsigned int y = 0; y < dim_y; ++y) 2084a0f08674SEwan Crawford { 2085a0f08674SEwan Crawford // Use stride to index start of next row. 2086a0f08674SEwan Crawford if (!(y==0 && z==0)) 2087a0f08674SEwan Crawford offset = prev_row + stride; 2088a0f08674SEwan Crawford prev_row = offset; 2089a0f08674SEwan Crawford 2090a0f08674SEwan Crawford // Print each element in the row individually 2091a0f08674SEwan Crawford for (unsigned int x = 0; x < dim_x; ++x) 2092a0f08674SEwan Crawford { 2093a0f08674SEwan Crawford strm.Printf("\n(%u, %u, %u) = ", x, y, z); 2094a0f08674SEwan Crawford alloc_data.Dump(&strm, offset, format, data_size, 1, 1, LLDB_INVALID_ADDRESS, 0, 0); 2095a0f08674SEwan Crawford offset += data_size + elem_padding; 2096a0f08674SEwan Crawford } 2097a0f08674SEwan Crawford } 2098a0f08674SEwan Crawford } 2099a0f08674SEwan Crawford strm.EOL(); 2100a0f08674SEwan Crawford 2101a0f08674SEwan Crawford return true; 2102a0f08674SEwan Crawford } 2103a0f08674SEwan Crawford 210415f2bd95SEwan Crawford // Prints infomation regarding all the currently loaded allocations. 210515f2bd95SEwan Crawford // These details are gathered by jitting the runtime, which has as latency. 210615f2bd95SEwan Crawford void 210715f2bd95SEwan Crawford RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute) 210815f2bd95SEwan Crawford { 210915f2bd95SEwan Crawford strm.Printf("RenderScript Allocations:"); 211015f2bd95SEwan Crawford strm.EOL(); 211115f2bd95SEwan Crawford strm.IndentMore(); 211215f2bd95SEwan Crawford 211315f2bd95SEwan Crawford for (auto &alloc : m_allocations) 211415f2bd95SEwan Crawford { 211515f2bd95SEwan Crawford // JIT the allocation info if we haven't done it, or the user forces us to. 211615f2bd95SEwan Crawford bool do_refresh = !alloc->data_ptr.isValid() || recompute; 211715f2bd95SEwan Crawford 211815f2bd95SEwan Crawford // JIT current allocation information 211915f2bd95SEwan Crawford if (do_refresh && !RefreshAllocation(alloc.get(), frame_ptr)) 212015f2bd95SEwan Crawford { 212115f2bd95SEwan Crawford strm.Printf("Error: Couldn't evaluate details for allocation %u\n", alloc->id); 212215f2bd95SEwan Crawford continue; 212315f2bd95SEwan Crawford } 212415f2bd95SEwan Crawford 212515f2bd95SEwan Crawford strm.Printf("%u:\n",alloc->id); 212615f2bd95SEwan Crawford strm.IndentMore(); 212715f2bd95SEwan Crawford 212815f2bd95SEwan Crawford strm.Indent("Context: "); 212915f2bd95SEwan Crawford if (!alloc->context.isValid()) 213015f2bd95SEwan Crawford strm.Printf("unknown\n"); 213115f2bd95SEwan Crawford else 213215f2bd95SEwan Crawford strm.Printf("0x%" PRIx64 "\n", *alloc->context.get()); 213315f2bd95SEwan Crawford 213415f2bd95SEwan Crawford strm.Indent("Address: "); 213515f2bd95SEwan Crawford if (!alloc->address.isValid()) 213615f2bd95SEwan Crawford strm.Printf("unknown\n"); 213715f2bd95SEwan Crawford else 213815f2bd95SEwan Crawford strm.Printf("0x%" PRIx64 "\n", *alloc->address.get()); 213915f2bd95SEwan Crawford 214015f2bd95SEwan Crawford strm.Indent("Data pointer: "); 214115f2bd95SEwan Crawford if (!alloc->data_ptr.isValid()) 214215f2bd95SEwan Crawford strm.Printf("unknown\n"); 214315f2bd95SEwan Crawford else 214415f2bd95SEwan Crawford strm.Printf("0x%" PRIx64 "\n", *alloc->data_ptr.get()); 214515f2bd95SEwan Crawford 214615f2bd95SEwan Crawford strm.Indent("Dimensions: "); 214715f2bd95SEwan Crawford if (!alloc->dimension.isValid()) 214815f2bd95SEwan Crawford strm.Printf("unknown\n"); 214915f2bd95SEwan Crawford else 215015f2bd95SEwan Crawford strm.Printf("(%d, %d, %d)\n", alloc->dimension.get()->dim_1, 215115f2bd95SEwan Crawford alloc->dimension.get()->dim_2, 215215f2bd95SEwan Crawford alloc->dimension.get()->dim_3); 215315f2bd95SEwan Crawford 215415f2bd95SEwan Crawford strm.Indent("Data Type: "); 215515f2bd95SEwan Crawford if (!alloc->type.isValid() || !alloc->type_vec_size.isValid()) 215615f2bd95SEwan Crawford strm.Printf("unknown\n"); 215715f2bd95SEwan Crawford else 215815f2bd95SEwan Crawford { 215915f2bd95SEwan Crawford const int vector_size = *alloc->type_vec_size.get(); 216015f2bd95SEwan Crawford const AllocationDetails::DataType type = *alloc->type.get(); 216115f2bd95SEwan Crawford 216215f2bd95SEwan Crawford if (vector_size > 4 || vector_size < 1 || 216315f2bd95SEwan Crawford type < AllocationDetails::RS_TYPE_NONE || type > AllocationDetails::RS_TYPE_BOOLEAN) 216415f2bd95SEwan Crawford strm.Printf("invalid type\n"); 216515f2bd95SEwan Crawford else 216615f2bd95SEwan Crawford strm.Printf("%s\n", AllocationDetails::RsDataTypeToString[static_cast<unsigned int>(type)][vector_size-1]); 216715f2bd95SEwan Crawford } 216815f2bd95SEwan Crawford 216915f2bd95SEwan Crawford strm.Indent("Data Kind: "); 217015f2bd95SEwan Crawford if (!alloc->type_kind.isValid()) 217115f2bd95SEwan Crawford strm.Printf("unknown\n"); 217215f2bd95SEwan Crawford else 217315f2bd95SEwan Crawford { 217415f2bd95SEwan Crawford const AllocationDetails::DataKind kind = *alloc->type_kind.get(); 217515f2bd95SEwan Crawford if (kind < AllocationDetails::RS_KIND_USER || kind > AllocationDetails::RS_KIND_PIXEL_YUV) 217615f2bd95SEwan Crawford strm.Printf("invalid kind\n"); 217715f2bd95SEwan Crawford else 217815f2bd95SEwan Crawford strm.Printf("%s\n", AllocationDetails::RsDataKindToString[static_cast<unsigned int>(kind)]); 217915f2bd95SEwan Crawford } 218015f2bd95SEwan Crawford 218115f2bd95SEwan Crawford strm.EOL(); 218215f2bd95SEwan Crawford strm.IndentLess(); 218315f2bd95SEwan Crawford } 218415f2bd95SEwan Crawford strm.IndentLess(); 218515f2bd95SEwan Crawford } 218615f2bd95SEwan Crawford 21877dc7771cSEwan Crawford // Set breakpoints on every kernel found in RS module 21887dc7771cSEwan Crawford void 21897dc7771cSEwan Crawford RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp) 21907dc7771cSEwan Crawford { 21917dc7771cSEwan Crawford for (const auto &kernel : rsmodule_sp->m_kernels) 21927dc7771cSEwan Crawford { 21937dc7771cSEwan Crawford // Don't set breakpoint on 'root' kernel 21947dc7771cSEwan Crawford if (strcmp(kernel.m_name.AsCString(), "root") == 0) 21957dc7771cSEwan Crawford continue; 21967dc7771cSEwan Crawford 21977dc7771cSEwan Crawford CreateKernelBreakpoint(kernel.m_name); 21987dc7771cSEwan Crawford } 21997dc7771cSEwan Crawford } 22007dc7771cSEwan Crawford 22017dc7771cSEwan Crawford // Method is internally called by the 'kernel breakpoint all' command to 22027dc7771cSEwan Crawford // enable or disable breaking on all kernels. 22037dc7771cSEwan Crawford // 22047dc7771cSEwan Crawford // When do_break is true we want to enable this functionality. 22057dc7771cSEwan Crawford // When do_break is false we want to disable it. 22067dc7771cSEwan Crawford void 22077dc7771cSEwan Crawford RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target) 22087dc7771cSEwan Crawford { 220954782db7SEwan Crawford Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); 22107dc7771cSEwan Crawford 22117dc7771cSEwan Crawford InitSearchFilter(target); 22127dc7771cSEwan Crawford 22137dc7771cSEwan Crawford // Set breakpoints on all the kernels 22147dc7771cSEwan Crawford if (do_break && !m_breakAllKernels) 22157dc7771cSEwan Crawford { 22167dc7771cSEwan Crawford m_breakAllKernels = true; 22177dc7771cSEwan Crawford 22187dc7771cSEwan Crawford for (const auto &module : m_rsmodules) 22197dc7771cSEwan Crawford BreakOnModuleKernels(module); 22207dc7771cSEwan Crawford 22217dc7771cSEwan Crawford if (log) 22227dc7771cSEwan Crawford log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)" 22237dc7771cSEwan Crawford "- breakpoints set on all currently loaded kernels"); 22247dc7771cSEwan Crawford } 22257dc7771cSEwan Crawford else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels. 22267dc7771cSEwan Crawford { 22277dc7771cSEwan Crawford m_breakAllKernels = false; 22287dc7771cSEwan Crawford 22297dc7771cSEwan Crawford if (log) 22307dc7771cSEwan Crawford log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set"); 22317dc7771cSEwan Crawford } 22327dc7771cSEwan Crawford } 22337dc7771cSEwan Crawford 22347dc7771cSEwan Crawford // Given the name of a kernel this function creates a breakpoint using our 22357dc7771cSEwan Crawford // own breakpoint resolver, and returns the Breakpoint shared pointer. 22367dc7771cSEwan Crawford BreakpointSP 22377dc7771cSEwan Crawford RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name) 22387dc7771cSEwan Crawford { 223954782db7SEwan Crawford Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); 22407dc7771cSEwan Crawford 22417dc7771cSEwan Crawford if (!m_filtersp) 22427dc7771cSEwan Crawford { 22437dc7771cSEwan Crawford if (log) 22447dc7771cSEwan Crawford log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set"); 22457dc7771cSEwan Crawford return nullptr; 22467dc7771cSEwan Crawford } 22477dc7771cSEwan Crawford 22487dc7771cSEwan Crawford BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name)); 22497dc7771cSEwan Crawford BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false); 22507dc7771cSEwan Crawford 225154782db7SEwan Crawford // Give RS breakpoints a specific name, so the user can manipulate them as a group. 225254782db7SEwan Crawford Error err; 225354782db7SEwan Crawford if (!bp->AddName("RenderScriptKernel", err) && log) 225454782db7SEwan Crawford log->Printf("RenderScriptRuntime::CreateKernelBreakpoint: Error setting break name, %s", err.AsCString()); 225554782db7SEwan Crawford 22567dc7771cSEwan Crawford return bp; 22577dc7771cSEwan Crawford } 22587dc7771cSEwan Crawford 22594640cde1SColin Riley void 226098156583SEwan Crawford RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target) 22614640cde1SColin Riley { 22624640cde1SColin Riley if (!name) 22634640cde1SColin Riley { 22644640cde1SColin Riley error.SetErrorString("invalid kernel name"); 22654640cde1SColin Riley return; 22664640cde1SColin Riley } 22674640cde1SColin Riley 22687dc7771cSEwan Crawford InitSearchFilter(target); 226998156583SEwan Crawford 22704640cde1SColin Riley ConstString kernel_name(name); 22717dc7771cSEwan Crawford BreakpointSP bp = CreateKernelBreakpoint(kernel_name); 227298156583SEwan Crawford if (bp) 227398156583SEwan Crawford bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false); 22744640cde1SColin Riley 22754640cde1SColin Riley return; 22764640cde1SColin Riley } 22774640cde1SColin Riley 22784640cde1SColin Riley void 22795ec532a9SColin Riley RenderScriptRuntime::DumpModules(Stream &strm) const 22805ec532a9SColin Riley { 22815ec532a9SColin Riley strm.Printf("RenderScript Modules:"); 22825ec532a9SColin Riley strm.EOL(); 22835ec532a9SColin Riley strm.IndentMore(); 22845ec532a9SColin Riley for (const auto &module : m_rsmodules) 22855ec532a9SColin Riley { 22864640cde1SColin Riley module->Dump(strm); 22875ec532a9SColin Riley } 22885ec532a9SColin Riley strm.IndentLess(); 22895ec532a9SColin Riley } 22905ec532a9SColin Riley 229178f339d1SEwan Crawford RenderScriptRuntime::ScriptDetails* 229278f339d1SEwan Crawford RenderScriptRuntime::LookUpScript(addr_t address, bool create) 229378f339d1SEwan Crawford { 229478f339d1SEwan Crawford for (const auto & s : m_scripts) 229578f339d1SEwan Crawford { 229678f339d1SEwan Crawford if (s->script.isValid()) 229778f339d1SEwan Crawford if (*s->script == address) 229878f339d1SEwan Crawford return s.get(); 229978f339d1SEwan Crawford } 230078f339d1SEwan Crawford if (create) 230178f339d1SEwan Crawford { 230278f339d1SEwan Crawford std::unique_ptr<ScriptDetails> s(new ScriptDetails); 230378f339d1SEwan Crawford s->script = address; 230478f339d1SEwan Crawford m_scripts.push_back(std::move(s)); 2305d10ca9deSEwan Crawford return m_scripts.back().get(); 230678f339d1SEwan Crawford } 230778f339d1SEwan Crawford return nullptr; 230878f339d1SEwan Crawford } 230978f339d1SEwan Crawford 231078f339d1SEwan Crawford RenderScriptRuntime::AllocationDetails* 231178f339d1SEwan Crawford RenderScriptRuntime::LookUpAllocation(addr_t address, bool create) 231278f339d1SEwan Crawford { 231378f339d1SEwan Crawford for (const auto & a : m_allocations) 231478f339d1SEwan Crawford { 231578f339d1SEwan Crawford if (a->address.isValid()) 231678f339d1SEwan Crawford if (*a->address == address) 231778f339d1SEwan Crawford return a.get(); 231878f339d1SEwan Crawford } 231978f339d1SEwan Crawford if (create) 232078f339d1SEwan Crawford { 232178f339d1SEwan Crawford std::unique_ptr<AllocationDetails> a(new AllocationDetails); 232278f339d1SEwan Crawford a->address = address; 232378f339d1SEwan Crawford m_allocations.push_back(std::move(a)); 2324d10ca9deSEwan Crawford return m_allocations.back().get(); 232578f339d1SEwan Crawford } 232678f339d1SEwan Crawford return nullptr; 232778f339d1SEwan Crawford } 232878f339d1SEwan Crawford 23295ec532a9SColin Riley void 23305ec532a9SColin Riley RSModuleDescriptor::Dump(Stream &strm) const 23315ec532a9SColin Riley { 23325ec532a9SColin Riley strm.Indent(); 23335ec532a9SColin Riley m_module->GetFileSpec().Dump(&strm); 23344640cde1SColin Riley if(m_module->GetNumCompileUnits()) 23354640cde1SColin Riley { 23364640cde1SColin Riley strm.Indent("Debug info loaded."); 23374640cde1SColin Riley } 23384640cde1SColin Riley else 23394640cde1SColin Riley { 23404640cde1SColin Riley strm.Indent("Debug info does not exist."); 23414640cde1SColin Riley } 23425ec532a9SColin Riley strm.EOL(); 23435ec532a9SColin Riley strm.IndentMore(); 23445ec532a9SColin Riley strm.Indent(); 2345189598edSColin Riley strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size())); 23465ec532a9SColin Riley strm.EOL(); 23475ec532a9SColin Riley strm.IndentMore(); 23485ec532a9SColin Riley for (const auto &global : m_globals) 23495ec532a9SColin Riley { 23505ec532a9SColin Riley global.Dump(strm); 23515ec532a9SColin Riley } 23525ec532a9SColin Riley strm.IndentLess(); 23535ec532a9SColin Riley strm.Indent(); 2354189598edSColin Riley strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size())); 23555ec532a9SColin Riley strm.EOL(); 23565ec532a9SColin Riley strm.IndentMore(); 23575ec532a9SColin Riley for (const auto &kernel : m_kernels) 23585ec532a9SColin Riley { 23595ec532a9SColin Riley kernel.Dump(strm); 23605ec532a9SColin Riley } 23614640cde1SColin Riley strm.Printf("Pragmas: %" PRIu64 , static_cast<uint64_t>(m_pragmas.size())); 23624640cde1SColin Riley strm.EOL(); 23634640cde1SColin Riley strm.IndentMore(); 23644640cde1SColin Riley for (const auto &key_val : m_pragmas) 23654640cde1SColin Riley { 23664640cde1SColin Riley strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str()); 23674640cde1SColin Riley strm.EOL(); 23684640cde1SColin Riley } 23695ec532a9SColin Riley strm.IndentLess(4); 23705ec532a9SColin Riley } 23715ec532a9SColin Riley 23725ec532a9SColin Riley void 23735ec532a9SColin Riley RSGlobalDescriptor::Dump(Stream &strm) const 23745ec532a9SColin Riley { 23755ec532a9SColin Riley strm.Indent(m_name.AsCString()); 23764640cde1SColin Riley VariableList var_list; 23774640cde1SColin Riley m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list); 23784640cde1SColin Riley if (var_list.GetSize() == 1) 23794640cde1SColin Riley { 23804640cde1SColin Riley auto var = var_list.GetVariableAtIndex(0); 23814640cde1SColin Riley auto type = var->GetType(); 23824640cde1SColin Riley if(type) 23834640cde1SColin Riley { 23844640cde1SColin Riley strm.Printf(" - "); 23854640cde1SColin Riley type->DumpTypeName(&strm); 23864640cde1SColin Riley } 23874640cde1SColin Riley else 23884640cde1SColin Riley { 23894640cde1SColin Riley strm.Printf(" - Unknown Type"); 23904640cde1SColin Riley } 23914640cde1SColin Riley } 23924640cde1SColin Riley else 23934640cde1SColin Riley { 23944640cde1SColin Riley strm.Printf(" - variable identified, but not found in binary"); 23954640cde1SColin Riley const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData); 23964640cde1SColin Riley if (s) 23974640cde1SColin Riley { 23984640cde1SColin Riley strm.Printf(" (symbol exists) "); 23994640cde1SColin Riley } 24004640cde1SColin Riley } 24014640cde1SColin Riley 24025ec532a9SColin Riley strm.EOL(); 24035ec532a9SColin Riley } 24045ec532a9SColin Riley 24055ec532a9SColin Riley void 24065ec532a9SColin Riley RSKernelDescriptor::Dump(Stream &strm) const 24075ec532a9SColin Riley { 24085ec532a9SColin Riley strm.Indent(m_name.AsCString()); 24095ec532a9SColin Riley strm.EOL(); 24105ec532a9SColin Riley } 24115ec532a9SColin Riley 24125ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed 24135ec532a9SColin Riley { 24145ec532a9SColin Riley private: 24155ec532a9SColin Riley public: 24165ec532a9SColin Riley CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter) 24175ec532a9SColin Riley : CommandObjectParsed(interpreter, "renderscript module probe", 24185ec532a9SColin Riley "Initiates a Probe of all loaded modules for kernels and other renderscript objects.", 24195ec532a9SColin Riley "renderscript module probe", 2420e87764f2SEnrico Granata eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched) 24215ec532a9SColin Riley { 24225ec532a9SColin Riley } 24235ec532a9SColin Riley 24245ec532a9SColin Riley ~CommandObjectRenderScriptRuntimeModuleProbe() {} 24255ec532a9SColin Riley 24265ec532a9SColin Riley bool 24275ec532a9SColin Riley DoExecute(Args &command, CommandReturnObject &result) 24285ec532a9SColin Riley { 24295ec532a9SColin Riley const size_t argc = command.GetArgumentCount(); 24305ec532a9SColin Riley if (argc == 0) 24315ec532a9SColin Riley { 24325ec532a9SColin Riley Target *target = m_exe_ctx.GetTargetPtr(); 24335ec532a9SColin Riley RenderScriptRuntime *runtime = 24345ec532a9SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 24355ec532a9SColin Riley auto module_list = target->GetImages(); 24365ec532a9SColin Riley bool new_rs_details = runtime->ProbeModules(module_list); 24375ec532a9SColin Riley if (new_rs_details) 24385ec532a9SColin Riley { 24395ec532a9SColin Riley result.AppendMessage("New renderscript modules added to runtime model."); 24405ec532a9SColin Riley } 24415ec532a9SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 24425ec532a9SColin Riley return true; 24435ec532a9SColin Riley } 24445ec532a9SColin Riley 24455ec532a9SColin Riley result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str()); 24465ec532a9SColin Riley result.SetStatus(eReturnStatusFailed); 24475ec532a9SColin Riley return false; 24485ec532a9SColin Riley } 24495ec532a9SColin Riley }; 24505ec532a9SColin Riley 24515ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed 24525ec532a9SColin Riley { 24535ec532a9SColin Riley private: 24545ec532a9SColin Riley public: 24555ec532a9SColin Riley CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter) 24565ec532a9SColin Riley : CommandObjectParsed(interpreter, "renderscript module dump", 24575ec532a9SColin Riley "Dumps renderscript specific information for all modules.", "renderscript module dump", 2458e87764f2SEnrico Granata eCommandRequiresProcess | eCommandProcessMustBeLaunched) 24595ec532a9SColin Riley { 24605ec532a9SColin Riley } 24615ec532a9SColin Riley 24625ec532a9SColin Riley ~CommandObjectRenderScriptRuntimeModuleDump() {} 24635ec532a9SColin Riley 24645ec532a9SColin Riley bool 24655ec532a9SColin Riley DoExecute(Args &command, CommandReturnObject &result) 24665ec532a9SColin Riley { 24675ec532a9SColin Riley RenderScriptRuntime *runtime = 24685ec532a9SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 24695ec532a9SColin Riley runtime->DumpModules(result.GetOutputStream()); 24705ec532a9SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 24715ec532a9SColin Riley return true; 24725ec532a9SColin Riley } 24735ec532a9SColin Riley }; 24745ec532a9SColin Riley 24755ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword 24765ec532a9SColin Riley { 24775ec532a9SColin Riley private: 24785ec532a9SColin Riley public: 24795ec532a9SColin Riley CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter) 24805ec532a9SColin Riley : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.", 24815ec532a9SColin Riley NULL) 24825ec532a9SColin Riley { 24835ec532a9SColin Riley LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter))); 24845ec532a9SColin Riley LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter))); 24855ec532a9SColin Riley } 24865ec532a9SColin Riley 24875ec532a9SColin Riley ~CommandObjectRenderScriptRuntimeModule() {} 24885ec532a9SColin Riley }; 24895ec532a9SColin Riley 24904640cde1SColin Riley class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed 24914640cde1SColin Riley { 24924640cde1SColin Riley private: 24934640cde1SColin Riley public: 24944640cde1SColin Riley CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter) 24954640cde1SColin Riley : CommandObjectParsed(interpreter, "renderscript kernel list", 24964640cde1SColin Riley "Lists renderscript kernel names and associated script resources.", "renderscript kernel list", 24974640cde1SColin Riley eCommandRequiresProcess | eCommandProcessMustBeLaunched) 24984640cde1SColin Riley { 24994640cde1SColin Riley } 25004640cde1SColin Riley 25014640cde1SColin Riley ~CommandObjectRenderScriptRuntimeKernelList() {} 25024640cde1SColin Riley 25034640cde1SColin Riley bool 25044640cde1SColin Riley DoExecute(Args &command, CommandReturnObject &result) 25054640cde1SColin Riley { 25064640cde1SColin Riley RenderScriptRuntime *runtime = 25074640cde1SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 25084640cde1SColin Riley runtime->DumpKernels(result.GetOutputStream()); 25094640cde1SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 25104640cde1SColin Riley return true; 25114640cde1SColin Riley } 25124640cde1SColin Riley }; 25134640cde1SColin Riley 25147dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed 25154640cde1SColin Riley { 25164640cde1SColin Riley private: 25174640cde1SColin Riley public: 25187dc7771cSEwan Crawford CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter) 25197dc7771cSEwan Crawford : CommandObjectParsed(interpreter, "renderscript kernel breakpoint set", 25207dc7771cSEwan Crawford "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name>", 25214640cde1SColin Riley eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) 25224640cde1SColin Riley { 25234640cde1SColin Riley } 25244640cde1SColin Riley 25257dc7771cSEwan Crawford ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() {} 25264640cde1SColin Riley 25274640cde1SColin Riley bool 25284640cde1SColin Riley DoExecute(Args &command, CommandReturnObject &result) 25294640cde1SColin Riley { 25304640cde1SColin Riley const size_t argc = command.GetArgumentCount(); 25314640cde1SColin Riley if (argc == 1) 25324640cde1SColin Riley { 25334640cde1SColin Riley RenderScriptRuntime *runtime = 25344640cde1SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 25354640cde1SColin Riley 25364640cde1SColin Riley Error error; 253798156583SEwan Crawford runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0), 253898156583SEwan Crawford error, m_exe_ctx.GetTargetSP()); 25394640cde1SColin Riley 25404640cde1SColin Riley if (error.Success()) 25414640cde1SColin Riley { 25424640cde1SColin Riley result.AppendMessage("Breakpoint(s) created"); 25434640cde1SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 25444640cde1SColin Riley return true; 25454640cde1SColin Riley } 25464640cde1SColin Riley result.SetStatus(eReturnStatusFailed); 25474640cde1SColin Riley result.AppendErrorWithFormat("Error: %s", error.AsCString()); 25484640cde1SColin Riley return false; 25494640cde1SColin Riley } 25504640cde1SColin Riley 25514640cde1SColin Riley result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name", m_cmd_name.c_str()); 25524640cde1SColin Riley result.SetStatus(eReturnStatusFailed); 25534640cde1SColin Riley return false; 25544640cde1SColin Riley } 25554640cde1SColin Riley }; 25564640cde1SColin Riley 25577dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed 25587dc7771cSEwan Crawford { 25597dc7771cSEwan Crawford private: 25607dc7771cSEwan Crawford public: 25617dc7771cSEwan Crawford CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter) 25627dc7771cSEwan Crawford : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all", 25637dc7771cSEwan Crawford "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n" 25647dc7771cSEwan Crawford "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, " 25657dc7771cSEwan Crawford "but does not remove currently set breakpoints.", 25667dc7771cSEwan Crawford "renderscript kernel breakpoint all <enable/disable>", 25677dc7771cSEwan Crawford eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) 25687dc7771cSEwan Crawford { 25697dc7771cSEwan Crawford } 25707dc7771cSEwan Crawford 25717dc7771cSEwan Crawford ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() {} 25727dc7771cSEwan Crawford 25737dc7771cSEwan Crawford bool 25747dc7771cSEwan Crawford DoExecute(Args &command, CommandReturnObject &result) 25757dc7771cSEwan Crawford { 25767dc7771cSEwan Crawford const size_t argc = command.GetArgumentCount(); 25777dc7771cSEwan Crawford if (argc != 1) 25787dc7771cSEwan Crawford { 25797dc7771cSEwan Crawford result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str()); 25807dc7771cSEwan Crawford result.SetStatus(eReturnStatusFailed); 25817dc7771cSEwan Crawford return false; 25827dc7771cSEwan Crawford } 25837dc7771cSEwan Crawford 25847dc7771cSEwan Crawford RenderScriptRuntime *runtime = 25857dc7771cSEwan Crawford static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 25867dc7771cSEwan Crawford 25877dc7771cSEwan Crawford bool do_break = false; 25887dc7771cSEwan Crawford const char* argument = command.GetArgumentAtIndex(0); 25897dc7771cSEwan Crawford if (strcmp(argument, "enable") == 0) 25907dc7771cSEwan Crawford { 25917dc7771cSEwan Crawford do_break = true; 25927dc7771cSEwan Crawford result.AppendMessage("Breakpoints will be set on all kernels."); 25937dc7771cSEwan Crawford } 25947dc7771cSEwan Crawford else if (strcmp(argument, "disable") == 0) 25957dc7771cSEwan Crawford { 25967dc7771cSEwan Crawford do_break = false; 25977dc7771cSEwan Crawford result.AppendMessage("Breakpoints will not be set on any new kernels."); 25987dc7771cSEwan Crawford } 25997dc7771cSEwan Crawford else 26007dc7771cSEwan Crawford { 26017dc7771cSEwan Crawford result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'"); 26027dc7771cSEwan Crawford result.SetStatus(eReturnStatusFailed); 26037dc7771cSEwan Crawford return false; 26047dc7771cSEwan Crawford } 26057dc7771cSEwan Crawford 26067dc7771cSEwan Crawford runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP()); 26077dc7771cSEwan Crawford 26087dc7771cSEwan Crawford result.SetStatus(eReturnStatusSuccessFinishResult); 26097dc7771cSEwan Crawford return true; 26107dc7771cSEwan Crawford } 26117dc7771cSEwan Crawford }; 26127dc7771cSEwan Crawford 26137dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword 26147dc7771cSEwan Crawford { 26157dc7771cSEwan Crawford private: 26167dc7771cSEwan Crawford public: 26177dc7771cSEwan Crawford CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter) 26187dc7771cSEwan Crawford : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.", 26197dc7771cSEwan Crawford nullptr) 26207dc7771cSEwan Crawford { 26217dc7771cSEwan Crawford LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter))); 26227dc7771cSEwan Crawford LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter))); 26237dc7771cSEwan Crawford } 26247dc7771cSEwan Crawford 26257dc7771cSEwan Crawford ~CommandObjectRenderScriptRuntimeKernelBreakpoint() {} 26267dc7771cSEwan Crawford }; 26277dc7771cSEwan Crawford 26284640cde1SColin Riley class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword 26294640cde1SColin Riley { 26304640cde1SColin Riley private: 26314640cde1SColin Riley public: 26324640cde1SColin Riley CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter) 26334640cde1SColin Riley : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.", 26344640cde1SColin Riley NULL) 26354640cde1SColin Riley { 26364640cde1SColin Riley LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter))); 26374640cde1SColin Riley LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter))); 26384640cde1SColin Riley } 26394640cde1SColin Riley 26404640cde1SColin Riley ~CommandObjectRenderScriptRuntimeKernel() {} 26414640cde1SColin Riley }; 26424640cde1SColin Riley 26434640cde1SColin Riley class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed 26444640cde1SColin Riley { 26454640cde1SColin Riley private: 26464640cde1SColin Riley public: 26474640cde1SColin Riley CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter) 26484640cde1SColin Riley : CommandObjectParsed(interpreter, "renderscript context dump", 26494640cde1SColin Riley "Dumps renderscript context information.", "renderscript context dump", 26504640cde1SColin Riley eCommandRequiresProcess | eCommandProcessMustBeLaunched) 26514640cde1SColin Riley { 26524640cde1SColin Riley } 26534640cde1SColin Riley 26544640cde1SColin Riley ~CommandObjectRenderScriptRuntimeContextDump() {} 26554640cde1SColin Riley 26564640cde1SColin Riley bool 26574640cde1SColin Riley DoExecute(Args &command, CommandReturnObject &result) 26584640cde1SColin Riley { 26594640cde1SColin Riley RenderScriptRuntime *runtime = 26604640cde1SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 26614640cde1SColin Riley runtime->DumpContexts(result.GetOutputStream()); 26624640cde1SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 26634640cde1SColin Riley return true; 26644640cde1SColin Riley } 26654640cde1SColin Riley }; 26664640cde1SColin Riley 26674640cde1SColin Riley class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword 26684640cde1SColin Riley { 26694640cde1SColin Riley private: 26704640cde1SColin Riley public: 26714640cde1SColin Riley CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter) 26724640cde1SColin Riley : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.", 26734640cde1SColin Riley NULL) 26744640cde1SColin Riley { 26754640cde1SColin Riley LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter))); 26764640cde1SColin Riley } 26774640cde1SColin Riley 26784640cde1SColin Riley ~CommandObjectRenderScriptRuntimeContext() {} 26794640cde1SColin Riley }; 26804640cde1SColin Riley 2681a0f08674SEwan Crawford 2682a0f08674SEwan Crawford class CommandObjectRenderScriptRuntimeAllocationDump : public CommandObjectParsed 2683a0f08674SEwan Crawford { 2684a0f08674SEwan Crawford private: 2685a0f08674SEwan Crawford public: 2686a0f08674SEwan Crawford CommandObjectRenderScriptRuntimeAllocationDump(CommandInterpreter &interpreter) 2687a0f08674SEwan Crawford : CommandObjectParsed(interpreter, "renderscript allocation dump", 2688a0f08674SEwan Crawford "Displays the contents of a particular allocation", "renderscript allocation dump <ID>", 2689a0f08674SEwan Crawford eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter) 2690a0f08674SEwan Crawford { 2691a0f08674SEwan Crawford } 2692a0f08674SEwan Crawford 2693a0f08674SEwan Crawford virtual Options* 2694a0f08674SEwan Crawford GetOptions() 2695a0f08674SEwan Crawford { 2696a0f08674SEwan Crawford return &m_options; 2697a0f08674SEwan Crawford } 2698a0f08674SEwan Crawford 2699a0f08674SEwan Crawford class CommandOptions : public Options 2700a0f08674SEwan Crawford { 2701a0f08674SEwan Crawford public: 2702a0f08674SEwan Crawford CommandOptions(CommandInterpreter &interpreter) : Options(interpreter) 2703a0f08674SEwan Crawford { 2704a0f08674SEwan Crawford } 2705a0f08674SEwan Crawford 2706a0f08674SEwan Crawford virtual 2707a0f08674SEwan Crawford ~CommandOptions() 2708a0f08674SEwan Crawford { 2709a0f08674SEwan Crawford } 2710a0f08674SEwan Crawford 2711a0f08674SEwan Crawford virtual Error 2712a0f08674SEwan Crawford SetOptionValue(uint32_t option_idx, const char *option_arg) 2713a0f08674SEwan Crawford { 2714a0f08674SEwan Crawford Error error; 2715a0f08674SEwan Crawford const int short_option = m_getopt_table[option_idx].val; 2716a0f08674SEwan Crawford 2717a0f08674SEwan Crawford switch (short_option) 2718a0f08674SEwan Crawford { 2719a0f08674SEwan Crawford case 'f': 2720a0f08674SEwan Crawford m_outfile.SetFile(option_arg, true); 2721a0f08674SEwan Crawford if (m_outfile.Exists()) 2722a0f08674SEwan Crawford { 2723a0f08674SEwan Crawford m_outfile.Clear(); 2724a0f08674SEwan Crawford error.SetErrorStringWithFormat("file already exists: '%s'", option_arg); 2725a0f08674SEwan Crawford } 2726a0f08674SEwan Crawford break; 2727a0f08674SEwan Crawford default: 2728a0f08674SEwan Crawford error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); 2729a0f08674SEwan Crawford break; 2730a0f08674SEwan Crawford } 2731a0f08674SEwan Crawford return error; 2732a0f08674SEwan Crawford } 2733a0f08674SEwan Crawford 2734a0f08674SEwan Crawford void 2735a0f08674SEwan Crawford OptionParsingStarting() 2736a0f08674SEwan Crawford { 2737a0f08674SEwan Crawford m_outfile.Clear(); 2738a0f08674SEwan Crawford } 2739a0f08674SEwan Crawford 2740a0f08674SEwan Crawford const OptionDefinition* 2741a0f08674SEwan Crawford GetDefinitions() 2742a0f08674SEwan Crawford { 2743a0f08674SEwan Crawford return g_option_table; 2744a0f08674SEwan Crawford } 2745a0f08674SEwan Crawford 2746a0f08674SEwan Crawford static OptionDefinition g_option_table[]; 2747a0f08674SEwan Crawford FileSpec m_outfile; 2748a0f08674SEwan Crawford }; 2749a0f08674SEwan Crawford 2750a0f08674SEwan Crawford ~CommandObjectRenderScriptRuntimeAllocationDump() {} 2751a0f08674SEwan Crawford 2752a0f08674SEwan Crawford bool 2753a0f08674SEwan Crawford DoExecute(Args &command, CommandReturnObject &result) 2754a0f08674SEwan Crawford { 2755a0f08674SEwan Crawford const size_t argc = command.GetArgumentCount(); 2756a0f08674SEwan Crawford if (argc < 1) 2757a0f08674SEwan Crawford { 2758a0f08674SEwan Crawford result.AppendErrorWithFormat("'%s' takes 1 argument, an allocation ID. As well as an optional -f argument", 2759a0f08674SEwan Crawford m_cmd_name.c_str()); 2760a0f08674SEwan Crawford result.SetStatus(eReturnStatusFailed); 2761a0f08674SEwan Crawford return false; 2762a0f08674SEwan Crawford } 2763a0f08674SEwan Crawford 2764a0f08674SEwan Crawford RenderScriptRuntime *runtime = 2765a0f08674SEwan Crawford static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 2766a0f08674SEwan Crawford 2767a0f08674SEwan Crawford const char* id_cstr = command.GetArgumentAtIndex(0); 2768a0f08674SEwan Crawford bool convert_complete = false; 2769a0f08674SEwan Crawford const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete); 2770a0f08674SEwan Crawford if (!convert_complete) 2771a0f08674SEwan Crawford { 2772a0f08674SEwan Crawford result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr); 2773a0f08674SEwan Crawford result.SetStatus(eReturnStatusFailed); 2774a0f08674SEwan Crawford return false; 2775a0f08674SEwan Crawford } 2776a0f08674SEwan Crawford 2777a0f08674SEwan Crawford Stream* output_strm = nullptr; 2778a0f08674SEwan Crawford StreamFile outfile_stream; 2779a0f08674SEwan Crawford const FileSpec &outfile_spec = m_options.m_outfile; // Dump allocation to file instead 2780a0f08674SEwan Crawford if (outfile_spec) 2781a0f08674SEwan Crawford { 2782a0f08674SEwan Crawford // Open output file 2783a0f08674SEwan Crawford char path[256]; 2784a0f08674SEwan Crawford outfile_spec.GetPath(path, sizeof(path)); 2785a0f08674SEwan Crawford if (outfile_stream.GetFile().Open(path, File::eOpenOptionWrite | File::eOpenOptionCanCreate).Success()) 2786a0f08674SEwan Crawford { 2787a0f08674SEwan Crawford output_strm = &outfile_stream; 2788a0f08674SEwan Crawford result.GetOutputStream().Printf("Results written to '%s'", path); 2789a0f08674SEwan Crawford result.GetOutputStream().EOL(); 2790a0f08674SEwan Crawford } 2791a0f08674SEwan Crawford else 2792a0f08674SEwan Crawford { 2793a0f08674SEwan Crawford result.AppendErrorWithFormat("Couldn't open file '%s'", path); 2794a0f08674SEwan Crawford result.SetStatus(eReturnStatusFailed); 2795a0f08674SEwan Crawford return false; 2796a0f08674SEwan Crawford } 2797a0f08674SEwan Crawford } 2798a0f08674SEwan Crawford else 2799a0f08674SEwan Crawford output_strm = &result.GetOutputStream(); 2800a0f08674SEwan Crawford 2801a0f08674SEwan Crawford assert(output_strm != nullptr); 2802a0f08674SEwan Crawford bool success = runtime->DumpAllocation(*output_strm, m_exe_ctx.GetFramePtr(), id); 2803a0f08674SEwan Crawford 2804a0f08674SEwan Crawford if (success) 2805a0f08674SEwan Crawford result.SetStatus(eReturnStatusSuccessFinishResult); 2806a0f08674SEwan Crawford else 2807a0f08674SEwan Crawford result.SetStatus(eReturnStatusFailed); 2808a0f08674SEwan Crawford 2809a0f08674SEwan Crawford return true; 2810a0f08674SEwan Crawford } 2811a0f08674SEwan Crawford 2812a0f08674SEwan Crawford private: 2813a0f08674SEwan Crawford CommandOptions m_options; 2814a0f08674SEwan Crawford }; 2815a0f08674SEwan Crawford 2816a0f08674SEwan Crawford OptionDefinition 2817a0f08674SEwan Crawford CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions::g_option_table[] = 2818a0f08674SEwan Crawford { 2819a0f08674SEwan Crawford { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, 2820a0f08674SEwan Crawford "Print results to specified file instead of command line."}, 2821a0f08674SEwan Crawford { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2822a0f08674SEwan Crawford }; 2823a0f08674SEwan Crawford 2824a0f08674SEwan Crawford 282515f2bd95SEwan Crawford class CommandObjectRenderScriptRuntimeAllocationList : public CommandObjectParsed 282615f2bd95SEwan Crawford { 282715f2bd95SEwan Crawford public: 282815f2bd95SEwan Crawford CommandObjectRenderScriptRuntimeAllocationList(CommandInterpreter &interpreter) 282915f2bd95SEwan Crawford : CommandObjectParsed(interpreter, "renderscript allocation list", 283015f2bd95SEwan Crawford "List renderscript allocations and their information.", "renderscript allocation list", 283115f2bd95SEwan Crawford eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter) 283215f2bd95SEwan Crawford { 283315f2bd95SEwan Crawford } 283415f2bd95SEwan Crawford 283515f2bd95SEwan Crawford virtual Options* 283615f2bd95SEwan Crawford GetOptions() 283715f2bd95SEwan Crawford { 283815f2bd95SEwan Crawford return &m_options; 283915f2bd95SEwan Crawford } 284015f2bd95SEwan Crawford 284115f2bd95SEwan Crawford class CommandOptions : public Options 284215f2bd95SEwan Crawford { 284315f2bd95SEwan Crawford public: 284415f2bd95SEwan Crawford CommandOptions(CommandInterpreter &interpreter) : Options(interpreter), m_refresh(false) 284515f2bd95SEwan Crawford { 284615f2bd95SEwan Crawford } 284715f2bd95SEwan Crawford 284815f2bd95SEwan Crawford virtual 284915f2bd95SEwan Crawford ~CommandOptions() 285015f2bd95SEwan Crawford { 285115f2bd95SEwan Crawford } 285215f2bd95SEwan Crawford 285315f2bd95SEwan Crawford virtual Error 285415f2bd95SEwan Crawford SetOptionValue(uint32_t option_idx, const char *option_arg) 285515f2bd95SEwan Crawford { 285615f2bd95SEwan Crawford Error error; 285715f2bd95SEwan Crawford const int short_option = m_getopt_table[option_idx].val; 285815f2bd95SEwan Crawford 285915f2bd95SEwan Crawford switch (short_option) 286015f2bd95SEwan Crawford { 286115f2bd95SEwan Crawford case 'r': 286215f2bd95SEwan Crawford m_refresh = true; 286315f2bd95SEwan Crawford break; 286415f2bd95SEwan Crawford default: 286515f2bd95SEwan Crawford error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); 286615f2bd95SEwan Crawford break; 286715f2bd95SEwan Crawford } 286815f2bd95SEwan Crawford return error; 286915f2bd95SEwan Crawford } 287015f2bd95SEwan Crawford 287115f2bd95SEwan Crawford void 287215f2bd95SEwan Crawford OptionParsingStarting() 287315f2bd95SEwan Crawford { 287415f2bd95SEwan Crawford m_refresh = false; 287515f2bd95SEwan Crawford } 287615f2bd95SEwan Crawford 287715f2bd95SEwan Crawford const OptionDefinition* 287815f2bd95SEwan Crawford GetDefinitions() 287915f2bd95SEwan Crawford { 288015f2bd95SEwan Crawford return g_option_table; 288115f2bd95SEwan Crawford } 288215f2bd95SEwan Crawford 288315f2bd95SEwan Crawford static OptionDefinition g_option_table[]; 288415f2bd95SEwan Crawford bool m_refresh; 288515f2bd95SEwan Crawford }; 288615f2bd95SEwan Crawford 288715f2bd95SEwan Crawford ~CommandObjectRenderScriptRuntimeAllocationList() {} 288815f2bd95SEwan Crawford 288915f2bd95SEwan Crawford bool 289015f2bd95SEwan Crawford DoExecute(Args &command, CommandReturnObject &result) 289115f2bd95SEwan Crawford { 289215f2bd95SEwan Crawford RenderScriptRuntime *runtime = 289315f2bd95SEwan Crawford static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 289415f2bd95SEwan Crawford runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), m_options.m_refresh); 289515f2bd95SEwan Crawford result.SetStatus(eReturnStatusSuccessFinishResult); 289615f2bd95SEwan Crawford return true; 289715f2bd95SEwan Crawford } 289815f2bd95SEwan Crawford 289915f2bd95SEwan Crawford private: 290015f2bd95SEwan Crawford CommandOptions m_options; 290115f2bd95SEwan Crawford }; 290215f2bd95SEwan Crawford 290315f2bd95SEwan Crawford OptionDefinition 290415f2bd95SEwan Crawford CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::g_option_table[] = 290515f2bd95SEwan Crawford { 290615f2bd95SEwan Crawford { LLDB_OPT_SET_1, false, "refresh", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 290715f2bd95SEwan Crawford "Recompute allocation details."}, 290815f2bd95SEwan Crawford { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 290915f2bd95SEwan Crawford }; 291015f2bd95SEwan Crawford 291115f2bd95SEwan Crawford 2912*55232f09SEwan Crawford class CommandObjectRenderScriptRuntimeAllocationLoad : public CommandObjectParsed 2913*55232f09SEwan Crawford { 2914*55232f09SEwan Crawford private: 2915*55232f09SEwan Crawford public: 2916*55232f09SEwan Crawford CommandObjectRenderScriptRuntimeAllocationLoad(CommandInterpreter &interpreter) 2917*55232f09SEwan Crawford : CommandObjectParsed(interpreter, "renderscript allocation load", 2918*55232f09SEwan Crawford "Loads renderscript allocation contents from a file.", "renderscript allocation load <ID> <filename>", 2919*55232f09SEwan Crawford eCommandRequiresProcess | eCommandProcessMustBeLaunched) 2920*55232f09SEwan Crawford { 2921*55232f09SEwan Crawford } 2922*55232f09SEwan Crawford 2923*55232f09SEwan Crawford ~CommandObjectRenderScriptRuntimeAllocationLoad() {} 2924*55232f09SEwan Crawford 2925*55232f09SEwan Crawford bool 2926*55232f09SEwan Crawford DoExecute(Args &command, CommandReturnObject &result) 2927*55232f09SEwan Crawford { 2928*55232f09SEwan Crawford const size_t argc = command.GetArgumentCount(); 2929*55232f09SEwan Crawford if (argc != 2) 2930*55232f09SEwan Crawford { 2931*55232f09SEwan Crawford result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str()); 2932*55232f09SEwan Crawford result.SetStatus(eReturnStatusFailed); 2933*55232f09SEwan Crawford return false; 2934*55232f09SEwan Crawford } 2935*55232f09SEwan Crawford 2936*55232f09SEwan Crawford RenderScriptRuntime *runtime = 2937*55232f09SEwan Crawford static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 2938*55232f09SEwan Crawford 2939*55232f09SEwan Crawford const char* id_cstr = command.GetArgumentAtIndex(0); 2940*55232f09SEwan Crawford bool convert_complete = false; 2941*55232f09SEwan Crawford const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete); 2942*55232f09SEwan Crawford if (!convert_complete) 2943*55232f09SEwan Crawford { 2944*55232f09SEwan Crawford result.AppendErrorWithFormat ("invalid allocation id argument '%s'", id_cstr); 2945*55232f09SEwan Crawford result.SetStatus (eReturnStatusFailed); 2946*55232f09SEwan Crawford return false; 2947*55232f09SEwan Crawford } 2948*55232f09SEwan Crawford 2949*55232f09SEwan Crawford const char* filename = command.GetArgumentAtIndex(1); 2950*55232f09SEwan Crawford bool success = runtime->LoadAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr()); 2951*55232f09SEwan Crawford 2952*55232f09SEwan Crawford if (success) 2953*55232f09SEwan Crawford result.SetStatus(eReturnStatusSuccessFinishResult); 2954*55232f09SEwan Crawford else 2955*55232f09SEwan Crawford result.SetStatus(eReturnStatusFailed); 2956*55232f09SEwan Crawford 2957*55232f09SEwan Crawford return true; 2958*55232f09SEwan Crawford } 2959*55232f09SEwan Crawford }; 2960*55232f09SEwan Crawford 2961*55232f09SEwan Crawford 2962*55232f09SEwan Crawford class CommandObjectRenderScriptRuntimeAllocationSave : public CommandObjectParsed 2963*55232f09SEwan Crawford { 2964*55232f09SEwan Crawford private: 2965*55232f09SEwan Crawford public: 2966*55232f09SEwan Crawford CommandObjectRenderScriptRuntimeAllocationSave(CommandInterpreter &interpreter) 2967*55232f09SEwan Crawford : CommandObjectParsed(interpreter, "renderscript allocation save", 2968*55232f09SEwan Crawford "Write renderscript allocation contents to a file.", "renderscript allocation save <ID> <filename>", 2969*55232f09SEwan Crawford eCommandRequiresProcess | eCommandProcessMustBeLaunched) 2970*55232f09SEwan Crawford { 2971*55232f09SEwan Crawford } 2972*55232f09SEwan Crawford 2973*55232f09SEwan Crawford ~CommandObjectRenderScriptRuntimeAllocationSave() {} 2974*55232f09SEwan Crawford 2975*55232f09SEwan Crawford bool 2976*55232f09SEwan Crawford DoExecute(Args &command, CommandReturnObject &result) 2977*55232f09SEwan Crawford { 2978*55232f09SEwan Crawford const size_t argc = command.GetArgumentCount(); 2979*55232f09SEwan Crawford if (argc != 2) 2980*55232f09SEwan Crawford { 2981*55232f09SEwan Crawford result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str()); 2982*55232f09SEwan Crawford result.SetStatus(eReturnStatusFailed); 2983*55232f09SEwan Crawford return false; 2984*55232f09SEwan Crawford } 2985*55232f09SEwan Crawford 2986*55232f09SEwan Crawford RenderScriptRuntime *runtime = 2987*55232f09SEwan Crawford static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 2988*55232f09SEwan Crawford 2989*55232f09SEwan Crawford const char* id_cstr = command.GetArgumentAtIndex(0); 2990*55232f09SEwan Crawford bool convert_complete = false; 2991*55232f09SEwan Crawford const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete); 2992*55232f09SEwan Crawford if (!convert_complete) 2993*55232f09SEwan Crawford { 2994*55232f09SEwan Crawford result.AppendErrorWithFormat ("invalid allocation id argument '%s'", id_cstr); 2995*55232f09SEwan Crawford result.SetStatus (eReturnStatusFailed); 2996*55232f09SEwan Crawford return false; 2997*55232f09SEwan Crawford } 2998*55232f09SEwan Crawford 2999*55232f09SEwan Crawford const char* filename = command.GetArgumentAtIndex(1); 3000*55232f09SEwan Crawford bool success = runtime->SaveAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr()); 3001*55232f09SEwan Crawford 3002*55232f09SEwan Crawford if (success) 3003*55232f09SEwan Crawford result.SetStatus(eReturnStatusSuccessFinishResult); 3004*55232f09SEwan Crawford else 3005*55232f09SEwan Crawford result.SetStatus(eReturnStatusFailed); 3006*55232f09SEwan Crawford 3007*55232f09SEwan Crawford return true; 3008*55232f09SEwan Crawford } 3009*55232f09SEwan Crawford }; 3010*55232f09SEwan Crawford 301115f2bd95SEwan Crawford class CommandObjectRenderScriptRuntimeAllocation : public CommandObjectMultiword 301215f2bd95SEwan Crawford { 301315f2bd95SEwan Crawford private: 301415f2bd95SEwan Crawford public: 301515f2bd95SEwan Crawford CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter) 301615f2bd95SEwan Crawford : CommandObjectMultiword(interpreter, "renderscript allocation", "Commands that deal with renderscript allocations.", 301715f2bd95SEwan Crawford NULL) 301815f2bd95SEwan Crawford { 301915f2bd95SEwan Crawford LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationList(interpreter))); 3020a0f08674SEwan Crawford LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationDump(interpreter))); 3021*55232f09SEwan Crawford LoadSubCommand("save", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationSave(interpreter))); 3022*55232f09SEwan Crawford LoadSubCommand("load", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationLoad(interpreter))); 302315f2bd95SEwan Crawford } 302415f2bd95SEwan Crawford 302515f2bd95SEwan Crawford ~CommandObjectRenderScriptRuntimeAllocation() {} 302615f2bd95SEwan Crawford }; 302715f2bd95SEwan Crawford 302815f2bd95SEwan Crawford 30294640cde1SColin Riley class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed 30304640cde1SColin Riley { 30314640cde1SColin Riley private: 30324640cde1SColin Riley public: 30334640cde1SColin Riley CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter) 30344640cde1SColin Riley : CommandObjectParsed(interpreter, "renderscript status", 30354640cde1SColin Riley "Displays current renderscript runtime status.", "renderscript status", 30364640cde1SColin Riley eCommandRequiresProcess | eCommandProcessMustBeLaunched) 30374640cde1SColin Riley { 30384640cde1SColin Riley } 30394640cde1SColin Riley 30404640cde1SColin Riley ~CommandObjectRenderScriptRuntimeStatus() {} 30414640cde1SColin Riley 30424640cde1SColin Riley bool 30434640cde1SColin Riley DoExecute(Args &command, CommandReturnObject &result) 30444640cde1SColin Riley { 30454640cde1SColin Riley RenderScriptRuntime *runtime = 30464640cde1SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 30474640cde1SColin Riley runtime->Status(result.GetOutputStream()); 30484640cde1SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 30494640cde1SColin Riley return true; 30504640cde1SColin Riley } 30514640cde1SColin Riley }; 30524640cde1SColin Riley 30535ec532a9SColin Riley class CommandObjectRenderScriptRuntime : public CommandObjectMultiword 30545ec532a9SColin Riley { 30555ec532a9SColin Riley public: 30565ec532a9SColin Riley CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter) 30575ec532a9SColin Riley : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.", 30585ec532a9SColin Riley "renderscript <subcommand> [<subcommand-options>]") 30595ec532a9SColin Riley { 30605ec532a9SColin Riley LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter))); 30614640cde1SColin Riley LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter))); 30624640cde1SColin Riley LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter))); 30634640cde1SColin Riley LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter))); 306415f2bd95SEwan Crawford LoadSubCommand("allocation", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocation(interpreter))); 30655ec532a9SColin Riley } 30665ec532a9SColin Riley 30675ec532a9SColin Riley ~CommandObjectRenderScriptRuntime() {} 30685ec532a9SColin Riley }; 3069ef20b08fSColin Riley 3070ef20b08fSColin Riley void 3071ef20b08fSColin Riley RenderScriptRuntime::Initiate() 30725ec532a9SColin Riley { 3073ef20b08fSColin Riley assert(!m_initiated); 30745ec532a9SColin Riley } 3075ef20b08fSColin Riley 3076ef20b08fSColin Riley RenderScriptRuntime::RenderScriptRuntime(Process *process) 30777dc7771cSEwan Crawford : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false), 30787dc7771cSEwan Crawford m_breakAllKernels(false) 3079ef20b08fSColin Riley { 30804640cde1SColin Riley ModulesDidLoad(process->GetTarget().GetImages()); 3081ef20b08fSColin Riley } 30824640cde1SColin Riley 30834640cde1SColin Riley lldb::CommandObjectSP 30844640cde1SColin Riley RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter) 30854640cde1SColin Riley { 30864640cde1SColin Riley static CommandObjectSP command_object; 30874640cde1SColin Riley if(!command_object) 30884640cde1SColin Riley { 30894640cde1SColin Riley command_object.reset(new CommandObjectRenderScriptRuntime(interpreter)); 30904640cde1SColin Riley } 30914640cde1SColin Riley return command_object; 30924640cde1SColin Riley } 30934640cde1SColin Riley 309478f339d1SEwan Crawford RenderScriptRuntime::~RenderScriptRuntime() = default; 3095