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 18255232f09SEwan Crawford // Header for reading and writing allocation contents 18355232f09SEwan Crawford // to a binary file. 18455232f09SEwan Crawford struct FileHeader 18555232f09SEwan Crawford { 18655232f09SEwan Crawford uint8_t ident[4]; // ASCII 'RSAD' identifying the file 18755232f09SEwan Crawford uint16_t hdr_size; // Header size in bytes, for backwards compatability 18855232f09SEwan Crawford uint16_t type; // DataType enum 18955232f09SEwan Crawford uint32_t kind; // DataKind enum 19055232f09SEwan Crawford uint32_t dims[3]; // Dimensions 19155232f09SEwan Crawford uint32_t element_size; // Size of a single element, including padding 19255232f09SEwan Crawford }; 19355232f09SEwan 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; 61202f1c5d1SEwan Crawford success = reg_ctx->ReadRegister(rArg, rVal); 61302f1c5d1SEwan Crawford if (success) 61402f1c5d1SEwan Crawford { 6154640cde1SColin Riley (*data) = rVal.GetAsUInt32(); 61602f1c5d1SEwan Crawford } 61702f1c5d1SEwan Crawford else 61802f1c5d1SEwan Crawford { 61902f1c5d1SEwan Crawford if (log) 62002f1c5d1SEwan Crawford log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading ARM register: %d.", arg); 62102f1c5d1SEwan Crawford } 6224640cde1SColin Riley } 6234640cde1SColin Riley else 6244640cde1SColin Riley { 6254640cde1SColin Riley uint64_t sp = reg_ctx->GetSP(); 6264640cde1SColin Riley uint32_t offset = (arg-4) * sizeof(uint32_t); 6274640cde1SColin Riley process->ReadMemory(sp + offset, &data, sizeof(uint32_t), error); 6284640cde1SColin Riley if (error.Fail()) 6294640cde1SColin Riley { 6304640cde1SColin Riley if (log) 63182780287SAidan Dodds log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading ARM stack: %s.", error.AsCString()); 63282780287SAidan Dodds } 63382780287SAidan Dodds else 63482780287SAidan Dodds { 63582780287SAidan Dodds success = true; 6364640cde1SColin Riley } 6374640cde1SColin Riley } 63882780287SAidan Dodds 63982780287SAidan Dodds break; 6404640cde1SColin Riley } 64182780287SAidan Dodds case llvm::Triple::ArchType::aarch64: 64282780287SAidan Dodds { 64382780287SAidan Dodds // arm 64 bit 64482780287SAidan Dodds // first 8 arguments are in the registers 64582780287SAidan Dodds if (arg < 8) 64682780287SAidan Dodds { 64782780287SAidan Dodds const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg); 64882780287SAidan Dodds RegisterValue rVal; 64982780287SAidan Dodds success = reg_ctx->ReadRegister(rArg, rVal); 65082780287SAidan Dodds if (success) 65182780287SAidan Dodds { 65282780287SAidan Dodds *data = rVal.GetAsUInt64(); 65382780287SAidan Dodds } 65482780287SAidan Dodds else 65582780287SAidan Dodds { 65682780287SAidan Dodds if (log) 65782780287SAidan Dodds log->Printf("RenderScriptRuntime::GetArgSimple() - AARCH64 - Error while reading the argument #%d", arg); 65882780287SAidan Dodds } 65982780287SAidan Dodds } 66082780287SAidan Dodds else 66182780287SAidan Dodds { 66282780287SAidan Dodds // @TODO: need to find the argument in the stack 66382780287SAidan Dodds if (log) 66482780287SAidan Dodds log->Printf("RenderScriptRuntime::GetArgSimple - AARCH64 - FOR #ARG >= 8 NOT IMPLEMENTED YET. Argument number: %d", arg); 66582780287SAidan Dodds } 66682780287SAidan Dodds break; 66782780287SAidan Dodds } 66802f1c5d1SEwan Crawford case llvm::Triple::ArchType::mips64el: 66902f1c5d1SEwan Crawford { 67002f1c5d1SEwan Crawford // read from the registers 67102f1c5d1SEwan Crawford if (arg < 8) 67202f1c5d1SEwan Crawford { 67302f1c5d1SEwan Crawford const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg + 4); 67402f1c5d1SEwan Crawford RegisterValue rVal; 67502f1c5d1SEwan Crawford success = reg_ctx->ReadRegister(rArg, rVal); 67602f1c5d1SEwan Crawford if (success) 67702f1c5d1SEwan Crawford { 67802f1c5d1SEwan Crawford (*data) = rVal.GetAsUInt64(); 67902f1c5d1SEwan Crawford } 68002f1c5d1SEwan Crawford else 68102f1c5d1SEwan Crawford { 68202f1c5d1SEwan Crawford if (log) 68302f1c5d1SEwan Crawford log->Printf("RenderScriptRuntime::GetArgSimple - Mips64 - Error reading the argument #%d", arg); 68402f1c5d1SEwan Crawford } 68502f1c5d1SEwan Crawford } 68602f1c5d1SEwan Crawford 68702f1c5d1SEwan Crawford // read from the stack 68802f1c5d1SEwan Crawford else 68902f1c5d1SEwan Crawford { 69002f1c5d1SEwan Crawford uint64_t sp = reg_ctx->GetSP(); 69102f1c5d1SEwan Crawford uint32_t offset = (arg - 8) * sizeof(uint64_t); 69202f1c5d1SEwan Crawford process->ReadMemory(sp + offset, &data, sizeof(uint64_t), error); 69302f1c5d1SEwan Crawford if (error.Fail()) 69402f1c5d1SEwan Crawford { 69502f1c5d1SEwan Crawford if (log) 69602f1c5d1SEwan Crawford log->Printf ("RenderScriptRuntime::GetArgSimple - Mips64 - Error reading Mips64 stack: %s.", error.AsCString()); 69702f1c5d1SEwan Crawford } 69802f1c5d1SEwan Crawford else 69902f1c5d1SEwan Crawford { 70002f1c5d1SEwan Crawford success = true; 70102f1c5d1SEwan Crawford } 70202f1c5d1SEwan Crawford } 70302f1c5d1SEwan Crawford 70402f1c5d1SEwan Crawford break; 70502f1c5d1SEwan Crawford } 70682780287SAidan Dodds default: 70782780287SAidan Dodds { 70882780287SAidan Dodds // invalid architecture 70982780287SAidan Dodds if (log) 71082780287SAidan Dodds log->Printf("RenderScriptRuntime::GetArgSimple - Architecture not supported"); 71182780287SAidan Dodds 71282780287SAidan Dodds } 71382780287SAidan Dodds } 71482780287SAidan Dodds 71582780287SAidan Dodds 71682780287SAidan Dodds return success; 7174640cde1SColin Riley } 7184640cde1SColin Riley 7194640cde1SColin Riley void 7204640cde1SColin Riley RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context) 7214640cde1SColin Riley { 7224640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 7234640cde1SColin Riley 7244640cde1SColin Riley //Context, Script, int, data, length 7254640cde1SColin Riley 72682780287SAidan Dodds uint64_t rs_context_u64 = 0U; 72782780287SAidan Dodds uint64_t rs_script_u64 = 0U; 72882780287SAidan Dodds uint64_t rs_id_u64 = 0U; 72982780287SAidan Dodds uint64_t rs_data_u64 = 0U; 73082780287SAidan Dodds uint64_t rs_length_u64 = 0U; 7314640cde1SColin Riley 73282780287SAidan Dodds bool success = 73382780287SAidan Dodds GetArgSimple(context, 0, &rs_context_u64) && 73482780287SAidan Dodds GetArgSimple(context, 1, &rs_script_u64) && 73582780287SAidan Dodds GetArgSimple(context, 2, &rs_id_u64) && 73682780287SAidan Dodds GetArgSimple(context, 3, &rs_data_u64) && 73782780287SAidan Dodds GetArgSimple(context, 4, &rs_length_u64); 7384640cde1SColin Riley 73982780287SAidan Dodds if (!success) 74082780287SAidan Dodds { 74182780287SAidan Dodds if (log) 74282780287SAidan Dodds log->Printf("RenderScriptRuntime::CaptureSetGlobalVar1 - Error while reading the function parameters"); 74382780287SAidan Dodds return; 74482780287SAidan Dodds } 7454640cde1SColin Riley 7464640cde1SColin Riley if (log) 7474640cde1SColin Riley { 7484640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.", 74982780287SAidan Dodds rs_context_u64, rs_script_u64, rs_id_u64, rs_data_u64, rs_length_u64); 7504640cde1SColin Riley 75182780287SAidan Dodds addr_t script_addr = (addr_t)rs_script_u64; 7524640cde1SColin Riley if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end()) 7534640cde1SColin Riley { 7544640cde1SColin Riley auto rsm = m_scriptMappings[script_addr]; 75582780287SAidan Dodds if (rs_id_u64 < rsm->m_globals.size()) 7564640cde1SColin Riley { 75782780287SAidan Dodds auto rsg = rsm->m_globals[rs_id_u64]; 7584640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(), 7594640cde1SColin Riley rsm->m_module->GetFileSpec().GetFilename().AsCString()); 7604640cde1SColin Riley } 7614640cde1SColin Riley } 7624640cde1SColin Riley } 7634640cde1SColin Riley } 7644640cde1SColin Riley 7654640cde1SColin Riley void 7664640cde1SColin Riley RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context) 7674640cde1SColin Riley { 7684640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 7694640cde1SColin Riley 7704640cde1SColin Riley //Context, Alloc, bool 7714640cde1SColin Riley 77282780287SAidan Dodds uint64_t rs_context_u64 = 0U; 77382780287SAidan Dodds uint64_t rs_alloc_u64 = 0U; 77482780287SAidan Dodds uint64_t rs_forceZero_u64 = 0U; 7754640cde1SColin Riley 77682780287SAidan Dodds bool success = 77782780287SAidan Dodds GetArgSimple(context, 0, &rs_context_u64) && 77882780287SAidan Dodds GetArgSimple(context, 1, &rs_alloc_u64) && 77982780287SAidan Dodds GetArgSimple(context, 2, &rs_forceZero_u64); 78082780287SAidan Dodds if (!success) // error case 78182780287SAidan Dodds { 78282780287SAidan Dodds if (log) 78382780287SAidan Dodds log->Printf("RenderScriptRuntime::CaptureAllocationInit1 - Error while reading the function parameters"); 78482780287SAidan Dodds return; // abort 78582780287SAidan Dodds } 7864640cde1SColin Riley 7874640cde1SColin Riley if (log) 7884640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .", 78982780287SAidan Dodds rs_context_u64, rs_alloc_u64, rs_forceZero_u64); 79078f339d1SEwan Crawford 79178f339d1SEwan Crawford AllocationDetails* alloc = LookUpAllocation(rs_alloc_u64, true); 79278f339d1SEwan Crawford if (alloc) 79378f339d1SEwan Crawford alloc->context = rs_context_u64; 7944640cde1SColin Riley } 7954640cde1SColin Riley 7964640cde1SColin Riley void 7974640cde1SColin Riley RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context) 7984640cde1SColin Riley { 7994640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 8004640cde1SColin Riley 8014640cde1SColin Riley //Context, Script, resname Str, cachedir Str 8024640cde1SColin Riley Error error; 8034640cde1SColin Riley Process* process = context.GetProcessPtr(); 8044640cde1SColin Riley 80582780287SAidan Dodds uint64_t rs_context_u64 = 0U; 80682780287SAidan Dodds uint64_t rs_script_u64 = 0U; 80782780287SAidan Dodds uint64_t rs_resnameptr_u64 = 0U; 80882780287SAidan Dodds uint64_t rs_cachedirptr_u64 = 0U; 8094640cde1SColin Riley 8104640cde1SColin Riley std::string resname; 8114640cde1SColin Riley std::string cachedir; 8124640cde1SColin Riley 81382780287SAidan Dodds // read the function parameters 81482780287SAidan Dodds bool success = 81582780287SAidan Dodds GetArgSimple(context, 0, &rs_context_u64) && 81682780287SAidan Dodds GetArgSimple(context, 1, &rs_script_u64) && 81782780287SAidan Dodds GetArgSimple(context, 2, &rs_resnameptr_u64) && 81882780287SAidan Dodds GetArgSimple(context, 3, &rs_cachedirptr_u64); 8194640cde1SColin Riley 82082780287SAidan Dodds if (!success) 82182780287SAidan Dodds { 82282780287SAidan Dodds if (log) 82382780287SAidan Dodds log->Printf("RenderScriptRuntime::CaptureScriptInit1 - Error while reading the function parameters"); 82482780287SAidan Dodds return; 82582780287SAidan Dodds } 82682780287SAidan Dodds 82782780287SAidan Dodds process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u64, resname, error); 8284640cde1SColin Riley if (error.Fail()) 8294640cde1SColin Riley { 8304640cde1SColin Riley if (log) 8314640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString()); 8324640cde1SColin Riley 8334640cde1SColin Riley } 8344640cde1SColin Riley 83582780287SAidan Dodds process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u64, cachedir, error); 8364640cde1SColin Riley if (error.Fail()) 8374640cde1SColin Riley { 8384640cde1SColin Riley if (log) 8394640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString()); 8404640cde1SColin Riley } 8414640cde1SColin Riley 8424640cde1SColin Riley if (log) 8434640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .", 84482780287SAidan Dodds rs_context_u64, rs_script_u64, resname.c_str(), cachedir.c_str()); 8454640cde1SColin Riley 8464640cde1SColin Riley if (resname.size() > 0) 8474640cde1SColin Riley { 8484640cde1SColin Riley StreamString strm; 8494640cde1SColin Riley strm.Printf("librs.%s.so", resname.c_str()); 8504640cde1SColin Riley 85178f339d1SEwan Crawford ScriptDetails* script = LookUpScript(rs_script_u64, true); 85278f339d1SEwan Crawford if (script) 85378f339d1SEwan Crawford { 85478f339d1SEwan Crawford script->type = ScriptDetails::eScriptC; 85578f339d1SEwan Crawford script->cacheDir = cachedir; 85678f339d1SEwan Crawford script->resName = resname; 85778f339d1SEwan Crawford script->scriptDyLib = strm.GetData(); 85878f339d1SEwan Crawford script->context = addr_t(rs_context_u64); 85978f339d1SEwan Crawford } 8604640cde1SColin Riley 8614640cde1SColin Riley if (log) 8624640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".", 86382780287SAidan Dodds strm.GetData(), rs_context_u64, rs_script_u64); 8644640cde1SColin Riley } 8654640cde1SColin Riley else if (log) 8664640cde1SColin Riley { 8674640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged"); 8684640cde1SColin Riley } 8694640cde1SColin Riley 8704640cde1SColin Riley } 8714640cde1SColin Riley 8724640cde1SColin Riley void 8734640cde1SColin Riley RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind) 8744640cde1SColin Riley { 8754640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 8764640cde1SColin Riley 8774640cde1SColin Riley if (!module) 8784640cde1SColin Riley { 8794640cde1SColin Riley return; 8804640cde1SColin Riley } 8814640cde1SColin Riley 88282780287SAidan Dodds Target &target = GetProcess()->GetTarget(); 88382780287SAidan Dodds llvm::Triple::ArchType targetArchType = target.GetArchitecture().GetMachine(); 88482780287SAidan Dodds 88582780287SAidan Dodds if (targetArchType != llvm::Triple::ArchType::x86 88682780287SAidan Dodds && targetArchType != llvm::Triple::ArchType::arm 88702f1c5d1SEwan Crawford && targetArchType != llvm::Triple::ArchType::aarch64 88802f1c5d1SEwan Crawford && targetArchType != llvm::Triple::ArchType::mips64el 88902f1c5d1SEwan Crawford ) 8904640cde1SColin Riley { 8914640cde1SColin Riley if (log) 89202f1c5d1SEwan Crawford log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM, Mips64 supported currently."); 8934640cde1SColin Riley 8944640cde1SColin Riley return; 8954640cde1SColin Riley } 8964640cde1SColin Riley 89782780287SAidan Dodds uint32_t archByteSize = target.GetArchitecture().GetAddressByteSize(); 8984640cde1SColin Riley 8994640cde1SColin Riley for (size_t idx = 0; idx < s_runtimeHookCount; idx++) 9004640cde1SColin Riley { 9014640cde1SColin Riley const HookDefn* hook_defn = &s_runtimeHookDefns[idx]; 9024640cde1SColin Riley if (hook_defn->kind != kind) { 9034640cde1SColin Riley continue; 9044640cde1SColin Riley } 9054640cde1SColin Riley 90682780287SAidan Dodds const char* symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64; 90782780287SAidan Dodds 90882780287SAidan Dodds const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(symbol_name), eSymbolTypeCode); 90982780287SAidan Dodds if (!sym){ 91082780287SAidan Dodds if (log){ 91182780287SAidan Dodds log->Printf("RenderScriptRuntime::LoadRuntimeHooks - ERROR: Symbol '%s' related to the function %s not found", symbol_name, hook_defn->name); 91282780287SAidan Dodds } 91382780287SAidan Dodds continue; 91482780287SAidan Dodds } 9154640cde1SColin Riley 916358cf1eaSGreg Clayton addr_t addr = sym->GetLoadAddress(&target); 9174640cde1SColin Riley if (addr == LLDB_INVALID_ADDRESS) 9184640cde1SColin Riley { 9194640cde1SColin Riley if (log) 9204640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.", 92182780287SAidan Dodds hook_defn->name, symbol_name); 9224640cde1SColin Riley continue; 9234640cde1SColin Riley } 92482780287SAidan Dodds else 92582780287SAidan Dodds { 92682780287SAidan Dodds if (log) 92782780287SAidan Dodds log->Printf("RenderScriptRuntime::LoadRuntimeHooks - Function %s, address resolved at 0x%" PRIx64, hook_defn->name, addr); 92882780287SAidan Dodds } 9294640cde1SColin Riley 9304640cde1SColin Riley RuntimeHookSP hook(new RuntimeHook()); 9314640cde1SColin Riley hook->address = addr; 9324640cde1SColin Riley hook->defn = hook_defn; 9334640cde1SColin Riley hook->bp_sp = target.CreateBreakpoint(addr, true, false); 9344640cde1SColin Riley hook->bp_sp->SetCallback(HookCallback, hook.get(), true); 9354640cde1SColin Riley m_runtimeHooks[addr] = hook; 9364640cde1SColin Riley if (log) 9374640cde1SColin Riley { 9384640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".", 9394640cde1SColin Riley hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr); 9404640cde1SColin Riley } 9414640cde1SColin Riley } 9424640cde1SColin Riley } 9434640cde1SColin Riley 9444640cde1SColin Riley void 9454640cde1SColin Riley RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) 9464640cde1SColin Riley { 9474640cde1SColin Riley if (!rsmodule_sp) 9484640cde1SColin Riley return; 9494640cde1SColin Riley 9504640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 9514640cde1SColin Riley 9524640cde1SColin Riley const ModuleSP module = rsmodule_sp->m_module; 9534640cde1SColin Riley const FileSpec& file = module->GetPlatformFileSpec(); 9544640cde1SColin Riley 95578f339d1SEwan Crawford // Iterate over all of the scripts that we currently know of. 95678f339d1SEwan Crawford // Note: We cant push or pop to m_scripts here or it may invalidate rs_script. 9574640cde1SColin Riley for (const auto & rs_script : m_scripts) 9584640cde1SColin Riley { 95978f339d1SEwan Crawford // Extract the expected .so file path for this script. 96078f339d1SEwan Crawford std::string dylib; 96178f339d1SEwan Crawford if (!rs_script->scriptDyLib.get(dylib)) 96278f339d1SEwan Crawford continue; 96378f339d1SEwan Crawford 96478f339d1SEwan Crawford // Only proceed if the module that has loaded corresponds to this script. 96578f339d1SEwan Crawford if (file.GetFilename() != ConstString(dylib.c_str())) 96678f339d1SEwan Crawford continue; 96778f339d1SEwan Crawford 96878f339d1SEwan Crawford // Obtain the script address which we use as a key. 96978f339d1SEwan Crawford lldb::addr_t script; 97078f339d1SEwan Crawford if (!rs_script->script.get(script)) 97178f339d1SEwan Crawford continue; 97278f339d1SEwan Crawford 97378f339d1SEwan Crawford // If we have a script mapping for the current script. 97478f339d1SEwan Crawford if (m_scriptMappings.find(script) != m_scriptMappings.end()) 9754640cde1SColin Riley { 97678f339d1SEwan Crawford // if the module we have stored is different to the one we just received. 97778f339d1SEwan Crawford if (m_scriptMappings[script] != rsmodule_sp) 9784640cde1SColin Riley { 9794640cde1SColin Riley if (log) 9804640cde1SColin Riley log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.", 98178f339d1SEwan Crawford (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); 9824640cde1SColin Riley } 9834640cde1SColin Riley } 98478f339d1SEwan Crawford // We don't have a script mapping for the current script. 9854640cde1SColin Riley else 9864640cde1SColin Riley { 98778f339d1SEwan Crawford // Obtain the script resource name. 98878f339d1SEwan Crawford std::string resName; 98978f339d1SEwan Crawford if (rs_script->resName.get(resName)) 99078f339d1SEwan Crawford // Set the modules resource name. 99178f339d1SEwan Crawford rsmodule_sp->m_resname = resName; 99278f339d1SEwan Crawford // Add Script/Module pair to map. 99378f339d1SEwan Crawford m_scriptMappings[script] = rsmodule_sp; 9944640cde1SColin Riley if (log) 9954640cde1SColin Riley log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.", 99678f339d1SEwan Crawford (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); 9974640cde1SColin Riley } 9984640cde1SColin Riley } 9994640cde1SColin Riley } 10004640cde1SColin Riley 100115f2bd95SEwan Crawford // Uses the Target API to evaluate the expression passed as a parameter to the function 100215f2bd95SEwan Crawford // The result of that expression is returned an unsigned 64 bit int, via the result* paramter. 100315f2bd95SEwan Crawford // Function returns true on success, and false on failure 100415f2bd95SEwan Crawford bool 100515f2bd95SEwan Crawford RenderScriptRuntime::EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result) 100615f2bd95SEwan Crawford { 100715f2bd95SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 100815f2bd95SEwan Crawford if (log) 100915f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::EvalRSExpression(%s)", expression); 101015f2bd95SEwan Crawford 101115f2bd95SEwan Crawford ValueObjectSP expr_result; 101215f2bd95SEwan Crawford // Perform the actual expression evaluation 101315f2bd95SEwan Crawford GetProcess()->GetTarget().EvaluateExpression(expression, frame_ptr, expr_result); 101415f2bd95SEwan Crawford 101515f2bd95SEwan Crawford if (!expr_result) 101615f2bd95SEwan Crawford { 101715f2bd95SEwan Crawford if (log) 101815f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::EvalRSExpression - Error: Couldn't evaluate expression"); 101915f2bd95SEwan Crawford return false; 102015f2bd95SEwan Crawford } 102115f2bd95SEwan Crawford 102215f2bd95SEwan Crawford // The result of the expression is invalid 102315f2bd95SEwan Crawford if (!expr_result->GetError().Success()) 102415f2bd95SEwan Crawford { 102515f2bd95SEwan Crawford Error err = expr_result->GetError(); 102615f2bd95SEwan Crawford if (err.GetError() == UserExpression::kNoResult) // Expression returned void, so this is actually a success 102715f2bd95SEwan Crawford { 102815f2bd95SEwan Crawford if (log) 102915f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::EvalRSExpression - Expression returned void"); 103015f2bd95SEwan Crawford 103115f2bd95SEwan Crawford result = nullptr; 103215f2bd95SEwan Crawford return true; 103315f2bd95SEwan Crawford } 103415f2bd95SEwan Crawford 103515f2bd95SEwan Crawford if (log) 103615f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::EvalRSExpression - Error evaluating expression result: %s", err.AsCString()); 103715f2bd95SEwan Crawford return false; 103815f2bd95SEwan Crawford } 103915f2bd95SEwan Crawford 104015f2bd95SEwan Crawford bool success = false; 104115f2bd95SEwan Crawford *result = expr_result->GetValueAsUnsigned(0, &success); // We only read the result as an unsigned int. 104215f2bd95SEwan Crawford 104315f2bd95SEwan Crawford if (!success) 104415f2bd95SEwan Crawford { 104515f2bd95SEwan Crawford if (log) 104615f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::EvalRSExpression - Error: Couldn't convert expression result to unsigned int"); 104715f2bd95SEwan Crawford return false; 104815f2bd95SEwan Crawford } 104915f2bd95SEwan Crawford 105015f2bd95SEwan Crawford return true; 105115f2bd95SEwan Crawford } 105215f2bd95SEwan Crawford 105315f2bd95SEwan Crawford // Used to index expression format strings 105415f2bd95SEwan Crawford enum ExpressionStrings 105515f2bd95SEwan Crawford { 105615f2bd95SEwan Crawford eExprGetOffsetPtr = 0, 105715f2bd95SEwan Crawford eExprAllocGetType, 105815f2bd95SEwan Crawford eExprTypeDimX, 105915f2bd95SEwan Crawford eExprTypeDimY, 106015f2bd95SEwan Crawford eExprTypeDimZ, 106115f2bd95SEwan Crawford eExprTypeElemPtr, 106215f2bd95SEwan Crawford eExprElementType, 106315f2bd95SEwan Crawford eExprElementKind, 106415f2bd95SEwan Crawford eExprElementVec 106515f2bd95SEwan Crawford }; 106615f2bd95SEwan Crawford 106715f2bd95SEwan Crawford // Format strings containing the expressions we may need to evaluate. 106815f2bd95SEwan Crawford const char runtimeExpressions[][256] = 106915f2bd95SEwan Crawford { 107015f2bd95SEwan Crawford // Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap) 107115f2bd95SEwan Crawford "(int*)_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace(0x%lx, %u, %u, %u, 0, 0)", 107215f2bd95SEwan Crawford 107315f2bd95SEwan Crawford // Type* rsaAllocationGetType(Context*, Allocation*) 107415f2bd95SEwan Crawford "(void*)rsaAllocationGetType(0x%lx, 0x%lx)", 107515f2bd95SEwan Crawford 107615f2bd95SEwan Crawford // rsaTypeGetNativeData(Context*, Type*, void* typeData, size) 107715f2bd95SEwan Crawford // Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ; 107815f2bd95SEwan Crawford // mHal.state.lodCount; mHal.state.faces; mElement; into typeData 107915f2bd95SEwan Crawford // Need to specify 32 or 64 bit for uint_t since this differs between devices 108015f2bd95SEwan Crawford "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[0]", // X dim 108115f2bd95SEwan Crawford "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[1]", // Y dim 108215f2bd95SEwan Crawford "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[2]", // Z dim 108315f2bd95SEwan Crawford "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[5]", // Element ptr 108415f2bd95SEwan Crawford 108515f2bd95SEwan Crawford // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size) 108615f2bd95SEwan Crawford // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData 108715f2bd95SEwan Crawford "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[0]", // Type 108815f2bd95SEwan Crawford "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[1]", // Kind 108915f2bd95SEwan Crawford "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[3]" // Vector Size 109015f2bd95SEwan Crawford }; 109115f2bd95SEwan Crawford 109215f2bd95SEwan Crawford // JITs the RS runtime for the internal data pointer of an allocation. 109315f2bd95SEwan Crawford // Is passed x,y,z coordinates for the pointer to a specific element. 109415f2bd95SEwan Crawford // Then sets the data_ptr member in Allocation with the result. 109515f2bd95SEwan Crawford // Returns true on success, false otherwise 109615f2bd95SEwan Crawford bool 109715f2bd95SEwan Crawford RenderScriptRuntime::JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr, 109815f2bd95SEwan Crawford unsigned int x, unsigned int y, unsigned int z) 109915f2bd95SEwan Crawford { 110015f2bd95SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 110115f2bd95SEwan Crawford 110215f2bd95SEwan Crawford if (!allocation->address.isValid()) 110315f2bd95SEwan Crawford { 110415f2bd95SEwan Crawford if (log) 110515f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITDataPointer - Failed to find allocation details"); 110615f2bd95SEwan Crawford return false; 110715f2bd95SEwan Crawford } 110815f2bd95SEwan Crawford 110915f2bd95SEwan Crawford const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr]; 111015f2bd95SEwan Crawford const int max_expr_size = 512; // Max expression size 111115f2bd95SEwan Crawford char buffer[max_expr_size]; 111215f2bd95SEwan Crawford 111315f2bd95SEwan Crawford int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->address.get(), x, y, z); 111415f2bd95SEwan Crawford if (chars_written < 0) 111515f2bd95SEwan Crawford { 111615f2bd95SEwan Crawford if (log) 111715f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()"); 111815f2bd95SEwan Crawford return false; 111915f2bd95SEwan Crawford } 112015f2bd95SEwan Crawford else if (chars_written >= max_expr_size) 112115f2bd95SEwan Crawford { 112215f2bd95SEwan Crawford if (log) 112315f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITDataPointer - Expression too long"); 112415f2bd95SEwan Crawford return false; 112515f2bd95SEwan Crawford } 112615f2bd95SEwan Crawford 112715f2bd95SEwan Crawford uint64_t result = 0; 112815f2bd95SEwan Crawford if (!EvalRSExpression(buffer, frame_ptr, &result)) 112915f2bd95SEwan Crawford return false; 113015f2bd95SEwan Crawford 113115f2bd95SEwan Crawford addr_t mem_ptr = static_cast<lldb::addr_t>(result); 113215f2bd95SEwan Crawford allocation->data_ptr = mem_ptr; 113315f2bd95SEwan Crawford 113415f2bd95SEwan Crawford return true; 113515f2bd95SEwan Crawford } 113615f2bd95SEwan Crawford 113715f2bd95SEwan Crawford // JITs the RS runtime for the internal pointer to the RS Type of an allocation 113815f2bd95SEwan Crawford // Then sets the type_ptr member in Allocation with the result. 113915f2bd95SEwan Crawford // Returns true on success, false otherwise 114015f2bd95SEwan Crawford bool 114115f2bd95SEwan Crawford RenderScriptRuntime::JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr) 114215f2bd95SEwan Crawford { 114315f2bd95SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 114415f2bd95SEwan Crawford 114515f2bd95SEwan Crawford if (!allocation->address.isValid() || !allocation->context.isValid()) 114615f2bd95SEwan Crawford { 114715f2bd95SEwan Crawford if (log) 114815f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITTypePointer - Failed to find allocation details"); 114915f2bd95SEwan Crawford return false; 115015f2bd95SEwan Crawford } 115115f2bd95SEwan Crawford 115215f2bd95SEwan Crawford const char* expr_cstr = runtimeExpressions[eExprAllocGetType]; 115315f2bd95SEwan Crawford const int max_expr_size = 512; // Max expression size 115415f2bd95SEwan Crawford char buffer[max_expr_size]; 115515f2bd95SEwan Crawford 115615f2bd95SEwan Crawford int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->context.get(), *allocation->address.get()); 115715f2bd95SEwan Crawford if (chars_written < 0) 115815f2bd95SEwan Crawford { 115915f2bd95SEwan Crawford if (log) 116015f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()"); 116115f2bd95SEwan Crawford return false; 116215f2bd95SEwan Crawford } 116315f2bd95SEwan Crawford else if (chars_written >= max_expr_size) 116415f2bd95SEwan Crawford { 116515f2bd95SEwan Crawford if (log) 116615f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITTypePointer - Expression too long"); 116715f2bd95SEwan Crawford return false; 116815f2bd95SEwan Crawford } 116915f2bd95SEwan Crawford 117015f2bd95SEwan Crawford uint64_t result = 0; 117115f2bd95SEwan Crawford if (!EvalRSExpression(buffer, frame_ptr, &result)) 117215f2bd95SEwan Crawford return false; 117315f2bd95SEwan Crawford 117415f2bd95SEwan Crawford addr_t type_ptr = static_cast<lldb::addr_t>(result); 117515f2bd95SEwan Crawford allocation->type_ptr = type_ptr; 117615f2bd95SEwan Crawford 117715f2bd95SEwan Crawford return true; 117815f2bd95SEwan Crawford } 117915f2bd95SEwan Crawford 118015f2bd95SEwan Crawford // JITs the RS runtime for information about the dimensions and type of an allocation 118115f2bd95SEwan Crawford // Then sets dimension and element_ptr members in Allocation with the result. 118215f2bd95SEwan Crawford // Returns true on success, false otherwise 118315f2bd95SEwan Crawford bool 118415f2bd95SEwan Crawford RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr) 118515f2bd95SEwan Crawford { 118615f2bd95SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 118715f2bd95SEwan Crawford 118815f2bd95SEwan Crawford if (!allocation->type_ptr.isValid() || !allocation->context.isValid()) 118915f2bd95SEwan Crawford { 119015f2bd95SEwan Crawford if (log) 119115f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITTypePacked - Failed to find allocation details"); 119215f2bd95SEwan Crawford return false; 119315f2bd95SEwan Crawford } 119415f2bd95SEwan Crawford 119515f2bd95SEwan Crawford // Expression is different depending on if device is 32 or 64 bit 119615f2bd95SEwan Crawford uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize(); 119715f2bd95SEwan Crawford const unsigned int bits = archByteSize == 4 ? 32 : 64; 119815f2bd95SEwan Crawford 119915f2bd95SEwan Crawford // We want 4 elements from packed data 120015f2bd95SEwan Crawford const unsigned int num_exprs = 4; 120115f2bd95SEwan Crawford assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1) && "Invalid number of expressions"); 120215f2bd95SEwan Crawford 120315f2bd95SEwan Crawford const int max_expr_size = 512; // Max expression size 120415f2bd95SEwan Crawford char buffer[num_exprs][max_expr_size]; 120515f2bd95SEwan Crawford uint64_t results[num_exprs]; 120615f2bd95SEwan Crawford 120715f2bd95SEwan Crawford for (unsigned int i = 0; i < num_exprs; ++i) 120815f2bd95SEwan Crawford { 120915f2bd95SEwan Crawford int chars_written = snprintf(buffer[i], max_expr_size, runtimeExpressions[eExprTypeDimX + i], bits, 121015f2bd95SEwan Crawford *allocation->context.get(), *allocation->type_ptr.get()); 121115f2bd95SEwan Crawford if (chars_written < 0) 121215f2bd95SEwan Crawford { 121315f2bd95SEwan Crawford if (log) 121415f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()"); 121515f2bd95SEwan Crawford return false; 121615f2bd95SEwan Crawford } 121715f2bd95SEwan Crawford else if (chars_written >= max_expr_size) 121815f2bd95SEwan Crawford { 121915f2bd95SEwan Crawford if (log) 122015f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITTypePacked - Expression too long"); 122115f2bd95SEwan Crawford return false; 122215f2bd95SEwan Crawford } 122315f2bd95SEwan Crawford 122415f2bd95SEwan Crawford // Perform expression evaluation 122515f2bd95SEwan Crawford if (!EvalRSExpression(buffer[i], frame_ptr, &results[i])) 122615f2bd95SEwan Crawford return false; 122715f2bd95SEwan Crawford } 122815f2bd95SEwan Crawford 122915f2bd95SEwan Crawford // Assign results to allocation members 123015f2bd95SEwan Crawford AllocationDetails::Dimension dims; 123115f2bd95SEwan Crawford dims.dim_1 = static_cast<uint32_t>(results[0]); 123215f2bd95SEwan Crawford dims.dim_2 = static_cast<uint32_t>(results[1]); 123315f2bd95SEwan Crawford dims.dim_3 = static_cast<uint32_t>(results[2]); 123415f2bd95SEwan Crawford allocation->dimension = dims; 123515f2bd95SEwan Crawford 123615f2bd95SEwan Crawford addr_t elem_ptr = static_cast<lldb::addr_t>(results[3]); 123715f2bd95SEwan Crawford allocation->element_ptr = elem_ptr; 123815f2bd95SEwan Crawford 123915f2bd95SEwan Crawford if (log) 124015f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITTypePacked - dims (%u, %u, %u) Element*: 0x%" PRIx64, 124115f2bd95SEwan Crawford dims.dim_1, dims.dim_2, dims.dim_3, elem_ptr); 124215f2bd95SEwan Crawford 124315f2bd95SEwan Crawford return true; 124415f2bd95SEwan Crawford } 124515f2bd95SEwan Crawford 124615f2bd95SEwan Crawford // JITs the RS runtime for information about the Element of an allocation 124715f2bd95SEwan Crawford // Then sets type, type_vec_size, and type_kind members in Allocation with the result. 124815f2bd95SEwan Crawford // Returns true on success, false otherwise 124915f2bd95SEwan Crawford bool 125015f2bd95SEwan Crawford RenderScriptRuntime::JITElementPacked(AllocationDetails* allocation, StackFrame* frame_ptr) 125115f2bd95SEwan Crawford { 125215f2bd95SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 125315f2bd95SEwan Crawford 125415f2bd95SEwan Crawford if (!allocation->element_ptr.isValid() || !allocation->context.isValid()) 125515f2bd95SEwan Crawford { 125615f2bd95SEwan Crawford if (log) 125715f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITElementPacked - Failed to find allocation details"); 125815f2bd95SEwan Crawford return false; 125915f2bd95SEwan Crawford } 126015f2bd95SEwan Crawford 126115f2bd95SEwan Crawford // We want 3 elements from packed data 126215f2bd95SEwan Crawford const unsigned int num_exprs = 3; 126315f2bd95SEwan Crawford assert(num_exprs == (eExprElementVec - eExprElementType + 1) && "Invalid number of expressions"); 126415f2bd95SEwan Crawford 126515f2bd95SEwan Crawford const int max_expr_size = 512; // Max expression size 126615f2bd95SEwan Crawford char buffer[num_exprs][max_expr_size]; 126715f2bd95SEwan Crawford uint64_t results[num_exprs]; 126815f2bd95SEwan Crawford 126915f2bd95SEwan Crawford for (unsigned int i = 0; i < num_exprs; i++) 127015f2bd95SEwan Crawford { 127115f2bd95SEwan Crawford int chars_written = snprintf(buffer[i], max_expr_size, runtimeExpressions[eExprElementType + i], *allocation->context.get(), *allocation->element_ptr.get()); 127215f2bd95SEwan Crawford if (chars_written < 0) 127315f2bd95SEwan Crawford { 127415f2bd95SEwan Crawford if (log) 127515f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()"); 127615f2bd95SEwan Crawford return false; 127715f2bd95SEwan Crawford } 127815f2bd95SEwan Crawford else if (chars_written >= max_expr_size) 127915f2bd95SEwan Crawford { 128015f2bd95SEwan Crawford if (log) 128115f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITElementPacked - Expression too long"); 128215f2bd95SEwan Crawford return false; 128315f2bd95SEwan Crawford } 128415f2bd95SEwan Crawford 128515f2bd95SEwan Crawford // Perform expression evaluation 128615f2bd95SEwan Crawford if (!EvalRSExpression(buffer[i], frame_ptr, &results[i])) 128715f2bd95SEwan Crawford return false; 128815f2bd95SEwan Crawford } 128915f2bd95SEwan Crawford 129015f2bd95SEwan Crawford // Assign results to allocation members 129115f2bd95SEwan Crawford allocation->type = static_cast<RenderScriptRuntime::AllocationDetails::DataType>(results[0]); 129215f2bd95SEwan Crawford allocation->type_kind = static_cast<RenderScriptRuntime::AllocationDetails::DataKind>(results[1]); 129315f2bd95SEwan Crawford allocation->type_vec_size = static_cast<uint32_t>(results[2]); 129415f2bd95SEwan Crawford 129515f2bd95SEwan Crawford if (log) 129615f2bd95SEwan Crawford log->Printf("RenderScriptRuntime::JITElementPacked - data type %u, pixel type %u, vector size %u", 129715f2bd95SEwan Crawford *allocation->type.get(), *allocation->type_kind.get(), *allocation->type_vec_size.get()); 129815f2bd95SEwan Crawford 129915f2bd95SEwan Crawford return true; 130015f2bd95SEwan Crawford } 130115f2bd95SEwan Crawford 1302a0f08674SEwan Crawford // JITs the RS runtime for the address of the last element in the allocation. 1303a0f08674SEwan Crawford // The `elem_size` paramter represents the size of a single element, including padding. 1304a0f08674SEwan Crawford // Which is needed as an offset from the last element pointer. 1305a0f08674SEwan Crawford // Using this offset minus the starting address we can calculate the size of the allocation. 1306a0f08674SEwan Crawford // Returns true on success, false otherwise 1307a0f08674SEwan Crawford bool 1308a0f08674SEwan Crawford RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame* frame_ptr, 1309a0f08674SEwan Crawford const uint32_t elem_size) 1310a0f08674SEwan Crawford { 1311a0f08674SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1312a0f08674SEwan Crawford 1313a0f08674SEwan Crawford if (!allocation->address.isValid() || !allocation->dimension.isValid() 1314a0f08674SEwan Crawford || !allocation->data_ptr.isValid()) 1315a0f08674SEwan Crawford { 1316a0f08674SEwan Crawford if (log) 1317a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::JITAllocationSize - Failed to find allocation details"); 1318a0f08674SEwan Crawford return false; 1319a0f08674SEwan Crawford } 1320a0f08674SEwan Crawford 1321a0f08674SEwan Crawford const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr]; 1322a0f08674SEwan Crawford const int max_expr_size = 512; // Max expression size 1323a0f08674SEwan Crawford char buffer[max_expr_size]; 1324a0f08674SEwan Crawford 1325a0f08674SEwan Crawford // Find dimensions 1326a0f08674SEwan Crawford unsigned int dim_x = allocation->dimension.get()->dim_1; 1327a0f08674SEwan Crawford unsigned int dim_y = allocation->dimension.get()->dim_2; 1328a0f08674SEwan Crawford unsigned int dim_z = allocation->dimension.get()->dim_3; 1329a0f08674SEwan Crawford 1330a0f08674SEwan Crawford // Calculate last element 1331a0f08674SEwan Crawford dim_x = dim_x == 0 ? 0 : dim_x - 1; 1332a0f08674SEwan Crawford dim_y = dim_y == 0 ? 0 : dim_y - 1; 1333a0f08674SEwan Crawford dim_z = dim_z == 0 ? 0 : dim_z - 1; 1334a0f08674SEwan Crawford 1335a0f08674SEwan Crawford int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->address.get(), 1336a0f08674SEwan Crawford dim_x, dim_y, dim_z); 1337a0f08674SEwan Crawford if (chars_written < 0) 1338a0f08674SEwan Crawford { 1339a0f08674SEwan Crawford if (log) 1340a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::JITAllocationSize - 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::JITAllocationSize - 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 // Find pointer to last element and add on size of an element 1356a0f08674SEwan Crawford allocation->size = static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get()) + elem_size; 1357a0f08674SEwan Crawford 1358a0f08674SEwan Crawford return true; 1359a0f08674SEwan Crawford } 1360a0f08674SEwan Crawford 1361a0f08674SEwan Crawford // JITs the RS runtime for information about the stride between rows in the allocation. 1362a0f08674SEwan Crawford // This is done to detect padding, since allocated memory is 16-byte aligned. 1363a0f08674SEwan Crawford // Returns true on success, false otherwise 1364a0f08674SEwan Crawford bool 1365a0f08674SEwan Crawford RenderScriptRuntime::JITAllocationStride(AllocationDetails* allocation, StackFrame* frame_ptr) 1366a0f08674SEwan Crawford { 1367a0f08674SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1368a0f08674SEwan Crawford 1369a0f08674SEwan Crawford if (!allocation->address.isValid() || !allocation->data_ptr.isValid()) 1370a0f08674SEwan Crawford { 1371a0f08674SEwan Crawford if (log) 1372a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::JITAllocationStride - Failed to find allocation details"); 1373a0f08674SEwan Crawford return false; 1374a0f08674SEwan Crawford } 1375a0f08674SEwan Crawford 1376a0f08674SEwan Crawford const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr]; 1377a0f08674SEwan Crawford const int max_expr_size = 512; // Max expression size 1378a0f08674SEwan Crawford char buffer[max_expr_size]; 1379a0f08674SEwan Crawford 1380a0f08674SEwan Crawford int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->address.get(), 1381a0f08674SEwan Crawford 0, 1, 0); 1382a0f08674SEwan Crawford if (chars_written < 0) 1383a0f08674SEwan Crawford { 1384a0f08674SEwan Crawford if (log) 1385a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::JITAllocationStride - Encoding error in snprintf()"); 1386a0f08674SEwan Crawford return false; 1387a0f08674SEwan Crawford } 1388a0f08674SEwan Crawford else if (chars_written >= max_expr_size) 1389a0f08674SEwan Crawford { 1390a0f08674SEwan Crawford if (log) 1391a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::JITAllocationStride - Expression too long"); 1392a0f08674SEwan Crawford return false; 1393a0f08674SEwan Crawford } 1394a0f08674SEwan Crawford 1395a0f08674SEwan Crawford uint64_t result = 0; 1396a0f08674SEwan Crawford if (!EvalRSExpression(buffer, frame_ptr, &result)) 1397a0f08674SEwan Crawford return false; 1398a0f08674SEwan Crawford 1399a0f08674SEwan Crawford addr_t mem_ptr = static_cast<lldb::addr_t>(result); 1400a0f08674SEwan Crawford allocation->stride = static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get()); 1401a0f08674SEwan Crawford 1402a0f08674SEwan Crawford return true; 1403a0f08674SEwan Crawford } 1404a0f08674SEwan Crawford 140515f2bd95SEwan Crawford // JIT all the current runtime info regarding an allocation 140615f2bd95SEwan Crawford bool 140715f2bd95SEwan Crawford RenderScriptRuntime::RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr) 140815f2bd95SEwan Crawford { 140915f2bd95SEwan Crawford // GetOffsetPointer() 141015f2bd95SEwan Crawford if (!JITDataPointer(allocation, frame_ptr)) 141115f2bd95SEwan Crawford return false; 141215f2bd95SEwan Crawford 141315f2bd95SEwan Crawford // rsaAllocationGetType() 141415f2bd95SEwan Crawford if (!JITTypePointer(allocation, frame_ptr)) 141515f2bd95SEwan Crawford return false; 141615f2bd95SEwan Crawford 141715f2bd95SEwan Crawford // rsaTypeGetNativeData() 141815f2bd95SEwan Crawford if (!JITTypePacked(allocation, frame_ptr)) 141915f2bd95SEwan Crawford return false; 142015f2bd95SEwan Crawford 142115f2bd95SEwan Crawford // rsaElementGetNativeData() 142215f2bd95SEwan Crawford if (!JITElementPacked(allocation, frame_ptr)) 142315f2bd95SEwan Crawford return false; 142415f2bd95SEwan Crawford 142555232f09SEwan Crawford // Use GetOffsetPointer() to infer size of the allocation 142655232f09SEwan Crawford const unsigned int element_size = GetElementSize(allocation); 142755232f09SEwan Crawford if (!JITAllocationSize(allocation, frame_ptr, element_size)) 142855232f09SEwan Crawford return false; 142955232f09SEwan Crawford 143055232f09SEwan Crawford return true; 143155232f09SEwan Crawford } 143255232f09SEwan Crawford 143355232f09SEwan Crawford // Returns the size of a single allocation element including padding. 143455232f09SEwan Crawford // Assumes the relevant allocation information has already been jitted. 143555232f09SEwan Crawford unsigned int 143655232f09SEwan Crawford RenderScriptRuntime::GetElementSize(const AllocationDetails* allocation) 143755232f09SEwan Crawford { 143855232f09SEwan Crawford const AllocationDetails::DataType type = *allocation->type.get(); 143955232f09SEwan Crawford assert(type >= AllocationDetails::RS_TYPE_NONE && type <= AllocationDetails::RS_TYPE_BOOLEAN 144055232f09SEwan Crawford && "Invalid allocation type"); 144155232f09SEwan Crawford 144255232f09SEwan Crawford const unsigned int vec_size = *allocation->type_vec_size.get(); 144355232f09SEwan Crawford const unsigned int data_size = vec_size * AllocationDetails::RSTypeToFormat[type][eElementSize]; 144455232f09SEwan Crawford const unsigned int padding = vec_size == 3 ? AllocationDetails::RSTypeToFormat[type][eElementSize] : 0; 144555232f09SEwan Crawford 144655232f09SEwan Crawford return data_size + padding; 144755232f09SEwan Crawford } 144855232f09SEwan Crawford 144955232f09SEwan Crawford // Given an allocation, this function copies the allocation contents from device into a buffer on the heap. 145055232f09SEwan Crawford // Returning a shared pointer to the buffer containing the data. 145155232f09SEwan Crawford std::shared_ptr<uint8_t> 145255232f09SEwan Crawford RenderScriptRuntime::GetAllocationData(AllocationDetails* allocation, StackFrame* frame_ptr) 145355232f09SEwan Crawford { 145455232f09SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 145555232f09SEwan Crawford 145655232f09SEwan Crawford // JIT all the allocation details 145755232f09SEwan Crawford if (!allocation->data_ptr.isValid() || !allocation->type.isValid() || !allocation->type_vec_size.isValid() 145855232f09SEwan Crawford || !allocation->size.isValid()) 145955232f09SEwan Crawford { 146055232f09SEwan Crawford if (log) 146155232f09SEwan Crawford log->Printf("RenderScriptRuntime::GetAllocationData - Allocation details not calculated yet, jitting info"); 146255232f09SEwan Crawford 146355232f09SEwan Crawford if (!RefreshAllocation(allocation, frame_ptr)) 146455232f09SEwan Crawford { 146555232f09SEwan Crawford if (log) 146655232f09SEwan Crawford log->Printf("RenderScriptRuntime::GetAllocationData - Couldn't JIT allocation details"); 146755232f09SEwan Crawford return nullptr; 146855232f09SEwan Crawford } 146955232f09SEwan Crawford } 147055232f09SEwan Crawford 147155232f09SEwan Crawford assert(allocation->data_ptr.isValid() && allocation->type.isValid() && allocation->type_vec_size.isValid() 147255232f09SEwan Crawford && allocation->size.isValid() && "Allocation information not available"); 147355232f09SEwan Crawford 147455232f09SEwan Crawford // Allocate a buffer to copy data into 147555232f09SEwan Crawford const unsigned int size = *allocation->size.get(); 147655232f09SEwan Crawford std::shared_ptr<uint8_t> buffer(new uint8_t[size]); 147755232f09SEwan Crawford if (!buffer) 147855232f09SEwan Crawford { 147955232f09SEwan Crawford if (log) 148055232f09SEwan Crawford log->Printf("RenderScriptRuntime::GetAllocationData - Couldn't allocate a %u byte buffer", size); 148155232f09SEwan Crawford return nullptr; 148255232f09SEwan Crawford } 148355232f09SEwan Crawford 148455232f09SEwan Crawford // Read the inferior memory 148555232f09SEwan Crawford Error error; 148655232f09SEwan Crawford lldb::addr_t data_ptr = *allocation->data_ptr.get(); 148755232f09SEwan Crawford GetProcess()->ReadMemory(data_ptr, buffer.get(), size, error); 148855232f09SEwan Crawford if (error.Fail()) 148955232f09SEwan Crawford { 149055232f09SEwan Crawford if (log) 149155232f09SEwan Crawford log->Printf("RenderScriptRuntime::GetAllocationData - '%s' Couldn't read %u bytes of allocation data from 0x%" PRIx64, 149255232f09SEwan Crawford error.AsCString(), size, data_ptr); 149355232f09SEwan Crawford return nullptr; 149455232f09SEwan Crawford } 149555232f09SEwan Crawford 149655232f09SEwan Crawford return buffer; 149755232f09SEwan Crawford } 149855232f09SEwan Crawford 149955232f09SEwan Crawford // Function copies data from a binary file into an allocation. 150055232f09SEwan Crawford // There is a header at the start of the file, FileHeader, before the data content itself. 150155232f09SEwan Crawford // Information from this header is used to display warnings to the user about incompatabilities 150255232f09SEwan Crawford bool 150355232f09SEwan Crawford RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr) 150455232f09SEwan Crawford { 150555232f09SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 150655232f09SEwan Crawford 150755232f09SEwan Crawford // Find allocation with the given id 150855232f09SEwan Crawford AllocationDetails* alloc = FindAllocByID(strm, alloc_id); 150955232f09SEwan Crawford if (!alloc) 151055232f09SEwan Crawford return false; 151155232f09SEwan Crawford 151255232f09SEwan Crawford if (log) 151355232f09SEwan Crawford log->Printf("RenderScriptRuntime::LoadAllocation - Found allocation 0x%" PRIx64, *alloc->address.get()); 151455232f09SEwan Crawford 151555232f09SEwan Crawford // JIT all the allocation details 151655232f09SEwan Crawford if (!alloc->data_ptr.isValid() || !alloc->type.isValid() || !alloc->type_vec_size.isValid() || !alloc->size.isValid()) 151755232f09SEwan Crawford { 151855232f09SEwan Crawford if (log) 151955232f09SEwan Crawford log->Printf("RenderScriptRuntime::LoadAllocation - Allocation details not calculated yet, jitting info"); 152055232f09SEwan Crawford 152155232f09SEwan Crawford if (!RefreshAllocation(alloc, frame_ptr)) 152255232f09SEwan Crawford { 152355232f09SEwan Crawford if (log) 152455232f09SEwan Crawford log->Printf("RenderScriptRuntime::LoadAllocation - Couldn't JIT allocation details"); 1525*4cfc9198SSylvestre Ledru return false; 152655232f09SEwan Crawford } 152755232f09SEwan Crawford } 152855232f09SEwan Crawford 152955232f09SEwan Crawford assert(alloc->data_ptr.isValid() && alloc->type.isValid() && alloc->type_vec_size.isValid() && alloc->size.isValid() 153055232f09SEwan Crawford && "Allocation information not available"); 153155232f09SEwan Crawford 153255232f09SEwan Crawford // Check we can read from file 153355232f09SEwan Crawford FileSpec file(filename, true); 153455232f09SEwan Crawford if (!file.Exists()) 153555232f09SEwan Crawford { 153655232f09SEwan Crawford strm.Printf("Error: File %s does not exist", filename); 153755232f09SEwan Crawford strm.EOL(); 153855232f09SEwan Crawford return false; 153955232f09SEwan Crawford } 154055232f09SEwan Crawford 154155232f09SEwan Crawford if (!file.Readable()) 154255232f09SEwan Crawford { 154355232f09SEwan Crawford strm.Printf("Error: File %s does not have readable permissions", filename); 154455232f09SEwan Crawford strm.EOL(); 154555232f09SEwan Crawford return false; 154655232f09SEwan Crawford } 154755232f09SEwan Crawford 154855232f09SEwan Crawford // Read file into data buffer 154955232f09SEwan Crawford DataBufferSP data_sp(file.ReadFileContents()); 155055232f09SEwan Crawford 155155232f09SEwan Crawford // Cast start of buffer to FileHeader and use pointer to read metadata 155255232f09SEwan Crawford void* file_buffer = data_sp->GetBytes(); 155355232f09SEwan Crawford const AllocationDetails::FileHeader* head = static_cast<AllocationDetails::FileHeader*>(file_buffer); 155455232f09SEwan Crawford 155555232f09SEwan Crawford // Advance buffer past header 155655232f09SEwan Crawford file_buffer = static_cast<uint8_t*>(file_buffer) + head->hdr_size; 155755232f09SEwan Crawford 155855232f09SEwan Crawford if (log) 155955232f09SEwan Crawford log->Printf("RenderScriptRuntime::LoadAllocation - header type %u, element size %u", 156055232f09SEwan Crawford head->type, head->element_size); 156155232f09SEwan Crawford 156255232f09SEwan Crawford // Check if the target allocation and file both have the same number of bytes for an Element 156355232f09SEwan Crawford const unsigned int elem_size = GetElementSize(alloc); 156455232f09SEwan Crawford if (elem_size != head->element_size) 156555232f09SEwan Crawford { 156655232f09SEwan Crawford strm.Printf("Warning: Mismatched Element sizes - file %u bytes, allocation %u bytes", 156755232f09SEwan Crawford head->element_size, elem_size); 156855232f09SEwan Crawford strm.EOL(); 156955232f09SEwan Crawford } 157055232f09SEwan Crawford 157155232f09SEwan Crawford // Check if the target allocation and file both have the same integral type 157255232f09SEwan Crawford const unsigned int type = static_cast<unsigned int>(*alloc->type.get()); 157355232f09SEwan Crawford if (type != head->type) 157455232f09SEwan Crawford { 157555232f09SEwan Crawford const char* file_type_cstr = AllocationDetails::RsDataTypeToString[head->type][0]; 157655232f09SEwan Crawford const char* alloc_type_cstr = AllocationDetails::RsDataTypeToString[type][0]; 157755232f09SEwan Crawford 157855232f09SEwan Crawford strm.Printf("Warning: Mismatched Types - file '%s' type, allocation '%s' type", 157955232f09SEwan Crawford file_type_cstr, alloc_type_cstr); 158055232f09SEwan Crawford strm.EOL(); 158155232f09SEwan Crawford } 158255232f09SEwan Crawford 158355232f09SEwan Crawford // Calculate size of allocation data in file 158455232f09SEwan Crawford size_t length = data_sp->GetByteSize() - head->hdr_size; 158555232f09SEwan Crawford 158655232f09SEwan Crawford // Check if the target allocation and file both have the same total data size. 158755232f09SEwan Crawford const unsigned int alloc_size = *alloc->size.get(); 158855232f09SEwan Crawford if (alloc_size != length) 158955232f09SEwan Crawford { 159055232f09SEwan Crawford strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64 " bytes, allocation 0x%x bytes", 159155232f09SEwan Crawford length, alloc_size); 159255232f09SEwan Crawford strm.EOL(); 159355232f09SEwan Crawford length = alloc_size < length ? alloc_size : length; // Set length to copy to minimum 159455232f09SEwan Crawford } 159555232f09SEwan Crawford 159655232f09SEwan Crawford // Copy file data from our buffer into the target allocation. 159755232f09SEwan Crawford lldb::addr_t alloc_data = *alloc->data_ptr.get(); 159855232f09SEwan Crawford Error error; 159955232f09SEwan Crawford size_t bytes_written = GetProcess()->WriteMemory(alloc_data, file_buffer, length, error); 160055232f09SEwan Crawford if (!error.Success() || bytes_written != length) 160155232f09SEwan Crawford { 160255232f09SEwan Crawford strm.Printf("Error: Couldn't write data to allocation %s", error.AsCString()); 160355232f09SEwan Crawford strm.EOL(); 160455232f09SEwan Crawford return false; 160555232f09SEwan Crawford } 160655232f09SEwan Crawford 160755232f09SEwan Crawford strm.Printf("Contents of file '%s' read into allocation %u", filename, alloc->id); 160855232f09SEwan Crawford strm.EOL(); 160955232f09SEwan Crawford 161055232f09SEwan Crawford return true; 161155232f09SEwan Crawford } 161255232f09SEwan Crawford 161355232f09SEwan Crawford // Function copies allocation contents into a binary file. 161455232f09SEwan Crawford // This file can then be loaded later into a different allocation. 161555232f09SEwan Crawford // There is a header, FileHeader, before the allocation data containing meta-data. 161655232f09SEwan Crawford bool 161755232f09SEwan Crawford RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr) 161855232f09SEwan Crawford { 161955232f09SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 162055232f09SEwan Crawford 162155232f09SEwan Crawford // Find allocation with the given id 162255232f09SEwan Crawford AllocationDetails* alloc = FindAllocByID(strm, alloc_id); 162355232f09SEwan Crawford if (!alloc) 162455232f09SEwan Crawford return false; 162555232f09SEwan Crawford 162655232f09SEwan Crawford if (log) 162755232f09SEwan Crawford log->Printf("RenderScriptRuntime::SaveAllocation - Found allocation 0x%" PRIx64, *alloc->address.get()); 162855232f09SEwan Crawford 162955232f09SEwan Crawford // JIT all the allocation details 163055232f09SEwan Crawford if (!alloc->data_ptr.isValid() || !alloc->type.isValid() || !alloc->type_vec_size.isValid() 163155232f09SEwan Crawford || !alloc->type_kind.isValid() || !alloc->dimension.isValid()) 163255232f09SEwan Crawford { 163355232f09SEwan Crawford if (log) 163455232f09SEwan Crawford log->Printf("RenderScriptRuntime::SaveAllocation - Allocation details not calculated yet, jitting info"); 163555232f09SEwan Crawford 163655232f09SEwan Crawford if (!RefreshAllocation(alloc, frame_ptr)) 163755232f09SEwan Crawford { 163855232f09SEwan Crawford if (log) 163955232f09SEwan Crawford log->Printf("RenderScriptRuntime::SaveAllocation - Couldn't JIT allocation details"); 1640*4cfc9198SSylvestre Ledru return false; 164155232f09SEwan Crawford } 164255232f09SEwan Crawford } 164355232f09SEwan Crawford 164455232f09SEwan Crawford assert(alloc->data_ptr.isValid() && alloc->type.isValid() && alloc->type_vec_size.isValid() && alloc->type_kind.isValid() 164555232f09SEwan Crawford && alloc->dimension.isValid() && "Allocation information not available"); 164655232f09SEwan Crawford 164755232f09SEwan Crawford // Check we can create writable file 164855232f09SEwan Crawford FileSpec file_spec(filename, true); 164955232f09SEwan Crawford File file(file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionTruncate); 165055232f09SEwan Crawford if (!file) 165155232f09SEwan Crawford { 165255232f09SEwan Crawford strm.Printf("Error: Failed to open '%s' for writing", filename); 165355232f09SEwan Crawford strm.EOL(); 165455232f09SEwan Crawford return false; 165555232f09SEwan Crawford } 165655232f09SEwan Crawford 165755232f09SEwan Crawford // Read allocation into buffer of heap memory 165855232f09SEwan Crawford const std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr); 165955232f09SEwan Crawford if (!buffer) 166055232f09SEwan Crawford { 166155232f09SEwan Crawford strm.Printf("Error: Couldn't read allocation data into buffer"); 166255232f09SEwan Crawford strm.EOL(); 166355232f09SEwan Crawford return false; 166455232f09SEwan Crawford } 166555232f09SEwan Crawford 166655232f09SEwan Crawford // Create the file header 166755232f09SEwan Crawford AllocationDetails::FileHeader head; 166855232f09SEwan Crawford head.ident[0] = 'R'; head.ident[1] = 'S'; head.ident[2] = 'A'; head.ident[3] = 'D'; 166955232f09SEwan Crawford head.hdr_size = static_cast<uint16_t>(sizeof(AllocationDetails::FileHeader)); 167055232f09SEwan Crawford head.type = static_cast<uint16_t>(*alloc->type.get()); 167155232f09SEwan Crawford head.kind = static_cast<uint32_t>(*alloc->type_kind.get()); 16722d62328aSEwan Crawford head.dims[0] = static_cast<uint32_t>(alloc->dimension.get()->dim_1); 16732d62328aSEwan Crawford head.dims[1] = static_cast<uint32_t>(alloc->dimension.get()->dim_2); 16742d62328aSEwan Crawford head.dims[2] = static_cast<uint32_t>(alloc->dimension.get()->dim_3); 167555232f09SEwan Crawford head.element_size = static_cast<uint32_t>(GetElementSize(alloc)); 167655232f09SEwan Crawford 167755232f09SEwan Crawford // Write the file header 167855232f09SEwan Crawford size_t num_bytes = sizeof(AllocationDetails::FileHeader); 167955232f09SEwan Crawford Error err = file.Write(static_cast<const void*>(&head), num_bytes); 168055232f09SEwan Crawford if (!err.Success()) 168155232f09SEwan Crawford { 168255232f09SEwan Crawford strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), filename); 168355232f09SEwan Crawford strm.EOL(); 168455232f09SEwan Crawford return false; 168555232f09SEwan Crawford } 168655232f09SEwan Crawford 168755232f09SEwan Crawford // Write allocation data to file 168855232f09SEwan Crawford num_bytes = static_cast<size_t>(*alloc->size.get()); 168955232f09SEwan Crawford if (log) 169055232f09SEwan Crawford log->Printf("RenderScriptRuntime::SaveAllocation - Writing %" PRIx64 "bytes from %p", num_bytes, buffer.get()); 169155232f09SEwan Crawford 169255232f09SEwan Crawford err = file.Write(buffer.get(), num_bytes); 169355232f09SEwan Crawford if (!err.Success()) 169455232f09SEwan Crawford { 169555232f09SEwan Crawford strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), filename); 169655232f09SEwan Crawford strm.EOL(); 169755232f09SEwan Crawford return false; 169855232f09SEwan Crawford } 169955232f09SEwan Crawford 170055232f09SEwan Crawford strm.Printf("Allocation written to file '%s'", filename); 170155232f09SEwan Crawford strm.EOL(); 170215f2bd95SEwan Crawford return true; 170315f2bd95SEwan Crawford } 170415f2bd95SEwan Crawford 17055ec532a9SColin Riley bool 17065ec532a9SColin Riley RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) 17075ec532a9SColin Riley { 17084640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 17094640cde1SColin Riley 17105ec532a9SColin Riley if (module_sp) 17115ec532a9SColin Riley { 17125ec532a9SColin Riley for (const auto &rs_module : m_rsmodules) 17135ec532a9SColin Riley { 17144640cde1SColin Riley if (rs_module->m_module == module_sp) 17157dc7771cSEwan Crawford { 17167dc7771cSEwan Crawford // Check if the user has enabled automatically breaking on 17177dc7771cSEwan Crawford // all RS kernels. 17187dc7771cSEwan Crawford if (m_breakAllKernels) 17197dc7771cSEwan Crawford BreakOnModuleKernels(rs_module); 17207dc7771cSEwan Crawford 17215ec532a9SColin Riley return false; 17225ec532a9SColin Riley } 17237dc7771cSEwan Crawford } 1724ef20b08fSColin Riley bool module_loaded = false; 1725ef20b08fSColin Riley switch (GetModuleKind(module_sp)) 1726ef20b08fSColin Riley { 1727ef20b08fSColin Riley case eModuleKindKernelObj: 1728ef20b08fSColin Riley { 17294640cde1SColin Riley RSModuleDescriptorSP module_desc; 17304640cde1SColin Riley module_desc.reset(new RSModuleDescriptor(module_sp)); 17314640cde1SColin Riley if (module_desc->ParseRSInfo()) 17325ec532a9SColin Riley { 17335ec532a9SColin Riley m_rsmodules.push_back(module_desc); 1734ef20b08fSColin Riley module_loaded = true; 17355ec532a9SColin Riley } 17364640cde1SColin Riley if (module_loaded) 17374640cde1SColin Riley { 17384640cde1SColin Riley FixupScriptDetails(module_desc); 17394640cde1SColin Riley } 1740ef20b08fSColin Riley break; 1741ef20b08fSColin Riley } 1742ef20b08fSColin Riley case eModuleKindDriver: 17434640cde1SColin Riley { 17444640cde1SColin Riley if (!m_libRSDriver) 17454640cde1SColin Riley { 17464640cde1SColin Riley m_libRSDriver = module_sp; 17474640cde1SColin Riley LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver); 17484640cde1SColin Riley } 17494640cde1SColin Riley break; 17504640cde1SColin Riley } 1751ef20b08fSColin Riley case eModuleKindImpl: 17524640cde1SColin Riley { 17534640cde1SColin Riley m_libRSCpuRef = module_sp; 17544640cde1SColin Riley break; 17554640cde1SColin Riley } 1756ef20b08fSColin Riley case eModuleKindLibRS: 17574640cde1SColin Riley { 17584640cde1SColin Riley if (!m_libRS) 17594640cde1SColin Riley { 17604640cde1SColin Riley m_libRS = module_sp; 17614640cde1SColin Riley static ConstString gDbgPresentStr("gDebuggerPresent"); 17624640cde1SColin Riley const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData); 17634640cde1SColin Riley if (debug_present) 17644640cde1SColin Riley { 17654640cde1SColin Riley Error error; 17664640cde1SColin Riley uint32_t flag = 0x00000001U; 17674640cde1SColin Riley Target &target = GetProcess()->GetTarget(); 1768358cf1eaSGreg Clayton addr_t addr = debug_present->GetLoadAddress(&target); 17694640cde1SColin Riley GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error); 17704640cde1SColin Riley if(error.Success()) 17714640cde1SColin Riley { 17724640cde1SColin Riley if (log) 17734640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee"); 17744640cde1SColin Riley 17754640cde1SColin Riley m_debuggerPresentFlagged = true; 17764640cde1SColin Riley } 17774640cde1SColin Riley else if (log) 17784640cde1SColin Riley { 17794640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString()); 17804640cde1SColin Riley } 17814640cde1SColin Riley } 17824640cde1SColin Riley else if (log) 17834640cde1SColin Riley { 17844640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found"); 17854640cde1SColin Riley } 17864640cde1SColin Riley } 17874640cde1SColin Riley break; 17884640cde1SColin Riley } 1789ef20b08fSColin Riley default: 1790ef20b08fSColin Riley break; 1791ef20b08fSColin Riley } 1792ef20b08fSColin Riley if (module_loaded) 1793ef20b08fSColin Riley Update(); 1794ef20b08fSColin Riley return module_loaded; 17955ec532a9SColin Riley } 17965ec532a9SColin Riley return false; 17975ec532a9SColin Riley } 17985ec532a9SColin Riley 1799ef20b08fSColin Riley void 1800ef20b08fSColin Riley RenderScriptRuntime::Update() 1801ef20b08fSColin Riley { 1802ef20b08fSColin Riley if (m_rsmodules.size() > 0) 1803ef20b08fSColin Riley { 1804ef20b08fSColin Riley if (!m_initiated) 1805ef20b08fSColin Riley { 1806ef20b08fSColin Riley Initiate(); 1807ef20b08fSColin Riley } 1808ef20b08fSColin Riley } 1809ef20b08fSColin Riley } 1810ef20b08fSColin Riley 1811ef20b08fSColin Riley 18125ec532a9SColin Riley // The maximum line length of an .rs.info packet 18135ec532a9SColin Riley #define MAXLINE 500 18145ec532a9SColin Riley 18155ec532a9SColin Riley // The .rs.info symbol in renderscript modules contains a string which needs to be parsed. 18165ec532a9SColin Riley // The string is basic and is parsed on a line by line basis. 18175ec532a9SColin Riley bool 18185ec532a9SColin Riley RSModuleDescriptor::ParseRSInfo() 18195ec532a9SColin Riley { 18205ec532a9SColin Riley const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData); 18215ec532a9SColin Riley if (info_sym) 18225ec532a9SColin Riley { 1823358cf1eaSGreg Clayton const addr_t addr = info_sym->GetAddressRef().GetFileAddress(); 18245ec532a9SColin Riley const addr_t size = info_sym->GetByteSize(); 18255ec532a9SColin Riley const FileSpec fs = m_module->GetFileSpec(); 18265ec532a9SColin Riley 18275ec532a9SColin Riley DataBufferSP buffer = fs.ReadFileContents(addr, size); 18285ec532a9SColin Riley 18295ec532a9SColin Riley if (!buffer) 18305ec532a9SColin Riley return false; 18315ec532a9SColin Riley 18325ec532a9SColin Riley std::string info((const char *)buffer->GetBytes()); 18335ec532a9SColin Riley 18345ec532a9SColin Riley std::vector<std::string> info_lines; 1835e8433cc1SBruce Mitchener size_t lpos = info.find('\n'); 18365ec532a9SColin Riley while (lpos != std::string::npos) 18375ec532a9SColin Riley { 18385ec532a9SColin Riley info_lines.push_back(info.substr(0, lpos)); 18395ec532a9SColin Riley info = info.substr(lpos + 1); 1840e8433cc1SBruce Mitchener lpos = info.find('\n'); 18415ec532a9SColin Riley } 18425ec532a9SColin Riley size_t offset = 0; 18435ec532a9SColin Riley while (offset < info_lines.size()) 18445ec532a9SColin Riley { 18455ec532a9SColin Riley std::string line = info_lines[offset]; 18465ec532a9SColin Riley // Parse directives 18475ec532a9SColin Riley uint32_t numDefns = 0; 18485ec532a9SColin Riley if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1) 18495ec532a9SColin Riley { 18505ec532a9SColin Riley while (numDefns--) 18514640cde1SColin Riley m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str())); 18525ec532a9SColin Riley } 18535ec532a9SColin Riley else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1) 18545ec532a9SColin Riley { 18555ec532a9SColin Riley } 18565ec532a9SColin Riley else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1) 18575ec532a9SColin Riley { 18585ec532a9SColin Riley char name[MAXLINE]; 18595ec532a9SColin Riley while (numDefns--) 18605ec532a9SColin Riley { 18615ec532a9SColin Riley uint32_t slot = 0; 18625ec532a9SColin Riley name[0] = '\0'; 18635ec532a9SColin Riley if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2) 18645ec532a9SColin Riley { 18654640cde1SColin Riley m_kernels.push_back(RSKernelDescriptor(this, name, slot)); 18664640cde1SColin Riley } 18674640cde1SColin Riley } 18684640cde1SColin Riley } 18694640cde1SColin Riley else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1) 18704640cde1SColin Riley { 18714640cde1SColin Riley char name[MAXLINE]; 18724640cde1SColin Riley char value[MAXLINE]; 18734640cde1SColin Riley while (numDefns--) 18744640cde1SColin Riley { 18754640cde1SColin Riley name[0] = '\0'; 18764640cde1SColin Riley value[0] = '\0'; 18774640cde1SColin Riley if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0 18784640cde1SColin Riley && (name[0] != '\0')) 18794640cde1SColin Riley { 18804640cde1SColin Riley m_pragmas[std::string(name)] = value; 18815ec532a9SColin Riley } 18825ec532a9SColin Riley } 18835ec532a9SColin Riley } 18845ec532a9SColin Riley else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1) 18855ec532a9SColin Riley { 18865ec532a9SColin Riley } 18875ec532a9SColin Riley 18885ec532a9SColin Riley offset++; 18895ec532a9SColin Riley } 18905ec532a9SColin Riley return m_kernels.size() > 0; 18915ec532a9SColin Riley } 18925ec532a9SColin Riley return false; 18935ec532a9SColin Riley } 18945ec532a9SColin Riley 18955ec532a9SColin Riley bool 18965ec532a9SColin Riley RenderScriptRuntime::ProbeModules(const ModuleList module_list) 18975ec532a9SColin Riley { 18985ec532a9SColin Riley bool rs_found = false; 18995ec532a9SColin Riley size_t num_modules = module_list.GetSize(); 19005ec532a9SColin Riley for (size_t i = 0; i < num_modules; i++) 19015ec532a9SColin Riley { 19025ec532a9SColin Riley auto module = module_list.GetModuleAtIndex(i); 19035ec532a9SColin Riley rs_found |= LoadModule(module); 19045ec532a9SColin Riley } 19055ec532a9SColin Riley return rs_found; 19065ec532a9SColin Riley } 19075ec532a9SColin Riley 19085ec532a9SColin Riley void 19094640cde1SColin Riley RenderScriptRuntime::Status(Stream &strm) const 19104640cde1SColin Riley { 19114640cde1SColin Riley if (m_libRS) 19124640cde1SColin Riley { 19134640cde1SColin Riley strm.Printf("Runtime Library discovered."); 19144640cde1SColin Riley strm.EOL(); 19154640cde1SColin Riley } 19164640cde1SColin Riley if (m_libRSDriver) 19174640cde1SColin Riley { 19184640cde1SColin Riley strm.Printf("Runtime Driver discovered."); 19194640cde1SColin Riley strm.EOL(); 19204640cde1SColin Riley } 19214640cde1SColin Riley if (m_libRSCpuRef) 19224640cde1SColin Riley { 19234640cde1SColin Riley strm.Printf("CPU Reference Implementation discovered."); 19244640cde1SColin Riley strm.EOL(); 19254640cde1SColin Riley } 19264640cde1SColin Riley 19274640cde1SColin Riley if (m_runtimeHooks.size()) 19284640cde1SColin Riley { 19294640cde1SColin Riley strm.Printf("Runtime functions hooked:"); 19304640cde1SColin Riley strm.EOL(); 19314640cde1SColin Riley for (auto b : m_runtimeHooks) 19324640cde1SColin Riley { 19334640cde1SColin Riley strm.Indent(b.second->defn->name); 19344640cde1SColin Riley strm.EOL(); 19354640cde1SColin Riley } 19364640cde1SColin Riley strm.EOL(); 19374640cde1SColin Riley } 19384640cde1SColin Riley else 19394640cde1SColin Riley { 19404640cde1SColin Riley strm.Printf("Runtime is not hooked."); 19414640cde1SColin Riley strm.EOL(); 19424640cde1SColin Riley } 19434640cde1SColin Riley } 19444640cde1SColin Riley 19454640cde1SColin Riley void 19464640cde1SColin Riley RenderScriptRuntime::DumpContexts(Stream &strm) const 19474640cde1SColin Riley { 19484640cde1SColin Riley strm.Printf("Inferred RenderScript Contexts:"); 19494640cde1SColin Riley strm.EOL(); 19504640cde1SColin Riley strm.IndentMore(); 19514640cde1SColin Riley 19524640cde1SColin Riley std::map<addr_t, uint64_t> contextReferences; 19534640cde1SColin Riley 195478f339d1SEwan Crawford // Iterate over all of the currently discovered scripts. 195578f339d1SEwan Crawford // Note: We cant push or pop from m_scripts inside this loop or it may invalidate script. 19564640cde1SColin Riley for (const auto & script : m_scripts) 19574640cde1SColin Riley { 195878f339d1SEwan Crawford if (!script->context.isValid()) 195978f339d1SEwan Crawford continue; 196078f339d1SEwan Crawford lldb::addr_t context = *script->context; 196178f339d1SEwan Crawford 196278f339d1SEwan Crawford if (contextReferences.find(context) != contextReferences.end()) 19634640cde1SColin Riley { 196478f339d1SEwan Crawford contextReferences[context]++; 19654640cde1SColin Riley } 19664640cde1SColin Riley else 19674640cde1SColin Riley { 196878f339d1SEwan Crawford contextReferences[context] = 1; 19694640cde1SColin Riley } 19704640cde1SColin Riley } 19714640cde1SColin Riley 19724640cde1SColin Riley for (const auto& cRef : contextReferences) 19734640cde1SColin Riley { 19744640cde1SColin Riley strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second); 19754640cde1SColin Riley strm.EOL(); 19764640cde1SColin Riley } 19774640cde1SColin Riley strm.IndentLess(); 19784640cde1SColin Riley } 19794640cde1SColin Riley 19804640cde1SColin Riley void 19814640cde1SColin Riley RenderScriptRuntime::DumpKernels(Stream &strm) const 19824640cde1SColin Riley { 19834640cde1SColin Riley strm.Printf("RenderScript Kernels:"); 19844640cde1SColin Riley strm.EOL(); 19854640cde1SColin Riley strm.IndentMore(); 19864640cde1SColin Riley for (const auto &module : m_rsmodules) 19874640cde1SColin Riley { 19884640cde1SColin Riley strm.Printf("Resource '%s':",module->m_resname.c_str()); 19894640cde1SColin Riley strm.EOL(); 19904640cde1SColin Riley for (const auto &kernel : module->m_kernels) 19914640cde1SColin Riley { 19924640cde1SColin Riley strm.Indent(kernel.m_name.AsCString()); 19934640cde1SColin Riley strm.EOL(); 19944640cde1SColin Riley } 19954640cde1SColin Riley } 19964640cde1SColin Riley strm.IndentLess(); 19974640cde1SColin Riley } 19984640cde1SColin Riley 1999a0f08674SEwan Crawford RenderScriptRuntime::AllocationDetails* 2000a0f08674SEwan Crawford RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id) 2001a0f08674SEwan Crawford { 2002a0f08674SEwan Crawford AllocationDetails* alloc = nullptr; 2003a0f08674SEwan Crawford 2004a0f08674SEwan Crawford // See if we can find allocation using id as an index; 2005a0f08674SEwan Crawford if (alloc_id <= m_allocations.size() && alloc_id != 0 2006a0f08674SEwan Crawford && m_allocations[alloc_id-1]->id == alloc_id) 2007a0f08674SEwan Crawford { 2008a0f08674SEwan Crawford alloc = m_allocations[alloc_id-1].get(); 2009a0f08674SEwan Crawford return alloc; 2010a0f08674SEwan Crawford } 2011a0f08674SEwan Crawford 2012a0f08674SEwan Crawford // Fallback to searching 2013a0f08674SEwan Crawford for (const auto & a : m_allocations) 2014a0f08674SEwan Crawford { 2015a0f08674SEwan Crawford if (a->id == alloc_id) 2016a0f08674SEwan Crawford { 2017a0f08674SEwan Crawford alloc = a.get(); 2018a0f08674SEwan Crawford break; 2019a0f08674SEwan Crawford } 2020a0f08674SEwan Crawford } 2021a0f08674SEwan Crawford 2022a0f08674SEwan Crawford if (alloc == nullptr) 2023a0f08674SEwan Crawford { 2024a0f08674SEwan Crawford strm.Printf("Error: Couldn't find allocation with id matching %u", alloc_id); 2025a0f08674SEwan Crawford strm.EOL(); 2026a0f08674SEwan Crawford } 2027a0f08674SEwan Crawford 2028a0f08674SEwan Crawford return alloc; 2029a0f08674SEwan Crawford } 2030a0f08674SEwan Crawford 2031a0f08674SEwan Crawford // Prints the contents of an allocation to the output stream, which may be a file 2032a0f08674SEwan Crawford bool 2033a0f08674SEwan Crawford RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const uint32_t id) 2034a0f08674SEwan Crawford { 2035a0f08674SEwan Crawford Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 2036a0f08674SEwan Crawford 2037a0f08674SEwan Crawford // Check we can find the desired allocation 2038a0f08674SEwan Crawford AllocationDetails* alloc = FindAllocByID(strm, id); 2039a0f08674SEwan Crawford if (!alloc) 2040a0f08674SEwan Crawford return false; // FindAllocByID() will print error message for us here 2041a0f08674SEwan Crawford 2042a0f08674SEwan Crawford if (log) 2043a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::DumpAllocation - Found allocation 0x%" PRIx64, *alloc->address.get()); 2044a0f08674SEwan Crawford 2045a0f08674SEwan Crawford // Check we have information about the allocation, if not calculate it 2046a0f08674SEwan Crawford if (!alloc->data_ptr.isValid() || !alloc->type.isValid() || 2047a0f08674SEwan Crawford !alloc->type_vec_size.isValid() || !alloc->dimension.isValid()) 2048a0f08674SEwan Crawford { 2049a0f08674SEwan Crawford if (log) 2050a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::DumpAllocation - Allocation details not calculated yet, jitting info"); 2051a0f08674SEwan Crawford 2052a0f08674SEwan Crawford // JIT all the allocation information 2053a0f08674SEwan Crawford if (!RefreshAllocation(alloc, frame_ptr)) 2054a0f08674SEwan Crawford { 2055a0f08674SEwan Crawford strm.Printf("Error: Couldn't JIT allocation details"); 2056a0f08674SEwan Crawford strm.EOL(); 2057a0f08674SEwan Crawford return false; 2058a0f08674SEwan Crawford } 2059a0f08674SEwan Crawford } 2060a0f08674SEwan Crawford 2061a0f08674SEwan Crawford // Establish format and size of each data element 2062a0f08674SEwan Crawford const unsigned int vec_size = *alloc->type_vec_size.get(); 2063a0f08674SEwan Crawford const AllocationDetails::DataType type = *alloc->type.get(); 2064a0f08674SEwan Crawford 2065a0f08674SEwan Crawford assert(type >= AllocationDetails::RS_TYPE_NONE && type <= AllocationDetails::RS_TYPE_BOOLEAN 2066a0f08674SEwan Crawford && "Invalid allocation type"); 2067a0f08674SEwan Crawford 2068a0f08674SEwan Crawford lldb::Format format = vec_size == 1 ? static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatSingle]) 2069a0f08674SEwan Crawford : static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatVector]); 2070a0f08674SEwan Crawford 2071a0f08674SEwan Crawford const unsigned int data_size = vec_size * AllocationDetails::RSTypeToFormat[type][eElementSize]; 2072a0f08674SEwan Crawford // Renderscript pads vector 3 elements to vector 4 2073a0f08674SEwan Crawford const unsigned int elem_padding = vec_size == 3 ? AllocationDetails::RSTypeToFormat[type][eElementSize] : 0; 2074a0f08674SEwan Crawford 2075a0f08674SEwan Crawford if (log) 2076a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::DumpAllocation - Element size %u bytes, element padding %u bytes", 2077a0f08674SEwan Crawford data_size, elem_padding); 2078a0f08674SEwan Crawford 207955232f09SEwan Crawford // Allocate a buffer to copy data into 208055232f09SEwan Crawford std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr); 208155232f09SEwan Crawford if (!buffer) 208255232f09SEwan Crawford { 208355232f09SEwan Crawford strm.Printf("Error: Couldn't allocate a read allocation data into memory"); 208455232f09SEwan Crawford strm.EOL(); 208555232f09SEwan Crawford return false; 208655232f09SEwan Crawford } 208755232f09SEwan Crawford 2088a0f08674SEwan Crawford // Calculate stride between rows as there may be padding at end of rows since 2089a0f08674SEwan Crawford // allocated memory is 16-byte aligned 2090a0f08674SEwan Crawford if (!alloc->stride.isValid()) 2091a0f08674SEwan Crawford { 2092a0f08674SEwan Crawford if (alloc->dimension.get()->dim_2 == 0) // We only have one dimension 2093a0f08674SEwan Crawford alloc->stride = 0; 2094a0f08674SEwan Crawford else if (!JITAllocationStride(alloc, frame_ptr)) 2095a0f08674SEwan Crawford { 2096a0f08674SEwan Crawford strm.Printf("Error: Couldn't calculate allocation row stride"); 2097a0f08674SEwan Crawford strm.EOL(); 2098a0f08674SEwan Crawford return false; 2099a0f08674SEwan Crawford } 2100a0f08674SEwan Crawford } 2101a0f08674SEwan Crawford const unsigned int stride = *alloc->stride.get(); 2102a0f08674SEwan Crawford const unsigned int size = *alloc->size.get(); //size of last element 2103a0f08674SEwan Crawford 2104a0f08674SEwan Crawford if (log) 2105a0f08674SEwan Crawford log->Printf("RenderScriptRuntime::DumpAllocation - stride %u bytes, size %u bytes", stride, size); 2106a0f08674SEwan Crawford 2107a0f08674SEwan Crawford // Find dimensions used to index loops, so need to be non-zero 2108a0f08674SEwan Crawford unsigned int dim_x = alloc->dimension.get()->dim_1; 2109a0f08674SEwan Crawford dim_x = dim_x == 0 ? 1 : dim_x; 2110a0f08674SEwan Crawford 2111a0f08674SEwan Crawford unsigned int dim_y = alloc->dimension.get()->dim_2; 2112a0f08674SEwan Crawford dim_y = dim_y == 0 ? 1 : dim_y; 2113a0f08674SEwan Crawford 2114a0f08674SEwan Crawford unsigned int dim_z = alloc->dimension.get()->dim_3; 2115a0f08674SEwan Crawford dim_z = dim_z == 0 ? 1 : dim_z; 2116a0f08674SEwan Crawford 211755232f09SEwan Crawford // Use data extractor to format output 211855232f09SEwan Crawford const uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize(); 211955232f09SEwan Crawford DataExtractor alloc_data(buffer.get(), size, GetProcess()->GetByteOrder(), archByteSize); 212055232f09SEwan Crawford 2121a0f08674SEwan Crawford unsigned int offset = 0; // Offset in buffer to next element to be printed 2122a0f08674SEwan Crawford unsigned int prev_row = 0; // Offset to the start of the previous row 2123a0f08674SEwan Crawford 2124a0f08674SEwan Crawford // Iterate over allocation dimensions, printing results to user 2125a0f08674SEwan Crawford strm.Printf("Data (X, Y, Z):"); 2126a0f08674SEwan Crawford for (unsigned int z = 0; z < dim_z; ++z) 2127a0f08674SEwan Crawford { 2128a0f08674SEwan Crawford for (unsigned int y = 0; y < dim_y; ++y) 2129a0f08674SEwan Crawford { 2130a0f08674SEwan Crawford // Use stride to index start of next row. 2131a0f08674SEwan Crawford if (!(y==0 && z==0)) 2132a0f08674SEwan Crawford offset = prev_row + stride; 2133a0f08674SEwan Crawford prev_row = offset; 2134a0f08674SEwan Crawford 2135a0f08674SEwan Crawford // Print each element in the row individually 2136a0f08674SEwan Crawford for (unsigned int x = 0; x < dim_x; ++x) 2137a0f08674SEwan Crawford { 2138a0f08674SEwan Crawford strm.Printf("\n(%u, %u, %u) = ", x, y, z); 2139a0f08674SEwan Crawford alloc_data.Dump(&strm, offset, format, data_size, 1, 1, LLDB_INVALID_ADDRESS, 0, 0); 2140a0f08674SEwan Crawford offset += data_size + elem_padding; 2141a0f08674SEwan Crawford } 2142a0f08674SEwan Crawford } 2143a0f08674SEwan Crawford } 2144a0f08674SEwan Crawford strm.EOL(); 2145a0f08674SEwan Crawford 2146a0f08674SEwan Crawford return true; 2147a0f08674SEwan Crawford } 2148a0f08674SEwan Crawford 214915f2bd95SEwan Crawford // Prints infomation regarding all the currently loaded allocations. 215015f2bd95SEwan Crawford // These details are gathered by jitting the runtime, which has as latency. 215115f2bd95SEwan Crawford void 215215f2bd95SEwan Crawford RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute) 215315f2bd95SEwan Crawford { 215415f2bd95SEwan Crawford strm.Printf("RenderScript Allocations:"); 215515f2bd95SEwan Crawford strm.EOL(); 215615f2bd95SEwan Crawford strm.IndentMore(); 215715f2bd95SEwan Crawford 215815f2bd95SEwan Crawford for (auto &alloc : m_allocations) 215915f2bd95SEwan Crawford { 216015f2bd95SEwan Crawford // JIT the allocation info if we haven't done it, or the user forces us to. 216115f2bd95SEwan Crawford bool do_refresh = !alloc->data_ptr.isValid() || recompute; 216215f2bd95SEwan Crawford 216315f2bd95SEwan Crawford // JIT current allocation information 216415f2bd95SEwan Crawford if (do_refresh && !RefreshAllocation(alloc.get(), frame_ptr)) 216515f2bd95SEwan Crawford { 216615f2bd95SEwan Crawford strm.Printf("Error: Couldn't evaluate details for allocation %u\n", alloc->id); 216715f2bd95SEwan Crawford continue; 216815f2bd95SEwan Crawford } 216915f2bd95SEwan Crawford 217015f2bd95SEwan Crawford strm.Printf("%u:\n",alloc->id); 217115f2bd95SEwan Crawford strm.IndentMore(); 217215f2bd95SEwan Crawford 217315f2bd95SEwan Crawford strm.Indent("Context: "); 217415f2bd95SEwan Crawford if (!alloc->context.isValid()) 217515f2bd95SEwan Crawford strm.Printf("unknown\n"); 217615f2bd95SEwan Crawford else 217715f2bd95SEwan Crawford strm.Printf("0x%" PRIx64 "\n", *alloc->context.get()); 217815f2bd95SEwan Crawford 217915f2bd95SEwan Crawford strm.Indent("Address: "); 218015f2bd95SEwan Crawford if (!alloc->address.isValid()) 218115f2bd95SEwan Crawford strm.Printf("unknown\n"); 218215f2bd95SEwan Crawford else 218315f2bd95SEwan Crawford strm.Printf("0x%" PRIx64 "\n", *alloc->address.get()); 218415f2bd95SEwan Crawford 218515f2bd95SEwan Crawford strm.Indent("Data pointer: "); 218615f2bd95SEwan Crawford if (!alloc->data_ptr.isValid()) 218715f2bd95SEwan Crawford strm.Printf("unknown\n"); 218815f2bd95SEwan Crawford else 218915f2bd95SEwan Crawford strm.Printf("0x%" PRIx64 "\n", *alloc->data_ptr.get()); 219015f2bd95SEwan Crawford 219115f2bd95SEwan Crawford strm.Indent("Dimensions: "); 219215f2bd95SEwan Crawford if (!alloc->dimension.isValid()) 219315f2bd95SEwan Crawford strm.Printf("unknown\n"); 219415f2bd95SEwan Crawford else 219515f2bd95SEwan Crawford strm.Printf("(%d, %d, %d)\n", alloc->dimension.get()->dim_1, 219615f2bd95SEwan Crawford alloc->dimension.get()->dim_2, 219715f2bd95SEwan Crawford alloc->dimension.get()->dim_3); 219815f2bd95SEwan Crawford 219915f2bd95SEwan Crawford strm.Indent("Data Type: "); 220015f2bd95SEwan Crawford if (!alloc->type.isValid() || !alloc->type_vec_size.isValid()) 220115f2bd95SEwan Crawford strm.Printf("unknown\n"); 220215f2bd95SEwan Crawford else 220315f2bd95SEwan Crawford { 220415f2bd95SEwan Crawford const int vector_size = *alloc->type_vec_size.get(); 220515f2bd95SEwan Crawford const AllocationDetails::DataType type = *alloc->type.get(); 220615f2bd95SEwan Crawford 220715f2bd95SEwan Crawford if (vector_size > 4 || vector_size < 1 || 220815f2bd95SEwan Crawford type < AllocationDetails::RS_TYPE_NONE || type > AllocationDetails::RS_TYPE_BOOLEAN) 220915f2bd95SEwan Crawford strm.Printf("invalid type\n"); 221015f2bd95SEwan Crawford else 221115f2bd95SEwan Crawford strm.Printf("%s\n", AllocationDetails::RsDataTypeToString[static_cast<unsigned int>(type)][vector_size-1]); 221215f2bd95SEwan Crawford } 221315f2bd95SEwan Crawford 221415f2bd95SEwan Crawford strm.Indent("Data Kind: "); 221515f2bd95SEwan Crawford if (!alloc->type_kind.isValid()) 221615f2bd95SEwan Crawford strm.Printf("unknown\n"); 221715f2bd95SEwan Crawford else 221815f2bd95SEwan Crawford { 221915f2bd95SEwan Crawford const AllocationDetails::DataKind kind = *alloc->type_kind.get(); 222015f2bd95SEwan Crawford if (kind < AllocationDetails::RS_KIND_USER || kind > AllocationDetails::RS_KIND_PIXEL_YUV) 222115f2bd95SEwan Crawford strm.Printf("invalid kind\n"); 222215f2bd95SEwan Crawford else 222315f2bd95SEwan Crawford strm.Printf("%s\n", AllocationDetails::RsDataKindToString[static_cast<unsigned int>(kind)]); 222415f2bd95SEwan Crawford } 222515f2bd95SEwan Crawford 222615f2bd95SEwan Crawford strm.EOL(); 222715f2bd95SEwan Crawford strm.IndentLess(); 222815f2bd95SEwan Crawford } 222915f2bd95SEwan Crawford strm.IndentLess(); 223015f2bd95SEwan Crawford } 223115f2bd95SEwan Crawford 22327dc7771cSEwan Crawford // Set breakpoints on every kernel found in RS module 22337dc7771cSEwan Crawford void 22347dc7771cSEwan Crawford RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp) 22357dc7771cSEwan Crawford { 22367dc7771cSEwan Crawford for (const auto &kernel : rsmodule_sp->m_kernels) 22377dc7771cSEwan Crawford { 22387dc7771cSEwan Crawford // Don't set breakpoint on 'root' kernel 22397dc7771cSEwan Crawford if (strcmp(kernel.m_name.AsCString(), "root") == 0) 22407dc7771cSEwan Crawford continue; 22417dc7771cSEwan Crawford 22427dc7771cSEwan Crawford CreateKernelBreakpoint(kernel.m_name); 22437dc7771cSEwan Crawford } 22447dc7771cSEwan Crawford } 22457dc7771cSEwan Crawford 22467dc7771cSEwan Crawford // Method is internally called by the 'kernel breakpoint all' command to 22477dc7771cSEwan Crawford // enable or disable breaking on all kernels. 22487dc7771cSEwan Crawford // 22497dc7771cSEwan Crawford // When do_break is true we want to enable this functionality. 22507dc7771cSEwan Crawford // When do_break is false we want to disable it. 22517dc7771cSEwan Crawford void 22527dc7771cSEwan Crawford RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target) 22537dc7771cSEwan Crawford { 225454782db7SEwan Crawford Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); 22557dc7771cSEwan Crawford 22567dc7771cSEwan Crawford InitSearchFilter(target); 22577dc7771cSEwan Crawford 22587dc7771cSEwan Crawford // Set breakpoints on all the kernels 22597dc7771cSEwan Crawford if (do_break && !m_breakAllKernels) 22607dc7771cSEwan Crawford { 22617dc7771cSEwan Crawford m_breakAllKernels = true; 22627dc7771cSEwan Crawford 22637dc7771cSEwan Crawford for (const auto &module : m_rsmodules) 22647dc7771cSEwan Crawford BreakOnModuleKernels(module); 22657dc7771cSEwan Crawford 22667dc7771cSEwan Crawford if (log) 22677dc7771cSEwan Crawford log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)" 22687dc7771cSEwan Crawford "- breakpoints set on all currently loaded kernels"); 22697dc7771cSEwan Crawford } 22707dc7771cSEwan Crawford else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels. 22717dc7771cSEwan Crawford { 22727dc7771cSEwan Crawford m_breakAllKernels = false; 22737dc7771cSEwan Crawford 22747dc7771cSEwan Crawford if (log) 22757dc7771cSEwan Crawford log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set"); 22767dc7771cSEwan Crawford } 22777dc7771cSEwan Crawford } 22787dc7771cSEwan Crawford 22797dc7771cSEwan Crawford // Given the name of a kernel this function creates a breakpoint using our 22807dc7771cSEwan Crawford // own breakpoint resolver, and returns the Breakpoint shared pointer. 22817dc7771cSEwan Crawford BreakpointSP 22827dc7771cSEwan Crawford RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name) 22837dc7771cSEwan Crawford { 228454782db7SEwan Crawford Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); 22857dc7771cSEwan Crawford 22867dc7771cSEwan Crawford if (!m_filtersp) 22877dc7771cSEwan Crawford { 22887dc7771cSEwan Crawford if (log) 22897dc7771cSEwan Crawford log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set"); 22907dc7771cSEwan Crawford return nullptr; 22917dc7771cSEwan Crawford } 22927dc7771cSEwan Crawford 22937dc7771cSEwan Crawford BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name)); 22947dc7771cSEwan Crawford BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false); 22957dc7771cSEwan Crawford 229654782db7SEwan Crawford // Give RS breakpoints a specific name, so the user can manipulate them as a group. 229754782db7SEwan Crawford Error err; 229854782db7SEwan Crawford if (!bp->AddName("RenderScriptKernel", err) && log) 229954782db7SEwan Crawford log->Printf("RenderScriptRuntime::CreateKernelBreakpoint: Error setting break name, %s", err.AsCString()); 230054782db7SEwan Crawford 23017dc7771cSEwan Crawford return bp; 23027dc7771cSEwan Crawford } 23037dc7771cSEwan Crawford 23044640cde1SColin Riley void 230598156583SEwan Crawford RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target) 23064640cde1SColin Riley { 23074640cde1SColin Riley if (!name) 23084640cde1SColin Riley { 23094640cde1SColin Riley error.SetErrorString("invalid kernel name"); 23104640cde1SColin Riley return; 23114640cde1SColin Riley } 23124640cde1SColin Riley 23137dc7771cSEwan Crawford InitSearchFilter(target); 231498156583SEwan Crawford 23154640cde1SColin Riley ConstString kernel_name(name); 23167dc7771cSEwan Crawford BreakpointSP bp = CreateKernelBreakpoint(kernel_name); 231798156583SEwan Crawford if (bp) 231898156583SEwan Crawford bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false); 23194640cde1SColin Riley 23204640cde1SColin Riley return; 23214640cde1SColin Riley } 23224640cde1SColin Riley 23234640cde1SColin Riley void 23245ec532a9SColin Riley RenderScriptRuntime::DumpModules(Stream &strm) const 23255ec532a9SColin Riley { 23265ec532a9SColin Riley strm.Printf("RenderScript Modules:"); 23275ec532a9SColin Riley strm.EOL(); 23285ec532a9SColin Riley strm.IndentMore(); 23295ec532a9SColin Riley for (const auto &module : m_rsmodules) 23305ec532a9SColin Riley { 23314640cde1SColin Riley module->Dump(strm); 23325ec532a9SColin Riley } 23335ec532a9SColin Riley strm.IndentLess(); 23345ec532a9SColin Riley } 23355ec532a9SColin Riley 233678f339d1SEwan Crawford RenderScriptRuntime::ScriptDetails* 233778f339d1SEwan Crawford RenderScriptRuntime::LookUpScript(addr_t address, bool create) 233878f339d1SEwan Crawford { 233978f339d1SEwan Crawford for (const auto & s : m_scripts) 234078f339d1SEwan Crawford { 234178f339d1SEwan Crawford if (s->script.isValid()) 234278f339d1SEwan Crawford if (*s->script == address) 234378f339d1SEwan Crawford return s.get(); 234478f339d1SEwan Crawford } 234578f339d1SEwan Crawford if (create) 234678f339d1SEwan Crawford { 234778f339d1SEwan Crawford std::unique_ptr<ScriptDetails> s(new ScriptDetails); 234878f339d1SEwan Crawford s->script = address; 234978f339d1SEwan Crawford m_scripts.push_back(std::move(s)); 2350d10ca9deSEwan Crawford return m_scripts.back().get(); 235178f339d1SEwan Crawford } 235278f339d1SEwan Crawford return nullptr; 235378f339d1SEwan Crawford } 235478f339d1SEwan Crawford 235578f339d1SEwan Crawford RenderScriptRuntime::AllocationDetails* 235678f339d1SEwan Crawford RenderScriptRuntime::LookUpAllocation(addr_t address, bool create) 235778f339d1SEwan Crawford { 235878f339d1SEwan Crawford for (const auto & a : m_allocations) 235978f339d1SEwan Crawford { 236078f339d1SEwan Crawford if (a->address.isValid()) 236178f339d1SEwan Crawford if (*a->address == address) 236278f339d1SEwan Crawford return a.get(); 236378f339d1SEwan Crawford } 236478f339d1SEwan Crawford if (create) 236578f339d1SEwan Crawford { 236678f339d1SEwan Crawford std::unique_ptr<AllocationDetails> a(new AllocationDetails); 236778f339d1SEwan Crawford a->address = address; 236878f339d1SEwan Crawford m_allocations.push_back(std::move(a)); 2369d10ca9deSEwan Crawford return m_allocations.back().get(); 237078f339d1SEwan Crawford } 237178f339d1SEwan Crawford return nullptr; 237278f339d1SEwan Crawford } 237378f339d1SEwan Crawford 23745ec532a9SColin Riley void 23755ec532a9SColin Riley RSModuleDescriptor::Dump(Stream &strm) const 23765ec532a9SColin Riley { 23775ec532a9SColin Riley strm.Indent(); 23785ec532a9SColin Riley m_module->GetFileSpec().Dump(&strm); 23794640cde1SColin Riley if(m_module->GetNumCompileUnits()) 23804640cde1SColin Riley { 23814640cde1SColin Riley strm.Indent("Debug info loaded."); 23824640cde1SColin Riley } 23834640cde1SColin Riley else 23844640cde1SColin Riley { 23854640cde1SColin Riley strm.Indent("Debug info does not exist."); 23864640cde1SColin Riley } 23875ec532a9SColin Riley strm.EOL(); 23885ec532a9SColin Riley strm.IndentMore(); 23895ec532a9SColin Riley strm.Indent(); 2390189598edSColin Riley strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size())); 23915ec532a9SColin Riley strm.EOL(); 23925ec532a9SColin Riley strm.IndentMore(); 23935ec532a9SColin Riley for (const auto &global : m_globals) 23945ec532a9SColin Riley { 23955ec532a9SColin Riley global.Dump(strm); 23965ec532a9SColin Riley } 23975ec532a9SColin Riley strm.IndentLess(); 23985ec532a9SColin Riley strm.Indent(); 2399189598edSColin Riley strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size())); 24005ec532a9SColin Riley strm.EOL(); 24015ec532a9SColin Riley strm.IndentMore(); 24025ec532a9SColin Riley for (const auto &kernel : m_kernels) 24035ec532a9SColin Riley { 24045ec532a9SColin Riley kernel.Dump(strm); 24055ec532a9SColin Riley } 24064640cde1SColin Riley strm.Printf("Pragmas: %" PRIu64 , static_cast<uint64_t>(m_pragmas.size())); 24074640cde1SColin Riley strm.EOL(); 24084640cde1SColin Riley strm.IndentMore(); 24094640cde1SColin Riley for (const auto &key_val : m_pragmas) 24104640cde1SColin Riley { 24114640cde1SColin Riley strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str()); 24124640cde1SColin Riley strm.EOL(); 24134640cde1SColin Riley } 24145ec532a9SColin Riley strm.IndentLess(4); 24155ec532a9SColin Riley } 24165ec532a9SColin Riley 24175ec532a9SColin Riley void 24185ec532a9SColin Riley RSGlobalDescriptor::Dump(Stream &strm) const 24195ec532a9SColin Riley { 24205ec532a9SColin Riley strm.Indent(m_name.AsCString()); 24214640cde1SColin Riley VariableList var_list; 24224640cde1SColin Riley m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list); 24234640cde1SColin Riley if (var_list.GetSize() == 1) 24244640cde1SColin Riley { 24254640cde1SColin Riley auto var = var_list.GetVariableAtIndex(0); 24264640cde1SColin Riley auto type = var->GetType(); 24274640cde1SColin Riley if(type) 24284640cde1SColin Riley { 24294640cde1SColin Riley strm.Printf(" - "); 24304640cde1SColin Riley type->DumpTypeName(&strm); 24314640cde1SColin Riley } 24324640cde1SColin Riley else 24334640cde1SColin Riley { 24344640cde1SColin Riley strm.Printf(" - Unknown Type"); 24354640cde1SColin Riley } 24364640cde1SColin Riley } 24374640cde1SColin Riley else 24384640cde1SColin Riley { 24394640cde1SColin Riley strm.Printf(" - variable identified, but not found in binary"); 24404640cde1SColin Riley const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData); 24414640cde1SColin Riley if (s) 24424640cde1SColin Riley { 24434640cde1SColin Riley strm.Printf(" (symbol exists) "); 24444640cde1SColin Riley } 24454640cde1SColin Riley } 24464640cde1SColin Riley 24475ec532a9SColin Riley strm.EOL(); 24485ec532a9SColin Riley } 24495ec532a9SColin Riley 24505ec532a9SColin Riley void 24515ec532a9SColin Riley RSKernelDescriptor::Dump(Stream &strm) const 24525ec532a9SColin Riley { 24535ec532a9SColin Riley strm.Indent(m_name.AsCString()); 24545ec532a9SColin Riley strm.EOL(); 24555ec532a9SColin Riley } 24565ec532a9SColin Riley 24575ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed 24585ec532a9SColin Riley { 24595ec532a9SColin Riley private: 24605ec532a9SColin Riley public: 24615ec532a9SColin Riley CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter) 24625ec532a9SColin Riley : CommandObjectParsed(interpreter, "renderscript module probe", 24635ec532a9SColin Riley "Initiates a Probe of all loaded modules for kernels and other renderscript objects.", 24645ec532a9SColin Riley "renderscript module probe", 2465e87764f2SEnrico Granata eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched) 24665ec532a9SColin Riley { 24675ec532a9SColin Riley } 24685ec532a9SColin Riley 24695ec532a9SColin Riley ~CommandObjectRenderScriptRuntimeModuleProbe() {} 24705ec532a9SColin Riley 24715ec532a9SColin Riley bool 24725ec532a9SColin Riley DoExecute(Args &command, CommandReturnObject &result) 24735ec532a9SColin Riley { 24745ec532a9SColin Riley const size_t argc = command.GetArgumentCount(); 24755ec532a9SColin Riley if (argc == 0) 24765ec532a9SColin Riley { 24775ec532a9SColin Riley Target *target = m_exe_ctx.GetTargetPtr(); 24785ec532a9SColin Riley RenderScriptRuntime *runtime = 24795ec532a9SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 24805ec532a9SColin Riley auto module_list = target->GetImages(); 24815ec532a9SColin Riley bool new_rs_details = runtime->ProbeModules(module_list); 24825ec532a9SColin Riley if (new_rs_details) 24835ec532a9SColin Riley { 24845ec532a9SColin Riley result.AppendMessage("New renderscript modules added to runtime model."); 24855ec532a9SColin Riley } 24865ec532a9SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 24875ec532a9SColin Riley return true; 24885ec532a9SColin Riley } 24895ec532a9SColin Riley 24905ec532a9SColin Riley result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str()); 24915ec532a9SColin Riley result.SetStatus(eReturnStatusFailed); 24925ec532a9SColin Riley return false; 24935ec532a9SColin Riley } 24945ec532a9SColin Riley }; 24955ec532a9SColin Riley 24965ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed 24975ec532a9SColin Riley { 24985ec532a9SColin Riley private: 24995ec532a9SColin Riley public: 25005ec532a9SColin Riley CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter) 25015ec532a9SColin Riley : CommandObjectParsed(interpreter, "renderscript module dump", 25025ec532a9SColin Riley "Dumps renderscript specific information for all modules.", "renderscript module dump", 2503e87764f2SEnrico Granata eCommandRequiresProcess | eCommandProcessMustBeLaunched) 25045ec532a9SColin Riley { 25055ec532a9SColin Riley } 25065ec532a9SColin Riley 25075ec532a9SColin Riley ~CommandObjectRenderScriptRuntimeModuleDump() {} 25085ec532a9SColin Riley 25095ec532a9SColin Riley bool 25105ec532a9SColin Riley DoExecute(Args &command, CommandReturnObject &result) 25115ec532a9SColin Riley { 25125ec532a9SColin Riley RenderScriptRuntime *runtime = 25135ec532a9SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 25145ec532a9SColin Riley runtime->DumpModules(result.GetOutputStream()); 25155ec532a9SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 25165ec532a9SColin Riley return true; 25175ec532a9SColin Riley } 25185ec532a9SColin Riley }; 25195ec532a9SColin Riley 25205ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword 25215ec532a9SColin Riley { 25225ec532a9SColin Riley private: 25235ec532a9SColin Riley public: 25245ec532a9SColin Riley CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter) 25255ec532a9SColin Riley : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.", 25265ec532a9SColin Riley NULL) 25275ec532a9SColin Riley { 25285ec532a9SColin Riley LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter))); 25295ec532a9SColin Riley LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter))); 25305ec532a9SColin Riley } 25315ec532a9SColin Riley 25325ec532a9SColin Riley ~CommandObjectRenderScriptRuntimeModule() {} 25335ec532a9SColin Riley }; 25345ec532a9SColin Riley 25354640cde1SColin Riley class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed 25364640cde1SColin Riley { 25374640cde1SColin Riley private: 25384640cde1SColin Riley public: 25394640cde1SColin Riley CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter) 25404640cde1SColin Riley : CommandObjectParsed(interpreter, "renderscript kernel list", 25414640cde1SColin Riley "Lists renderscript kernel names and associated script resources.", "renderscript kernel list", 25424640cde1SColin Riley eCommandRequiresProcess | eCommandProcessMustBeLaunched) 25434640cde1SColin Riley { 25444640cde1SColin Riley } 25454640cde1SColin Riley 25464640cde1SColin Riley ~CommandObjectRenderScriptRuntimeKernelList() {} 25474640cde1SColin Riley 25484640cde1SColin Riley bool 25494640cde1SColin Riley DoExecute(Args &command, CommandReturnObject &result) 25504640cde1SColin Riley { 25514640cde1SColin Riley RenderScriptRuntime *runtime = 25524640cde1SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 25534640cde1SColin Riley runtime->DumpKernels(result.GetOutputStream()); 25544640cde1SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 25554640cde1SColin Riley return true; 25564640cde1SColin Riley } 25574640cde1SColin Riley }; 25584640cde1SColin Riley 25597dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed 25604640cde1SColin Riley { 25614640cde1SColin Riley private: 25624640cde1SColin Riley public: 25637dc7771cSEwan Crawford CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter) 25647dc7771cSEwan Crawford : CommandObjectParsed(interpreter, "renderscript kernel breakpoint set", 25657dc7771cSEwan Crawford "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name>", 25664640cde1SColin Riley eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) 25674640cde1SColin Riley { 25684640cde1SColin Riley } 25694640cde1SColin Riley 25707dc7771cSEwan Crawford ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() {} 25714640cde1SColin Riley 25724640cde1SColin Riley bool 25734640cde1SColin Riley DoExecute(Args &command, CommandReturnObject &result) 25744640cde1SColin Riley { 25754640cde1SColin Riley const size_t argc = command.GetArgumentCount(); 25764640cde1SColin Riley if (argc == 1) 25774640cde1SColin Riley { 25784640cde1SColin Riley RenderScriptRuntime *runtime = 25794640cde1SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 25804640cde1SColin Riley 25814640cde1SColin Riley Error error; 258298156583SEwan Crawford runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0), 258398156583SEwan Crawford error, m_exe_ctx.GetTargetSP()); 25844640cde1SColin Riley 25854640cde1SColin Riley if (error.Success()) 25864640cde1SColin Riley { 25874640cde1SColin Riley result.AppendMessage("Breakpoint(s) created"); 25884640cde1SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 25894640cde1SColin Riley return true; 25904640cde1SColin Riley } 25914640cde1SColin Riley result.SetStatus(eReturnStatusFailed); 25924640cde1SColin Riley result.AppendErrorWithFormat("Error: %s", error.AsCString()); 25934640cde1SColin Riley return false; 25944640cde1SColin Riley } 25954640cde1SColin Riley 25964640cde1SColin Riley result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name", m_cmd_name.c_str()); 25974640cde1SColin Riley result.SetStatus(eReturnStatusFailed); 25984640cde1SColin Riley return false; 25994640cde1SColin Riley } 26004640cde1SColin Riley }; 26014640cde1SColin Riley 26027dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed 26037dc7771cSEwan Crawford { 26047dc7771cSEwan Crawford private: 26057dc7771cSEwan Crawford public: 26067dc7771cSEwan Crawford CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter) 26077dc7771cSEwan Crawford : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all", 26087dc7771cSEwan Crawford "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n" 26097dc7771cSEwan Crawford "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, " 26107dc7771cSEwan Crawford "but does not remove currently set breakpoints.", 26117dc7771cSEwan Crawford "renderscript kernel breakpoint all <enable/disable>", 26127dc7771cSEwan Crawford eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) 26137dc7771cSEwan Crawford { 26147dc7771cSEwan Crawford } 26157dc7771cSEwan Crawford 26167dc7771cSEwan Crawford ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() {} 26177dc7771cSEwan Crawford 26187dc7771cSEwan Crawford bool 26197dc7771cSEwan Crawford DoExecute(Args &command, CommandReturnObject &result) 26207dc7771cSEwan Crawford { 26217dc7771cSEwan Crawford const size_t argc = command.GetArgumentCount(); 26227dc7771cSEwan Crawford if (argc != 1) 26237dc7771cSEwan Crawford { 26247dc7771cSEwan Crawford result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str()); 26257dc7771cSEwan Crawford result.SetStatus(eReturnStatusFailed); 26267dc7771cSEwan Crawford return false; 26277dc7771cSEwan Crawford } 26287dc7771cSEwan Crawford 26297dc7771cSEwan Crawford RenderScriptRuntime *runtime = 26307dc7771cSEwan Crawford static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 26317dc7771cSEwan Crawford 26327dc7771cSEwan Crawford bool do_break = false; 26337dc7771cSEwan Crawford const char* argument = command.GetArgumentAtIndex(0); 26347dc7771cSEwan Crawford if (strcmp(argument, "enable") == 0) 26357dc7771cSEwan Crawford { 26367dc7771cSEwan Crawford do_break = true; 26377dc7771cSEwan Crawford result.AppendMessage("Breakpoints will be set on all kernels."); 26387dc7771cSEwan Crawford } 26397dc7771cSEwan Crawford else if (strcmp(argument, "disable") == 0) 26407dc7771cSEwan Crawford { 26417dc7771cSEwan Crawford do_break = false; 26427dc7771cSEwan Crawford result.AppendMessage("Breakpoints will not be set on any new kernels."); 26437dc7771cSEwan Crawford } 26447dc7771cSEwan Crawford else 26457dc7771cSEwan Crawford { 26467dc7771cSEwan Crawford result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'"); 26477dc7771cSEwan Crawford result.SetStatus(eReturnStatusFailed); 26487dc7771cSEwan Crawford return false; 26497dc7771cSEwan Crawford } 26507dc7771cSEwan Crawford 26517dc7771cSEwan Crawford runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP()); 26527dc7771cSEwan Crawford 26537dc7771cSEwan Crawford result.SetStatus(eReturnStatusSuccessFinishResult); 26547dc7771cSEwan Crawford return true; 26557dc7771cSEwan Crawford } 26567dc7771cSEwan Crawford }; 26577dc7771cSEwan Crawford 26587dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword 26597dc7771cSEwan Crawford { 26607dc7771cSEwan Crawford private: 26617dc7771cSEwan Crawford public: 26627dc7771cSEwan Crawford CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter) 26637dc7771cSEwan Crawford : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.", 26647dc7771cSEwan Crawford nullptr) 26657dc7771cSEwan Crawford { 26667dc7771cSEwan Crawford LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter))); 26677dc7771cSEwan Crawford LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter))); 26687dc7771cSEwan Crawford } 26697dc7771cSEwan Crawford 26707dc7771cSEwan Crawford ~CommandObjectRenderScriptRuntimeKernelBreakpoint() {} 26717dc7771cSEwan Crawford }; 26727dc7771cSEwan Crawford 26734640cde1SColin Riley class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword 26744640cde1SColin Riley { 26754640cde1SColin Riley private: 26764640cde1SColin Riley public: 26774640cde1SColin Riley CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter) 26784640cde1SColin Riley : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.", 26794640cde1SColin Riley NULL) 26804640cde1SColin Riley { 26814640cde1SColin Riley LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter))); 26824640cde1SColin Riley LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter))); 26834640cde1SColin Riley } 26844640cde1SColin Riley 26854640cde1SColin Riley ~CommandObjectRenderScriptRuntimeKernel() {} 26864640cde1SColin Riley }; 26874640cde1SColin Riley 26884640cde1SColin Riley class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed 26894640cde1SColin Riley { 26904640cde1SColin Riley private: 26914640cde1SColin Riley public: 26924640cde1SColin Riley CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter) 26934640cde1SColin Riley : CommandObjectParsed(interpreter, "renderscript context dump", 26944640cde1SColin Riley "Dumps renderscript context information.", "renderscript context dump", 26954640cde1SColin Riley eCommandRequiresProcess | eCommandProcessMustBeLaunched) 26964640cde1SColin Riley { 26974640cde1SColin Riley } 26984640cde1SColin Riley 26994640cde1SColin Riley ~CommandObjectRenderScriptRuntimeContextDump() {} 27004640cde1SColin Riley 27014640cde1SColin Riley bool 27024640cde1SColin Riley DoExecute(Args &command, CommandReturnObject &result) 27034640cde1SColin Riley { 27044640cde1SColin Riley RenderScriptRuntime *runtime = 27054640cde1SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 27064640cde1SColin Riley runtime->DumpContexts(result.GetOutputStream()); 27074640cde1SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 27084640cde1SColin Riley return true; 27094640cde1SColin Riley } 27104640cde1SColin Riley }; 27114640cde1SColin Riley 27124640cde1SColin Riley class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword 27134640cde1SColin Riley { 27144640cde1SColin Riley private: 27154640cde1SColin Riley public: 27164640cde1SColin Riley CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter) 27174640cde1SColin Riley : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.", 27184640cde1SColin Riley NULL) 27194640cde1SColin Riley { 27204640cde1SColin Riley LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter))); 27214640cde1SColin Riley } 27224640cde1SColin Riley 27234640cde1SColin Riley ~CommandObjectRenderScriptRuntimeContext() {} 27244640cde1SColin Riley }; 27254640cde1SColin Riley 2726a0f08674SEwan Crawford 2727a0f08674SEwan Crawford class CommandObjectRenderScriptRuntimeAllocationDump : public CommandObjectParsed 2728a0f08674SEwan Crawford { 2729a0f08674SEwan Crawford private: 2730a0f08674SEwan Crawford public: 2731a0f08674SEwan Crawford CommandObjectRenderScriptRuntimeAllocationDump(CommandInterpreter &interpreter) 2732a0f08674SEwan Crawford : CommandObjectParsed(interpreter, "renderscript allocation dump", 2733a0f08674SEwan Crawford "Displays the contents of a particular allocation", "renderscript allocation dump <ID>", 2734a0f08674SEwan Crawford eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter) 2735a0f08674SEwan Crawford { 2736a0f08674SEwan Crawford } 2737a0f08674SEwan Crawford 2738a0f08674SEwan Crawford virtual Options* 2739a0f08674SEwan Crawford GetOptions() 2740a0f08674SEwan Crawford { 2741a0f08674SEwan Crawford return &m_options; 2742a0f08674SEwan Crawford } 2743a0f08674SEwan Crawford 2744a0f08674SEwan Crawford class CommandOptions : public Options 2745a0f08674SEwan Crawford { 2746a0f08674SEwan Crawford public: 2747a0f08674SEwan Crawford CommandOptions(CommandInterpreter &interpreter) : Options(interpreter) 2748a0f08674SEwan Crawford { 2749a0f08674SEwan Crawford } 2750a0f08674SEwan Crawford 2751a0f08674SEwan Crawford virtual 2752a0f08674SEwan Crawford ~CommandOptions() 2753a0f08674SEwan Crawford { 2754a0f08674SEwan Crawford } 2755a0f08674SEwan Crawford 2756a0f08674SEwan Crawford virtual Error 2757a0f08674SEwan Crawford SetOptionValue(uint32_t option_idx, const char *option_arg) 2758a0f08674SEwan Crawford { 2759a0f08674SEwan Crawford Error error; 2760a0f08674SEwan Crawford const int short_option = m_getopt_table[option_idx].val; 2761a0f08674SEwan Crawford 2762a0f08674SEwan Crawford switch (short_option) 2763a0f08674SEwan Crawford { 2764a0f08674SEwan Crawford case 'f': 2765a0f08674SEwan Crawford m_outfile.SetFile(option_arg, true); 2766a0f08674SEwan Crawford if (m_outfile.Exists()) 2767a0f08674SEwan Crawford { 2768a0f08674SEwan Crawford m_outfile.Clear(); 2769a0f08674SEwan Crawford error.SetErrorStringWithFormat("file already exists: '%s'", option_arg); 2770a0f08674SEwan Crawford } 2771a0f08674SEwan Crawford break; 2772a0f08674SEwan Crawford default: 2773a0f08674SEwan Crawford error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); 2774a0f08674SEwan Crawford break; 2775a0f08674SEwan Crawford } 2776a0f08674SEwan Crawford return error; 2777a0f08674SEwan Crawford } 2778a0f08674SEwan Crawford 2779a0f08674SEwan Crawford void 2780a0f08674SEwan Crawford OptionParsingStarting() 2781a0f08674SEwan Crawford { 2782a0f08674SEwan Crawford m_outfile.Clear(); 2783a0f08674SEwan Crawford } 2784a0f08674SEwan Crawford 2785a0f08674SEwan Crawford const OptionDefinition* 2786a0f08674SEwan Crawford GetDefinitions() 2787a0f08674SEwan Crawford { 2788a0f08674SEwan Crawford return g_option_table; 2789a0f08674SEwan Crawford } 2790a0f08674SEwan Crawford 2791a0f08674SEwan Crawford static OptionDefinition g_option_table[]; 2792a0f08674SEwan Crawford FileSpec m_outfile; 2793a0f08674SEwan Crawford }; 2794a0f08674SEwan Crawford 2795a0f08674SEwan Crawford ~CommandObjectRenderScriptRuntimeAllocationDump() {} 2796a0f08674SEwan Crawford 2797a0f08674SEwan Crawford bool 2798a0f08674SEwan Crawford DoExecute(Args &command, CommandReturnObject &result) 2799a0f08674SEwan Crawford { 2800a0f08674SEwan Crawford const size_t argc = command.GetArgumentCount(); 2801a0f08674SEwan Crawford if (argc < 1) 2802a0f08674SEwan Crawford { 2803a0f08674SEwan Crawford result.AppendErrorWithFormat("'%s' takes 1 argument, an allocation ID. As well as an optional -f argument", 2804a0f08674SEwan Crawford m_cmd_name.c_str()); 2805a0f08674SEwan Crawford result.SetStatus(eReturnStatusFailed); 2806a0f08674SEwan Crawford return false; 2807a0f08674SEwan Crawford } 2808a0f08674SEwan Crawford 2809a0f08674SEwan Crawford RenderScriptRuntime *runtime = 2810a0f08674SEwan Crawford static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 2811a0f08674SEwan Crawford 2812a0f08674SEwan Crawford const char* id_cstr = command.GetArgumentAtIndex(0); 2813a0f08674SEwan Crawford bool convert_complete = false; 2814a0f08674SEwan Crawford const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete); 2815a0f08674SEwan Crawford if (!convert_complete) 2816a0f08674SEwan Crawford { 2817a0f08674SEwan Crawford result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr); 2818a0f08674SEwan Crawford result.SetStatus(eReturnStatusFailed); 2819a0f08674SEwan Crawford return false; 2820a0f08674SEwan Crawford } 2821a0f08674SEwan Crawford 2822a0f08674SEwan Crawford Stream* output_strm = nullptr; 2823a0f08674SEwan Crawford StreamFile outfile_stream; 2824a0f08674SEwan Crawford const FileSpec &outfile_spec = m_options.m_outfile; // Dump allocation to file instead 2825a0f08674SEwan Crawford if (outfile_spec) 2826a0f08674SEwan Crawford { 2827a0f08674SEwan Crawford // Open output file 2828a0f08674SEwan Crawford char path[256]; 2829a0f08674SEwan Crawford outfile_spec.GetPath(path, sizeof(path)); 2830a0f08674SEwan Crawford if (outfile_stream.GetFile().Open(path, File::eOpenOptionWrite | File::eOpenOptionCanCreate).Success()) 2831a0f08674SEwan Crawford { 2832a0f08674SEwan Crawford output_strm = &outfile_stream; 2833a0f08674SEwan Crawford result.GetOutputStream().Printf("Results written to '%s'", path); 2834a0f08674SEwan Crawford result.GetOutputStream().EOL(); 2835a0f08674SEwan Crawford } 2836a0f08674SEwan Crawford else 2837a0f08674SEwan Crawford { 2838a0f08674SEwan Crawford result.AppendErrorWithFormat("Couldn't open file '%s'", path); 2839a0f08674SEwan Crawford result.SetStatus(eReturnStatusFailed); 2840a0f08674SEwan Crawford return false; 2841a0f08674SEwan Crawford } 2842a0f08674SEwan Crawford } 2843a0f08674SEwan Crawford else 2844a0f08674SEwan Crawford output_strm = &result.GetOutputStream(); 2845a0f08674SEwan Crawford 2846a0f08674SEwan Crawford assert(output_strm != nullptr); 2847a0f08674SEwan Crawford bool success = runtime->DumpAllocation(*output_strm, m_exe_ctx.GetFramePtr(), id); 2848a0f08674SEwan Crawford 2849a0f08674SEwan Crawford if (success) 2850a0f08674SEwan Crawford result.SetStatus(eReturnStatusSuccessFinishResult); 2851a0f08674SEwan Crawford else 2852a0f08674SEwan Crawford result.SetStatus(eReturnStatusFailed); 2853a0f08674SEwan Crawford 2854a0f08674SEwan Crawford return true; 2855a0f08674SEwan Crawford } 2856a0f08674SEwan Crawford 2857a0f08674SEwan Crawford private: 2858a0f08674SEwan Crawford CommandOptions m_options; 2859a0f08674SEwan Crawford }; 2860a0f08674SEwan Crawford 2861a0f08674SEwan Crawford OptionDefinition 2862a0f08674SEwan Crawford CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions::g_option_table[] = 2863a0f08674SEwan Crawford { 2864a0f08674SEwan Crawford { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, 2865a0f08674SEwan Crawford "Print results to specified file instead of command line."}, 2866a0f08674SEwan Crawford { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2867a0f08674SEwan Crawford }; 2868a0f08674SEwan Crawford 2869a0f08674SEwan Crawford 287015f2bd95SEwan Crawford class CommandObjectRenderScriptRuntimeAllocationList : public CommandObjectParsed 287115f2bd95SEwan Crawford { 287215f2bd95SEwan Crawford public: 287315f2bd95SEwan Crawford CommandObjectRenderScriptRuntimeAllocationList(CommandInterpreter &interpreter) 287415f2bd95SEwan Crawford : CommandObjectParsed(interpreter, "renderscript allocation list", 287515f2bd95SEwan Crawford "List renderscript allocations and their information.", "renderscript allocation list", 287615f2bd95SEwan Crawford eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter) 287715f2bd95SEwan Crawford { 287815f2bd95SEwan Crawford } 287915f2bd95SEwan Crawford 288015f2bd95SEwan Crawford virtual Options* 288115f2bd95SEwan Crawford GetOptions() 288215f2bd95SEwan Crawford { 288315f2bd95SEwan Crawford return &m_options; 288415f2bd95SEwan Crawford } 288515f2bd95SEwan Crawford 288615f2bd95SEwan Crawford class CommandOptions : public Options 288715f2bd95SEwan Crawford { 288815f2bd95SEwan Crawford public: 288915f2bd95SEwan Crawford CommandOptions(CommandInterpreter &interpreter) : Options(interpreter), m_refresh(false) 289015f2bd95SEwan Crawford { 289115f2bd95SEwan Crawford } 289215f2bd95SEwan Crawford 289315f2bd95SEwan Crawford virtual 289415f2bd95SEwan Crawford ~CommandOptions() 289515f2bd95SEwan Crawford { 289615f2bd95SEwan Crawford } 289715f2bd95SEwan Crawford 289815f2bd95SEwan Crawford virtual Error 289915f2bd95SEwan Crawford SetOptionValue(uint32_t option_idx, const char *option_arg) 290015f2bd95SEwan Crawford { 290115f2bd95SEwan Crawford Error error; 290215f2bd95SEwan Crawford const int short_option = m_getopt_table[option_idx].val; 290315f2bd95SEwan Crawford 290415f2bd95SEwan Crawford switch (short_option) 290515f2bd95SEwan Crawford { 290615f2bd95SEwan Crawford case 'r': 290715f2bd95SEwan Crawford m_refresh = true; 290815f2bd95SEwan Crawford break; 290915f2bd95SEwan Crawford default: 291015f2bd95SEwan Crawford error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); 291115f2bd95SEwan Crawford break; 291215f2bd95SEwan Crawford } 291315f2bd95SEwan Crawford return error; 291415f2bd95SEwan Crawford } 291515f2bd95SEwan Crawford 291615f2bd95SEwan Crawford void 291715f2bd95SEwan Crawford OptionParsingStarting() 291815f2bd95SEwan Crawford { 291915f2bd95SEwan Crawford m_refresh = false; 292015f2bd95SEwan Crawford } 292115f2bd95SEwan Crawford 292215f2bd95SEwan Crawford const OptionDefinition* 292315f2bd95SEwan Crawford GetDefinitions() 292415f2bd95SEwan Crawford { 292515f2bd95SEwan Crawford return g_option_table; 292615f2bd95SEwan Crawford } 292715f2bd95SEwan Crawford 292815f2bd95SEwan Crawford static OptionDefinition g_option_table[]; 292915f2bd95SEwan Crawford bool m_refresh; 293015f2bd95SEwan Crawford }; 293115f2bd95SEwan Crawford 293215f2bd95SEwan Crawford ~CommandObjectRenderScriptRuntimeAllocationList() {} 293315f2bd95SEwan Crawford 293415f2bd95SEwan Crawford bool 293515f2bd95SEwan Crawford DoExecute(Args &command, CommandReturnObject &result) 293615f2bd95SEwan Crawford { 293715f2bd95SEwan Crawford RenderScriptRuntime *runtime = 293815f2bd95SEwan Crawford static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 293915f2bd95SEwan Crawford runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), m_options.m_refresh); 294015f2bd95SEwan Crawford result.SetStatus(eReturnStatusSuccessFinishResult); 294115f2bd95SEwan Crawford return true; 294215f2bd95SEwan Crawford } 294315f2bd95SEwan Crawford 294415f2bd95SEwan Crawford private: 294515f2bd95SEwan Crawford CommandOptions m_options; 294615f2bd95SEwan Crawford }; 294715f2bd95SEwan Crawford 294815f2bd95SEwan Crawford OptionDefinition 294915f2bd95SEwan Crawford CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::g_option_table[] = 295015f2bd95SEwan Crawford { 295115f2bd95SEwan Crawford { LLDB_OPT_SET_1, false, "refresh", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 295215f2bd95SEwan Crawford "Recompute allocation details."}, 295315f2bd95SEwan Crawford { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 295415f2bd95SEwan Crawford }; 295515f2bd95SEwan Crawford 295615f2bd95SEwan Crawford 295755232f09SEwan Crawford class CommandObjectRenderScriptRuntimeAllocationLoad : public CommandObjectParsed 295855232f09SEwan Crawford { 295955232f09SEwan Crawford private: 296055232f09SEwan Crawford public: 296155232f09SEwan Crawford CommandObjectRenderScriptRuntimeAllocationLoad(CommandInterpreter &interpreter) 296255232f09SEwan Crawford : CommandObjectParsed(interpreter, "renderscript allocation load", 296355232f09SEwan Crawford "Loads renderscript allocation contents from a file.", "renderscript allocation load <ID> <filename>", 296455232f09SEwan Crawford eCommandRequiresProcess | eCommandProcessMustBeLaunched) 296555232f09SEwan Crawford { 296655232f09SEwan Crawford } 296755232f09SEwan Crawford 296855232f09SEwan Crawford ~CommandObjectRenderScriptRuntimeAllocationLoad() {} 296955232f09SEwan Crawford 297055232f09SEwan Crawford bool 297155232f09SEwan Crawford DoExecute(Args &command, CommandReturnObject &result) 297255232f09SEwan Crawford { 297355232f09SEwan Crawford const size_t argc = command.GetArgumentCount(); 297455232f09SEwan Crawford if (argc != 2) 297555232f09SEwan Crawford { 297655232f09SEwan Crawford result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str()); 297755232f09SEwan Crawford result.SetStatus(eReturnStatusFailed); 297855232f09SEwan Crawford return false; 297955232f09SEwan Crawford } 298055232f09SEwan Crawford 298155232f09SEwan Crawford RenderScriptRuntime *runtime = 298255232f09SEwan Crawford static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 298355232f09SEwan Crawford 298455232f09SEwan Crawford const char* id_cstr = command.GetArgumentAtIndex(0); 298555232f09SEwan Crawford bool convert_complete = false; 298655232f09SEwan Crawford const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete); 298755232f09SEwan Crawford if (!convert_complete) 298855232f09SEwan Crawford { 298955232f09SEwan Crawford result.AppendErrorWithFormat ("invalid allocation id argument '%s'", id_cstr); 299055232f09SEwan Crawford result.SetStatus (eReturnStatusFailed); 299155232f09SEwan Crawford return false; 299255232f09SEwan Crawford } 299355232f09SEwan Crawford 299455232f09SEwan Crawford const char* filename = command.GetArgumentAtIndex(1); 299555232f09SEwan Crawford bool success = runtime->LoadAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr()); 299655232f09SEwan Crawford 299755232f09SEwan Crawford if (success) 299855232f09SEwan Crawford result.SetStatus(eReturnStatusSuccessFinishResult); 299955232f09SEwan Crawford else 300055232f09SEwan Crawford result.SetStatus(eReturnStatusFailed); 300155232f09SEwan Crawford 300255232f09SEwan Crawford return true; 300355232f09SEwan Crawford } 300455232f09SEwan Crawford }; 300555232f09SEwan Crawford 300655232f09SEwan Crawford 300755232f09SEwan Crawford class CommandObjectRenderScriptRuntimeAllocationSave : public CommandObjectParsed 300855232f09SEwan Crawford { 300955232f09SEwan Crawford private: 301055232f09SEwan Crawford public: 301155232f09SEwan Crawford CommandObjectRenderScriptRuntimeAllocationSave(CommandInterpreter &interpreter) 301255232f09SEwan Crawford : CommandObjectParsed(interpreter, "renderscript allocation save", 301355232f09SEwan Crawford "Write renderscript allocation contents to a file.", "renderscript allocation save <ID> <filename>", 301455232f09SEwan Crawford eCommandRequiresProcess | eCommandProcessMustBeLaunched) 301555232f09SEwan Crawford { 301655232f09SEwan Crawford } 301755232f09SEwan Crawford 301855232f09SEwan Crawford ~CommandObjectRenderScriptRuntimeAllocationSave() {} 301955232f09SEwan Crawford 302055232f09SEwan Crawford bool 302155232f09SEwan Crawford DoExecute(Args &command, CommandReturnObject &result) 302255232f09SEwan Crawford { 302355232f09SEwan Crawford const size_t argc = command.GetArgumentCount(); 302455232f09SEwan Crawford if (argc != 2) 302555232f09SEwan Crawford { 302655232f09SEwan Crawford result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str()); 302755232f09SEwan Crawford result.SetStatus(eReturnStatusFailed); 302855232f09SEwan Crawford return false; 302955232f09SEwan Crawford } 303055232f09SEwan Crawford 303155232f09SEwan Crawford RenderScriptRuntime *runtime = 303255232f09SEwan Crawford static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 303355232f09SEwan Crawford 303455232f09SEwan Crawford const char* id_cstr = command.GetArgumentAtIndex(0); 303555232f09SEwan Crawford bool convert_complete = false; 303655232f09SEwan Crawford const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete); 303755232f09SEwan Crawford if (!convert_complete) 303855232f09SEwan Crawford { 303955232f09SEwan Crawford result.AppendErrorWithFormat ("invalid allocation id argument '%s'", id_cstr); 304055232f09SEwan Crawford result.SetStatus (eReturnStatusFailed); 304155232f09SEwan Crawford return false; 304255232f09SEwan Crawford } 304355232f09SEwan Crawford 304455232f09SEwan Crawford const char* filename = command.GetArgumentAtIndex(1); 304555232f09SEwan Crawford bool success = runtime->SaveAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr()); 304655232f09SEwan Crawford 304755232f09SEwan Crawford if (success) 304855232f09SEwan Crawford result.SetStatus(eReturnStatusSuccessFinishResult); 304955232f09SEwan Crawford else 305055232f09SEwan Crawford result.SetStatus(eReturnStatusFailed); 305155232f09SEwan Crawford 305255232f09SEwan Crawford return true; 305355232f09SEwan Crawford } 305455232f09SEwan Crawford }; 305555232f09SEwan Crawford 305615f2bd95SEwan Crawford class CommandObjectRenderScriptRuntimeAllocation : public CommandObjectMultiword 305715f2bd95SEwan Crawford { 305815f2bd95SEwan Crawford private: 305915f2bd95SEwan Crawford public: 306015f2bd95SEwan Crawford CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter) 306115f2bd95SEwan Crawford : CommandObjectMultiword(interpreter, "renderscript allocation", "Commands that deal with renderscript allocations.", 306215f2bd95SEwan Crawford NULL) 306315f2bd95SEwan Crawford { 306415f2bd95SEwan Crawford LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationList(interpreter))); 3065a0f08674SEwan Crawford LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationDump(interpreter))); 306655232f09SEwan Crawford LoadSubCommand("save", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationSave(interpreter))); 306755232f09SEwan Crawford LoadSubCommand("load", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationLoad(interpreter))); 306815f2bd95SEwan Crawford } 306915f2bd95SEwan Crawford 307015f2bd95SEwan Crawford ~CommandObjectRenderScriptRuntimeAllocation() {} 307115f2bd95SEwan Crawford }; 307215f2bd95SEwan Crawford 307315f2bd95SEwan Crawford 30744640cde1SColin Riley class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed 30754640cde1SColin Riley { 30764640cde1SColin Riley private: 30774640cde1SColin Riley public: 30784640cde1SColin Riley CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter) 30794640cde1SColin Riley : CommandObjectParsed(interpreter, "renderscript status", 30804640cde1SColin Riley "Displays current renderscript runtime status.", "renderscript status", 30814640cde1SColin Riley eCommandRequiresProcess | eCommandProcessMustBeLaunched) 30824640cde1SColin Riley { 30834640cde1SColin Riley } 30844640cde1SColin Riley 30854640cde1SColin Riley ~CommandObjectRenderScriptRuntimeStatus() {} 30864640cde1SColin Riley 30874640cde1SColin Riley bool 30884640cde1SColin Riley DoExecute(Args &command, CommandReturnObject &result) 30894640cde1SColin Riley { 30904640cde1SColin Riley RenderScriptRuntime *runtime = 30914640cde1SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 30924640cde1SColin Riley runtime->Status(result.GetOutputStream()); 30934640cde1SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 30944640cde1SColin Riley return true; 30954640cde1SColin Riley } 30964640cde1SColin Riley }; 30974640cde1SColin Riley 30985ec532a9SColin Riley class CommandObjectRenderScriptRuntime : public CommandObjectMultiword 30995ec532a9SColin Riley { 31005ec532a9SColin Riley public: 31015ec532a9SColin Riley CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter) 31025ec532a9SColin Riley : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.", 31035ec532a9SColin Riley "renderscript <subcommand> [<subcommand-options>]") 31045ec532a9SColin Riley { 31055ec532a9SColin Riley LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter))); 31064640cde1SColin Riley LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter))); 31074640cde1SColin Riley LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter))); 31084640cde1SColin Riley LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter))); 310915f2bd95SEwan Crawford LoadSubCommand("allocation", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocation(interpreter))); 31105ec532a9SColin Riley } 31115ec532a9SColin Riley 31125ec532a9SColin Riley ~CommandObjectRenderScriptRuntime() {} 31135ec532a9SColin Riley }; 3114ef20b08fSColin Riley 3115ef20b08fSColin Riley void 3116ef20b08fSColin Riley RenderScriptRuntime::Initiate() 31175ec532a9SColin Riley { 3118ef20b08fSColin Riley assert(!m_initiated); 31195ec532a9SColin Riley } 3120ef20b08fSColin Riley 3121ef20b08fSColin Riley RenderScriptRuntime::RenderScriptRuntime(Process *process) 31227dc7771cSEwan Crawford : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false), 31237dc7771cSEwan Crawford m_breakAllKernels(false) 3124ef20b08fSColin Riley { 31254640cde1SColin Riley ModulesDidLoad(process->GetTarget().GetImages()); 3126ef20b08fSColin Riley } 31274640cde1SColin Riley 31284640cde1SColin Riley lldb::CommandObjectSP 31294640cde1SColin Riley RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter) 31304640cde1SColin Riley { 31314640cde1SColin Riley static CommandObjectSP command_object; 31324640cde1SColin Riley if(!command_object) 31334640cde1SColin Riley { 31344640cde1SColin Riley command_object.reset(new CommandObjectRenderScriptRuntime(interpreter)); 31354640cde1SColin Riley } 31364640cde1SColin Riley return command_object; 31374640cde1SColin Riley } 31384640cde1SColin Riley 313978f339d1SEwan Crawford RenderScriptRuntime::~RenderScriptRuntime() = default; 3140