41 #include "llvm/ADT/StringSwitch.h"
47 using namespace lldb_renderscript;
51 #define FMT_COORD "(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")"
61 template <
typename type_t>
class empirical_type {
64 empirical_type() =
default;
67 bool get(type_t &out)
const {
74 const type_t *get()
const {
return valid ? &data :
nullptr; }
77 void set(
const type_t in) {
83 void invalidate() { valid =
false; }
86 bool isValid()
const {
return valid; }
89 empirical_type<type_t> &operator=(
const type_t in) {
109 enum { ePointer, eInt32, eInt64, eLong, eBool } type;
113 explicit operator uint64_t()
const {
return value; }
123 bool GetArgsX86(
const GetArgsCtx &ctx, ArgItem *arg_list,
size_t num_args) {
129 uint64_t
sp = ctx.reg_ctx->GetSP();
131 for (
size_t i = 0; i < num_args; ++i) {
132 ArgItem &arg = arg_list[i];
141 ctx.process->ReadMemory(
sp, &arg.value,
sizeof(
uint32_t), err);
142 if (read != arg_size || !err.
Success()) {
143 LLDB_LOGF(log,
"%s - error reading argument: %" PRIu64
" '%s'",
144 __FUNCTION__, uint64_t(i), err.
AsCString());
151 bool GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list,
size_t num_args) {
155 static const uint32_t args_in_reg = 6;
157 static const std::array<const char *, args_in_reg> reg_names{
158 {
"rdi",
"rsi",
"rdx",
"rcx",
"r8",
"r9"}};
160 static const std::array<size_t, 5> arg_size{{
171 uint64_t
sp = ctx.reg_ctx->GetSP();
173 sp +=
sizeof(uint64_t);
176 if ((
sp & 0xf) != 0x0) {
177 LLDB_LOGF(log,
"%s - stack misaligned", __FUNCTION__);
182 uint64_t sp_offset = 0;
183 for (
uint32_t i = args_in_reg; i < num_args; ++i) {
184 sp_offset += arg_size[arg_list[i].type];
187 sp_offset = (sp_offset + 0xf) & 0xf;
190 for (
size_t i = 0; i < num_args; ++i) {
191 bool success =
false;
192 ArgItem &arg = arg_list[i];
194 if (i < args_in_reg) {
195 const RegisterInfo *reg =
196 ctx.reg_ctx->GetRegisterInfoByName(reg_names[i]);
198 if (ctx.reg_ctx->ReadRegister(reg, reg_val))
204 const size_t size = arg_size[arg_list[i].type];
209 size_t read = ctx.process->ReadMemory(
sp, &arg.value, size, err);
210 success = (err.
Success() && read == size);
216 LLDB_LOGF(log,
"%s - error reading argument: %" PRIu64
", reason: %s",
217 __FUNCTION__, uint64_t(i), err.
AsCString(
"n/a"));
224 bool GetArgsArm(GetArgsCtx &ctx, ArgItem *arg_list,
size_t num_args) {
226 static const uint32_t args_in_reg = 4;
233 uint64_t
sp = ctx.reg_ctx->GetSP();
235 for (
size_t i = 0; i < num_args; ++i) {
236 bool success =
false;
237 ArgItem &arg = arg_list[i];
239 if (i < args_in_reg) {
240 const RegisterInfo *reg = ctx.reg_ctx->GetRegisterInfoAtIndex(i);
242 if (ctx.reg_ctx->ReadRegister(reg, reg_val))
248 const size_t arg_size =
sizeof(
uint32_t);
253 ctx.process->ReadMemory(
sp, &arg.value, arg_size, err);
254 success = (err.
Success() && bytes_read == arg_size);
260 LLDB_LOGF(log,
"%s - error reading argument: %" PRIu64
", reason: %s",
261 __FUNCTION__, uint64_t(i), err.
AsCString(
"n/a"));
268 bool GetArgsAarch64(GetArgsCtx &ctx, ArgItem *arg_list,
size_t num_args) {
270 static const uint32_t args_in_reg = 8;
274 for (
size_t i = 0; i < num_args; ++i) {
275 bool success =
false;
276 ArgItem &arg = arg_list[i];
278 if (i < args_in_reg) {
279 const RegisterInfo *reg = ctx.reg_ctx->GetRegisterInfoAtIndex(i);
281 if (ctx.reg_ctx->ReadRegister(reg, reg_val))
286 LLDB_LOGF(log,
"%s - reading arguments spilled to stack not implemented",
291 LLDB_LOGF(log,
"%s - error reading argument: %" PRIu64, __FUNCTION__,
299 bool GetArgsMipsel(GetArgsCtx &ctx, ArgItem *arg_list,
size_t num_args) {
301 static const uint32_t args_in_reg = 4;
303 static const uint32_t reg_offset = 4;
311 uint64_t
sp = ctx.reg_ctx->GetSP() + 16;
313 for (
size_t i = 0; i < num_args; ++i) {
314 bool success =
false;
315 ArgItem &arg = arg_list[i];
317 if (i < args_in_reg) {
318 const RegisterInfo *reg =
319 ctx.reg_ctx->GetRegisterInfoAtIndex(i + reg_offset);
321 if (ctx.reg_ctx->ReadRegister(reg, reg_val))
326 const size_t arg_size =
sizeof(
uint32_t);
329 ctx.process->ReadMemory(
sp, &arg.value, arg_size, err);
330 success = (err.
Success() && bytes_read == arg_size);
336 LLDB_LOGF(log,
"%s - error reading argument: %" PRIu64
", reason: %s",
337 __FUNCTION__, uint64_t(i), err.
AsCString(
"n/a"));
344 bool GetArgsMips64el(GetArgsCtx &ctx, ArgItem *arg_list,
size_t num_args) {
346 static const uint32_t args_in_reg = 8;
348 static const uint32_t reg_offset = 4;
355 uint64_t
sp = ctx.reg_ctx->GetSP();
357 for (
size_t i = 0; i < num_args; ++i) {
358 bool success =
false;
359 ArgItem &arg = arg_list[i];
361 if (i < args_in_reg) {
362 const RegisterInfo *reg =
363 ctx.reg_ctx->GetRegisterInfoAtIndex(i + reg_offset);
365 if (ctx.reg_ctx->ReadRegister(reg, reg_val))
371 const size_t arg_size =
sizeof(uint64_t);
376 ctx.process->ReadMemory(
sp, &arg.value, arg_size, err);
377 success = (err.
Success() && bytes_read == arg_size);
383 LLDB_LOGF(log,
"%s - error reading argument: %" PRIu64
", reason: %s",
384 __FUNCTION__, uint64_t(i), err.
AsCString(
"n/a"));
391 bool GetArgs(
ExecutionContext &exe_ctx, ArgItem *arg_list,
size_t num_args) {
396 LLDB_LOGF(log,
"%s - invalid target", __FUNCTION__);
401 assert(ctx.reg_ctx && ctx.process);
405 case llvm::Triple::ArchType::x86:
406 return GetArgsX86(ctx, arg_list, num_args);
408 case llvm::Triple::ArchType::x86_64:
409 return GetArgsX86_64(ctx, arg_list, num_args);
411 case llvm::Triple::ArchType::arm:
412 return GetArgsArm(ctx, arg_list, num_args);
414 case llvm::Triple::ArchType::aarch64:
415 return GetArgsAarch64(ctx, arg_list, num_args);
417 case llvm::Triple::ArchType::mipsel:
418 return GetArgsMipsel(ctx, arg_list, num_args);
420 case llvm::Triple::ArchType::mips64el:
421 return GetArgsMips64el(ctx, arg_list, num_args);
426 LLDB_LOGF(log,
"%s - architecture not supported: '%s'", __FUNCTION__,
433 bool IsRenderScriptScriptModule(ModuleSP module) {
436 return module->FindFirstSymbolWithNameAndType(
ConstString(
".rs.info"),
440 bool ParseCoordinate(llvm::StringRef coord_s,
RSCoordinate &coord) {
447 llvm::SmallVector<llvm::StringRef, 4> matches;
450 .Execute(coord_s, &matches) &&
455 auto get_index = [&](
size_t idx,
uint32_t &i) ->
bool {
458 if (idx + 1 < matches.size()) {
459 return !llvm::StringRef(matches[idx + 1]).getAsInteger<
uint32_t>(10, i);
464 return get_index(0, coord.
x) && get_index(1, coord.
y) &&
465 get_index(2, coord.
z);
468 bool SkipPrologue(lldb::ModuleSP &module,
Address &addr) {
472 module->ResolveSymbolContextForAddress(addr, eSymbolContextFunction, sc);
473 if (resolved_flags & eSymbolContextFunction) {
479 LLDB_LOGF(log,
"%s: Prologue offset for %s is %" PRIu32, __FUNCTION__,
496 empirical_type<ScriptType>
type;
522 RS_KIND_INVALID = 100
549 RS_TYPE_ELEMENT = 1000,
561 RS_TYPE_INVALID = 10000
565 empirical_type<lldb::addr_t>
567 empirical_type<DataType>
569 empirical_type<DataKind>
571 empirical_type<uint32_t>
576 empirical_type<uint32_t>
581 GetFallbackStructName();
585 const bool valid_ptr = element_ptr.isValid() && *element_ptr.get() != 0x0;
586 const bool valid_type =
587 type.isValid() && type_vec_size.isValid() && type_kind.isValid();
588 return !valid_ptr || !valid_type || !datum_size.isValid();
640 static const char *RsDataTypeToString[][4];
643 static const char *RsDataKindToString[];
673 bool valid_ptrs = data_ptr.isValid() && *data_ptr.get() != 0x0;
674 valid_ptrs = valid_ptrs && type_ptr.isValid() && *type_ptr.get() != 0x0;
675 return !valid_ptrs || !dimension.isValid() || !size.isValid() ||
681 static const ConstString FallbackStructName(
"struct");
682 return FallbackStructName;
688 "User",
"Undefined",
"Undefined",
"Undefined",
689 "Undefined",
"Undefined",
"Undefined",
690 "L Pixel",
"A Pixel",
"LA Pixel",
"RGB Pixel",
691 "RGBA Pixel",
"Pixel Depth",
"YUV Pixel"};
694 {
"None",
"None",
"None",
"None"},
695 {
"half",
"half2",
"half3",
"half4"},
696 {
"float",
"float2",
"float3",
"float4"},
697 {
"double",
"double2",
"double3",
"double4"},
698 {
"char",
"char2",
"char3",
"char4"},
699 {
"short",
"short2",
"short3",
"short4"},
700 {
"int",
"int2",
"int3",
"int4"},
701 {
"long",
"long2",
"long3",
"long4"},
702 {
"uchar",
"uchar2",
"uchar3",
"uchar4"},
703 {
"ushort",
"ushort2",
"ushort3",
"ushort4"},
704 {
"uint",
"uint2",
"uint3",
"uint4"},
705 {
"ulong",
"ulong2",
"ulong3",
"ulong4"},
706 {
"bool",
"bool2",
"bool3",
"bool4"},
707 {
"packed_565",
"packed_565",
"packed_565",
"packed_565"},
708 {
"packed_5551",
"packed_5551",
"packed_5551",
"packed_5551"},
709 {
"packed_4444",
"packed_4444",
"packed_4444",
"packed_4444"},
710 {
"rs_matrix4x4",
"rs_matrix4x4",
"rs_matrix4x4",
"rs_matrix4x4"},
711 {
"rs_matrix3x3",
"rs_matrix3x3",
"rs_matrix3x3",
"rs_matrix3x3"},
712 {
"rs_matrix2x2",
"rs_matrix2x2",
"rs_matrix2x2",
"rs_matrix2x2"},
715 {
"RS Element",
"RS Element",
"RS Element",
"RS Element"},
716 {
"RS Type",
"RS Type",
"RS Type",
"RS Type"},
717 {
"RS Allocation",
"RS Allocation",
"RS Allocation",
"RS Allocation"},
718 {
"RS Sampler",
"RS Sampler",
"RS Sampler",
"RS Sampler"},
719 {
"RS Script",
"RS Script",
"RS Script",
"RS Script"},
722 {
"RS Mesh",
"RS Mesh",
"RS Mesh",
"RS Mesh"},
723 {
"RS Program Fragment",
"RS Program Fragment",
"RS Program Fragment",
724 "RS Program Fragment"},
725 {
"RS Program Vertex",
"RS Program Vertex",
"RS Program Vertex",
726 "RS Program Vertex"},
727 {
"RS Program Raster",
"RS Program Raster",
"RS Program Raster",
728 "RS Program Raster"},
729 {
"RS Program Store",
"RS Program Store",
"RS Program Store",
731 {
"RS Font",
"RS Font",
"RS Font",
"RS Font"}};
780 RenderScriptRuntime::CreateInstance(
Process *process,
796 BreakpointSP breakpoint_sp = GetBreakpoint();
797 assert(breakpoint_sp);
801 if (!module || !IsRenderScriptScriptModule(module))
802 return Searcher::eCallbackReturnContinue;
807 const Symbol *kernel_sym =
808 module->FindFirstSymbolWithNameAndType(m_kernel_name,
eSymbolTypeCode);
810 std::string kernel_name_expanded(m_kernel_name.AsCString());
811 kernel_name_expanded.append(
".expand");
812 kernel_sym = module->FindFirstSymbolWithNameAndType(
819 breakpoint_sp->AddLocation(bp_addr);
822 return Searcher::eCallbackReturnContinue;
829 BreakpointSP breakpoint_sp = GetBreakpoint();
830 assert(breakpoint_sp);
840 if (!module || !IsRenderScriptScriptModule(module))
841 return Searcher::eCallbackReturnContinue;
844 return Searcher::eCallbackReturnContinue;
846 for (
const auto &module_desc : *m_rsmodules) {
847 if (module_desc->m_module != module)
850 for (
const auto &reduction : module_desc->m_reductions) {
851 if (reduction.m_reduce_name != m_reduce_name)
854 std::array<std::pair<ConstString, int>, 5> funcs{
855 {{reduction.m_init_name, eKernelTypeInit},
856 {reduction.m_accum_name, eKernelTypeAccum},
857 {reduction.m_comb_name, eKernelTypeComb},
858 {reduction.m_outc_name, eKernelTypeOutC},
859 {reduction.m_halter_name, eKernelTypeHalter}}};
861 for (
const auto &kernel : funcs) {
863 if (!(m_kernel_types & kernel.second))
866 const auto kernel_name = kernel.first;
867 const auto symbol = module->FindFirstSymbolWithNameAndType(
872 auto address = symbol->GetAddress();
875 if (!SkipPrologue(module, address)) {
876 LLDB_LOGF(log,
"%s: Error trying to skip prologue", __FUNCTION__);
878 breakpoint_sp->AddLocation(address, &new_bp);
879 LLDB_LOGF(log,
"%s: %s reduction breakpoint on %s in %s",
880 __FUNCTION__, new_bp ?
"new" :
"existing",
881 kernel_name.GetCString(),
882 address.GetModule()->GetFileSpec().GetCString());
887 return eCallbackReturnContinue;
893 BreakpointSP breakpoint_sp = GetBreakpoint();
895 return eCallbackReturnContinue;
900 if (!module || !IsRenderScriptScriptModule(module))
901 return Searcher::eCallbackReturnContinue;
903 std::vector<std::string> names;
907 return eCallbackReturnContinue;
909 for (
auto &name : names) {
912 LLDB_LOGF(log,
"%s: could not find script group for %s", __FUNCTION__,
917 LLDB_LOGF(log,
"%s: Found ScriptGroup for %s", __FUNCTION__, name.c_str());
921 LLDB_LOGF(log,
"%s: Adding breakpoint for %s", __FUNCTION__,
923 LLDB_LOGF(log,
"%s: Kernel address 0x%" PRIx64, __FUNCTION__, k.
m_addr);
929 LLDB_LOGF(log,
"%s: Unable to find symbol for %s", __FUNCTION__,
935 LLDB_LOGF(log,
"%s: Found symbol name is %s", __FUNCTION__,
940 if (!SkipPrologue(module, address)) {
941 LLDB_LOGF(log,
"%s: Error trying to skip prologue", __FUNCTION__);
947 LLDB_LOGF(log,
"%s: Placed %sbreakpoint on %s", __FUNCTION__,
957 return eCallbackReturnContinue;
960 void RenderScriptRuntime::Initialize() {
961 PluginManager::RegisterPlugin(GetPluginNameStatic(),
962 "RenderScript language support", CreateInstance,
966 void RenderScriptRuntime::Terminate() {
967 PluginManager::UnregisterPlugin(CreateInstance);
971 RenderScriptRuntime::GetModuleKind(
const lldb::ModuleSP &module_sp) {
973 if (IsRenderScriptScriptModule(module_sp))
974 return eModuleKindKernelObj;
978 if (module_sp->GetFileSpec().GetFilename() == rs_lib) {
979 return eModuleKindLibRS;
983 if (module_sp->GetFileSpec().GetFilename() == rs_driverlib) {
984 return eModuleKindDriver;
988 if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib) {
989 return eModuleKindImpl;
992 return eModuleKindIgnored;
995 bool RenderScriptRuntime::IsRenderScriptModule(
996 const lldb::ModuleSP &module_sp) {
997 return GetModuleKind(module_sp) != eModuleKindIgnored;
1000 void RenderScriptRuntime::ModulesDidLoad(
const ModuleList &module_list) {
1001 std::lock_guard<std::recursive_mutex> guard(module_list.
GetMutex());
1003 size_t num_modules = module_list.
GetSize();
1004 for (
size_t i = 0; i < num_modules; i++) {
1006 if (IsRenderScriptModule(mod)) {
1012 bool RenderScriptRuntime::GetDynamicTypeAndAddress(
1022 return type_and_or_name;
1025 bool RenderScriptRuntime::CouldHaveDynamicValue(
ValueObject &in_value) {
1029 lldb::BreakpointResolverSP
1030 RenderScriptRuntime::CreateExceptionResolver(
const lldb::BreakpointSP &bp,
1031 bool catch_bp,
bool throw_bp) {
1032 BreakpointResolverSP resolver_sp;
1039 {
"rsdScriptInit",
"_Z13rsdScriptInitPKN7android12renderscript7ContextEP"
1040 "NS0_7ScriptCEPKcS7_PKhjj",
1041 "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_"
1042 "7ScriptCEPKcS7_PKhmj",
1043 0, RenderScriptRuntime::eModuleKindDriver,
1045 {
"rsdScriptInvokeForEachMulti",
1046 "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0"
1047 "_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall",
1048 "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0"
1049 "_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall",
1050 0, RenderScriptRuntime::eModuleKindDriver,
1052 {
"rsdScriptSetGlobalVar",
"_Z21rsdScriptSetGlobalVarPKN7android12render"
1053 "script7ContextEPKNS0_6ScriptEjPvj",
1054 "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_"
1056 0, RenderScriptRuntime::eModuleKindDriver,
1060 {
"rsdAllocationInit",
"_Z17rsdAllocationInitPKN7android12renderscript7C"
1061 "ontextEPNS0_10AllocationEb",
1062 "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_"
1064 0, RenderScriptRuntime::eModuleKindDriver,
1066 {
"rsdAllocationRead2D",
1067 "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_"
1068 "10AllocationEjjj23RsAllocationCubemapFacejjPvjj",
1069 "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_"
1070 "10AllocationEjjj23RsAllocationCubemapFacejjPvmm",
1071 0, RenderScriptRuntime::eModuleKindDriver,
nullptr},
1072 {
"rsdAllocationDestroy",
"_Z20rsdAllocationDestroyPKN7android12rendersc"
1073 "ript7ContextEPNS0_10AllocationE",
1074 "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_"
1076 0, RenderScriptRuntime::eModuleKindDriver,
1080 {
"rsdDebugHintScriptGroup2",
"_ZN7android12renderscript21debugHintScrip"
1081 "tGroup2EPKcjPKPFvPK24RsExpandKernelDriver"
1083 "_ZN7android12renderscript21debugHintScriptGroup2EPKcjPKPFvPK24RsExpan"
1084 "dKernelDriverInfojjjEj",
1085 0, RenderScriptRuntime::eModuleKindImpl,
1088 const size_t RenderScriptRuntime::s_runtimeHookCount =
1089 sizeof(s_runtimeHookDefns) /
sizeof(s_runtimeHookDefns[0]);
1091 bool RenderScriptRuntime::HookCallback(
void *baton,
1118 void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
1129 std::array<ArgItem, 4> args{{
1130 {ArgItem::ePointer, 0},
1131 {ArgItem::eInt32, 0},
1132 {ArgItem::ePointer, 0},
1133 {ArgItem::eInt32, 0},
1136 if (!GetArgs(context, args.data(), args.size())) {
1137 LLDB_LOGF(log,
"%s - Error while reading the function parameters",
1141 LLDB_LOGF(log,
"%s - groupName : 0x%" PRIx64, __FUNCTION__,
1142 addr_t(args[eGroupName]));
1143 LLDB_LOGF(log,
"%s - groupNameSize: %" PRIu64, __FUNCTION__,
1144 uint64_t(args[eGroupNameSize]));
1145 LLDB_LOGF(log,
"%s - kernel : 0x%" PRIx64, __FUNCTION__,
1147 LLDB_LOGF(log,
"%s - kernelCount : %" PRIu64, __FUNCTION__,
1148 uint64_t(args[eKernelCount]));
1155 const uint64_t len = uint64_t(args[eGroupNameSize]);
1156 std::unique_ptr<char[]> buffer(
new char[
uint32_t(len + 1)]);
1157 m_process->ReadMemory(
addr_t(args[eGroupName]), buffer.get(), len, err);
1158 buffer.get()[len] =
'\0';
1160 LLDB_LOGF(log,
"Error reading scriptgroup name from target");
1163 LLDB_LOGF(log,
"Extracted scriptgroup name %s", buffer.get());
1173 for (
auto sg : m_scriptGroups) {
1174 if (sg->m_name == group_name) {
1180 group = std::make_shared<RSScriptGroupDescriptor>();
1181 group->m_name = group_name;
1182 m_scriptGroups.push_back(group);
1185 LLDB_LOGF(log,
"Attempt to add duplicate script group %s",
1192 const uint32_t target_ptr_size = m_process->GetAddressByteSize();
1193 std::vector<addr_t> kernels;
1195 for (uint64_t i = 0; i < uint64_t(args[eKernelCount]); ++i) {
1198 const addr_t ptr_addr =
addr_t(args[eKernel]) + i * target_ptr_size;
1199 uint64_t kernel_addr = 0;
1202 m_process->ReadMemory(ptr_addr, &kernel_addr, target_ptr_size, err);
1203 if (!err.
Success() || read != target_ptr_size) {
1204 LLDB_LOGF(log,
"Error parsing kernel address %" PRIu64
" in script group",
1208 LLDB_LOGF(log,
"Extracted scriptgroup kernel address - 0x%" PRIx64,
1210 kernel.
m_addr = kernel_addr;
1213 if (!ResolveKernelName(kernel.
m_addr, kernel.
m_name)) {
1214 LLDB_LOGF(log,
"Parsed scriptgroup kernel %" PRIu64
" - 0x%" PRIx64, i,
1221 const llvm::StringRef expand(
".expand");
1223 if (name_ref.endswith(expand)) {
1224 const ConstString base_kernel(name_ref.drop_back(expand.size()));
1226 if (IsKnownKernel(base_kernel)) {
1227 kernel.
m_name = base_kernel;
1228 LLDB_LOGF(log,
"%s - found non expand version '%s'", __FUNCTION__,
1234 group->m_kernels.push_back(kernel);
1239 Target &target = m_process->GetTarget();
1241 const size_t num_breakpoints =
list.GetSize();
1242 LLDB_LOGF(log,
"Resolving %zu breakpoints", num_breakpoints);
1243 for (
size_t i = 0; i < num_breakpoints; ++i) {
1244 const BreakpointSP bp =
list.GetBreakpointAtIndex(i);
1246 if (bp->MatchesName(group_name.
AsCString())) {
1247 LLDB_LOGF(log,
"Found breakpoint with name %s",
1249 bp->ResolveBreakpoint();
1256 void RenderScriptRuntime::CaptureScriptInvokeForEachMulti(
1272 std::array<ArgItem, 9> args{{
1273 ArgItem{ArgItem::ePointer, 0},
1274 ArgItem{ArgItem::ePointer, 0},
1275 ArgItem{ArgItem::eInt32, 0},
1276 ArgItem{ArgItem::ePointer, 0},
1277 ArgItem{ArgItem::eInt32, 0},
1278 ArgItem{ArgItem::ePointer, 0},
1279 ArgItem{ArgItem::ePointer, 0},
1280 ArgItem{ArgItem::eInt32, 0},
1281 ArgItem{ArgItem::ePointer, 0},
1284 bool success = GetArgs(exe_ctx, &args[0], args.size());
1286 LLDB_LOGF(log,
"%s - Error while reading the function parameters",
1291 const uint32_t target_ptr_size = m_process->GetAddressByteSize();
1293 std::vector<uint64_t> allocs;
1296 for (uint64_t i = 0; i < uint64_t(args[eRsInLen]); ++i) {
1298 const addr_t addr =
addr_t(args[eRsAIns]) + i * target_ptr_size;
1302 uint64_t result = 0;
1303 size_t read = m_process->ReadMemory(addr, &result, target_ptr_size, err);
1304 if (read != target_ptr_size || !err.
Success()) {
1306 "%s - Error while reading allocation list argument %" PRIu64,
1309 allocs.push_back(result);
1314 if (uint64_t alloc_out = uint64_t(args[eRsAOut])) {
1315 allocs.push_back(alloc_out);
1319 for (
const uint64_t alloc_addr : allocs) {
1322 alloc = CreateAllocation(alloc_addr);
1326 if (alloc->
address.isValid()) {
1328 assert(*alloc->
address.get() == alloc_addr);
1335 if (alloc->
context.isValid() &&
1337 LLDB_LOGF(log,
"%s - Allocation used by multiple contexts",
1346 LookUpScript(
addr_t(args[eRsScript]),
true)) {
1348 if (script->context.isValid() &&
1349 *script->context.get() !=
addr_t(args[eRsContext]))
1350 LLDB_LOGF(log,
"%s - Script used by multiple contexts", __FUNCTION__);
1352 script->context =
addr_t(args[eRsContext]);
1368 std::array<ArgItem, 5> args{{
1369 ArgItem{ArgItem::ePointer, 0},
1370 ArgItem{ArgItem::ePointer, 0},
1371 ArgItem{ArgItem::eInt32, 0},
1372 ArgItem{ArgItem::ePointer, 0},
1373 ArgItem{ArgItem::eInt32, 0},
1376 bool success = GetArgs(context, &args[0], args.size());
1378 LLDB_LOGF(log,
"%s - error reading the function parameters.", __FUNCTION__);
1384 "%s - 0x%" PRIx64
",0x%" PRIx64
" slot %" PRIu64
" = 0x%" PRIx64
1385 ":%" PRIu64
"bytes.",
1386 __FUNCTION__, uint64_t(args[eRsContext]),
1387 uint64_t(args[eRsScript]), uint64_t(args[eRsId]),
1388 uint64_t(args[eRsData]), uint64_t(args[eRsLength]));
1391 if (m_scriptMappings.find(script_addr) != m_scriptMappings.end()) {
1392 auto rsm = m_scriptMappings[script_addr];
1393 if (uint64_t(args[eRsId]) < rsm->m_globals.size()) {
1394 auto rsg = rsm->m_globals[uint64_t(args[eRsId])];
1395 LLDB_LOGF(log,
"%s - Setting of '%s' within '%s' inferred",
1396 __FUNCTION__, rsg.m_name.AsCString(),
1397 rsm->m_module->GetFileSpec().GetFilename().AsCString());
1407 enum { eRsContext, eRsAlloc, eRsForceZero };
1409 std::array<ArgItem, 3> args{{
1410 ArgItem{ArgItem::ePointer, 0},
1411 ArgItem{ArgItem::ePointer, 0},
1412 ArgItem{ArgItem::eBool, 0},
1415 bool success = GetArgs(exe_ctx, &args[0], args.size());
1417 LLDB_LOGF(log,
"%s - error while reading the function parameters",
1422 LLDB_LOGF(log,
"%s - 0x%" PRIx64
",0x%" PRIx64
",0x%" PRIx64
" .",
1423 __FUNCTION__, uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]),
1424 uint64_t(args[eRsForceZero]));
1428 alloc->
context = uint64_t(args[eRsContext]);
1440 std::array<ArgItem, 2> args{{
1441 ArgItem{ArgItem::ePointer, 0},
1442 ArgItem{ArgItem::ePointer, 0},
1445 bool success = GetArgs(exe_ctx, &args[0], args.size());
1447 LLDB_LOGF(log,
"%s - error while reading the function parameters.",
1452 LLDB_LOGF(log,
"%s - 0x%" PRIx64
", 0x%" PRIx64
".", __FUNCTION__,
1453 uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]));
1455 for (
auto iter = m_allocations.begin(); iter != m_allocations.end(); ++iter) {
1456 auto &allocation_up = *iter;
1457 if (allocation_up->address.isValid() &&
1458 *allocation_up->address.get() ==
addr_t(args[eRsAlloc])) {
1459 m_allocations.erase(iter);
1460 LLDB_LOGF(log,
"%s - deleted allocation entry.", __FUNCTION__);
1465 LLDB_LOGF(log,
"%s - couldn't find destroyed allocation.", __FUNCTION__);
1475 enum { eRsContext, eRsScript, eRsResNamePtr, eRsCachedDirPtr };
1477 std::array<ArgItem, 4> args{
1478 {ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0},
1479 ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0}}};
1480 bool success = GetArgs(exe_ctx, &args[0], args.size());
1482 LLDB_LOGF(log,
"%s - error while reading the function parameters.",
1490 LLDB_LOGF(log,
"%s - error reading res_name: %s.", __FUNCTION__,
1497 LLDB_LOGF(log,
"%s - error reading cache_dir: %s.", __FUNCTION__,
1501 LLDB_LOGF(log,
"%s - 0x%" PRIx64
",0x%" PRIx64
" => '%s' at '%s' .",
1502 __FUNCTION__, uint64_t(args[eRsContext]), uint64_t(args[eRsScript]),
1503 res_name.c_str(), cache_dir.c_str());
1505 if (res_name.size() > 0) {
1507 strm.
Printf(
"librs.%s.so", res_name.c_str());
1511 script->
type = ScriptDetails::eScriptC;
1519 "%s - '%s' tagged with context 0x%" PRIx64
1520 " and script 0x%" PRIx64
".",
1521 __FUNCTION__, strm.
GetData(), uint64_t(args[eRsContext]),
1522 uint64_t(args[eRsScript]));
1524 LLDB_LOGF(log,
"%s - resource name invalid, Script not tagged.",
1529 void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module,
1537 Target &target = GetProcess()->GetTarget();
1540 if (machine != llvm::Triple::ArchType::x86 &&
1541 machine != llvm::Triple::ArchType::arm &&
1542 machine != llvm::Triple::ArchType::aarch64 &&
1543 machine != llvm::Triple::ArchType::mipsel &&
1544 machine != llvm::Triple::ArchType::mips64el &&
1545 machine != llvm::Triple::ArchType::x86_64) {
1546 LLDB_LOGF(log,
"%s - unable to hook runtime functions.", __FUNCTION__);
1553 std::array<bool, s_runtimeHookCount> hook_placed;
1554 hook_placed.fill(
false);
1556 for (
size_t idx = 0; idx < s_runtimeHookCount; idx++) {
1557 const HookDefn *hook_defn = &s_runtimeHookDefns[idx];
1558 if (hook_defn->
kind != kind) {
1562 const char *symbol_name = (target_ptr_size == 4)
1566 const Symbol *sym = module->FindFirstSymbolWithNameAndType(
1570 LLDB_LOGF(log,
"%s - symbol '%s' related to the function %s not found",
1571 __FUNCTION__, symbol_name, hook_defn->
name);
1576 addr_t addr = sym->GetLoadAddress(&target);
1579 "%s - unable to resolve the address of hook function '%s' "
1580 "with symbol '%s'.",
1581 __FUNCTION__, hook_defn->
name, symbol_name);
1584 LLDB_LOGF(log,
"%s - function %s, address resolved at 0x%" PRIx64,
1585 __FUNCTION__, hook_defn->
name, addr);
1589 hook->address = addr;
1590 hook->defn = hook_defn;
1592 hook->bp_sp->SetCallback(HookCallback, hook.get(),
true);
1593 m_runtimeHooks[addr] = hook;
1596 "%s - successfully hooked '%s' in '%s' version %" PRIu64
1597 " at 0x%" PRIx64
".",
1598 __FUNCTION__, hook_defn->
name,
1599 module->GetFileSpec().GetFilename().AsCString(),
1600 (uint64_t)hook_defn->
version, (uint64_t)addr);
1602 hook_placed[idx] =
true;
1607 for (
size_t i = 0; i < hook_placed.size(); ++i) {
1610 const HookDefn &hook_defn = s_runtimeHookDefns[i];
1611 if (hook_defn.
kind != kind)
1613 LLDB_LOGF(log,
"%s - function %s was not hooked", __FUNCTION__,
1625 const ModuleSP module = rsmodule_sp->m_module;
1626 const FileSpec &file = module->GetPlatformFileSpec();
1630 for (
const auto &rs_script : m_scripts) {
1633 if (!rs_script->shared_lib.get(shared_lib))
1642 if (!rs_script->script.get(script))
1646 if (m_scriptMappings.find(script) != m_scriptMappings.end()) {
1648 if (m_scriptMappings[script] != rsmodule_sp) {
1651 "%s - script %" PRIx64
" wants reassigned to new rsmodule '%s'.",
1652 __FUNCTION__, (uint64_t)script,
1653 rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
1660 if (rs_script->res_name.get(res_name))
1662 rsmodule_sp->m_resname = res_name;
1664 m_scriptMappings[script] = rsmodule_sp;
1665 LLDB_LOGF(log,
"%s - script %" PRIx64
" associated with rsmodule '%s'.",
1666 __FUNCTION__, (uint64_t)script,
1667 rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
1676 bool RenderScriptRuntime::EvalRSExpression(
const char *expr,
1680 LLDB_LOGF(log,
"%s(%s)", __FUNCTION__, expr);
1682 ValueObjectSP expr_result;
1686 auto &target = GetProcess()->GetTarget();
1687 target.EvaluateExpression(expr, frame_ptr, expr_result, options);
1690 LLDB_LOGF(log,
"%s: couldn't evaluate expression.", __FUNCTION__);
1695 if (!expr_result->GetError().Success()) {
1698 if (err.
GetError() == UserExpression::kNoResult) {
1699 LLDB_LOGF(log,
"%s - expression returned void.", __FUNCTION__);
1705 LLDB_LOGF(log,
"%s - error evaluating expression result: %s", __FUNCTION__,
1710 bool success =
false;
1712 *result = expr_result->GetValueAsUnsigned(0, &success);
1715 LLDB_LOGF(log,
"%s - couldn't convert expression result to uint32_t",
1725 enum ExpressionStrings {
1726 eExprGetOffsetPtr = 0,
1735 eExprElementFieldCount,
1737 eExprSubelementsName,
1738 eExprSubelementsArrSize,
1744 const int jit_max_expr_size = 512;
1747 #define JIT_TEMPLATE_CONTEXT "void* ctxt = (void*)rsDebugGetContextWrapper(0x%" PRIx64 "); "
1748 const char *JITTemplate(ExpressionStrings e) {
1750 static std::array<const char *, _eExprLast> runtime_expressions = {
1753 "Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocation"
1755 "(0x%" PRIx64
", %" PRIu32
", %" PRIu32
", %" PRIu32
", 0, 0)",
1766 "uint%" PRIu32
"_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
1767 ", 0x%" PRIx64
", data, 6); data[0]",
1769 "uint%" PRIu32
"_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
1770 ", 0x%" PRIx64
", data, 6); data[1]",
1772 "uint%" PRIu32
"_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
1773 ", 0x%" PRIx64
", data, 6); data[2]",
1775 "uint%" PRIu32
"_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
1776 ", 0x%" PRIx64
", data, 6); data[5]",
1782 "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt"
1783 ", 0x%" PRIx64
", data, 5); data[0]",
1785 "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt"
1786 ", 0x%" PRIx64
", data, 5); data[1]",
1788 "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt"
1789 ", 0x%" PRIx64
", data, 5); data[3]",
1791 "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt"
1792 ", 0x%" PRIx64
", data, 5); data[4]",
1799 "]; size_t arr_size[%" PRIu32
"];"
1800 "(void*)rsaElementGetSubElements(ctxt, 0x%" PRIx64
1801 ", ids, names, arr_size, %" PRIu32
"); ids[%" PRIu32
"]",
1805 "]; size_t arr_size[%" PRIu32
"];"
1806 "(void*)rsaElementGetSubElements(ctxt, 0x%" PRIx64
1807 ", ids, names, arr_size, %" PRIu32
"); names[%" PRIu32
"]",
1811 "]; size_t arr_size[%" PRIu32
"];"
1812 "(void*)rsaElementGetSubElements(ctxt, 0x%" PRIx64
1813 ", ids, names, arr_size, %" PRIu32
"); arr_size[%" PRIu32
"]"}};
1815 return runtime_expressions[e];
1828 if (!alloc->
address.isValid()) {
1829 LLDB_LOGF(log,
"%s - failed to find allocation details.", __FUNCTION__);
1833 const char *fmt_str = JITTemplate(eExprGetOffsetPtr);
1834 char expr_buf[jit_max_expr_size];
1836 int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
1837 *alloc->
address.get(), x, y, z);
1839 LLDB_LOGF(log,
"%s - encoding error in snprintf().", __FUNCTION__);
1841 }
else if (written >= jit_max_expr_size) {
1842 LLDB_LOGF(log,
"%s - expression too long.", __FUNCTION__);
1846 uint64_t result = 0;
1847 if (!EvalRSExpression(expr_buf, frame_ptr, &result))
1864 LLDB_LOGF(log,
"%s - failed to find allocation details.", __FUNCTION__);
1868 const char *fmt_str = JITTemplate(eExprAllocGetType);
1869 char expr_buf[jit_max_expr_size];
1871 int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
1874 LLDB_LOGF(log,
"%s - encoding error in snprintf().", __FUNCTION__);
1876 }
else if (written >= jit_max_expr_size) {
1877 LLDB_LOGF(log,
"%s - expression too long.", __FUNCTION__);
1881 uint64_t result = 0;
1882 if (!EvalRSExpression(expr_buf, frame_ptr, &result))
1899 LLDB_LOGF(log,
"%s - Failed to find allocation details.", __FUNCTION__);
1905 GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
1910 static_assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1),
1911 "Invalid number of expressions");
1913 char expr_bufs[num_exprs][jit_max_expr_size];
1914 uint64_t results[num_exprs];
1916 for (
uint32_t i = 0; i < num_exprs; ++i) {
1917 const char *fmt_str = JITTemplate(ExpressionStrings(eExprTypeDimX + i));
1918 int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str,
1921 LLDB_LOGF(log,
"%s - encoding error in snprintf().", __FUNCTION__);
1923 }
else if (written >= jit_max_expr_size) {
1924 LLDB_LOGF(log,
"%s - expression too long.", __FUNCTION__);
1929 if (!EvalRSExpression(expr_bufs[i], frame_ptr, &results[i]))
1944 "%s - dims (%" PRIu32
", %" PRIu32
", %" PRIu32
1945 ") Element*: 0x%" PRIx64
".",
1954 bool RenderScriptRuntime::JITElementPacked(
Element &elem,
1960 LLDB_LOGF(log,
"%s - failed to find allocation details.", __FUNCTION__);
1966 static_assert(num_exprs == (eExprElementFieldCount - eExprElementType + 1),
1967 "Invalid number of expressions");
1969 char expr_bufs[num_exprs][jit_max_expr_size];
1970 uint64_t results[num_exprs];
1972 for (
uint32_t i = 0; i < num_exprs; i++) {
1973 const char *fmt_str = JITTemplate(ExpressionStrings(eExprElementType + i));
1974 int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str, context,
1977 LLDB_LOGF(log,
"%s - encoding error in snprintf().", __FUNCTION__);
1979 }
else if (written >= jit_max_expr_size) {
1980 LLDB_LOGF(log,
"%s - expression too long.", __FUNCTION__);
1985 if (!EvalRSExpression(expr_bufs[i], frame_ptr, &results[i]))
1997 "%s - data type %" PRIu32
", pixel type %" PRIu32
1998 ", vector size %" PRIu32
", field count %" PRIu32,
2005 !JITSubelements(elem, context, frame_ptr));
2011 bool RenderScriptRuntime::JITSubelements(
Element &elem,
2017 LLDB_LOGF(log,
"%s - failed to find allocation details.", __FUNCTION__);
2021 const short num_exprs = 3;
2022 static_assert(num_exprs == (eExprSubelementsArrSize - eExprSubelementsId + 1),
2023 "Invalid number of expressions");
2025 char expr_buffer[jit_max_expr_size];
2030 for (
uint32_t field_index = 0; field_index < field_count; ++field_index) {
2032 for (
uint32_t expr_index = 0; expr_index < num_exprs; ++expr_index) {
2033 const char *fmt_str =
2034 JITTemplate(ExpressionStrings(eExprSubelementsId + expr_index));
2035 int written = snprintf(expr_buffer, jit_max_expr_size, fmt_str,
2036 context, field_count, field_count, field_count,
2037 *elem.
element_ptr.get(), field_count, field_index);
2039 LLDB_LOGF(log,
"%s - encoding error in snprintf().", __FUNCTION__);
2041 }
else if (written >= jit_max_expr_size) {
2042 LLDB_LOGF(log,
"%s - expression too long.", __FUNCTION__);
2047 if (!EvalRSExpression(expr_buffer, frame_ptr, &results))
2050 LLDB_LOGF(log,
"%s - expr result 0x%" PRIx64
".", __FUNCTION__, results);
2052 switch (expr_index) {
2061 GetProcess()->ReadCStringFromMemory(address, name, err);
2065 LLDB_LOGF(log,
"%s - warning: Couldn't read field name.",
2078 if (!JITElementPacked(child, context, frame_ptr))
2085 FindStructTypeName(elem, frame_ptr);
2101 LLDB_LOGF(log,
"%s - failed to find allocation details.", __FUNCTION__);
2123 LLDB_LOGF(log,
"%s - inferred size of struct allocation %" PRIu32
".",
2124 __FUNCTION__, *alloc->
size.get());
2128 const char *fmt_str = JITTemplate(eExprGetOffsetPtr);
2129 char expr_buf[jit_max_expr_size];
2132 dim_x = dim_x == 0 ? 0 : dim_x - 1;
2133 dim_y = dim_y == 0 ? 0 : dim_y - 1;
2134 dim_z = dim_z == 0 ? 0 : dim_z - 1;
2136 int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
2137 *alloc->
address.get(), dim_x, dim_y, dim_z);
2139 LLDB_LOGF(log,
"%s - encoding error in snprintf().", __FUNCTION__);
2141 }
else if (written >= jit_max_expr_size) {
2142 LLDB_LOGF(log,
"%s - expression too long.", __FUNCTION__);
2146 uint64_t result = 0;
2147 if (!EvalRSExpression(expr_buf, frame_ptr, &result))
2166 LLDB_LOGF(log,
"%s - failed to find allocation details.", __FUNCTION__);
2170 const char *fmt_str = JITTemplate(eExprGetOffsetPtr);
2171 char expr_buf[jit_max_expr_size];
2173 int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
2174 *alloc->
address.get(), 0, 1, 0);
2176 LLDB_LOGF(log,
"%s - encoding error in snprintf().", __FUNCTION__);
2178 }
else if (written >= jit_max_expr_size) {
2179 LLDB_LOGF(log,
"%s - expression too long.", __FUNCTION__);
2183 uint64_t result = 0;
2184 if (!EvalRSExpression(expr_buf, frame_ptr, &result))
2197 if (!JITDataPointer(alloc, frame_ptr))
2201 if (!JITTypePointer(alloc, frame_ptr))
2205 if (!JITTypePacked(alloc, frame_ptr))
2209 if (!JITElementPacked(alloc->
element, *alloc->
context.get(), frame_ptr))
2213 SetElementSize(alloc->
element);
2216 return JITAllocationSize(alloc, frame_ptr);
2222 void RenderScriptRuntime::FindStructTypeName(
Element &elem,
2229 elem.
type_name = Element::GetFallbackStructName();
2234 for (
auto module_sp : m_rsmodules)
2235 module_sp->m_module->FindGlobalVariables(
2241 for (
const VariableSP &var_sp : var_list) {
2245 ValueObjectSP valobj_sp = ValueObjectVariable::Create(frame_ptr, var_sp);
2253 size_t num_children = valobj_sp->GetNumChildren();
2254 if (num_children > elem.
children.size() || num_children == 0)
2262 for (
size_t i = 0; i < num_children; ++i) {
2263 ValueObjectSP child = valobj_sp->GetChildAtIndex(i,
true);
2264 if (!child || (child->GetName() != elem.
children[i].type_name)) {
2272 if (found && num_children < elem.
children.size()) {
2274 LLDB_LOGF(log,
"%s - %" PRIu32
" padding struct entries", __FUNCTION__,
2277 for (
uint32_t i = 0; i < size_diff; ++i) {
2279 if (strcmp(name.
AsCString(),
"#rs_padding") < 0)
2287 if (valobj_sp->IsPointerType()) {
2289 ValueObjectSP deref_valobj = valobj_sp->Dereference(err);
2291 valobj_sp = deref_valobj;
2295 elem.
type_name = valobj_sp->GetTypeName();
2296 LLDB_LOGF(log,
"%s - element name set to %s", __FUNCTION__,
2307 void RenderScriptRuntime::SetElementSize(
Element &elem) {
2310 assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT &&
2311 "Invalid allocation type");
2318 if ((type == Element::RS_TYPE_NONE) && (elem.
children.size() > 0)) {
2320 SetElementSize(child);
2323 data_size += *child.
datum_size.get() * array_size;
2327 else if (type == Element::RS_TYPE_UNSIGNED_5_6_5 ||
2328 type == Element::RS_TYPE_UNSIGNED_5_5_5_1 ||
2329 type == Element::RS_TYPE_UNSIGNED_4_4_4_4) {
2330 data_size = AllocationDetails::RSTypeToFormat[type][
eElementSize];
2331 }
else if (type < Element::RS_TYPE_ELEMENT) {
2333 vec_size * AllocationDetails::RSTypeToFormat[type][
eElementSize];
2335 padding = AllocationDetails::RSTypeToFormat[type][
eElementSize];
2338 GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
2342 LLDB_LOGF(log,
"%s - element size set to %" PRIu32, __FUNCTION__,
2343 data_size + padding);
2349 std::shared_ptr<uint8_t>
2356 LLDB_LOGF(log,
"%s - allocation details not calculated yet, jitting info",
2359 if (!RefreshAllocation(alloc, frame_ptr)) {
2360 LLDB_LOGF(log,
"%s - couldn't JIT allocation details", __FUNCTION__);
2367 "Allocation information not available");
2371 std::shared_ptr<uint8_t> buffer(
new uint8_t[size]);
2373 LLDB_LOGF(log,
"%s - couldn't allocate a %" PRIu32
" byte buffer",
2374 __FUNCTION__, size);
2381 GetProcess()->ReadMemory(data_ptr, buffer.get(), size, err);
2384 "%s - '%s' Couldn't read %" PRIu32
2385 " bytes of allocation data from 0x%" PRIx64,
2386 __FUNCTION__, err.
AsCString(), size, data_ptr);
2407 LLDB_LOGF(log,
"%s - found allocation 0x%" PRIx64, __FUNCTION__,
2412 LLDB_LOGF(log,
"%s - allocation details not calculated yet, jitting info.",
2415 if (!RefreshAllocation(alloc, frame_ptr)) {
2416 LLDB_LOGF(log,
"%s - couldn't JIT allocation details", __FUNCTION__);
2424 "Allocation information not available");
2428 FileSystem::Instance().Resolve(file);
2429 if (!FileSystem::Instance().Exists(file)) {
2430 strm.
Printf(
"Error: File %s does not exist", path);
2435 if (!FileSystem::Instance().Readable(file)) {
2436 strm.
Printf(
"Error: File %s does not have readable permissions", path);
2442 auto data_sp = FileSystem::Instance().CreateDataBuffer(file.
GetPath());
2445 const void *file_buf = data_sp->GetBytes();
2446 if (file_buf ==
nullptr ||
2449 strm.
Printf(
"Error: File %s does not contain enough data for header", path);
2457 if (memcmp(file_header->
ident,
"RSAD", 4)) {
2458 strm.
Printf(
"Error: File doesn't contain identifier for an RS allocation "
2459 "dump. Are you sure this is the correct file?");
2466 memcpy(&root_el_hdr,
2467 static_cast<const uint8_t *
>(file_buf) +
2471 LLDB_LOGF(log,
"%s - header type %" PRIu32
", element size %" PRIu32,
2477 strm.
Printf(
"Warning: Mismatched Element sizes - file %" PRIu32
2478 " bytes, allocation %" PRIu32
" bytes",
2487 if (file_type > Element::RS_TYPE_FONT) {
2488 strm.
Printf(
"Warning: File has unknown allocation type");
2490 }
else if (alloc_type != file_type) {
2493 uint32_t target_type_name_idx = alloc_type;
2494 uint32_t head_type_name_idx = file_type;
2495 if (alloc_type >= Element::RS_TYPE_ELEMENT &&
2496 alloc_type <= Element::RS_TYPE_FONT)
2498 (alloc_type - Element::RS_TYPE_ELEMENT) +
2499 Element::RS_TYPE_MATRIX_2X2 + 1);
2501 if (file_type >= Element::RS_TYPE_ELEMENT &&
2502 file_type <= Element::RS_TYPE_FONT)
2504 (file_type - Element::RS_TYPE_ELEMENT) + Element::RS_TYPE_MATRIX_2X2 +
2507 const char *head_type_name =
2508 AllocationDetails::RsDataTypeToString[head_type_name_idx][0];
2509 const char *target_type_name =
2510 AllocationDetails::RsDataTypeToString[target_type_name_idx][0];
2513 "Warning: Mismatched Types - file '%s' type, allocation '%s' type",
2514 head_type_name, target_type_name);
2519 file_buf =
static_cast<const uint8_t *
>(file_buf) + file_header->
hdr_size;
2522 size_t size = data_sp->GetByteSize() - file_header->
hdr_size;
2527 if (alloc_size != size) {
2528 strm.
Printf(
"Warning: Mismatched allocation sizes - file 0x%" PRIx64
2529 " bytes, allocation 0x%" PRIx32
" bytes",
2530 (uint64_t)size, alloc_size);
2533 size = alloc_size < size ? alloc_size : size;
2539 size_t written = GetProcess()->WriteMemory(alloc_data, file_buf, size, err);
2540 if (!err.
Success() || written != size) {
2541 strm.
Printf(
"Error: Couldn't write data to allocation %s", err.
AsCString());
2546 strm.
Printf(
"Contents of file '%s' read into allocation %" PRIu32, path,
2559 size_t RenderScriptRuntime::PopulateElementHeaders(
2560 const std::shared_ptr<uint8_t> header_buffer,
size_t offset,
2565 elem_header.
type = *elem.
type.get();
2575 memcpy(header_buffer.get() + offset, &elem_header, elem_header_size);
2576 offset += elem_header_size;
2579 size_t child_offset =
2585 memcpy(header_buffer.get() + offset, &child_offset,
sizeof(
uint32_t));
2588 child_offset = PopulateElementHeaders(header_buffer, child_offset, child);
2592 memset(header_buffer.get() + offset, 0,
sizeof(
uint32_t));
2594 return child_offset;
2602 size_t RenderScriptRuntime::CalculateElementHeaderSize(
const Element &elem) {
2610 size += CalculateElementHeaderSize(child);
2628 LLDB_LOGF(log,
"%s - found allocation 0x%" PRIx64
".", __FUNCTION__,
2633 LLDB_LOGF(log,
"%s - allocation details not calculated yet, jitting info.",
2636 if (!RefreshAllocation(alloc, frame_ptr)) {
2637 LLDB_LOGF(log,
"%s - couldn't JIT allocation details.", __FUNCTION__);
2646 "Allocation information not available");
2650 FileSystem::Instance().Resolve(file_spec);
2651 auto file = FileSystem::Instance().Open(
2652 file_spec, File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate |
2653 File::eOpenOptionTruncate);
2657 strm.
Printf(
"Error: Failed to open '%s' for writing: %s", path,
2664 const std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
2666 strm.
Printf(
"Error: Couldn't read allocation data into buffer");
2673 memcpy(head.
ident,
"RSAD", 4);
2678 const size_t element_header_size = CalculateElementHeaderSize(alloc->
element);
2681 "Element header too large");
2683 element_header_size);
2687 LLDB_LOGF(log,
"%s - writing File Header, 0x%" PRIx64
" bytes", __FUNCTION__,
2688 (uint64_t)num_bytes);
2690 Status err = file.get()->Write(&head, num_bytes);
2692 strm.
Printf(
"Error: '%s' when writing to file '%s'", err.
AsCString(), path);
2698 std::shared_ptr<uint8_t> element_header_buffer(
2699 new uint8_t[element_header_size]);
2700 if (element_header_buffer ==
nullptr) {
2701 strm.
Printf(
"Internal Error: Couldn't allocate %" PRIu64
2702 " bytes on the heap",
2703 (uint64_t)element_header_size);
2708 PopulateElementHeaders(element_header_buffer, 0, alloc->
element);
2711 num_bytes = element_header_size;
2712 LLDB_LOGF(log,
"%s - writing element headers, 0x%" PRIx64
" bytes.",
2713 __FUNCTION__, (uint64_t)num_bytes);
2715 err = file.get()->Write(element_header_buffer.get(), num_bytes);
2717 strm.
Printf(
"Error: '%s' when writing to file '%s'", err.
AsCString(), path);
2723 num_bytes =
static_cast<size_t>(*alloc->
size.get());
2724 LLDB_LOGF(log,
"%s - writing 0x%" PRIx64
" bytes", __FUNCTION__,
2725 (uint64_t)num_bytes);
2727 err = file.get()->Write(buffer.get(), num_bytes);
2729 strm.
Printf(
"Error: '%s' when writing to file '%s'", err.
AsCString(), path);
2734 strm.
Printf(
"Allocation written to file '%s'", path);
2739 bool RenderScriptRuntime::LoadModule(
const lldb::ModuleSP &module_sp) {
2743 for (
const auto &rs_module : m_rsmodules) {
2744 if (rs_module->m_module == module_sp) {
2747 if (m_breakAllKernels)
2748 BreakOnModuleKernels(rs_module);
2753 bool module_loaded =
false;
2754 switch (GetModuleKind(module_sp)) {
2755 case eModuleKindKernelObj: {
2757 module_desc = std::make_shared<RSModuleDescriptor>(module_sp);
2758 if (module_desc->ParseRSInfo()) {
2759 m_rsmodules.push_back(module_desc);
2760 module_desc->WarnIfVersionMismatch(GetProcess()
2763 .GetAsyncOutputStream()
2765 module_loaded =
true;
2767 if (module_loaded) {
2768 FixupScriptDetails(module_desc);
2772 case eModuleKindDriver: {
2773 if (!m_libRSDriver) {
2774 m_libRSDriver = module_sp;
2775 LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver);
2779 case eModuleKindImpl: {
2780 if (!m_libRSCpuRef) {
2781 m_libRSCpuRef = module_sp;
2782 LoadRuntimeHooks(m_libRSCpuRef, RenderScriptRuntime::eModuleKindImpl);
2786 case eModuleKindLibRS: {
2788 m_libRS = module_sp;
2789 static ConstString gDbgPresentStr(
"gDebuggerPresent");
2790 const Symbol *debug_present = m_libRS->FindFirstSymbolWithNameAndType(
2792 if (debug_present) {
2795 Target &target = GetProcess()->GetTarget();
2797 GetProcess()->WriteMemory(addr, &flag,
sizeof(flag), err);
2799 LLDB_LOGF(log,
"%s - debugger present flag set on debugee.",
2802 m_debuggerPresentFlagged =
true;
2804 LLDB_LOGF(log,
"%s - error writing debugger present flags '%s' ",
2810 "%s - error writing debugger present flags - symbol not found",
2821 return module_loaded;
2826 void RenderScriptRuntime::Update() {
2827 if (m_rsmodules.size() > 0) {
2838 if (m_slang_version.empty() || m_bcc_version.empty()) {
2839 s->
PutCString(
"WARNING: Unknown bcc or slang (llvm-rs-cc) version; debug "
2840 "experience may be unreliable");
2842 }
else if (m_slang_version != m_bcc_version) {
2843 s->
Printf(
"WARNING: The debug info emitted by the slang frontend "
2844 "(llvm-rs-cc) used to build this module (%s) does not match the "
2845 "version of bcc used to generate the debug information (%s). "
2846 "This is an unsupported configuration and may result in a poor "
2847 "debugging experience; proceed with caution",
2848 m_slang_version.c_str(), m_bcc_version.c_str());
2853 bool RSModuleDescriptor::ParsePragmaCount(llvm::StringRef *lines,
2857 for (; n_lines--; ++lines) {
2858 const auto kv_pair = lines->split(
" - ");
2859 m_pragmas[kv_pair.first.trim().str()] = kv_pair.second.trim().str();
2864 bool RSModuleDescriptor::ParseExportReduceCount(llvm::StringRef *lines,
2875 for (; n_lines--; ++lines) {
2876 llvm::SmallVector<llvm::StringRef, 8> spec;
2877 lines->split(spec,
" - ");
2878 if (spec.size() != 8) {
2879 if (spec.size() < 8) {
2881 log->
Error(
"Error parsing RenderScript reduction spec. wrong number "
2885 log->
Warning(
"Extraneous members in reduction spec: '%s'",
2886 lines->str().c_str());
2889 const auto sig_s = spec[0];
2891 if (sig_s.getAsInteger(10, sig)) {
2893 log->
Error(
"Error parsing Renderscript reduction spec: invalid kernel "
2895 sig_s.str().c_str());
2899 const auto accum_data_size_s = spec[1];
2901 if (accum_data_size_s.getAsInteger(10, accum_data_size)) {
2903 log->
Error(
"Error parsing Renderscript reduction spec: invalid "
2904 "accumulator data size %s",
2905 accum_data_size_s.str().c_str());
2909 LLDB_LOGF(log,
"Found RenderScript reduction '%s'", spec[2].str().c_str());
2912 spec[2], spec[3], spec[4],
2913 spec[5], spec[6], spec[7]));
2918 bool RSModuleDescriptor::ParseVersionInfo(llvm::StringRef *lines,
2922 for (; n_lines--; ++lines) {
2925 const auto kv_pair = lines->split(
" - ");
2926 if (kv_pair.first ==
"slang")
2927 m_slang_version = kv_pair.second.str();
2928 else if (kv_pair.first ==
"bcc")
2929 m_bcc_version = kv_pair.second.str();
2934 bool RSModuleDescriptor::ParseExportForeachCount(llvm::StringRef *lines,
2938 for (; n_lines--; ++lines) {
2942 const auto kv_pair = lines->split(
" - ");
2943 if (kv_pair.first.getAsInteger(10, slot))
2950 bool RSModuleDescriptor::ParseExportVarCount(llvm::StringRef *lines,
2954 for (; n_lines--; ++lines)
2961 bool RSModuleDescriptor::ParseRSInfo() {
2964 const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(
2974 const FileSpec fs = m_module->GetFileSpec();
2977 FileSystem::Instance().CreateDataBuffer(fs.
GetPath(), size, addr);
2982 llvm::SmallVector<llvm::StringRef, 128> info_lines;
2984 const llvm::StringRef raw_rs_info((
const char *)buffer->GetBytes());
2985 raw_rs_info.split(info_lines,
'\n');
2986 LLDB_LOGF(log,
"'.rs.info symbol for '%s':\n%s",
2987 m_module->GetFileSpec().GetCString(), raw_rs_info.str().c_str());
3000 const auto rs_info_handler = [](llvm::StringRef name) ->
int {
3001 return llvm::StringSwitch<int>(name)
3003 .Case(
"exportVarCount", eExportVar)
3005 .Case(
"exportForEachCount", eExportForEach)
3008 .Case(
"exportReduceCount", eExportReduce)
3011 .Case(
"pragmaCount", ePragma)
3012 .Case(
"objectSlotCount", eObjectSlot)
3013 .Case(
"versionInfo", eVersionInfo)
3018 for (
auto line = info_lines.begin(); line != info_lines.end(); ++line) {
3019 const auto kv_pair = line->split(
": ");
3020 const auto key = kv_pair.first;
3021 const auto val = kv_pair.second.trim();
3023 const auto handler = rs_info_handler(key);
3029 if (val.getAsInteger(10, n_lines)) {
3030 LLDB_LOGV(log,
"Failed to parse non-numeric '.rs.info' section {0}",
3034 if (info_lines.end() - (line + 1) < (ptrdiff_t)n_lines)
3037 bool success =
false;
3040 success = ParseExportVarCount(line, n_lines);
3042 case eExportForEach:
3043 success = ParseExportForeachCount(line, n_lines);
3046 success = ParseExportReduceCount(line, n_lines);
3049 success = ParsePragmaCount(line, n_lines);
3052 success = ParseVersionInfo(line, n_lines);
3055 LLDB_LOGF(log,
"%s - skipping .rs.info field '%s'", __FUNCTION__,
3056 line->str().c_str());
3064 return info_lines.size() > 0;
3067 void RenderScriptRuntime::DumpStatus(
Stream &strm)
const {
3069 strm.
Printf(
"Runtime Library discovered.");
3072 if (m_libRSDriver) {
3073 strm.
Printf(
"Runtime Driver discovered.");
3076 if (m_libRSCpuRef) {
3077 strm.
Printf(
"CPU Reference Implementation discovered.");
3081 if (m_runtimeHooks.size()) {
3082 strm.
Printf(
"Runtime functions hooked:");
3084 for (
auto b : m_runtimeHooks) {
3085 strm.
Indent(b.second->defn->name);
3089 strm.
Printf(
"Runtime is not hooked.");
3094 void RenderScriptRuntime::DumpContexts(
Stream &strm)
const {
3095 strm.
Printf(
"Inferred RenderScript Contexts:");
3099 std::map<addr_t, uint64_t> contextReferences;
3103 for (
const auto &script : m_scripts) {
3104 if (!script->context.isValid())
3108 if (contextReferences.find(context) != contextReferences.end()) {
3109 contextReferences[context]++;
3111 contextReferences[context] = 1;
3115 for (
const auto &cRef : contextReferences) {
3116 strm.
Printf(
"Context 0x%" PRIx64
": %" PRIu64
" script instances",
3117 cRef.first, cRef.second);
3123 void RenderScriptRuntime::DumpKernels(
Stream &strm)
const {
3124 strm.
Printf(
"RenderScript Kernels:");
3127 for (
const auto &module : m_rsmodules) {
3128 strm.
Printf(
"Resource '%s':", module->m_resname.c_str());
3130 for (
const auto &kernel : module->m_kernels) {
3131 strm.
Indent(kernel.m_name.GetStringRef());
3143 if (alloc_id <= m_allocations.size() && alloc_id != 0 &&
3144 m_allocations[alloc_id - 1]->id == alloc_id) {
3145 alloc = m_allocations[alloc_id - 1].get();
3150 for (
const auto &a : m_allocations) {
3151 if (a->id == alloc_id) {
3157 if (alloc ==
nullptr) {
3158 strm.
Printf(
"Error: Couldn't find allocation with id matching %" PRIu32,
3177 LLDB_LOGF(log,
"%s - found allocation 0x%" PRIx64, __FUNCTION__,
3182 LLDB_LOGF(log,
"%s - allocation details not calculated yet, jitting info.",
3186 if (!RefreshAllocation(alloc, frame_ptr)) {
3187 strm.
Printf(
"Error: Couldn't JIT allocation details");
3197 assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT &&
3198 "Invalid allocation type");
3201 if (type >= Element::RS_TYPE_ELEMENT)
3204 format = vec_size == 1
3212 LLDB_LOGF(log,
"%s - element size %" PRIu32
" bytes, including padding",
3213 __FUNCTION__, data_size);
3216 std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
3218 strm.
Printf(
"Error: Couldn't read allocation data");
3225 if (!alloc->
stride.isValid()) {
3228 else if (!JITAllocationStride(alloc, frame_ptr)) {
3229 strm.
Printf(
"Error: Couldn't calculate allocation row stride");
3239 "%s - stride %" PRIu32
" bytes, size %" PRIu32
3240 " bytes, padding %" PRIu32,
3241 __FUNCTION__, stride, size, padding);
3245 dim_x = dim_x == 0 ? 1 : dim_x;
3248 dim_y = dim_y == 0 ? 1 : dim_y;
3251 dim_z = dim_z == 0 ? 1 : dim_z;
3255 GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
3256 DataExtractor alloc_data(buffer.get(), size, GetProcess()->GetByteOrder(),
3263 strm.
Printf(
"Data (X, Y, Z):");
3264 for (
uint32_t z = 0; z < dim_z; ++z) {
3265 for (
uint32_t y = 0; y < dim_y; ++y) {
3267 if (!(y == 0 && z == 0))
3268 offset = prev_row + stride;
3272 for (
uint32_t x = 0; x < dim_x; ++x) {
3273 strm.
Printf(
"\n(%" PRIu32
", %" PRIu32
", %" PRIu32
") = ", x, y, z);
3274 if ((type == Element::RS_TYPE_NONE) &&
3286 char expr_char_buffer[jit_max_expr_size];
3288 snprintf(expr_char_buffer, jit_max_expr_size,
"*(%s*) 0x%" PRIx64,
3292 if (written < 0 || written >= jit_max_expr_size) {
3293 LLDB_LOGF(log,
"%s - error in snprintf().", __FUNCTION__);
3298 ValueObjectSP expr_result;
3299 GetProcess()->GetTarget().EvaluateExpression(expr_char_buffer,
3300 frame_ptr, expr_result);
3303 expr_result->Dump(strm, expr_options);
3309 offset += data_size;
3321 bool RenderScriptRuntime::RecomputeAllAllocations(
Stream &strm,
3323 bool success =
true;
3324 for (
auto &alloc : m_allocations) {
3326 if (!RefreshAllocation(alloc.get(), frame_ptr)) {
3327 strm.
Printf(
"Error: Couldn't evaluate details for allocation %" PRIu32
3335 strm.
Printf(
"All allocations successfully recomputed");
3346 strm.
Printf(
"RenderScript Allocations:");
3350 for (
auto &alloc : m_allocations) {
3352 if (index != 0 && index != alloc->id)
3356 if (alloc->ShouldRefresh() && !RefreshAllocation(alloc.get(), frame_ptr)) {
3357 strm.
Printf(
"Error: Couldn't evaluate details for allocation %" PRIu32,
3363 strm.
Printf(
"%" PRIu32
":", alloc->id);
3367 strm.
Indent(
"Context: ");
3368 if (!alloc->context.isValid())
3369 strm.
Printf(
"unknown\n");
3371 strm.
Printf(
"0x%" PRIx64
"\n", *alloc->context.get());
3373 strm.
Indent(
"Address: ");
3374 if (!alloc->address.isValid())
3375 strm.
Printf(
"unknown\n");
3377 strm.
Printf(
"0x%" PRIx64
"\n", *alloc->address.get());
3379 strm.
Indent(
"Data pointer: ");
3380 if (!alloc->data_ptr.isValid())
3381 strm.
Printf(
"unknown\n");
3383 strm.
Printf(
"0x%" PRIx64
"\n", *alloc->data_ptr.get());
3385 strm.
Indent(
"Dimensions: ");
3386 if (!alloc->dimension.isValid())
3387 strm.
Printf(
"unknown\n");
3389 strm.
Printf(
"(%" PRId32
", %" PRId32
", %" PRId32
")\n",
3390 alloc->dimension.get()->dim_1, alloc->dimension.get()->dim_2,
3391 alloc->dimension.get()->dim_3);
3393 strm.
Indent(
"Data Type: ");
3394 if (!alloc->element.type.isValid() ||
3395 !alloc->element.type_vec_size.isValid())
3396 strm.
Printf(
"unknown\n");
3398 const int vector_size = *alloc->element.type_vec_size.get();
3401 if (!alloc->element.type_name.IsEmpty())
3402 strm.
Printf(
"%s\n", alloc->element.type_name.AsCString());
3406 if (type >= Element::RS_TYPE_ELEMENT && type <= Element::RS_TYPE_FONT)
3409 Element::RS_TYPE_MATRIX_2X2 + 1);
3411 if (type >= (
sizeof(AllocationDetails::RsDataTypeToString) /
3412 sizeof(AllocationDetails::RsDataTypeToString[0])) ||
3413 vector_size > 4 || vector_size < 1)
3414 strm.
Printf(
"invalid type\n");
3418 AllocationDetails::RsDataTypeToString[
static_cast<uint32_t>(type)]
3423 strm.
Indent(
"Data Kind: ");
3424 if (!alloc->element.type_kind.isValid())
3425 strm.
Printf(
"unknown\n");
3428 if (kind < Element::RS_KIND_USER || kind > Element::RS_KIND_PIXEL_YUV)
3429 strm.
Printf(
"invalid kind\n");
3433 AllocationDetails::RsDataKindToString[
static_cast<uint32_t>(kind)]);
3443 void RenderScriptRuntime::BreakOnModuleKernels(
3445 for (
const auto &kernel : rsmodule_sp->m_kernels) {
3447 if (strcmp(kernel.m_name.AsCString(),
"root") == 0)
3450 CreateKernelBreakpoint(kernel.m_name);
3457 void RenderScriptRuntime::SetBreakAllKernels(
bool do_break, TargetSP target) {
3458 Log *log =
GetLog(LLDBLog::Language | LLDBLog::Breakpoints);
3460 InitSearchFilter(target);
3463 if (do_break && !m_breakAllKernels) {
3464 m_breakAllKernels =
true;
3466 for (
const auto &module : m_rsmodules)
3467 BreakOnModuleKernels(module);
3470 "%s(True) - breakpoints set on all currently loaded kernels.",
3472 }
else if (!do_break &&
3475 m_breakAllKernels =
false;
3477 LLDB_LOGF(log,
"%s(False) - breakpoints no longer automatically set.",
3486 Log *log =
GetLog(LLDBLog::Language | LLDBLog::Breakpoints);
3489 LLDB_LOGF(log,
"%s - error, no breakpoint search filter set.",
3495 Target &target = GetProcess()->GetTarget();
3497 m_filtersp, resolver_sp,
false,
false,
false);
3503 if (err.
Fail() && log)
3504 LLDB_LOGF(log,
"%s - error setting break name, '%s'.", __FUNCTION__,
3513 Log *log =
GetLog(LLDBLog::Language | LLDBLog::Breakpoints);
3516 LLDB_LOGF(log,
"%s - error, no breakpoint search filter set.",
3522 nullptr, name, &m_rsmodules, kernel_types));
3523 Target &target = GetProcess()->GetTarget();
3525 m_filtersp, resolver_sp,
false,
false,
false);
3531 if (err.
Fail() && log)
3532 LLDB_LOGF(log,
"%s - error setting break name, '%s'.", __FUNCTION__,
3541 bool RenderScriptRuntime::GetFrameVarAsUnsigned(
const StackFrameSP frame_sp,
3542 const char *var_name,
3549 ValueObjectSP value_sp(frame_sp->GetValueForVariableExpressionPath(
3551 StackFrame::eExpressionPathOptionCheckPtrVsMember |
3552 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
3555 LLDB_LOGF(log,
"%s - error, couldn't find '%s' in frame", __FUNCTION__,
3561 bool success =
false;
3562 val = value_sp->GetValueAsUnsigned(0, &success);
3564 LLDB_LOGF(log,
"%s - error, couldn't parse '%s' as an uint32_t.",
3565 __FUNCTION__, var_name);
3578 static const char *
const x_expr =
"rsIndex";
3579 static const char *
const y_expr =
"p->current.y";
3580 static const char *
const z_expr =
"p->current.z";
3585 LLDB_LOGF(log,
"%s - Error, No thread pointer", __FUNCTION__);
3602 frame_sp->GetSymbolContext(eSymbolContextFunction);
3607 LLDB_LOGF(log,
"%s - Inspecting function '%s'", __FUNCTION__,
3614 LLDB_LOGF(log,
"%s - Found .expand function '%s'", __FUNCTION__,
3620 bool found = GetFrameVarAsUnsigned(frame_sp, x_expr, x) &&
3621 GetFrameVarAsUnsigned(frame_sp, y_expr, y) &&
3622 GetFrameVarAsUnsigned(frame_sp, z_expr, z);
3644 bool RenderScriptRuntime::KernelBreakpointHit(
void *baton,
3648 Log *log =
GetLog(LLDBLog::Language | LLDBLog::Breakpoints);
3651 "Error: null baton in conditional kernel breakpoint callback");
3657 break_id, target_coord.
x, target_coord.
y, target_coord.
z);
3662 assert(thread_ptr &&
"Null thread pointer");
3666 if (!GetKernelCoordinate(current_coord, thread_ptr)) {
3667 LLDB_LOGF(log,
"%s - Error, couldn't select .expand stack frame",
3673 current_coord.y, current_coord.z);
3677 if (target_coord == current_coord) {
3679 current_coord.y, current_coord.z);
3681 BreakpointSP breakpoint_sp =
3683 assert(breakpoint_sp !=
nullptr &&
3684 "Error: Couldn't find breakpoint matching break id for callback");
3685 breakpoint_sp->SetEnabled(
false);
3694 void RenderScriptRuntime::SetConditional(BreakpointSP bp,
Stream &messages,
3696 messages.
Printf(
"Conditional kernel breakpoint on coordinate " FMT_COORD,
3697 coord.
x, coord.
y, coord.
z);
3706 bp->SetCallback(KernelBreakpointHit, baton,
true);
3710 m_conditional_breaks[bp->GetID()] = std::unique_ptr<RSCoordinate>(baton);
3717 bool RenderScriptRuntime::PlaceBreakpointOnKernel(TargetSP target,
3724 InitSearchFilter(target);
3727 BreakpointSP bp = CreateKernelBreakpoint(kernel_name);
3733 SetConditional(bp, messages, *coord);
3743 Log *log =
GetLog(LLDBLog::Language | LLDBLog::Breakpoints);
3746 LLDB_LOGF(log,
"%s - error, no breakpoint search filter set.",
3752 nullptr, name, m_scriptGroups, stop_on_all));
3753 Target &target = GetProcess()->GetTarget();
3755 m_filtersp, resolver_sp,
false,
false,
false);
3760 if (err.
Fail() && log)
3761 LLDB_LOGF(log,
"%s - error setting break name, '%s'.", __FUNCTION__,
3764 bp->ResolveBreakpoint();
3768 bool RenderScriptRuntime::PlaceBreakpointOnScriptGroup(TargetSP target,
3772 InitSearchFilter(target);
3773 BreakpointSP bp = CreateScriptGroupBreakpoint(name, multi);
3779 bool RenderScriptRuntime::PlaceBreakpointOnReduction(TargetSP target,
3781 const char *reduce_name,
3787 InitSearchFilter(target);
3789 CreateReductionBreakpoint(
ConstString(reduce_name), kernel_types);
3794 SetConditional(bp, messages, *coord);
3801 void RenderScriptRuntime::DumpModules(
Stream &strm)
const {
3802 strm.
Printf(
"RenderScript Modules:");
3805 for (
const auto &module : m_rsmodules) {
3812 RenderScriptRuntime::LookUpScript(
addr_t address,
bool create) {
3813 for (
const auto &s : m_scripts) {
3814 if (s->script.isValid())
3815 if (*s->script == address)
3820 s->script = address;
3821 m_scripts.push_back(std::move(s));
3822 return m_scripts.back().get();
3828 RenderScriptRuntime::LookUpAllocation(
addr_t address) {
3829 for (
const auto &a : m_allocations) {
3830 if (a->address.isValid())
3831 if (*a->address == address)
3838 RenderScriptRuntime::CreateAllocation(
addr_t address) {
3842 auto it = m_allocations.begin();
3843 while (it != m_allocations.end()) {
3844 if (*((*it)->address) == address) {
3845 LLDB_LOGF(log,
"%s - Removing allocation id: %d, address: 0x%" PRIx64,
3846 __FUNCTION__, (*it)->id, address);
3848 it = m_allocations.erase(it);
3855 a->address = address;
3856 m_allocations.push_back(std::move(a));
3857 return m_allocations.back().get();
3864 Target &target = GetProcess()->GetTarget();
3868 LLDB_LOGF(log,
"%s: unable to resolve 0x%" PRIx64
" to a loaded symbol",
3869 __FUNCTION__, kernel_addr);
3879 LLDB_LOGF(log,
"%s: 0x%" PRIx64
" resolved to the symbol '%s'", __FUNCTION__,
3884 void RSModuleDescriptor::Dump(
Stream &strm)
const {
3889 strm.
Indent(m_module->GetNumCompileUnits() ?
"Debug info loaded."
3890 :
"Debug info does not exist.");
3895 strm.
Printf(
"Globals: %" PRIu64,
static_cast<uint64_t
>(m_globals.size()));
3898 for (
const auto &global : m_globals) {
3904 strm.
Printf(
"Kernels: %" PRIu64,
static_cast<uint64_t
>(m_kernels.size()));
3907 for (
const auto &kernel : m_kernels) {
3913 strm.
Printf(
"Pragmas: %" PRIu64,
static_cast<uint64_t
>(m_pragmas.size()));
3916 for (
const auto &key_val : m_pragmas) {
3918 strm.
Printf(
"%s: %s", key_val.first.c_str(), key_val.second.c_str());
3924 strm.
Printf(
"Reductions: %" PRIu64,
3925 static_cast<uint64_t
>(m_reductions.size()));
3928 for (
const auto &reduction : m_reductions) {
3929 reduction.Dump(strm);
3935 void RSGlobalDescriptor::Dump(
Stream &strm)
const {
3936 strm.
Indent(m_name.GetStringRef());
3940 if (var_list.
GetSize() == 1) {
3942 auto type = var->GetType();
3945 type->DumpTypeName(&strm);
3947 strm.
Printf(
" - Unknown Type");
3950 strm.
Printf(
" - variable identified, but not found in binary");
3951 const Symbol *s = m_module->m_module->FindFirstSymbolWithNameAndType(
3954 strm.
Printf(
" (symbol exists) ");
3961 void RSKernelDescriptor::Dump(
Stream &strm)
const {
3962 strm.
Indent(m_name.GetStringRef());
3967 stream.
Indent(m_reduce_name.GetStringRef());
3971 stream.
Printf(
"accumulator: %s", m_accum_name.AsCString());
3974 stream.
Printf(
"initializer: %s", m_init_name.AsCString());
3977 stream.
Printf(
"combiner: %s", m_comb_name.AsCString());
3980 stream.
Printf(
"outconverter: %s", m_outc_name.AsCString());
3993 interpreter,
"renderscript module dump",
3994 "Dumps renderscript specific information for all modules.",
3995 "renderscript module dump",
3996 eCommandRequiresProcess | eCommandProcessMustBeLaunched) {}
4002 m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4014 "Commands that deal with RenderScript modules.",
4028 interpreter,
"renderscript kernel list",
4029 "Lists renderscript kernel names and associated script resources.",
4030 "renderscript kernel list",
4031 eCommandRequiresProcess | eCommandProcessMustBeLaunched) {}
4037 m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4048 "Break on a comma separated set of reduction kernel types "
4049 "(accumulator,outcoverter,combiner,initializer"},
4050 {
LLDB_OPT_SET_1,
false,
"coordinate",
'c', OptionParser::eRequiredArgument,
4052 "Set a breakpoint on a single invocation of the kernel with specified "
4054 "Coordinate takes the form 'x[,y][,z] where x,y,z are positive "
4055 "integers representing kernel dimensions. "
4056 "Any unset dimensions will be defaulted to zero."}};
4064 interpreter,
"renderscript reduction breakpoint set",
4065 "Set a breakpoint on named RenderScript general reductions",
4066 "renderscript reduction breakpoint set <kernel_name> [-t "
4067 "<reduction_kernel_type,...>]",
4068 eCommandRequiresProcess | eCommandProcessMustBeLaunched |
4069 eCommandProcessMustBePaused),
4072 m_arguments.push_back({name_arg});
4085 const int short_option = m_getopt_table[option_idx].val;
4086 switch (short_option) {
4088 if (!ParseReductionTypes(option_arg, err_str))
4090 "Unable to deduce reduction types for %s: %s",
4091 option_arg.str().c_str(), err_str.
GetData());
4095 if (!ParseCoordinate(option_arg, coord))
4097 option_arg.str().c_str());
4099 m_have_coord =
true;
4111 m_have_coord =
false;
4120 m_kernel_types = RSReduceBreakpointResolver::eKernelTypeNone;
4121 const auto reduce_name_to_type = [](llvm::StringRef name) ->
int {
4122 return llvm::StringSwitch<int>(name)
4123 .Case(
"accumulator", RSReduceBreakpointResolver::eKernelTypeAccum)
4124 .Case(
"initializer", RSReduceBreakpointResolver::eKernelTypeInit)
4125 .Case(
"outconverter", RSReduceBreakpointResolver::eKernelTypeOutC)
4126 .Case(
"combiner", RSReduceBreakpointResolver::eKernelTypeComb)
4127 .Case(
"all", RSReduceBreakpointResolver::eKernelTypeAll)
4137 llvm::StringRef(
"^([[:alpha:]]+)(,[[:alpha:]]+){0,4}$"));
4139 assert(match_type_list.
IsValid());
4141 if (!match_type_list.
Execute(option_val)) {
4143 "a comma-separated list of kernel types is required");
4148 llvm::SmallVector<llvm::StringRef, 5> type_names;
4149 llvm::StringRef(option_val).split(type_names,
',');
4151 for (
const auto &name : type_names) {
4152 const int type = reduce_name_to_type(name);
4154 err_str.
Printf(
"unknown kernel type name %s", name.str().c_str());
4157 m_kernel_types |= type;
4163 int m_kernel_types = RSReduceBreakpointResolver::eKernelTypeAll;
4175 "and an optional kernel type list",
4176 m_cmd_name.c_str());
4181 m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4186 auto &target = m_exe_ctx.GetTargetSP();
4187 auto coord = m_options.m_have_coord ? &m_options.m_coord :
nullptr;
4189 m_options.m_kernel_types)) {
4190 result.
AppendError(
"Error: unable to place breakpoint on reduction");
4203 {
LLDB_OPT_SET_1,
false,
"coordinate",
'c', OptionParser::eRequiredArgument,
4205 "Set a breakpoint on a single invocation of the kernel with specified "
4207 "Coordinate takes the form 'x[,y][,z] where x,y,z are positive "
4208 "integers representing kernel dimensions. "
4209 "Any unset dimensions will be defaulted to zero."}};
4217 interpreter,
"renderscript kernel breakpoint set",
4218 "Sets a breakpoint on a renderscript kernel.",
4219 "renderscript kernel breakpoint set <kernel_name> [-c x,y,z]",
4220 eCommandRequiresProcess | eCommandProcessMustBeLaunched |
4221 eCommandProcessMustBePaused),
4224 m_arguments.push_back({name_arg});
4240 const int short_option = m_getopt_table[option_idx].val;
4242 switch (short_option) {
4245 if (!ParseCoordinate(option_arg, coord))
4247 "Couldn't parse coordinate '%s', should be in format 'x,y,z'.",
4248 option_arg.str().c_str());
4250 m_have_coord =
true;
4263 m_have_coord =
false;
4278 "'%s' takes 1 argument of kernel name, and an optional coordinate.",
4279 m_cmd_name.c_str());
4284 m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4288 auto &target = m_exe_ctx.GetTargetSP();
4290 auto coord = m_options.m_have_coord ? &m_options.m_coord :
nullptr;
4293 "Error: unable to set breakpoint on kernel '%s'", name);
4312 interpreter,
"renderscript kernel breakpoint all",
4313 "Automatically sets a breakpoint on all renderscript kernels that "
4314 "are or will be loaded.\n"
4315 "Disabling option means breakpoints will no longer be set on any "
4316 "kernels loaded in the future, "
4317 "but does not remove currently set breakpoints.",
4318 "renderscript kernel breakpoint all <enable/disable>",
4319 eCommandRequiresProcess | eCommandProcessMustBeLaunched |
4320 eCommandProcessMustBePaused) {
4322 m_arguments.push_back({enable_arg});
4331 "'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
4336 m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4339 bool do_break =
false;
4341 if (strcmp(argument,
"enable") == 0) {
4343 result.
AppendMessage(
"Breakpoints will be set on all kernels.");
4344 }
else if (strcmp(argument,
"disable") == 0) {
4346 result.
AppendMessage(
"Breakpoints will not be set on any new kernels.");
4349 "Argument must be either 'enable' or 'disable'");
4366 "Commands that manipulate breakpoints on "
4367 "renderscript general reductions.",
4370 "set", CommandObjectSP(
4384 interpreter,
"renderscript kernel coordinate",
4385 "Shows the (x,y,z) coordinate of the current kernel invocation.",
4386 "renderscript kernel coordinate",
4387 eCommandRequiresProcess | eCommandProcessMustBeLaunched |
4388 eCommandProcessMustBePaused) {}
4394 bool success = RenderScriptRuntime::GetKernelCoordinate(
4395 coord, m_exe_ctx.GetThreadPtr());
4403 stream.
Printf(
"Error: Coordinate could not be found.");
4417 interpreter,
"renderscript kernel",
4418 "Commands that generate breakpoints on renderscript kernels.",
4437 "Commands that deal with RenderScript kernels.",
4459 "Dumps renderscript context information.",
4460 "renderscript context dump",
4461 eCommandRequiresProcess |
4462 eCommandProcessMustBeLaunched) {}
4468 m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4477 {
LLDB_OPT_SET_1,
false,
"file",
'f', OptionParser::eRequiredArgument,
4479 "Print results to specified file instead of command line."}};
4485 "Commands that deal with RenderScript contexts.",
4501 "Displays the contents of a particular allocation",
4502 "renderscript allocation dump <ID>",
4503 eCommandRequiresProcess |
4504 eCommandProcessMustBeLaunched),
4507 m_arguments.push_back({id_arg});
4523 const int short_option = m_getopt_table[option_idx].val;
4525 switch (short_option) {
4527 m_outfile.SetFile(option_arg, FileSpec::Style::native);
4528 FileSystem::Instance().Resolve(m_outfile);
4529 if (FileSystem::Instance().Exists(m_outfile)) {
4532 option_arg.str().c_str());
4557 "As well as an optional -f argument",
4558 m_cmd_name.c_str());
4563 m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4568 if (!llvm::to_integer(id_cstr,
id)) {
4574 Stream *output_stream_p =
nullptr;
4575 std::unique_ptr<Stream> output_stream_storage;
4578 m_options.m_outfile;
4582 auto file = FileSystem::Instance().Open(outfile_spec,
4583 File::eOpenOptionWriteOnly |
4584 File::eOpenOptionCanCreate);
4586 output_stream_storage =
4587 std::make_unique<StreamFile>(std::move(file.get()));
4588 output_stream_p = output_stream_storage.get();
4595 path.c_str(),
error.c_str());
4601 assert(output_stream_p !=
nullptr);
4603 runtime->
DumpAllocation(*output_stream_p, m_exe_ctx.GetFramePtr(),
id);
4618 {
LLDB_OPT_SET_1,
false,
"id",
'i', OptionParser::eRequiredArgument,
nullptr,
4620 "Only show details of a single allocation with specified id."}};
4628 interpreter,
"renderscript allocation list",
4629 "List renderscript allocations and their information.",
4630 "renderscript allocation list",
4631 eCommandRequiresProcess | eCommandProcessMustBeLaunched),
4647 const int short_option = m_getopt_table[option_idx].val;
4649 switch (short_option) {
4651 if (option_arg.getAsInteger(0, m_id))
4673 m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4691 interpreter,
"renderscript allocation load",
4692 "Loads renderscript allocation contents from a file.",
4693 "renderscript allocation load <ID> <filename>",
4694 eCommandRequiresProcess | eCommandProcessMustBeLaunched) {
4697 m_arguments.push_back({id_arg});
4698 m_arguments.push_back({name_arg});
4707 "'%s' takes 2 arguments, an allocation ID and filename to read from.",
4708 m_cmd_name.c_str());
4713 m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4718 if (!llvm::to_integer(id_cstr,
id)) {
4726 m_exe_ctx.GetFramePtr());
4743 "Write renderscript allocation contents to a file.",
4744 "renderscript allocation save <ID> <filename>",
4745 eCommandRequiresProcess |
4746 eCommandProcessMustBeLaunched) {
4749 m_arguments.push_back({id_arg});
4750 m_arguments.push_back({name_arg});
4759 "'%s' takes 2 arguments, an allocation ID and filename to read from.",
4760 m_cmd_name.c_str());
4765 m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4770 if (!llvm::to_integer(id_cstr,
id)) {
4778 m_exe_ctx.GetFramePtr());
4795 "Recomputes the details of all allocations.",
4796 "renderscript allocation refresh",
4797 eCommandRequiresProcess |
4798 eCommandProcessMustBeLaunched) {}
4804 m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4808 m_exe_ctx.GetFramePtr());
4825 interpreter,
"renderscript allocation",
4826 "Commands that deal with RenderScript allocations.", nullptr) {
4856 "Displays current RenderScript runtime status.",
4857 "renderscript status",
4858 eCommandRequiresProcess |
4859 eCommandProcessMustBeLaunched) {}
4865 m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4878 "Commands that handle general reduction kernels",
4892 interpreter,
"renderscript",
4893 "Commands for operating on the RenderScript runtime.",
4894 "renderscript <subcommand> [<subcommand-options>]") {
4896 "module", CommandObjectSP(
4899 "status", CommandObjectSP(
4902 "kernel", CommandObjectSP(
4904 LoadSubCommand(
"context",
4911 LoadSubCommand(
"scriptgroup",
4922 void RenderScriptRuntime::Initiate() { assert(!m_initiated); }
4924 RenderScriptRuntime::RenderScriptRuntime(
Process *process)
4926 m_debuggerPresentFlagged(false), m_breakAllKernels(false),
4927 m_ir_passes(nullptr) {