LLDB  mainline
RenderScriptRuntime.cpp
Go to the documentation of this file.
1 //===-- RenderScriptRuntime.cpp -------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "RenderScriptRuntime.h"
11 
13 #include "lldb/Core/Debugger.h"
19 #include "lldb/Host/OptionParser.h"
25 #include "lldb/Symbol/Function.h"
26 #include "lldb/Symbol/Symbol.h"
27 #include "lldb/Symbol/Type.h"
29 #include "lldb/Target/Process.h"
32 #include "lldb/Target/Target.h"
33 #include "lldb/Target/Thread.h"
34 #include "lldb/Utility/Args.h"
36 #include "lldb/Utility/Log.h"
39 #include "lldb/Utility/Status.h"
40 
41 #include "llvm/ADT/StringSwitch.h"
42 
43 #include <memory>
44 
45 using namespace lldb;
46 using namespace lldb_private;
47 using namespace lldb_renderscript;
48 
50 
51 #define FMT_COORD "(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")"
52 
54 
55 namespace {
56 
57 // The empirical_type adds a basic level of validation to arbitrary data
58 // allowing us to track if data has been discovered and stored or not. An
59 // empirical_type will be marked as valid only if it has been explicitly
60 // assigned to.
61 template <typename type_t> class empirical_type {
62 public:
63  // Ctor. Contents is invalid when constructed.
64  empirical_type() = default;
65 
66  // Return true and copy contents to out if valid, else return false.
67  bool get(type_t &out) const {
68  if (valid)
69  out = data;
70  return valid;
71  }
72 
73  // Return a pointer to the contents or nullptr if it was not valid.
74  const type_t *get() const { return valid ? &data : nullptr; }
75 
76  // Assign data explicitly.
77  void set(const type_t in) {
78  data = in;
79  valid = true;
80  }
81 
82  // Mark contents as invalid.
83  void invalidate() { valid = false; }
84 
85  // Returns true if this type contains valid data.
86  bool isValid() const { return valid; }
87 
88  // Assignment operator.
89  empirical_type<type_t> &operator=(const type_t in) {
90  set(in);
91  return *this;
92  }
93 
94  // Dereference operator returns contents.
95  // Warning: Will assert if not valid so use only when you know data is valid.
96  const type_t &operator*() const {
97  assert(valid);
98  return data;
99  }
100 
101 protected:
102  bool valid = false;
103  type_t data;
104 };
105 
106 // ArgItem is used by the GetArgs() function when reading function arguments
107 // from the target.
108 struct ArgItem {
109  enum { ePointer, eInt32, eInt64, eLong, eBool } type;
110 
111  uint64_t value;
112 
113  explicit operator uint64_t() const { return value; }
114 };
115 
116 // Context structure to be passed into GetArgsXXX(), argument reading functions
117 // below.
118 struct GetArgsCtx {
119  RegisterContext *reg_ctx;
120  Process *process;
121 };
122 
123 bool GetArgsX86(const GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
125 
126  Status err;
127 
128  // get the current stack pointer
129  uint64_t sp = ctx.reg_ctx->GetSP();
130 
131  for (size_t i = 0; i < num_args; ++i) {
132  ArgItem &arg = arg_list[i];
133  // advance up the stack by one argument
134  sp += sizeof(uint32_t);
135  // get the argument type size
136  size_t arg_size = sizeof(uint32_t);
137  // read the argument from memory
138  arg.value = 0;
139  Status err;
140  size_t read =
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());
145  return false;
146  }
147  }
148  return true;
149 }
150 
151 bool GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
153 
154  // number of arguments passed in registers
155  static const uint32_t args_in_reg = 6;
156  // register passing order
157  static const std::array<const char *, args_in_reg> reg_names{
158  {"rdi", "rsi", "rdx", "rcx", "r8", "r9"}};
159  // argument type to size mapping
160  static const std::array<size_t, 5> arg_size{{
161  8, // ePointer,
162  4, // eInt32,
163  8, // eInt64,
164  8, // eLong,
165  4, // eBool,
166  }};
167 
168  Status err;
169 
170  // get the current stack pointer
171  uint64_t sp = ctx.reg_ctx->GetSP();
172  // step over the return address
173  sp += sizeof(uint64_t);
174 
175  // check the stack alignment was correct (16 byte aligned)
176  if ((sp & 0xf) != 0x0) {
177  LLDB_LOGF(log, "%s - stack misaligned", __FUNCTION__);
178  return false;
179  }
180 
181  // find the start of arguments on the stack
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];
185  }
186  // round up to multiple of 16
187  sp_offset = (sp_offset + 0xf) & 0xf;
188  sp += sp_offset;
189 
190  for (size_t i = 0; i < num_args; ++i) {
191  bool success = false;
192  ArgItem &arg = arg_list[i];
193  // arguments passed in registers
194  if (i < args_in_reg) {
195  const RegisterInfo *reg =
196  ctx.reg_ctx->GetRegisterInfoByName(reg_names[i]);
197  RegisterValue reg_val;
198  if (ctx.reg_ctx->ReadRegister(reg, reg_val))
199  arg.value = reg_val.GetAsUInt64(0, &success);
200  }
201  // arguments passed on the stack
202  else {
203  // get the argument type size
204  const size_t size = arg_size[arg_list[i].type];
205  // read the argument from memory
206  arg.value = 0;
207  // note: due to little endian layout reading 4 or 8 bytes will give the
208  // correct value.
209  size_t read = ctx.process->ReadMemory(sp, &arg.value, size, err);
210  success = (err.Success() && read == size);
211  // advance past this argument
212  sp -= size;
213  }
214  // fail if we couldn't read this argument
215  if (!success) {
216  LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s",
217  __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
218  return false;
219  }
220  }
221  return true;
222 }
223 
224 bool GetArgsArm(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
225  // number of arguments passed in registers
226  static const uint32_t args_in_reg = 4;
227 
229 
230  Status err;
231 
232  // get the current stack pointer
233  uint64_t sp = ctx.reg_ctx->GetSP();
234 
235  for (size_t i = 0; i < num_args; ++i) {
236  bool success = false;
237  ArgItem &arg = arg_list[i];
238  // arguments passed in registers
239  if (i < args_in_reg) {
240  const RegisterInfo *reg = ctx.reg_ctx->GetRegisterInfoAtIndex(i);
241  RegisterValue reg_val;
242  if (ctx.reg_ctx->ReadRegister(reg, reg_val))
243  arg.value = reg_val.GetAsUInt32(0, &success);
244  }
245  // arguments passed on the stack
246  else {
247  // get the argument type size
248  const size_t arg_size = sizeof(uint32_t);
249  // clear all 64bits
250  arg.value = 0;
251  // read this argument from memory
252  size_t bytes_read =
253  ctx.process->ReadMemory(sp, &arg.value, arg_size, err);
254  success = (err.Success() && bytes_read == arg_size);
255  // advance the stack pointer
256  sp += sizeof(uint32_t);
257  }
258  // fail if we couldn't read this argument
259  if (!success) {
260  LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s",
261  __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
262  return false;
263  }
264  }
265  return true;
266 }
267 
268 bool GetArgsAarch64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
269  // number of arguments passed in registers
270  static const uint32_t args_in_reg = 8;
271 
273 
274  for (size_t i = 0; i < num_args; ++i) {
275  bool success = false;
276  ArgItem &arg = arg_list[i];
277  // arguments passed in registers
278  if (i < args_in_reg) {
279  const RegisterInfo *reg = ctx.reg_ctx->GetRegisterInfoAtIndex(i);
280  RegisterValue reg_val;
281  if (ctx.reg_ctx->ReadRegister(reg, reg_val))
282  arg.value = reg_val.GetAsUInt64(0, &success);
283  }
284  // arguments passed on the stack
285  else {
286  LLDB_LOGF(log, "%s - reading arguments spilled to stack not implemented",
287  __FUNCTION__);
288  }
289  // fail if we couldn't read this argument
290  if (!success) {
291  LLDB_LOGF(log, "%s - error reading argument: %" PRIu64, __FUNCTION__,
292  uint64_t(i));
293  return false;
294  }
295  }
296  return true;
297 }
298 
299 bool GetArgsMipsel(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
300  // number of arguments passed in registers
301  static const uint32_t args_in_reg = 4;
302  // register file offset to first argument
303  static const uint32_t reg_offset = 4;
304 
306 
307  Status err;
308 
309  // find offset to arguments on the stack (+16 to skip over a0-a3 shadow
310  // space)
311  uint64_t sp = ctx.reg_ctx->GetSP() + 16;
312 
313  for (size_t i = 0; i < num_args; ++i) {
314  bool success = false;
315  ArgItem &arg = arg_list[i];
316  // arguments passed in registers
317  if (i < args_in_reg) {
318  const RegisterInfo *reg =
319  ctx.reg_ctx->GetRegisterInfoAtIndex(i + reg_offset);
320  RegisterValue reg_val;
321  if (ctx.reg_ctx->ReadRegister(reg, reg_val))
322  arg.value = reg_val.GetAsUInt64(0, &success);
323  }
324  // arguments passed on the stack
325  else {
326  const size_t arg_size = sizeof(uint32_t);
327  arg.value = 0;
328  size_t bytes_read =
329  ctx.process->ReadMemory(sp, &arg.value, arg_size, err);
330  success = (err.Success() && bytes_read == arg_size);
331  // advance the stack pointer
332  sp += arg_size;
333  }
334  // fail if we couldn't read this argument
335  if (!success) {
336  LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s",
337  __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
338  return false;
339  }
340  }
341  return true;
342 }
343 
344 bool GetArgsMips64el(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) {
345  // number of arguments passed in registers
346  static const uint32_t args_in_reg = 8;
347  // register file offset to first argument
348  static const uint32_t reg_offset = 4;
349 
351 
352  Status err;
353 
354  // get the current stack pointer
355  uint64_t sp = ctx.reg_ctx->GetSP();
356 
357  for (size_t i = 0; i < num_args; ++i) {
358  bool success = false;
359  ArgItem &arg = arg_list[i];
360  // arguments passed in registers
361  if (i < args_in_reg) {
362  const RegisterInfo *reg =
363  ctx.reg_ctx->GetRegisterInfoAtIndex(i + reg_offset);
364  RegisterValue reg_val;
365  if (ctx.reg_ctx->ReadRegister(reg, reg_val))
366  arg.value = reg_val.GetAsUInt64(0, &success);
367  }
368  // arguments passed on the stack
369  else {
370  // get the argument type size
371  const size_t arg_size = sizeof(uint64_t);
372  // clear all 64bits
373  arg.value = 0;
374  // read this argument from memory
375  size_t bytes_read =
376  ctx.process->ReadMemory(sp, &arg.value, arg_size, err);
377  success = (err.Success() && bytes_read == arg_size);
378  // advance the stack pointer
379  sp += arg_size;
380  }
381  // fail if we couldn't read this argument
382  if (!success) {
383  LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s",
384  __FUNCTION__, uint64_t(i), err.AsCString("n/a"));
385  return false;
386  }
387  }
388  return true;
389 }
390 
391 bool GetArgs(ExecutionContext &exe_ctx, ArgItem *arg_list, size_t num_args) {
393 
394  // verify that we have a target
395  if (!exe_ctx.GetTargetPtr()) {
396  LLDB_LOGF(log, "%s - invalid target", __FUNCTION__);
397  return false;
398  }
399 
400  GetArgsCtx ctx = {exe_ctx.GetRegisterContext(), exe_ctx.GetProcessPtr()};
401  assert(ctx.reg_ctx && ctx.process);
402 
403  // dispatch based on architecture
404  switch (exe_ctx.GetTargetPtr()->GetArchitecture().GetMachine()) {
405  case llvm::Triple::ArchType::x86:
406  return GetArgsX86(ctx, arg_list, num_args);
407 
408  case llvm::Triple::ArchType::x86_64:
409  return GetArgsX86_64(ctx, arg_list, num_args);
410 
411  case llvm::Triple::ArchType::arm:
412  return GetArgsArm(ctx, arg_list, num_args);
413 
414  case llvm::Triple::ArchType::aarch64:
415  return GetArgsAarch64(ctx, arg_list, num_args);
416 
417  case llvm::Triple::ArchType::mipsel:
418  return GetArgsMipsel(ctx, arg_list, num_args);
419 
420  case llvm::Triple::ArchType::mips64el:
421  return GetArgsMips64el(ctx, arg_list, num_args);
422 
423  default:
424  // unsupported architecture
425  if (log) {
426  LLDB_LOGF(log, "%s - architecture not supported: '%s'", __FUNCTION__,
428  }
429  return false;
430  }
431 }
432 
433 bool IsRenderScriptScriptModule(ModuleSP module) {
434  if (!module)
435  return false;
436  return module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"),
437  eSymbolTypeData) != nullptr;
438 }
439 
440 bool ParseCoordinate(llvm::StringRef coord_s, RSCoordinate &coord) {
441  // takes an argument of the form 'num[,num][,num]'. Where 'coord_s' is a
442  // comma separated 1,2 or 3-dimensional coordinate with the whitespace
443  // trimmed. Missing coordinates are defaulted to zero. If parsing of any
444  // elements fails the contents of &coord are undefined and `false` is
445  // returned, `true` otherwise
446 
447  llvm::SmallVector<llvm::StringRef, 4> matches;
448 
449  if (!RegularExpression("^([0-9]+),([0-9]+),([0-9]+)$")
450  .Execute(coord_s, &matches) &&
451  !RegularExpression("^([0-9]+),([0-9]+)$").Execute(coord_s, &matches) &&
452  !RegularExpression("^([0-9]+)$").Execute(coord_s, &matches))
453  return false;
454 
455  auto get_index = [&](size_t idx, uint32_t &i) -> bool {
456  std::string group;
457  errno = 0;
458  if (idx + 1 < matches.size()) {
459  return !llvm::StringRef(matches[idx + 1]).getAsInteger<uint32_t>(10, i);
460  }
461  return true;
462  };
463 
464  return get_index(0, coord.x) && get_index(1, coord.y) &&
465  get_index(2, coord.z);
466 }
467 
468 bool SkipPrologue(lldb::ModuleSP &module, Address &addr) {
470  SymbolContext sc;
471  uint32_t resolved_flags =
472  module->ResolveSymbolContextForAddress(addr, eSymbolContextFunction, sc);
473  if (resolved_flags & eSymbolContextFunction) {
474  if (sc.function) {
475  const uint32_t offset = sc.function->GetPrologueByteSize();
476  ConstString name = sc.GetFunctionName();
477  if (offset)
478  addr.Slide(offset);
479  LLDB_LOGF(log, "%s: Prologue offset for %s is %" PRIu32, __FUNCTION__,
480  name.AsCString(), offset);
481  }
482  return true;
483  } else
484  return false;
485 }
486 } // anonymous namespace
487 
488 // The ScriptDetails class collects data associated with a single script
489 // instance.
491  ~ScriptDetails() = default;
492 
493  enum ScriptType { eScript, eScriptC };
494 
495  // The derived type of the script.
496  empirical_type<ScriptType> type;
497  // The name of the original source file.
498  empirical_type<std::string> res_name;
499  // Path to script .so file on the device.
500  empirical_type<std::string> shared_lib;
501  // Directory where kernel objects are cached on device.
502  empirical_type<std::string> cache_dir;
503  // Pointer to the context which owns this script.
504  empirical_type<lldb::addr_t> context;
505  // Pointer to the script object itself.
506  empirical_type<lldb::addr_t> script;
507 };
508 
509 // This Element class represents the Element object in RS, defining the type
510 // associated with an Allocation.
512  // Taken from rsDefines.h
513  enum DataKind {
515  RS_KIND_PIXEL_L = 7,
522  RS_KIND_INVALID = 100
523  };
524 
525  // Taken from rsDefines.h
526  enum DataType {
527  RS_TYPE_NONE = 0,
540 
544 
548 
549  RS_TYPE_ELEMENT = 1000,
560 
561  RS_TYPE_INVALID = 10000
562  };
563 
564  std::vector<Element> children; // Child Element fields for structs
565  empirical_type<lldb::addr_t>
566  element_ptr; // Pointer to the RS Element of the Type
567  empirical_type<DataType>
568  type; // Type of each data pointer stored by the allocation
569  empirical_type<DataKind>
570  type_kind; // Defines pixel type if Allocation is created from an image
571  empirical_type<uint32_t>
572  type_vec_size; // Vector size of each data point, e.g '4' for uchar4
573  empirical_type<uint32_t> field_count; // Number of Subelements
574  empirical_type<uint32_t> datum_size; // Size of a single Element with padding
575  empirical_type<uint32_t> padding; // Number of padding bytes
576  empirical_type<uint32_t>
577  array_size; // Number of items in array, only needed for structs
578  ConstString type_name; // Name of type, only needed for structs
579 
580  static ConstString
581  GetFallbackStructName(); // Print this as the type name of a struct Element
582  // If we can't resolve the actual struct name
583 
584  bool ShouldRefresh() const {
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();
589  }
590 };
591 
592 // This AllocationDetails class collects data associated with a single
593 // allocation instance.
595  struct Dimension {
600 
602  dim_1 = 0;
603  dim_2 = 0;
604  dim_3 = 0;
605  cube_map = 0;
606  }
607  };
608 
609  // The FileHeader struct specifies the header we use for writing allocations
610  // to a binary file. Our format begins with the ASCII characters "RSAD",
611  // identifying the file as an allocation dump. Member variables dims and
612  // hdr_size are then written consecutively, immediately followed by an
613  // instance of the ElementHeader struct. Because Elements can contain
614  // subelements, there may be more than one instance of the ElementHeader
615  // struct. With this first instance being the root element, and the other
616  // instances being the root's descendants. To identify which instances are an
617  // ElementHeader's children, each struct is immediately followed by a
618  // sequence of consecutive offsets to the start of its child structs. These
619  // offsets are
620  // 4 bytes in size, and the 0 offset signifies no more children.
621  struct FileHeader {
622  uint8_t ident[4]; // ASCII 'RSAD' identifying the file
623  uint32_t dims[3]; // Dimensions
624  uint16_t hdr_size; // Header size in bytes, including all element headers
625  };
626 
627  struct ElementHeader {
628  uint16_t type; // DataType enum
629  uint32_t kind; // DataKind enum
630  uint32_t element_size; // Size of a single element, including padding
631  uint16_t vector_size; // Vector width
632  uint32_t array_size; // Number of elements in array
633  };
634 
635  // Monotonically increasing from 1
636  static uint32_t ID;
637 
638  // Maps Allocation DataType enum and vector size to printable strings using
639  // mapping from RenderScript numerical types summary documentation
640  static const char *RsDataTypeToString[][4];
641 
642  // Maps Allocation DataKind enum to printable strings
643  static const char *RsDataKindToString[];
644 
645  // Maps allocation types to format sizes for printing.
646  static const uint32_t RSTypeToFormat[][3];
647 
648  // Give each allocation an ID as a way
649  // for commands to reference it.
650  const uint32_t id;
651 
652  // Allocation Element type
654  // Dimensions of the Allocation
655  empirical_type<Dimension> dimension;
656  // Pointer to address of the RS Allocation
657  empirical_type<lldb::addr_t> address;
658  // Pointer to the data held by the Allocation
659  empirical_type<lldb::addr_t> data_ptr;
660  // Pointer to the RS Type of the Allocation
661  empirical_type<lldb::addr_t> type_ptr;
662  // Pointer to the RS Context of the Allocation
663  empirical_type<lldb::addr_t> context;
664  // Size of the allocation
665  empirical_type<uint32_t> size;
666  // Stride between rows of the allocation
667  empirical_type<uint32_t> stride;
668 
669  // Give each allocation an id, so we can reference it in user commands.
671 
672  bool ShouldRefresh() const {
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() ||
676  element.ShouldRefresh();
677  }
678 };
679 
681  static const ConstString FallbackStructName("struct");
682  return FallbackStructName;
683 }
684 
686 
688  "User", "Undefined", "Undefined", "Undefined",
689  "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7
690  "L Pixel", "A Pixel", "LA Pixel", "RGB Pixel",
691  "RGBA Pixel", "Pixel Depth", "YUV Pixel"};
692 
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"},
713 
714  // Handlers
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"},
720 
721  // Deprecated
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",
730  "RS Program Store"},
731  {"RS Font", "RS Font", "RS Font", "RS Font"}};
732 
733 // Used as an index into the RSTypeToFormat array elements
735 
736 // { format enum of single element, format enum of element vector, size of
737 // element}
739  // RS_TYPE_NONE
740  {eFormatHex, eFormatHex, 1},
741  // RS_TYPE_FLOAT_16
743  // RS_TYPE_FLOAT_32
744  {eFormatFloat, eFormatVectorOfFloat32, sizeof(float)},
745  // RS_TYPE_FLOAT_64
746  {eFormatFloat, eFormatVectorOfFloat64, sizeof(double)},
747  // RS_TYPE_SIGNED_8
748  {eFormatDecimal, eFormatVectorOfSInt8, sizeof(int8_t)},
749  // RS_TYPE_SIGNED_16
750  {eFormatDecimal, eFormatVectorOfSInt16, sizeof(int16_t)},
751  // RS_TYPE_SIGNED_32
752  {eFormatDecimal, eFormatVectorOfSInt32, sizeof(int32_t)},
753  // RS_TYPE_SIGNED_64
754  {eFormatDecimal, eFormatVectorOfSInt64, sizeof(int64_t)},
755  // RS_TYPE_UNSIGNED_8
756  {eFormatDecimal, eFormatVectorOfUInt8, sizeof(uint8_t)},
757  // RS_TYPE_UNSIGNED_16
759  // RS_TYPE_UNSIGNED_32
761  // RS_TYPE_UNSIGNED_64
762  {eFormatDecimal, eFormatVectorOfUInt64, sizeof(uint64_t)},
763  // RS_TYPE_BOOL
765  // RS_TYPE_UNSIGNED_5_6_5
766  {eFormatHex, eFormatHex, sizeof(uint16_t)},
767  // RS_TYPE_UNSIGNED_5_5_5_1
768  {eFormatHex, eFormatHex, sizeof(uint16_t)},
769  // RS_TYPE_UNSIGNED_4_4_4_4
770  {eFormatHex, eFormatHex, sizeof(uint16_t)},
771  // RS_TYPE_MATRIX_4X4
772  {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 16},
773  // RS_TYPE_MATRIX_3X3
774  {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 9},
775  // RS_TYPE_MATRIX_2X2
776  {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 4}};
777 
778 // Static Functions
780 RenderScriptRuntime::CreateInstance(Process *process,
781  lldb::LanguageType language) {
782 
783  if (language == eLanguageTypeExtRenderScript)
784  return new RenderScriptRuntime(process);
785  else
786  return nullptr;
787 }
788 
789 // Callback with a module to search for matching symbols. We first check that
790 // the module contains RS kernels. Then look for a symbol which matches our
791 // kernel name. The breakpoint address is finally set using the address of this
792 // symbol.
794 RSBreakpointResolver::SearchCallback(SearchFilter &filter,
795  SymbolContext &context, Address *) {
796  BreakpointSP breakpoint_sp = GetBreakpoint();
797  assert(breakpoint_sp);
798 
799  ModuleSP module = context.module_sp;
800 
801  if (!module || !IsRenderScriptScriptModule(module))
802  return Searcher::eCallbackReturnContinue;
803 
804  // Attempt to set a breakpoint on the kernel name symbol within the module
805  // library. If it's not found, it's likely debug info is unavailable - try to
806  // set a breakpoint on <name>.expand.
807  const Symbol *kernel_sym =
808  module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
809  if (!kernel_sym) {
810  std::string kernel_name_expanded(m_kernel_name.AsCString());
811  kernel_name_expanded.append(".expand");
812  kernel_sym = module->FindFirstSymbolWithNameAndType(
813  ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode);
814  }
815 
816  if (kernel_sym) {
817  Address bp_addr = kernel_sym->GetAddress();
818  if (filter.AddressPasses(bp_addr))
819  breakpoint_sp->AddLocation(bp_addr);
820  }
821 
822  return Searcher::eCallbackReturnContinue;
823 }
824 
826 RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter,
828  Address *) {
829  BreakpointSP breakpoint_sp = GetBreakpoint();
830  assert(breakpoint_sp);
831 
832  // We need to have access to the list of reductions currently parsed, as
833  // reduce names don't actually exist as symbols in a module. They are only
834  // identifiable by parsing the .rs.info packet, or finding the expand symbol.
835  // We therefore need access to the list of parsed rs modules to properly
836  // resolve reduction names.
838  ModuleSP module = context.module_sp;
839 
840  if (!module || !IsRenderScriptScriptModule(module))
841  return Searcher::eCallbackReturnContinue;
842 
843  if (!m_rsmodules)
844  return Searcher::eCallbackReturnContinue;
845 
846  for (const auto &module_desc : *m_rsmodules) {
847  if (module_desc->m_module != module)
848  continue;
849 
850  for (const auto &reduction : module_desc->m_reductions) {
851  if (reduction.m_reduce_name != m_reduce_name)
852  continue;
853 
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}}};
860 
861  for (const auto &kernel : funcs) {
862  // Skip constituent functions that don't match our spec
863  if (!(m_kernel_types & kernel.second))
864  continue;
865 
866  const auto kernel_name = kernel.first;
867  const auto symbol = module->FindFirstSymbolWithNameAndType(
868  kernel_name, eSymbolTypeCode);
869  if (!symbol)
870  continue;
871 
872  auto address = symbol->GetAddress();
873  if (filter.AddressPasses(address)) {
874  bool new_bp;
875  if (!SkipPrologue(module, address)) {
876  LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__);
877  }
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());
883  }
884  }
885  }
886  }
887  return eCallbackReturnContinue;
888 }
889 
890 Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback(
891  SearchFilter &filter, SymbolContext &context, Address *addr) {
892 
893  BreakpointSP breakpoint_sp = GetBreakpoint();
894  if (!breakpoint_sp)
895  return eCallbackReturnContinue;
896 
898  ModuleSP &module = context.module_sp;
899 
900  if (!module || !IsRenderScriptScriptModule(module))
901  return Searcher::eCallbackReturnContinue;
902 
903  std::vector<std::string> names;
904  Breakpoint& breakpoint = *breakpoint_sp;
905  breakpoint.GetNames(names);
906  if (names.empty())
907  return eCallbackReturnContinue;
908 
909  for (auto &name : names) {
910  const RSScriptGroupDescriptorSP sg = FindScriptGroup(ConstString(name));
911  if (!sg) {
912  LLDB_LOGF(log, "%s: could not find script group for %s", __FUNCTION__,
913  name.c_str());
914  continue;
915  }
916 
917  LLDB_LOGF(log, "%s: Found ScriptGroup for %s", __FUNCTION__, name.c_str());
918 
919  for (const RSScriptGroupDescriptor::Kernel &k : sg->m_kernels) {
920  if (log) {
921  LLDB_LOGF(log, "%s: Adding breakpoint for %s", __FUNCTION__,
922  k.m_name.AsCString());
923  LLDB_LOGF(log, "%s: Kernel address 0x%" PRIx64, __FUNCTION__, k.m_addr);
924  }
925 
926  const lldb_private::Symbol *sym =
927  module->FindFirstSymbolWithNameAndType(k.m_name, eSymbolTypeCode);
928  if (!sym) {
929  LLDB_LOGF(log, "%s: Unable to find symbol for %s", __FUNCTION__,
930  k.m_name.AsCString());
931  continue;
932  }
933 
934  if (log) {
935  LLDB_LOGF(log, "%s: Found symbol name is %s", __FUNCTION__,
936  sym->GetName().AsCString());
937  }
938 
939  auto address = sym->GetAddress();
940  if (!SkipPrologue(module, address)) {
941  LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__);
942  }
943 
944  bool new_bp;
945  breakpoint.AddLocation(address, &new_bp);
946 
947  LLDB_LOGF(log, "%s: Placed %sbreakpoint on %s", __FUNCTION__,
948  new_bp ? "new " : "", k.m_name.AsCString());
949 
950  // exit after placing the first breakpoint if we do not intend to stop on
951  // all kernels making up this script group
952  if (!m_stop_on_all)
953  break;
954  }
955  }
956 
957  return eCallbackReturnContinue;
958 }
959 
960 void RenderScriptRuntime::Initialize() {
961  PluginManager::RegisterPlugin(GetPluginNameStatic(),
962  "RenderScript language support", CreateInstance,
963  GetCommandObject);
964 }
965 
966 void RenderScriptRuntime::Terminate() {
967  PluginManager::UnregisterPlugin(CreateInstance);
968 }
969 
970 lldb_private::ConstString RenderScriptRuntime::GetPluginNameStatic() {
971  static ConstString plugin_name("renderscript");
972  return plugin_name;
973 }
974 
976 RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp) {
977  if (module_sp) {
978  if (IsRenderScriptScriptModule(module_sp))
979  return eModuleKindKernelObj;
980 
981  // Is this the main RS runtime library
982  const ConstString rs_lib("libRS.so");
983  if (module_sp->GetFileSpec().GetFilename() == rs_lib) {
984  return eModuleKindLibRS;
985  }
986 
987  const ConstString rs_driverlib("libRSDriver.so");
988  if (module_sp->GetFileSpec().GetFilename() == rs_driverlib) {
989  return eModuleKindDriver;
990  }
991 
992  const ConstString rs_cpureflib("libRSCpuRef.so");
993  if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib) {
994  return eModuleKindImpl;
995  }
996  }
997  return eModuleKindIgnored;
998 }
999 
1000 bool RenderScriptRuntime::IsRenderScriptModule(
1001  const lldb::ModuleSP &module_sp) {
1002  return GetModuleKind(module_sp) != eModuleKindIgnored;
1003 }
1004 
1005 void RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list) {
1006  std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1007 
1008  size_t num_modules = module_list.GetSize();
1009  for (size_t i = 0; i < num_modules; i++) {
1010  auto mod = module_list.GetModuleAtIndex(i);
1011  if (IsRenderScriptModule(mod)) {
1012  LoadModule(mod);
1013  }
1014  }
1015 }
1016 
1017 // PluginInterface protocol
1018 lldb_private::ConstString RenderScriptRuntime::GetPluginName() {
1019  return GetPluginNameStatic();
1020 }
1021 
1022 uint32_t RenderScriptRuntime::GetPluginVersion() { return 1; }
1023 
1024 bool RenderScriptRuntime::GetDynamicTypeAndAddress(
1025  ValueObject &in_value, lldb::DynamicValueType use_dynamic,
1026  TypeAndOrName &class_type_or_name, Address &address,
1027  Value::ValueType &value_type) {
1028  return false;
1029 }
1030 
1032 RenderScriptRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name,
1033  ValueObject &static_value) {
1034  return type_and_or_name;
1035 }
1036 
1037 bool RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value) {
1038  return false;
1039 }
1040 
1041 lldb::BreakpointResolverSP
1042 RenderScriptRuntime::CreateExceptionResolver(const lldb::BreakpointSP &bp,
1043  bool catch_bp, bool throw_bp) {
1044  BreakpointResolverSP resolver_sp;
1045  return resolver_sp;
1046 }
1047 
1048 const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] =
1049  {
1050  // rsdScript
1051  {"rsdScriptInit", "_Z13rsdScriptInitPKN7android12renderscript7ContextEP"
1052  "NS0_7ScriptCEPKcS7_PKhjj",
1053  "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_"
1054  "7ScriptCEPKcS7_PKhmj",
1055  0, RenderScriptRuntime::eModuleKindDriver,
1057  {"rsdScriptInvokeForEachMulti",
1058  "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0"
1059  "_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall",
1060  "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0"
1061  "_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall",
1062  0, RenderScriptRuntime::eModuleKindDriver,
1064  {"rsdScriptSetGlobalVar", "_Z21rsdScriptSetGlobalVarPKN7android12render"
1065  "script7ContextEPKNS0_6ScriptEjPvj",
1066  "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_"
1067  "6ScriptEjPvm",
1068  0, RenderScriptRuntime::eModuleKindDriver,
1070 
1071  // rsdAllocation
1072  {"rsdAllocationInit", "_Z17rsdAllocationInitPKN7android12renderscript7C"
1073  "ontextEPNS0_10AllocationEb",
1074  "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_"
1075  "10AllocationEb",
1076  0, RenderScriptRuntime::eModuleKindDriver,
1078  {"rsdAllocationRead2D",
1079  "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_"
1080  "10AllocationEjjj23RsAllocationCubemapFacejjPvjj",
1081  "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_"
1082  "10AllocationEjjj23RsAllocationCubemapFacejjPvmm",
1083  0, RenderScriptRuntime::eModuleKindDriver, nullptr},
1084  {"rsdAllocationDestroy", "_Z20rsdAllocationDestroyPKN7android12rendersc"
1085  "ript7ContextEPNS0_10AllocationE",
1086  "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_"
1087  "10AllocationE",
1088  0, RenderScriptRuntime::eModuleKindDriver,
1090 
1091  // renderscript script groups
1092  {"rsdDebugHintScriptGroup2", "_ZN7android12renderscript21debugHintScrip"
1093  "tGroup2EPKcjPKPFvPK24RsExpandKernelDriver"
1094  "InfojjjEj",
1095  "_ZN7android12renderscript21debugHintScriptGroup2EPKcjPKPFvPK24RsExpan"
1096  "dKernelDriverInfojjjEj",
1097  0, RenderScriptRuntime::eModuleKindImpl,
1099 
1100 const size_t RenderScriptRuntime::s_runtimeHookCount =
1101  sizeof(s_runtimeHookDefns) / sizeof(s_runtimeHookDefns[0]);
1102 
1103 bool RenderScriptRuntime::HookCallback(void *baton,
1105  lldb::user_id_t break_id,
1106  lldb::user_id_t break_loc_id) {
1107  RuntimeHook *hook = (RuntimeHook *)baton;
1108  ExecutionContext exe_ctx(ctx->exe_ctx_ref);
1109 
1110  RenderScriptRuntime *lang_rt = llvm::cast<RenderScriptRuntime>(
1111  exe_ctx.GetProcessPtr()->GetLanguageRuntime(
1113 
1114  lang_rt->HookCallback(hook, exe_ctx);
1115 
1116  return false;
1117 }
1118 
1119 void RenderScriptRuntime::HookCallback(RuntimeHook *hook,
1120  ExecutionContext &exe_ctx) {
1122 
1123  LLDB_LOGF(log, "%s - '%s'", __FUNCTION__, hook->defn->name);
1124 
1125  if (hook->defn->grabber) {
1126  (this->*(hook->defn->grabber))(hook, exe_ctx);
1127  }
1128 }
1129 
1130 void RenderScriptRuntime::CaptureDebugHintScriptGroup2(
1131  RuntimeHook *hook_info, ExecutionContext &context) {
1133 
1134  enum {
1135  eGroupName = 0,
1136  eGroupNameSize,
1137  eKernel,
1138  eKernelCount,
1139  };
1140 
1141  std::array<ArgItem, 4> args{{
1142  {ArgItem::ePointer, 0}, // const char *groupName
1143  {ArgItem::eInt32, 0}, // const uint32_t groupNameSize
1144  {ArgItem::ePointer, 0}, // const ExpandFuncTy *kernel
1145  {ArgItem::eInt32, 0}, // const uint32_t kernelCount
1146  }};
1147 
1148  if (!GetArgs(context, args.data(), args.size())) {
1149  LLDB_LOGF(log, "%s - Error while reading the function parameters",
1150  __FUNCTION__);
1151  return;
1152  } else if (log) {
1153  LLDB_LOGF(log, "%s - groupName : 0x%" PRIx64, __FUNCTION__,
1154  addr_t(args[eGroupName]));
1155  LLDB_LOGF(log, "%s - groupNameSize: %" PRIu64, __FUNCTION__,
1156  uint64_t(args[eGroupNameSize]));
1157  LLDB_LOGF(log, "%s - kernel : 0x%" PRIx64, __FUNCTION__,
1158  addr_t(args[eKernel]));
1159  LLDB_LOGF(log, "%s - kernelCount : %" PRIu64, __FUNCTION__,
1160  uint64_t(args[eKernelCount]));
1161  }
1162 
1163  // parse script group name
1164  ConstString group_name;
1165  {
1166  Status err;
1167  const uint64_t len = uint64_t(args[eGroupNameSize]);
1168  std::unique_ptr<char[]> buffer(new char[uint32_t(len + 1)]);
1169  m_process->ReadMemory(addr_t(args[eGroupName]), buffer.get(), len, err);
1170  buffer.get()[len] = '\0';
1171  if (!err.Success()) {
1172  LLDB_LOGF(log, "Error reading scriptgroup name from target");
1173  return;
1174  } else {
1175  LLDB_LOGF(log, "Extracted scriptgroup name %s", buffer.get());
1176  }
1177  // write back the script group name
1178  group_name.SetCString(buffer.get());
1179  }
1180 
1181  // create or access existing script group
1183  {
1184  // search for existing script group
1185  for (auto sg : m_scriptGroups) {
1186  if (sg->m_name == group_name) {
1187  group = sg;
1188  break;
1189  }
1190  }
1191  if (!group) {
1192  group = std::make_shared<RSScriptGroupDescriptor>();
1193  group->m_name = group_name;
1194  m_scriptGroups.push_back(group);
1195  } else {
1196  // already have this script group
1197  LLDB_LOGF(log, "Attempt to add duplicate script group %s",
1198  group_name.AsCString());
1199  return;
1200  }
1201  }
1202  assert(group);
1203 
1204  const uint32_t target_ptr_size = m_process->GetAddressByteSize();
1205  std::vector<addr_t> kernels;
1206  // parse kernel addresses in script group
1207  for (uint64_t i = 0; i < uint64_t(args[eKernelCount]); ++i) {
1209  // extract script group kernel addresses from the target
1210  const addr_t ptr_addr = addr_t(args[eKernel]) + i * target_ptr_size;
1211  uint64_t kernel_addr = 0;
1212  Status err;
1213  size_t read =
1214  m_process->ReadMemory(ptr_addr, &kernel_addr, target_ptr_size, err);
1215  if (!err.Success() || read != target_ptr_size) {
1216  LLDB_LOGF(log, "Error parsing kernel address %" PRIu64 " in script group",
1217  i);
1218  return;
1219  }
1220  LLDB_LOGF(log, "Extracted scriptgroup kernel address - 0x%" PRIx64,
1221  kernel_addr);
1222  kernel.m_addr = kernel_addr;
1223 
1224  // try to resolve the associated kernel name
1225  if (!ResolveKernelName(kernel.m_addr, kernel.m_name)) {
1226  LLDB_LOGF(log, "Parsed scriptgroup kernel %" PRIu64 " - 0x%" PRIx64, i,
1227  kernel_addr);
1228  return;
1229  }
1230 
1231  // try to find the non '.expand' function
1232  {
1233  const llvm::StringRef expand(".expand");
1234  const llvm::StringRef name_ref = kernel.m_name.GetStringRef();
1235  if (name_ref.endswith(expand)) {
1236  const ConstString base_kernel(name_ref.drop_back(expand.size()));
1237  // verify this function is a valid kernel
1238  if (IsKnownKernel(base_kernel)) {
1239  kernel.m_name = base_kernel;
1240  LLDB_LOGF(log, "%s - found non expand version '%s'", __FUNCTION__,
1241  base_kernel.GetCString());
1242  }
1243  }
1244  }
1245  // add to a list of script group kernels we know about
1246  group->m_kernels.push_back(kernel);
1247  }
1248 
1249  // Resolve any pending scriptgroup breakpoints
1250  {
1251  Target &target = m_process->GetTarget();
1252  const BreakpointList &list = target.GetBreakpointList();
1253  const size_t num_breakpoints = list.GetSize();
1254  LLDB_LOGF(log, "Resolving %zu breakpoints", num_breakpoints);
1255  for (size_t i = 0; i < num_breakpoints; ++i) {
1256  const BreakpointSP bp = list.GetBreakpointAtIndex(i);
1257  if (bp) {
1258  if (bp->MatchesName(group_name.AsCString())) {
1259  LLDB_LOGF(log, "Found breakpoint with name %s",
1260  group_name.AsCString());
1261  bp->ResolveBreakpoint();
1262  }
1263  }
1264  }
1265  }
1266 }
1267 
1268 void RenderScriptRuntime::CaptureScriptInvokeForEachMulti(
1269  RuntimeHook *hook, ExecutionContext &exe_ctx) {
1271 
1272  enum {
1273  eRsContext = 0,
1274  eRsScript,
1275  eRsSlot,
1276  eRsAIns,
1277  eRsInLen,
1278  eRsAOut,
1279  eRsUsr,
1280  eRsUsrLen,
1281  eRsSc,
1282  };
1283 
1284  std::array<ArgItem, 9> args{{
1285  ArgItem{ArgItem::ePointer, 0}, // const Context *rsc
1286  ArgItem{ArgItem::ePointer, 0}, // Script *s
1287  ArgItem{ArgItem::eInt32, 0}, // uint32_t slot
1288  ArgItem{ArgItem::ePointer, 0}, // const Allocation **aIns
1289  ArgItem{ArgItem::eInt32, 0}, // size_t inLen
1290  ArgItem{ArgItem::ePointer, 0}, // Allocation *aout
1291  ArgItem{ArgItem::ePointer, 0}, // const void *usr
1292  ArgItem{ArgItem::eInt32, 0}, // size_t usrLen
1293  ArgItem{ArgItem::ePointer, 0}, // const RsScriptCall *sc
1294  }};
1295 
1296  bool success = GetArgs(exe_ctx, &args[0], args.size());
1297  if (!success) {
1298  LLDB_LOGF(log, "%s - Error while reading the function parameters",
1299  __FUNCTION__);
1300  return;
1301  }
1302 
1303  const uint32_t target_ptr_size = m_process->GetAddressByteSize();
1304  Status err;
1305  std::vector<uint64_t> allocs;
1306 
1307  // traverse allocation list
1308  for (uint64_t i = 0; i < uint64_t(args[eRsInLen]); ++i) {
1309  // calculate offest to allocation pointer
1310  const addr_t addr = addr_t(args[eRsAIns]) + i * target_ptr_size;
1311 
1312  // Note: due to little endian layout, reading 32bits or 64bits into res
1313  // will give the correct results.
1314  uint64_t result = 0;
1315  size_t read = m_process->ReadMemory(addr, &result, target_ptr_size, err);
1316  if (read != target_ptr_size || !err.Success()) {
1317  LLDB_LOGF(log,
1318  "%s - Error while reading allocation list argument %" PRIu64,
1319  __FUNCTION__, i);
1320  } else {
1321  allocs.push_back(result);
1322  }
1323  }
1324 
1325  // if there is an output allocation track it
1326  if (uint64_t alloc_out = uint64_t(args[eRsAOut])) {
1327  allocs.push_back(alloc_out);
1328  }
1329 
1330  // for all allocations we have found
1331  for (const uint64_t alloc_addr : allocs) {
1332  AllocationDetails *alloc = LookUpAllocation(alloc_addr);
1333  if (!alloc)
1334  alloc = CreateAllocation(alloc_addr);
1335 
1336  if (alloc) {
1337  // save the allocation address
1338  if (alloc->address.isValid()) {
1339  // check the allocation address we already have matches
1340  assert(*alloc->address.get() == alloc_addr);
1341  } else {
1342  alloc->address = alloc_addr;
1343  }
1344 
1345  // save the context
1346  if (log) {
1347  if (alloc->context.isValid() &&
1348  *alloc->context.get() != addr_t(args[eRsContext]))
1349  LLDB_LOGF(log, "%s - Allocation used by multiple contexts",
1350  __FUNCTION__);
1351  }
1352  alloc->context = addr_t(args[eRsContext]);
1353  }
1354  }
1355 
1356  // make sure we track this script object
1358  LookUpScript(addr_t(args[eRsScript]), true)) {
1359  if (log) {
1360  if (script->context.isValid() &&
1361  *script->context.get() != addr_t(args[eRsContext]))
1362  LLDB_LOGF(log, "%s - Script used by multiple contexts", __FUNCTION__);
1363  }
1364  script->context = addr_t(args[eRsContext]);
1365  }
1366 }
1367 
1368 void RenderScriptRuntime::CaptureSetGlobalVar(RuntimeHook *hook,
1369  ExecutionContext &context) {
1371 
1372  enum {
1373  eRsContext,
1374  eRsScript,
1375  eRsId,
1376  eRsData,
1377  eRsLength,
1378  };
1379 
1380  std::array<ArgItem, 5> args{{
1381  ArgItem{ArgItem::ePointer, 0}, // eRsContext
1382  ArgItem{ArgItem::ePointer, 0}, // eRsScript
1383  ArgItem{ArgItem::eInt32, 0}, // eRsId
1384  ArgItem{ArgItem::ePointer, 0}, // eRsData
1385  ArgItem{ArgItem::eInt32, 0}, // eRsLength
1386  }};
1387 
1388  bool success = GetArgs(context, &args[0], args.size());
1389  if (!success) {
1390  LLDB_LOGF(log, "%s - error reading the function parameters.", __FUNCTION__);
1391  return;
1392  }
1393 
1394  if (log) {
1395  LLDB_LOGF(log,
1396  "%s - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64
1397  ":%" PRIu64 "bytes.",
1398  __FUNCTION__, uint64_t(args[eRsContext]),
1399  uint64_t(args[eRsScript]), uint64_t(args[eRsId]),
1400  uint64_t(args[eRsData]), uint64_t(args[eRsLength]));
1401 
1402  addr_t script_addr = addr_t(args[eRsScript]);
1403  if (m_scriptMappings.find(script_addr) != m_scriptMappings.end()) {
1404  auto rsm = m_scriptMappings[script_addr];
1405  if (uint64_t(args[eRsId]) < rsm->m_globals.size()) {
1406  auto rsg = rsm->m_globals[uint64_t(args[eRsId])];
1407  LLDB_LOGF(log, "%s - Setting of '%s' within '%s' inferred",
1408  __FUNCTION__, rsg.m_name.AsCString(),
1409  rsm->m_module->GetFileSpec().GetFilename().AsCString());
1410  }
1411  }
1412  }
1413 }
1414 
1415 void RenderScriptRuntime::CaptureAllocationInit(RuntimeHook *hook,
1416  ExecutionContext &exe_ctx) {
1418 
1419  enum { eRsContext, eRsAlloc, eRsForceZero };
1420 
1421  std::array<ArgItem, 3> args{{
1422  ArgItem{ArgItem::ePointer, 0}, // eRsContext
1423  ArgItem{ArgItem::ePointer, 0}, // eRsAlloc
1424  ArgItem{ArgItem::eBool, 0}, // eRsForceZero
1425  }};
1426 
1427  bool success = GetArgs(exe_ctx, &args[0], args.size());
1428  if (!success) {
1429  LLDB_LOGF(log, "%s - error while reading the function parameters",
1430  __FUNCTION__);
1431  return;
1432  }
1433 
1434  LLDB_LOGF(log, "%s - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
1435  __FUNCTION__, uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]),
1436  uint64_t(args[eRsForceZero]));
1437 
1438  AllocationDetails *alloc = CreateAllocation(uint64_t(args[eRsAlloc]));
1439  if (alloc)
1440  alloc->context = uint64_t(args[eRsContext]);
1441 }
1442 
1443 void RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook *hook,
1444  ExecutionContext &exe_ctx) {
1446 
1447  enum {
1448  eRsContext,
1449  eRsAlloc,
1450  };
1451 
1452  std::array<ArgItem, 2> args{{
1453  ArgItem{ArgItem::ePointer, 0}, // eRsContext
1454  ArgItem{ArgItem::ePointer, 0}, // eRsAlloc
1455  }};
1456 
1457  bool success = GetArgs(exe_ctx, &args[0], args.size());
1458  if (!success) {
1459  LLDB_LOGF(log, "%s - error while reading the function parameters.",
1460  __FUNCTION__);
1461  return;
1462  }
1463 
1464  LLDB_LOGF(log, "%s - 0x%" PRIx64 ", 0x%" PRIx64 ".", __FUNCTION__,
1465  uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]));
1466 
1467  for (auto iter = m_allocations.begin(); iter != m_allocations.end(); ++iter) {
1468  auto &allocation_up = *iter; // get the unique pointer
1469  if (allocation_up->address.isValid() &&
1470  *allocation_up->address.get() == addr_t(args[eRsAlloc])) {
1471  m_allocations.erase(iter);
1472  LLDB_LOGF(log, "%s - deleted allocation entry.", __FUNCTION__);
1473  return;
1474  }
1475  }
1476 
1477  LLDB_LOGF(log, "%s - couldn't find destroyed allocation.", __FUNCTION__);
1478 }
1479 
1480 void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook,
1481  ExecutionContext &exe_ctx) {
1483 
1484  Status err;
1485  Process *process = exe_ctx.GetProcessPtr();
1486 
1487  enum { eRsContext, eRsScript, eRsResNamePtr, eRsCachedDirPtr };
1488 
1489  std::array<ArgItem, 4> args{
1490  {ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0},
1491  ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0}}};
1492  bool success = GetArgs(exe_ctx, &args[0], args.size());
1493  if (!success) {
1494  LLDB_LOGF(log, "%s - error while reading the function parameters.",
1495  __FUNCTION__);
1496  return;
1497  }
1498 
1499  std::string res_name;
1500  process->ReadCStringFromMemory(addr_t(args[eRsResNamePtr]), res_name, err);
1501  if (err.Fail()) {
1502  LLDB_LOGF(log, "%s - error reading res_name: %s.", __FUNCTION__,
1503  err.AsCString());
1504  }
1505 
1506  std::string cache_dir;
1507  process->ReadCStringFromMemory(addr_t(args[eRsCachedDirPtr]), cache_dir, err);
1508  if (err.Fail()) {
1509  LLDB_LOGF(log, "%s - error reading cache_dir: %s.", __FUNCTION__,
1510  err.AsCString());
1511  }
1512 
1513  LLDB_LOGF(log, "%s - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
1514  __FUNCTION__, uint64_t(args[eRsContext]), uint64_t(args[eRsScript]),
1515  res_name.c_str(), cache_dir.c_str());
1516 
1517  if (res_name.size() > 0) {
1518  StreamString strm;
1519  strm.Printf("librs.%s.so", res_name.c_str());
1520 
1521  ScriptDetails *script = LookUpScript(addr_t(args[eRsScript]), true);
1522  if (script) {
1523  script->type = ScriptDetails::eScriptC;
1524  script->cache_dir = cache_dir;
1525  script->res_name = res_name;
1526  script->shared_lib = std::string(strm.GetString());
1527  script->context = addr_t(args[eRsContext]);
1528  }
1529 
1530  LLDB_LOGF(log,
1531  "%s - '%s' tagged with context 0x%" PRIx64
1532  " and script 0x%" PRIx64 ".",
1533  __FUNCTION__, strm.GetData(), uint64_t(args[eRsContext]),
1534  uint64_t(args[eRsScript]));
1535  } else if (log) {
1536  LLDB_LOGF(log, "%s - resource name invalid, Script not tagged.",
1537  __FUNCTION__);
1538  }
1539 }
1540 
1541 void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module,
1542  ModuleKind kind) {
1544 
1545  if (!module) {
1546  return;
1547  }
1548 
1549  Target &target = GetProcess()->GetTarget();
1550  const llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();
1551 
1552  if (machine != llvm::Triple::ArchType::x86 &&
1553  machine != llvm::Triple::ArchType::arm &&
1554  machine != llvm::Triple::ArchType::aarch64 &&
1555  machine != llvm::Triple::ArchType::mipsel &&
1556  machine != llvm::Triple::ArchType::mips64el &&
1557  machine != llvm::Triple::ArchType::x86_64) {
1558  LLDB_LOGF(log, "%s - unable to hook runtime functions.", __FUNCTION__);
1559  return;
1560  }
1561 
1562  const uint32_t target_ptr_size =
1564 
1565  std::array<bool, s_runtimeHookCount> hook_placed;
1566  hook_placed.fill(false);
1567 
1568  for (size_t idx = 0; idx < s_runtimeHookCount; idx++) {
1569  const HookDefn *hook_defn = &s_runtimeHookDefns[idx];
1570  if (hook_defn->kind != kind) {
1571  continue;
1572  }
1573 
1574  const char *symbol_name = (target_ptr_size == 4)
1575  ? hook_defn->symbol_name_m32
1576  : hook_defn->symbol_name_m64;
1577 
1578  const Symbol *sym = module->FindFirstSymbolWithNameAndType(
1579  ConstString(symbol_name), eSymbolTypeCode);
1580  if (!sym) {
1581  if (log) {
1582  LLDB_LOGF(log, "%s - symbol '%s' related to the function %s not found",
1583  __FUNCTION__, symbol_name, hook_defn->name);
1584  }
1585  continue;
1586  }
1587 
1588  addr_t addr = sym->GetLoadAddress(&target);
1589  if (addr == LLDB_INVALID_ADDRESS) {
1590  LLDB_LOGF(log,
1591  "%s - unable to resolve the address of hook function '%s' "
1592  "with symbol '%s'.",
1593  __FUNCTION__, hook_defn->name, symbol_name);
1594  continue;
1595  } else {
1596  LLDB_LOGF(log, "%s - function %s, address resolved at 0x%" PRIx64,
1597  __FUNCTION__, hook_defn->name, addr);
1598  }
1599 
1600  RuntimeHookSP hook(new RuntimeHook());
1601  hook->address = addr;
1602  hook->defn = hook_defn;
1603  hook->bp_sp = target.CreateBreakpoint(addr, true, false);
1604  hook->bp_sp->SetCallback(HookCallback, hook.get(), true);
1605  m_runtimeHooks[addr] = hook;
1606  if (log) {
1607  LLDB_LOGF(log,
1608  "%s - successfully hooked '%s' in '%s' version %" PRIu64
1609  " at 0x%" PRIx64 ".",
1610  __FUNCTION__, hook_defn->name,
1611  module->GetFileSpec().GetFilename().AsCString(),
1612  (uint64_t)hook_defn->version, (uint64_t)addr);
1613  }
1614  hook_placed[idx] = true;
1615  }
1616 
1617  // log any unhooked function
1618  if (log) {
1619  for (size_t i = 0; i < hook_placed.size(); ++i) {
1620  if (hook_placed[i])
1621  continue;
1622  const HookDefn &hook_defn = s_runtimeHookDefns[i];
1623  if (hook_defn.kind != kind)
1624  continue;
1625  LLDB_LOGF(log, "%s - function %s was not hooked", __FUNCTION__,
1626  hook_defn.name);
1627  }
1628  }
1629 }
1630 
1631 void RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) {
1632  if (!rsmodule_sp)
1633  return;
1634 
1636 
1637  const ModuleSP module = rsmodule_sp->m_module;
1638  const FileSpec &file = module->GetPlatformFileSpec();
1639 
1640  // Iterate over all of the scripts that we currently know of. Note: We cant
1641  // push or pop to m_scripts here or it may invalidate rs_script.
1642  for (const auto &rs_script : m_scripts) {
1643  // Extract the expected .so file path for this script.
1644  std::string shared_lib;
1645  if (!rs_script->shared_lib.get(shared_lib))
1646  continue;
1647 
1648  // Only proceed if the module that has loaded corresponds to this script.
1649  if (file.GetFilename() != ConstString(shared_lib.c_str()))
1650  continue;
1651 
1652  // Obtain the script address which we use as a key.
1653  lldb::addr_t script;
1654  if (!rs_script->script.get(script))
1655  continue;
1656 
1657  // If we have a script mapping for the current script.
1658  if (m_scriptMappings.find(script) != m_scriptMappings.end()) {
1659  // if the module we have stored is different to the one we just received.
1660  if (m_scriptMappings[script] != rsmodule_sp) {
1661  LLDB_LOGF(
1662  log,
1663  "%s - script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
1664  __FUNCTION__, (uint64_t)script,
1665  rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
1666  }
1667  }
1668  // We don't have a script mapping for the current script.
1669  else {
1670  // Obtain the script resource name.
1671  std::string res_name;
1672  if (rs_script->res_name.get(res_name))
1673  // Set the modules resource name.
1674  rsmodule_sp->m_resname = res_name;
1675  // Add Script/Module pair to map.
1676  m_scriptMappings[script] = rsmodule_sp;
1677  LLDB_LOGF(log, "%s - script %" PRIx64 " associated with rsmodule '%s'.",
1678  __FUNCTION__, (uint64_t)script,
1679  rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
1680  }
1681  }
1682 }
1683 
1684 // Uses the Target API to evaluate the expression passed as a parameter to the
1685 // function The result of that expression is returned an unsigned 64 bit int,
1686 // via the result* parameter. Function returns true on success, and false on
1687 // failure
1688 bool RenderScriptRuntime::EvalRSExpression(const char *expr,
1689  StackFrame *frame_ptr,
1690  uint64_t *result) {
1692  LLDB_LOGF(log, "%s(%s)", __FUNCTION__, expr);
1693 
1694  ValueObjectSP expr_result;
1695  EvaluateExpressionOptions options;
1697  // Perform the actual expression evaluation
1698  auto &target = GetProcess()->GetTarget();
1699  target.EvaluateExpression(expr, frame_ptr, expr_result, options);
1700 
1701  if (!expr_result) {
1702  LLDB_LOGF(log, "%s: couldn't evaluate expression.", __FUNCTION__);
1703  return false;
1704  }
1705 
1706  // The result of the expression is invalid
1707  if (!expr_result->GetError().Success()) {
1708  Status err = expr_result->GetError();
1709  // Expression returned is void, so this is actually a success
1710  if (err.GetError() == UserExpression::kNoResult) {
1711  LLDB_LOGF(log, "%s - expression returned void.", __FUNCTION__);
1712 
1713  result = nullptr;
1714  return true;
1715  }
1716 
1717  LLDB_LOGF(log, "%s - error evaluating expression result: %s", __FUNCTION__,
1718  err.AsCString());
1719  return false;
1720  }
1721 
1722  bool success = false;
1723  // We only read the result as an uint32_t.
1724  *result = expr_result->GetValueAsUnsigned(0, &success);
1725 
1726  if (!success) {
1727  LLDB_LOGF(log, "%s - couldn't convert expression result to uint32_t",
1728  __FUNCTION__);
1729  return false;
1730  }
1731 
1732  return true;
1733 }
1734 
1735 namespace {
1736 // Used to index expression format strings
1737 enum ExpressionStrings {
1738  eExprGetOffsetPtr = 0,
1739  eExprAllocGetType,
1740  eExprTypeDimX,
1741  eExprTypeDimY,
1742  eExprTypeDimZ,
1743  eExprTypeElemPtr,
1744  eExprElementType,
1745  eExprElementKind,
1746  eExprElementVec,
1747  eExprElementFieldCount,
1748  eExprSubelementsId,
1749  eExprSubelementsName,
1750  eExprSubelementsArrSize,
1751 
1752  _eExprLast // keep at the end, implicit size of the array runtime_expressions
1753 };
1754 
1755 // max length of an expanded expression
1756 const int jit_max_expr_size = 512;
1757 
1758 // Retrieve the string to JIT for the given expression
1759 #define JIT_TEMPLATE_CONTEXT "void* ctxt = (void*)rsDebugGetContextWrapper(0x%" PRIx64 "); "
1760 const char *JITTemplate(ExpressionStrings e) {
1761  // Format strings containing the expressions we may need to evaluate.
1762  static std::array<const char *, _eExprLast> runtime_expressions = {
1763  {// Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap)
1764  "(int*)_"
1765  "Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocation"
1766  "CubemapFace"
1767  "(0x%" PRIx64 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", 0, 0)", // eExprGetOffsetPtr
1768 
1769  // Type* rsaAllocationGetType(Context*, Allocation*)
1770  JIT_TEMPLATE_CONTEXT "(void*)rsaAllocationGetType(ctxt, 0x%" PRIx64 ")", // eExprAllocGetType
1771 
1772  // rsaTypeGetNativeData(Context*, Type*, void* typeData, size) Pack the
1773  // data in the following way mHal.state.dimX; mHal.state.dimY;
1774  // mHal.state.dimZ; mHal.state.lodCount; mHal.state.faces; mElement;
1775  // into typeData Need to specify 32 or 64 bit for uint_t since this
1776  // differs between devices
1778  "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
1779  ", 0x%" PRIx64 ", data, 6); data[0]", // eExprTypeDimX
1781  "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
1782  ", 0x%" PRIx64 ", data, 6); data[1]", // eExprTypeDimY
1784  "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
1785  ", 0x%" PRIx64 ", data, 6); data[2]", // eExprTypeDimZ
1787  "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt"
1788  ", 0x%" PRIx64 ", data, 6); data[5]", // eExprTypeElemPtr
1789 
1790  // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
1791  // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into
1792  // elemData
1794  "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt"
1795  ", 0x%" PRIx64 ", data, 5); data[0]", // eExprElementType
1797  "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt"
1798  ", 0x%" PRIx64 ", data, 5); data[1]", // eExprElementKind
1800  "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt"
1801  ", 0x%" PRIx64 ", data, 5); data[3]", // eExprElementVec
1803  "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt"
1804  ", 0x%" PRIx64 ", data, 5); data[4]", // eExprElementFieldCount
1805 
1806  // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t
1807  // *ids, const char **names, size_t *arraySizes, uint32_t dataSize)
1808  // Needed for Allocations of structs to gather details about
1809  // fields/Subelements Element* of field
1810  JIT_TEMPLATE_CONTEXT "void* ids[%" PRIu32 "]; const char* names[%" PRIu32
1811  "]; size_t arr_size[%" PRIu32 "];"
1812  "(void*)rsaElementGetSubElements(ctxt, 0x%" PRIx64
1813  ", ids, names, arr_size, %" PRIu32 "); ids[%" PRIu32 "]", // eExprSubelementsId
1814 
1815  // Name of field
1816  JIT_TEMPLATE_CONTEXT "void* ids[%" PRIu32 "]; const char* names[%" PRIu32
1817  "]; size_t arr_size[%" PRIu32 "];"
1818  "(void*)rsaElementGetSubElements(ctxt, 0x%" PRIx64
1819  ", ids, names, arr_size, %" PRIu32 "); names[%" PRIu32 "]", // eExprSubelementsName
1820 
1821  // Array size of field
1822  JIT_TEMPLATE_CONTEXT "void* ids[%" PRIu32 "]; const char* names[%" PRIu32
1823  "]; size_t arr_size[%" PRIu32 "];"
1824  "(void*)rsaElementGetSubElements(ctxt, 0x%" PRIx64
1825  ", ids, names, arr_size, %" PRIu32 "); arr_size[%" PRIu32 "]"}}; // eExprSubelementsArrSize
1826 
1827  return runtime_expressions[e];
1828 }
1829 } // end of the anonymous namespace
1830 
1831 // JITs the RS runtime for the internal data pointer of an allocation. Is
1832 // passed x,y,z coordinates for the pointer to a specific element. Then sets
1833 // the data_ptr member in Allocation with the result. Returns true on success,
1834 // false otherwise
1835 bool RenderScriptRuntime::JITDataPointer(AllocationDetails *alloc,
1836  StackFrame *frame_ptr, uint32_t x,
1837  uint32_t y, uint32_t z) {
1839 
1840  if (!alloc->address.isValid()) {
1841  LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
1842  return false;
1843  }
1844 
1845  const char *fmt_str = JITTemplate(eExprGetOffsetPtr);
1846  char expr_buf[jit_max_expr_size];
1847 
1848  int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
1849  *alloc->address.get(), x, y, z);
1850  if (written < 0) {
1851  LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
1852  return false;
1853  } else if (written >= jit_max_expr_size) {
1854  LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
1855  return false;
1856  }
1857 
1858  uint64_t result = 0;
1859  if (!EvalRSExpression(expr_buf, frame_ptr, &result))
1860  return false;
1861 
1862  addr_t data_ptr = static_cast<lldb::addr_t>(result);
1863  alloc->data_ptr = data_ptr;
1864 
1865  return true;
1866 }
1867 
1868 // JITs the RS runtime for the internal pointer to the RS Type of an allocation
1869 // Then sets the type_ptr member in Allocation with the result. Returns true on
1870 // success, false otherwise
1871 bool RenderScriptRuntime::JITTypePointer(AllocationDetails *alloc,
1872  StackFrame *frame_ptr) {
1874 
1875  if (!alloc->address.isValid() || !alloc->context.isValid()) {
1876  LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
1877  return false;
1878  }
1879 
1880  const char *fmt_str = JITTemplate(eExprAllocGetType);
1881  char expr_buf[jit_max_expr_size];
1882 
1883  int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
1884  *alloc->context.get(), *alloc->address.get());
1885  if (written < 0) {
1886  LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
1887  return false;
1888  } else if (written >= jit_max_expr_size) {
1889  LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
1890  return false;
1891  }
1892 
1893  uint64_t result = 0;
1894  if (!EvalRSExpression(expr_buf, frame_ptr, &result))
1895  return false;
1896 
1897  addr_t type_ptr = static_cast<lldb::addr_t>(result);
1898  alloc->type_ptr = type_ptr;
1899 
1900  return true;
1901 }
1902 
1903 // JITs the RS runtime for information about the dimensions and type of an
1904 // allocation Then sets dimension and element_ptr members in Allocation with
1905 // the result. Returns true on success, false otherwise
1906 bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc,
1907  StackFrame *frame_ptr) {
1909 
1910  if (!alloc->type_ptr.isValid() || !alloc->context.isValid()) {
1911  LLDB_LOGF(log, "%s - Failed to find allocation details.", __FUNCTION__);
1912  return false;
1913  }
1914 
1915  // Expression is different depending on if device is 32 or 64 bit
1916  uint32_t target_ptr_size =
1917  GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
1918  const uint32_t bits = target_ptr_size == 4 ? 32 : 64;
1919 
1920  // We want 4 elements from packed data
1921  const uint32_t num_exprs = 4;
1922  static_assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1),
1923  "Invalid number of expressions");
1924 
1925  char expr_bufs[num_exprs][jit_max_expr_size];
1926  uint64_t results[num_exprs];
1927 
1928  for (uint32_t i = 0; i < num_exprs; ++i) {
1929  const char *fmt_str = JITTemplate(ExpressionStrings(eExprTypeDimX + i));
1930  int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str,
1931  *alloc->context.get(), bits, *alloc->type_ptr.get());
1932  if (written < 0) {
1933  LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
1934  return false;
1935  } else if (written >= jit_max_expr_size) {
1936  LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
1937  return false;
1938  }
1939 
1940  // Perform expression evaluation
1941  if (!EvalRSExpression(expr_bufs[i], frame_ptr, &results[i]))
1942  return false;
1943  }
1944 
1945  // Assign results to allocation members
1947  dims.dim_1 = static_cast<uint32_t>(results[0]);
1948  dims.dim_2 = static_cast<uint32_t>(results[1]);
1949  dims.dim_3 = static_cast<uint32_t>(results[2]);
1950  alloc->dimension = dims;
1951 
1952  addr_t element_ptr = static_cast<lldb::addr_t>(results[3]);
1953  alloc->element.element_ptr = element_ptr;
1954 
1955  LLDB_LOGF(log,
1956  "%s - dims (%" PRIu32 ", %" PRIu32 ", %" PRIu32
1957  ") Element*: 0x%" PRIx64 ".",
1958  __FUNCTION__, dims.dim_1, dims.dim_2, dims.dim_3, element_ptr);
1959 
1960  return true;
1961 }
1962 
1963 // JITs the RS runtime for information about the Element of an allocation Then
1964 // sets type, type_vec_size, field_count and type_kind members in Element with
1965 // the result. Returns true on success, false otherwise
1966 bool RenderScriptRuntime::JITElementPacked(Element &elem,
1967  const lldb::addr_t context,
1968  StackFrame *frame_ptr) {
1970 
1971  if (!elem.element_ptr.isValid()) {
1972  LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
1973  return false;
1974  }
1975 
1976  // We want 4 elements from packed data
1977  const uint32_t num_exprs = 4;
1978  static_assert(num_exprs == (eExprElementFieldCount - eExprElementType + 1),
1979  "Invalid number of expressions");
1980 
1981  char expr_bufs[num_exprs][jit_max_expr_size];
1982  uint64_t results[num_exprs];
1983 
1984  for (uint32_t i = 0; i < num_exprs; i++) {
1985  const char *fmt_str = JITTemplate(ExpressionStrings(eExprElementType + i));
1986  int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str, context,
1987  *elem.element_ptr.get());
1988  if (written < 0) {
1989  LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
1990  return false;
1991  } else if (written >= jit_max_expr_size) {
1992  LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
1993  return false;
1994  }
1995 
1996  // Perform expression evaluation
1997  if (!EvalRSExpression(expr_bufs[i], frame_ptr, &results[i]))
1998  return false;
1999  }
2000 
2001  // Assign results to allocation members
2002  elem.type = static_cast<RenderScriptRuntime::Element::DataType>(results[0]);
2003  elem.type_kind =
2004  static_cast<RenderScriptRuntime::Element::DataKind>(results[1]);
2005  elem.type_vec_size = static_cast<uint32_t>(results[2]);
2006  elem.field_count = static_cast<uint32_t>(results[3]);
2007 
2008  LLDB_LOGF(log,
2009  "%s - data type %" PRIu32 ", pixel type %" PRIu32
2010  ", vector size %" PRIu32 ", field count %" PRIu32,
2011  __FUNCTION__, *elem.type.get(), *elem.type_kind.get(),
2012  *elem.type_vec_size.get(), *elem.field_count.get());
2013 
2014  // If this Element has subelements then JIT rsaElementGetSubElements() for
2015  // details about its fields
2016  return !(*elem.field_count.get() > 0 &&
2017  !JITSubelements(elem, context, frame_ptr));
2018 }
2019 
2020 // JITs the RS runtime for information about the subelements/fields of a struct
2021 // allocation This is necessary for infering the struct type so we can pretty
2022 // print the allocation's contents. Returns true on success, false otherwise
2023 bool RenderScriptRuntime::JITSubelements(Element &elem,
2024  const lldb::addr_t context,
2025  StackFrame *frame_ptr) {
2027 
2028  if (!elem.element_ptr.isValid() || !elem.field_count.isValid()) {
2029  LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
2030  return false;
2031  }
2032 
2033  const short num_exprs = 3;
2034  static_assert(num_exprs == (eExprSubelementsArrSize - eExprSubelementsId + 1),
2035  "Invalid number of expressions");
2036 
2037  char expr_buffer[jit_max_expr_size];
2038  uint64_t results;
2039 
2040  // Iterate over struct fields.
2041  const uint32_t field_count = *elem.field_count.get();
2042  for (uint32_t field_index = 0; field_index < field_count; ++field_index) {
2043  Element child;
2044  for (uint32_t expr_index = 0; expr_index < num_exprs; ++expr_index) {
2045  const char *fmt_str =
2046  JITTemplate(ExpressionStrings(eExprSubelementsId + expr_index));
2047  int written = snprintf(expr_buffer, jit_max_expr_size, fmt_str,
2048  context, field_count, field_count, field_count,
2049  *elem.element_ptr.get(), field_count, field_index);
2050  if (written < 0) {
2051  LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
2052  return false;
2053  } else if (written >= jit_max_expr_size) {
2054  LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
2055  return false;
2056  }
2057 
2058  // Perform expression evaluation
2059  if (!EvalRSExpression(expr_buffer, frame_ptr, &results))
2060  return false;
2061 
2062  LLDB_LOGF(log, "%s - expr result 0x%" PRIx64 ".", __FUNCTION__, results);
2063 
2064  switch (expr_index) {
2065  case 0: // Element* of child
2066  child.element_ptr = static_cast<addr_t>(results);
2067  break;
2068  case 1: // Name of child
2069  {
2070  lldb::addr_t address = static_cast<addr_t>(results);
2071  Status err;
2072  std::string name;
2073  GetProcess()->ReadCStringFromMemory(address, name, err);
2074  if (!err.Fail())
2075  child.type_name = ConstString(name);
2076  else {
2077  LLDB_LOGF(log, "%s - warning: Couldn't read field name.",
2078  __FUNCTION__);
2079  }
2080  break;
2081  }
2082  case 2: // Array size of child
2083  child.array_size = static_cast<uint32_t>(results);
2084  break;
2085  }
2086  }
2087 
2088  // We need to recursively JIT each Element field of the struct since
2089  // structs can be nested inside structs.
2090  if (!JITElementPacked(child, context, frame_ptr))
2091  return false;
2092  elem.children.push_back(child);
2093  }
2094 
2095  // Try to infer the name of the struct type so we can pretty print the
2096  // allocation contents.
2097  FindStructTypeName(elem, frame_ptr);
2098 
2099  return true;
2100 }
2101 
2102 // JITs the RS runtime for the address of the last element in the allocation.
2103 // The `elem_size` parameter represents the size of a single element, including
2104 // padding. Which is needed as an offset from the last element pointer. Using
2105 // this offset minus the starting address we can calculate the size of the
2106 // allocation. Returns true on success, false otherwise
2107 bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc,
2108  StackFrame *frame_ptr) {
2110 
2111  if (!alloc->address.isValid() || !alloc->dimension.isValid() ||
2112  !alloc->data_ptr.isValid() || !alloc->element.datum_size.isValid()) {
2113  LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
2114  return false;
2115  }
2116 
2117  // Find dimensions
2118  uint32_t dim_x = alloc->dimension.get()->dim_1;
2119  uint32_t dim_y = alloc->dimension.get()->dim_2;
2120  uint32_t dim_z = alloc->dimension.get()->dim_3;
2121 
2122  // Our plan of jitting the last element address doesn't seem to work for
2123  // struct Allocations` Instead try to infer the size ourselves without any
2124  // inter element padding.
2125  if (alloc->element.children.size() > 0) {
2126  if (dim_x == 0)
2127  dim_x = 1;
2128  if (dim_y == 0)
2129  dim_y = 1;
2130  if (dim_z == 0)
2131  dim_z = 1;
2132 
2133  alloc->size = dim_x * dim_y * dim_z * *alloc->element.datum_size.get();
2134 
2135  LLDB_LOGF(log, "%s - inferred size of struct allocation %" PRIu32 ".",
2136  __FUNCTION__, *alloc->size.get());
2137  return true;
2138  }
2139 
2140  const char *fmt_str = JITTemplate(eExprGetOffsetPtr);
2141  char expr_buf[jit_max_expr_size];
2142 
2143  // Calculate last element
2144  dim_x = dim_x == 0 ? 0 : dim_x - 1;
2145  dim_y = dim_y == 0 ? 0 : dim_y - 1;
2146  dim_z = dim_z == 0 ? 0 : dim_z - 1;
2147 
2148  int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
2149  *alloc->address.get(), dim_x, dim_y, dim_z);
2150  if (written < 0) {
2151  LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
2152  return false;
2153  } else if (written >= jit_max_expr_size) {
2154  LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
2155  return false;
2156  }
2157 
2158  uint64_t result = 0;
2159  if (!EvalRSExpression(expr_buf, frame_ptr, &result))
2160  return false;
2161 
2162  addr_t mem_ptr = static_cast<lldb::addr_t>(result);
2163  // Find pointer to last element and add on size of an element
2164  alloc->size = static_cast<uint32_t>(mem_ptr - *alloc->data_ptr.get()) +
2165  *alloc->element.datum_size.get();
2166 
2167  return true;
2168 }
2169 
2170 // JITs the RS runtime for information about the stride between rows in the
2171 // allocation. This is done to detect padding, since allocated memory is
2172 // 16-byte aligned. Returns true on success, false otherwise
2173 bool RenderScriptRuntime::JITAllocationStride(AllocationDetails *alloc,
2174  StackFrame *frame_ptr) {
2176 
2177  if (!alloc->address.isValid() || !alloc->data_ptr.isValid()) {
2178  LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__);
2179  return false;
2180  }
2181 
2182  const char *fmt_str = JITTemplate(eExprGetOffsetPtr);
2183  char expr_buf[jit_max_expr_size];
2184 
2185  int written = snprintf(expr_buf, jit_max_expr_size, fmt_str,
2186  *alloc->address.get(), 0, 1, 0);
2187  if (written < 0) {
2188  LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__);
2189  return false;
2190  } else if (written >= jit_max_expr_size) {
2191  LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__);
2192  return false;
2193  }
2194 
2195  uint64_t result = 0;
2196  if (!EvalRSExpression(expr_buf, frame_ptr, &result))
2197  return false;
2198 
2199  addr_t mem_ptr = static_cast<lldb::addr_t>(result);
2200  alloc->stride = static_cast<uint32_t>(mem_ptr - *alloc->data_ptr.get());
2201 
2202  return true;
2203 }
2204 
2205 // JIT all the current runtime info regarding an allocation
2206 bool RenderScriptRuntime::RefreshAllocation(AllocationDetails *alloc,
2207  StackFrame *frame_ptr) {
2208  // GetOffsetPointer()
2209  if (!JITDataPointer(alloc, frame_ptr))
2210  return false;
2211 
2212  // rsaAllocationGetType()
2213  if (!JITTypePointer(alloc, frame_ptr))
2214  return false;
2215 
2216  // rsaTypeGetNativeData()
2217  if (!JITTypePacked(alloc, frame_ptr))
2218  return false;
2219 
2220  // rsaElementGetNativeData()
2221  if (!JITElementPacked(alloc->element, *alloc->context.get(), frame_ptr))
2222  return false;
2223 
2224  // Sets the datum_size member in Element
2225  SetElementSize(alloc->element);
2226 
2227  // Use GetOffsetPointer() to infer size of the allocation
2228  return JITAllocationSize(alloc, frame_ptr);
2229 }
2230 
2231 // Function attempts to set the type_name member of the parameterised Element
2232 // object. This string should be the name of the struct type the Element
2233 // represents. We need this string for pretty printing the Element to users.
2234 void RenderScriptRuntime::FindStructTypeName(Element &elem,
2235  StackFrame *frame_ptr) {
2237 
2238  if (!elem.type_name.IsEmpty()) // Name already set
2239  return;
2240  else
2241  elem.type_name = Element::GetFallbackStructName(); // Default type name if
2242  // we don't succeed
2243 
2244  // Find all the global variables from the script rs modules
2245  VariableList var_list;
2246  for (auto module_sp : m_rsmodules)
2247  module_sp->m_module->FindGlobalVariables(
2248  RegularExpression(llvm::StringRef(".")), UINT32_MAX, var_list);
2249 
2250  // Iterate over all the global variables looking for one with a matching type
2251  // to the Element. We make the assumption a match exists since there needs to
2252  // be a global variable to reflect the struct type back into java host code.
2253  for (const VariableSP &var_sp : var_list) {
2254  if (!var_sp)
2255  continue;
2256 
2257  ValueObjectSP valobj_sp = ValueObjectVariable::Create(frame_ptr, var_sp);
2258  if (!valobj_sp)
2259  continue;
2260 
2261  // Find the number of variable fields.
2262  // If it has no fields, or more fields than our Element, then it can't be
2263  // the struct we're looking for. Don't check for equality since RS can add
2264  // extra struct members for padding.
2265  size_t num_children = valobj_sp->GetNumChildren();
2266  if (num_children > elem.children.size() || num_children == 0)
2267  continue;
2268 
2269  // Iterate over children looking for members with matching field names. If
2270  // all the field names match, this is likely the struct we want.
2271  // TODO: This could be made more robust by also checking children data
2272  // sizes, or array size
2273  bool found = true;
2274  for (size_t i = 0; i < num_children; ++i) {
2275  ValueObjectSP child = valobj_sp->GetChildAtIndex(i, true);
2276  if (!child || (child->GetName() != elem.children[i].type_name)) {
2277  found = false;
2278  break;
2279  }
2280  }
2281 
2282  // RS can add extra struct members for padding in the format
2283  // '#rs_padding_[0-9]+'
2284  if (found && num_children < elem.children.size()) {
2285  const uint32_t size_diff = elem.children.size() - num_children;
2286  LLDB_LOGF(log, "%s - %" PRIu32 " padding struct entries", __FUNCTION__,
2287  size_diff);
2288 
2289  for (uint32_t i = 0; i < size_diff; ++i) {
2290  ConstString name = elem.children[num_children + i].type_name;
2291  if (strcmp(name.AsCString(), "#rs_padding") < 0)
2292  found = false;
2293  }
2294  }
2295 
2296  // We've found a global variable with matching type
2297  if (found) {
2298  // Dereference since our Element type isn't a pointer.
2299  if (valobj_sp->IsPointerType()) {
2300  Status err;
2301  ValueObjectSP deref_valobj = valobj_sp->Dereference(err);
2302  if (!err.Fail())
2303  valobj_sp = deref_valobj;
2304  }
2305 
2306  // Save name of variable in Element.
2307  elem.type_name = valobj_sp->GetTypeName();
2308  LLDB_LOGF(log, "%s - element name set to %s", __FUNCTION__,
2309  elem.type_name.AsCString());
2310 
2311  return;
2312  }
2313  }
2314 }
2315 
2316 // Function sets the datum_size member of Element. Representing the size of a
2317 // single instance including padding. Assumes the relevant allocation
2318 // information has already been jitted.
2319 void RenderScriptRuntime::SetElementSize(Element &elem) {
2321  const Element::DataType type = *elem.type.get();
2322  assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT &&
2323  "Invalid allocation type");
2324 
2325  const uint32_t vec_size = *elem.type_vec_size.get();
2326  uint32_t data_size = 0;
2327  uint32_t padding = 0;
2328 
2329  // Element is of a struct type, calculate size recursively.
2330  if ((type == Element::RS_TYPE_NONE) && (elem.children.size() > 0)) {
2331  for (Element &child : elem.children) {
2332  SetElementSize(child);
2333  const uint32_t array_size =
2334  child.array_size.isValid() ? *child.array_size.get() : 1;
2335  data_size += *child.datum_size.get() * array_size;
2336  }
2337  }
2338  // These have been packed already
2339  else if (type == Element::RS_TYPE_UNSIGNED_5_6_5 ||
2340  type == Element::RS_TYPE_UNSIGNED_5_5_5_1 ||
2341  type == Element::RS_TYPE_UNSIGNED_4_4_4_4) {
2342  data_size = AllocationDetails::RSTypeToFormat[type][eElementSize];
2343  } else if (type < Element::RS_TYPE_ELEMENT) {
2344  data_size =
2345  vec_size * AllocationDetails::RSTypeToFormat[type][eElementSize];
2346  if (vec_size == 3)
2347  padding = AllocationDetails::RSTypeToFormat[type][eElementSize];
2348  } else
2349  data_size =
2350  GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
2351 
2352  elem.padding = padding;
2353  elem.datum_size = data_size + padding;
2354  LLDB_LOGF(log, "%s - element size set to %" PRIu32, __FUNCTION__,
2355  data_size + padding);
2356 }
2357 
2358 // Given an allocation, this function copies the allocation contents from
2359 // device into a buffer on the heap. Returning a shared pointer to the buffer
2360 // containing the data.
2361 std::shared_ptr<uint8_t>
2362 RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc,
2363  StackFrame *frame_ptr) {
2365 
2366  // JIT all the allocation details
2367  if (alloc->ShouldRefresh()) {
2368  LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info",
2369  __FUNCTION__);
2370 
2371  if (!RefreshAllocation(alloc, frame_ptr)) {
2372  LLDB_LOGF(log, "%s - couldn't JIT allocation details", __FUNCTION__);
2373  return nullptr;
2374  }
2375  }
2376 
2377  assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() &&
2378  alloc->element.type_vec_size.isValid() && alloc->size.isValid() &&
2379  "Allocation information not available");
2380 
2381  // Allocate a buffer to copy data into
2382  const uint32_t size = *alloc->size.get();
2383  std::shared_ptr<uint8_t> buffer(new uint8_t[size]);
2384  if (!buffer) {
2385  LLDB_LOGF(log, "%s - couldn't allocate a %" PRIu32 " byte buffer",
2386  __FUNCTION__, size);
2387  return nullptr;
2388  }
2389 
2390  // Read the inferior memory
2391  Status err;
2392  lldb::addr_t data_ptr = *alloc->data_ptr.get();
2393  GetProcess()->ReadMemory(data_ptr, buffer.get(), size, err);
2394  if (err.Fail()) {
2395  LLDB_LOGF(log,
2396  "%s - '%s' Couldn't read %" PRIu32
2397  " bytes of allocation data from 0x%" PRIx64,
2398  __FUNCTION__, err.AsCString(), size, data_ptr);
2399  return nullptr;
2400  }
2401 
2402  return buffer;
2403 }
2404 
2405 // Function copies data from a binary file into an allocation. There is a
2406 // header at the start of the file, FileHeader, before the data content itself.
2407 // Information from this header is used to display warnings to the user about
2408 // incompatibilities
2409 bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id,
2410  const char *path,
2411  StackFrame *frame_ptr) {
2413 
2414  // Find allocation with the given id
2415  AllocationDetails *alloc = FindAllocByID(strm, alloc_id);
2416  if (!alloc)
2417  return false;
2418 
2419  LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64, __FUNCTION__,
2420  *alloc->address.get());
2421 
2422  // JIT all the allocation details
2423  if (alloc->ShouldRefresh()) {
2424  LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.",
2425  __FUNCTION__);
2426 
2427  if (!RefreshAllocation(alloc, frame_ptr)) {
2428  LLDB_LOGF(log, "%s - couldn't JIT allocation details", __FUNCTION__);
2429  return false;
2430  }
2431  }
2432 
2433  assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() &&
2434  alloc->element.type_vec_size.isValid() && alloc->size.isValid() &&
2435  alloc->element.datum_size.isValid() &&
2436  "Allocation information not available");
2437 
2438  // Check we can read from file
2439  FileSpec file(path);
2440  FileSystem::Instance().Resolve(file);
2441  if (!FileSystem::Instance().Exists(file)) {
2442  strm.Printf("Error: File %s does not exist", path);
2443  strm.EOL();
2444  return false;
2445  }
2446 
2447  if (!FileSystem::Instance().Readable(file)) {
2448  strm.Printf("Error: File %s does not have readable permissions", path);
2449  strm.EOL();
2450  return false;
2451  }
2452 
2453  // Read file into data buffer
2454  auto data_sp = FileSystem::Instance().CreateDataBuffer(file.GetPath());
2455 
2456  // Cast start of buffer to FileHeader and use pointer to read metadata
2457  void *file_buf = data_sp->GetBytes();
2458  if (file_buf == nullptr ||
2459  data_sp->GetByteSize() < (sizeof(AllocationDetails::FileHeader) +
2461  strm.Printf("Error: File %s does not contain enough data for header", path);
2462  strm.EOL();
2463  return false;
2464  }
2465  const AllocationDetails::FileHeader *file_header =
2466  static_cast<AllocationDetails::FileHeader *>(file_buf);
2467 
2468  // Check file starts with ascii characters "RSAD"
2469  if (memcmp(file_header->ident, "RSAD", 4)) {
2470  strm.Printf("Error: File doesn't contain identifier for an RS allocation "
2471  "dump. Are you sure this is the correct file?");
2472  strm.EOL();
2473  return false;
2474  }
2475 
2476  // Look at the type of the root element in the header
2478  memcpy(&root_el_hdr, static_cast<uint8_t *>(file_buf) +
2481 
2482  LLDB_LOGF(log, "%s - header type %" PRIu32 ", element size %" PRIu32,
2483  __FUNCTION__, root_el_hdr.type, root_el_hdr.element_size);
2484 
2485  // Check if the target allocation and file both have the same number of bytes
2486  // for an Element
2487  if (*alloc->element.datum_size.get() != root_el_hdr.element_size) {
2488  strm.Printf("Warning: Mismatched Element sizes - file %" PRIu32
2489  " bytes, allocation %" PRIu32 " bytes",
2490  root_el_hdr.element_size, *alloc->element.datum_size.get());
2491  strm.EOL();
2492  }
2493 
2494  // Check if the target allocation and file both have the same type
2495  const uint32_t alloc_type = static_cast<uint32_t>(*alloc->element.type.get());
2496  const uint32_t file_type = root_el_hdr.type;
2497 
2498  if (file_type > Element::RS_TYPE_FONT) {
2499  strm.Printf("Warning: File has unknown allocation type");
2500  strm.EOL();
2501  } else if (alloc_type != file_type) {
2502  // Enum value isn't monotonous, so doesn't always index RsDataTypeToString
2503  // array
2504  uint32_t target_type_name_idx = alloc_type;
2505  uint32_t head_type_name_idx = file_type;
2506  if (alloc_type >= Element::RS_TYPE_ELEMENT &&
2507  alloc_type <= Element::RS_TYPE_FONT)
2508  target_type_name_idx = static_cast<Element::DataType>(
2509  (alloc_type - Element::RS_TYPE_ELEMENT) +
2510  Element::RS_TYPE_MATRIX_2X2 + 1);
2511 
2512  if (file_type >= Element::RS_TYPE_ELEMENT &&
2513  file_type <= Element::RS_TYPE_FONT)
2514  head_type_name_idx = static_cast<Element::DataType>(
2515  (file_type - Element::RS_TYPE_ELEMENT) + Element::RS_TYPE_MATRIX_2X2 +
2516  1);
2517 
2518  const char *head_type_name =
2519  AllocationDetails::RsDataTypeToString[head_type_name_idx][0];
2520  const char *target_type_name =
2521  AllocationDetails::RsDataTypeToString[target_type_name_idx][0];
2522 
2523  strm.Printf(
2524  "Warning: Mismatched Types - file '%s' type, allocation '%s' type",
2525  head_type_name, target_type_name);
2526  strm.EOL();
2527  }
2528 
2529  // Advance buffer past header
2530  file_buf = static_cast<uint8_t *>(file_buf) + file_header->hdr_size;
2531 
2532  // Calculate size of allocation data in file
2533  size_t size = data_sp->GetByteSize() - file_header->hdr_size;
2534 
2535  // Check if the target allocation and file both have the same total data
2536  // size.
2537  const uint32_t alloc_size = *alloc->size.get();
2538  if (alloc_size != size) {
2539  strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64
2540  " bytes, allocation 0x%" PRIx32 " bytes",
2541  (uint64_t)size, alloc_size);
2542  strm.EOL();
2543  // Set length to copy to minimum
2544  size = alloc_size < size ? alloc_size : size;
2545  }
2546 
2547  // Copy file data from our buffer into the target allocation.
2548  lldb::addr_t alloc_data = *alloc->data_ptr.get();
2549  Status err;
2550  size_t written = GetProcess()->WriteMemory(alloc_data, file_buf, size, err);
2551  if (!err.Success() || written != size) {
2552  strm.Printf("Error: Couldn't write data to allocation %s", err.AsCString());
2553  strm.EOL();
2554  return false;
2555  }
2556 
2557  strm.Printf("Contents of file '%s' read into allocation %" PRIu32, path,
2558  alloc->id);
2559  strm.EOL();
2560 
2561  return true;
2562 }
2563 
2564 // Function takes as parameters a byte buffer, which will eventually be written
2565 // to file as the element header, an offset into that buffer, and an Element
2566 // that will be saved into the buffer at the parametrised offset. Return value
2567 // is the new offset after writing the element into the buffer. Elements are
2568 // saved to the file as the ElementHeader struct followed by offsets to the
2569 // structs of all the element's children.
2570 size_t RenderScriptRuntime::PopulateElementHeaders(
2571  const std::shared_ptr<uint8_t> header_buffer, size_t offset,
2572  const Element &elem) {
2573  // File struct for an element header with all the relevant details copied
2574  // from elem. We assume members are valid already.
2576  elem_header.type = *elem.type.get();
2577  elem_header.kind = *elem.type_kind.get();
2578  elem_header.element_size = *elem.datum_size.get();
2579  elem_header.vector_size = *elem.type_vec_size.get();
2580  elem_header.array_size =
2581  elem.array_size.isValid() ? *elem.array_size.get() : 0;
2582  const size_t elem_header_size = sizeof(AllocationDetails::ElementHeader);
2583 
2584  // Copy struct into buffer and advance offset We assume that header_buffer
2585  // has been checked for nullptr before this method is called
2586  memcpy(header_buffer.get() + offset, &elem_header, elem_header_size);
2587  offset += elem_header_size;
2588 
2589  // Starting offset of child ElementHeader struct
2590  size_t child_offset =
2591  offset + ((elem.children.size() + 1) * sizeof(uint32_t));
2592  for (const RenderScriptRuntime::Element &child : elem.children) {
2593  // Recursively populate the buffer with the element header structs of
2594  // children. Then save the offsets where they were set after the parent
2595  // element header.
2596  memcpy(header_buffer.get() + offset, &child_offset, sizeof(uint32_t));
2597  offset += sizeof(uint32_t);
2598 
2599  child_offset = PopulateElementHeaders(header_buffer, child_offset, child);
2600  }
2601 
2602  // Zero indicates no more children
2603  memset(header_buffer.get() + offset, 0, sizeof(uint32_t));
2604 
2605  return child_offset;
2606 }
2607 
2608 // Given an Element object this function returns the total size needed in the
2609 // file header to store the element's details. Taking into account the size of
2610 // the element header struct, plus the offsets to all the element's children.
2611 // Function is recursive so that the size of all ancestors is taken into
2612 // account.
2613 size_t RenderScriptRuntime::CalculateElementHeaderSize(const Element &elem) {
2614  // Offsets to children plus zero terminator
2615  size_t size = (elem.children.size() + 1) * sizeof(uint32_t);
2616  // Size of header struct with type details
2617  size += sizeof(AllocationDetails::ElementHeader);
2618 
2619  // Calculate recursively for all descendants
2620  for (const Element &child : elem.children)
2621  size += CalculateElementHeaderSize(child);
2622 
2623  return size;
2624 }
2625 
2626 // Function copies allocation contents into a binary file. This file can then
2627 // be loaded later into a different allocation. There is a header, FileHeader,
2628 // before the allocation data containing meta-data.
2629 bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id,
2630  const char *path,
2631  StackFrame *frame_ptr) {
2633 
2634  // Find allocation with the given id
2635  AllocationDetails *alloc = FindAllocByID(strm, alloc_id);
2636  if (!alloc)
2637  return false;
2638 
2639  LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64 ".", __FUNCTION__,
2640  *alloc->address.get());
2641 
2642  // JIT all the allocation details
2643  if (alloc->ShouldRefresh()) {
2644  LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.",
2645  __FUNCTION__);
2646 
2647  if (!RefreshAllocation(alloc, frame_ptr)) {
2648  LLDB_LOGF(log, "%s - couldn't JIT allocation details.", __FUNCTION__);
2649  return false;
2650  }
2651  }
2652 
2653  assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() &&
2654  alloc->element.type_vec_size.isValid() &&
2655  alloc->element.datum_size.get() &&
2656  alloc->element.type_kind.isValid() && alloc->dimension.isValid() &&
2657  "Allocation information not available");
2658 
2659  // Check we can create writable file
2660  FileSpec file_spec(path);
2661  FileSystem::Instance().Resolve(file_spec);
2662  auto file = FileSystem::Instance().Open(
2663  file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate |
2664  File::eOpenOptionTruncate);
2665 
2666  if (!file) {
2667  std::string error = llvm::toString(file.takeError());
2668  strm.Printf("Error: Failed to open '%s' for writing: %s", path,
2669  error.c_str());
2670  strm.EOL();
2671  return false;
2672  }
2673 
2674  // Read allocation into buffer of heap memory
2675  const std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
2676  if (!buffer) {
2677  strm.Printf("Error: Couldn't read allocation data into buffer");
2678  strm.EOL();
2679  return false;
2680  }
2681 
2682  // Create the file header
2684  memcpy(head.ident, "RSAD", 4);
2685  head.dims[0] = static_cast<uint32_t>(alloc->dimension.get()->dim_1);
2686  head.dims[1] = static_cast<uint32_t>(alloc->dimension.get()->dim_2);
2687  head.dims[2] = static_cast<uint32_t>(alloc->dimension.get()->dim_3);
2688 
2689  const size_t element_header_size = CalculateElementHeaderSize(alloc->element);
2690  assert((sizeof(AllocationDetails::FileHeader) + element_header_size) <
2691  UINT16_MAX &&
2692  "Element header too large");
2693  head.hdr_size = static_cast<uint16_t>(sizeof(AllocationDetails::FileHeader) +
2694  element_header_size);
2695 
2696  // Write the file header
2697  size_t num_bytes = sizeof(AllocationDetails::FileHeader);
2698  LLDB_LOGF(log, "%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__,
2699  (uint64_t)num_bytes);
2700 
2701  Status err = file.get()->Write(&head, num_bytes);
2702  if (!err.Success()) {
2703  strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path);
2704  strm.EOL();
2705  return false;
2706  }
2707 
2708  // Create the headers describing the element type of the allocation.
2709  std::shared_ptr<uint8_t> element_header_buffer(
2710  new uint8_t[element_header_size]);
2711  if (element_header_buffer == nullptr) {
2712  strm.Printf("Internal Error: Couldn't allocate %" PRIu64
2713  " bytes on the heap",
2714  (uint64_t)element_header_size);
2715  strm.EOL();
2716  return false;
2717  }
2718 
2719  PopulateElementHeaders(element_header_buffer, 0, alloc->element);
2720 
2721  // Write headers for allocation element type to file
2722  num_bytes = element_header_size;
2723  LLDB_LOGF(log, "%s - writing element headers, 0x%" PRIx64 " bytes.",
2724  __FUNCTION__, (uint64_t)num_bytes);
2725 
2726  err = file.get()->Write(element_header_buffer.get(), num_bytes);
2727  if (!err.Success()) {
2728  strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path);
2729  strm.EOL();
2730  return false;
2731  }
2732 
2733  // Write allocation data to file
2734  num_bytes = static_cast<size_t>(*alloc->size.get());
2735  LLDB_LOGF(log, "%s - writing 0x%" PRIx64 " bytes", __FUNCTION__,
2736  (uint64_t)num_bytes);
2737 
2738  err = file.get()->Write(buffer.get(), num_bytes);
2739  if (!err.Success()) {
2740  strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path);
2741  strm.EOL();
2742  return false;
2743  }
2744 
2745  strm.Printf("Allocation written to file '%s'", path);
2746  strm.EOL();
2747  return true;
2748 }
2749 
2750 bool RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) {
2752 
2753  if (module_sp) {
2754  for (const auto &rs_module : m_rsmodules) {
2755  if (rs_module->m_module == module_sp) {
2756  // Check if the user has enabled automatically breaking on all RS
2757  // kernels.
2758  if (m_breakAllKernels)
2759  BreakOnModuleKernels(rs_module);
2760 
2761  return false;
2762  }
2763  }
2764  bool module_loaded = false;
2765  switch (GetModuleKind(module_sp)) {
2766  case eModuleKindKernelObj: {
2767  RSModuleDescriptorSP module_desc;
2768  module_desc = std::make_shared<RSModuleDescriptor>(module_sp);
2769  if (module_desc->ParseRSInfo()) {
2770  m_rsmodules.push_back(module_desc);
2771  module_desc->WarnIfVersionMismatch(GetProcess()
2772  ->GetTarget()
2773  .GetDebugger()
2774  .GetAsyncOutputStream()
2775  .get());
2776  module_loaded = true;
2777  }
2778  if (module_loaded) {
2779  FixupScriptDetails(module_desc);
2780  }
2781  break;
2782  }
2783  case eModuleKindDriver: {
2784  if (!m_libRSDriver) {
2785  m_libRSDriver = module_sp;
2786  LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver);
2787  }
2788  break;
2789  }
2790  case eModuleKindImpl: {
2791  if (!m_libRSCpuRef) {
2792  m_libRSCpuRef = module_sp;
2793  LoadRuntimeHooks(m_libRSCpuRef, RenderScriptRuntime::eModuleKindImpl);
2794  }
2795  break;
2796  }
2797  case eModuleKindLibRS: {
2798  if (!m_libRS) {
2799  m_libRS = module_sp;
2800  static ConstString gDbgPresentStr("gDebuggerPresent");
2801  const Symbol *debug_present = m_libRS->FindFirstSymbolWithNameAndType(
2802  gDbgPresentStr, eSymbolTypeData);
2803  if (debug_present) {
2804  Status err;
2805  uint32_t flag = 0x00000001U;
2806  Target &target = GetProcess()->GetTarget();
2807  addr_t addr = debug_present->GetLoadAddress(&target);
2808  GetProcess()->WriteMemory(addr, &flag, sizeof(flag), err);
2809  if (err.Success()) {
2810  LLDB_LOGF(log, "%s - debugger present flag set on debugee.",
2811  __FUNCTION__);
2812 
2813  m_debuggerPresentFlagged = true;
2814  } else if (log) {
2815  LLDB_LOGF(log, "%s - error writing debugger present flags '%s' ",
2816  __FUNCTION__, err.AsCString());
2817  }
2818  } else if (log) {
2819  LLDB_LOGF(
2820  log,
2821  "%s - error writing debugger present flags - symbol not found",
2822  __FUNCTION__);
2823  }
2824  }
2825  break;
2826  }
2827  default:
2828  break;
2829  }
2830  if (module_loaded)
2831  Update();
2832  return module_loaded;
2833  }
2834  return false;
2835 }
2836 
2837 void RenderScriptRuntime::Update() {
2838  if (m_rsmodules.size() > 0) {
2839  if (!m_initiated) {
2840  Initiate();
2841  }
2842  }
2843 }
2844 
2845 void RSModuleDescriptor::WarnIfVersionMismatch(lldb_private::Stream *s) const {
2846  if (!s)
2847  return;
2848 
2849  if (m_slang_version.empty() || m_bcc_version.empty()) {
2850  s->PutCString("WARNING: Unknown bcc or slang (llvm-rs-cc) version; debug "
2851  "experience may be unreliable");
2852  s->EOL();
2853  } else if (m_slang_version != m_bcc_version) {
2854  s->Printf("WARNING: The debug info emitted by the slang frontend "
2855  "(llvm-rs-cc) used to build this module (%s) does not match the "
2856  "version of bcc used to generate the debug information (%s). "
2857  "This is an unsupported configuration and may result in a poor "
2858  "debugging experience; proceed with caution",
2859  m_slang_version.c_str(), m_bcc_version.c_str());
2860  s->EOL();
2861  }
2862 }
2863 
2864 bool RSModuleDescriptor::ParsePragmaCount(llvm::StringRef *lines,
2865  size_t n_lines) {
2866  // Skip the pragma prototype line
2867  ++lines;
2868  for (; n_lines--; ++lines) {
2869  const auto kv_pair = lines->split(" - ");
2870  m_pragmas[kv_pair.first.trim().str()] = kv_pair.second.trim().str();
2871  }
2872  return true;
2873 }
2874 
2875 bool RSModuleDescriptor::ParseExportReduceCount(llvm::StringRef *lines,
2876  size_t n_lines) {
2877  // The list of reduction kernels in the `.rs.info` symbol is of the form
2878  // "signature - accumulatordatasize - reduction_name - initializer_name -
2879  // accumulator_name - combiner_name - outconverter_name - halter_name" Where
2880  // a function is not explicitly named by the user, or is not generated by the
2881  // compiler, it is named "." so the dash separated list should always be 8
2882  // items long
2884  // Skip the exportReduceCount line
2885  ++lines;
2886  for (; n_lines--; ++lines) {
2887  llvm::SmallVector<llvm::StringRef, 8> spec;
2888  lines->split(spec, " - ");
2889  if (spec.size() != 8) {
2890  if (spec.size() < 8) {
2891  if (log)
2892  log->Error("Error parsing RenderScript reduction spec. wrong number "
2893  "of fields");
2894  return false;
2895  } else if (log)
2896  log->Warning("Extraneous members in reduction spec: '%s'",
2897  lines->str().c_str());
2898  }
2899 
2900  const auto sig_s = spec[0];
2901  uint32_t sig;
2902  if (sig_s.getAsInteger(10, sig)) {
2903  if (log)
2904  log->Error("Error parsing Renderscript reduction spec: invalid kernel "
2905  "signature: '%s'",
2906  sig_s.str().c_str());
2907  return false;
2908  }
2909 
2910  const auto accum_data_size_s = spec[1];
2911  uint32_t accum_data_size;
2912  if (accum_data_size_s.getAsInteger(10, accum_data_size)) {
2913  if (log)
2914  log->Error("Error parsing Renderscript reduction spec: invalid "
2915  "accumulator data size %s",
2916  accum_data_size_s.str().c_str());
2917  return false;
2918  }
2919 
2920  LLDB_LOGF(log, "Found RenderScript reduction '%s'", spec[2].str().c_str());
2921 
2922  m_reductions.push_back(RSReductionDescriptor(this, sig, accum_data_size,
2923  spec[2], spec[3], spec[4],
2924  spec[5], spec[6], spec[7]));
2925  }
2926  return true;
2927 }
2928 
2929 bool RSModuleDescriptor::ParseVersionInfo(llvm::StringRef *lines,
2930  size_t n_lines) {
2931  // Skip the versionInfo line
2932  ++lines;
2933  for (; n_lines--; ++lines) {
2934  // We're only interested in bcc and slang versions, and ignore all other
2935  // versionInfo lines
2936  const auto kv_pair = lines->split(" - ");
2937  if (kv_pair.first == "slang")
2938  m_slang_version = kv_pair.second.str();
2939  else if (kv_pair.first == "bcc")
2940  m_bcc_version = kv_pair.second.str();
2941  }
2942  return true;
2943 }
2944 
2945 bool RSModuleDescriptor::ParseExportForeachCount(llvm::StringRef *lines,
2946  size_t n_lines) {
2947  // Skip the exportForeachCount line
2948  ++lines;
2949  for (; n_lines--; ++lines) {
2950  uint32_t slot;
2951  // `forEach` kernels are listed in the `.rs.info` packet as a "slot - name"
2952  // pair per line
2953  const auto kv_pair = lines->split(" - ");
2954  if (kv_pair.first.getAsInteger(10, slot))
2955  return false;
2956  m_kernels.push_back(RSKernelDescriptor(this, kv_pair.second, slot));
2957  }
2958  return true;
2959 }
2960 
2961 bool RSModuleDescriptor::ParseExportVarCount(llvm::StringRef *lines,
2962  size_t n_lines) {
2963  // Skip the ExportVarCount line
2964  ++lines;
2965  for (; n_lines--; ++lines)
2966  m_globals.push_back(RSGlobalDescriptor(this, *lines));
2967  return true;
2968 }
2969 
2970 // The .rs.info symbol in renderscript modules contains a string which needs to
2971 // be parsed. The string is basic and is parsed on a line by line basis.
2972 bool RSModuleDescriptor::ParseRSInfo() {
2973  assert(m_module);
2975  const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(
2976  ConstString(".rs.info"), eSymbolTypeData);
2977  if (!info_sym)
2978  return false;
2979 
2980  const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
2981  if (addr == LLDB_INVALID_ADDRESS)
2982  return false;
2983 
2984  const addr_t size = info_sym->GetByteSize();
2985  const FileSpec fs = m_module->GetFileSpec();
2986 
2987  auto buffer =
2988  FileSystem::Instance().CreateDataBuffer(fs.GetPath(), size, addr);
2989  if (!buffer)
2990  return false;
2991 
2992  // split rs.info. contents into lines
2993  llvm::SmallVector<llvm::StringRef, 128> info_lines;
2994  {
2995  const llvm::StringRef raw_rs_info((const char *)buffer->GetBytes());
2996  raw_rs_info.split(info_lines, '\n');
2997  LLDB_LOGF(log, "'.rs.info symbol for '%s':\n%s",
2998  m_module->GetFileSpec().GetCString(), raw_rs_info.str().c_str());
2999  }
3000 
3001  enum {
3002  eExportVar,
3003  eExportForEach,
3004  eExportReduce,
3005  ePragma,
3006  eBuildChecksum,
3007  eObjectSlot,
3008  eVersionInfo,
3009  };
3010 
3011  const auto rs_info_handler = [](llvm::StringRef name) -> int {
3012  return llvm::StringSwitch<int>(name)
3013  // The number of visible global variables in the script
3014  .Case("exportVarCount", eExportVar)
3015  // The number of RenderScrip `forEach` kernels __attribute__((kernel))
3016  .Case("exportForEachCount", eExportForEach)
3017  // The number of generalreductions: This marked in the script by
3018  // `#pragma reduce()`
3019  .Case("exportReduceCount", eExportReduce)
3020  // Total count of all RenderScript specific `#pragmas` used in the
3021  // script
3022  .Case("pragmaCount", ePragma)
3023  .Case("objectSlotCount", eObjectSlot)
3024  .Case("versionInfo", eVersionInfo)
3025  .Default(-1);
3026  };
3027 
3028  // parse all text lines of .rs.info
3029  for (auto line = info_lines.begin(); line != info_lines.end(); ++line) {
3030  const auto kv_pair = line->split(": ");
3031  const auto key = kv_pair.first;
3032  const auto val = kv_pair.second.trim();
3033 
3034  const auto handler = rs_info_handler(key);
3035  if (handler == -1)
3036  continue;
3037  // getAsInteger returns `true` on an error condition - we're only
3038  // interested in numeric fields at the moment
3039  uint64_t n_lines;
3040  if (val.getAsInteger(10, n_lines)) {
3041  LLDB_LOGV(log, "Failed to parse non-numeric '.rs.info' section {0}",
3042  line->str());
3043  continue;
3044  }
3045  if (info_lines.end() - (line + 1) < (ptrdiff_t)n_lines)
3046  return false;
3047 
3048  bool success = false;
3049  switch (handler) {
3050  case eExportVar:
3051  success = ParseExportVarCount(line, n_lines);
3052  break;
3053  case eExportForEach:
3054  success = ParseExportForeachCount(line, n_lines);
3055  break;
3056  case eExportReduce:
3057  success = ParseExportReduceCount(line, n_lines);
3058  break;
3059  case ePragma:
3060  success = ParsePragmaCount(line, n_lines);
3061  break;
3062  case eVersionInfo:
3063  success = ParseVersionInfo(line, n_lines);
3064  break;
3065  default: {
3066  LLDB_LOGF(log, "%s - skipping .rs.info field '%s'", __FUNCTION__,
3067  line->str().c_str());
3068  continue;
3069  }
3070  }
3071  if (!success)
3072  return false;
3073  line += n_lines;
3074  }
3075  return info_lines.size() > 0;
3076 }
3077 
3078 void RenderScriptRuntime::DumpStatus(Stream &strm) const {
3079  if (m_libRS) {
3080  strm.Printf("Runtime Library discovered.");
3081  strm.EOL();
3082  }
3083  if (m_libRSDriver) {
3084  strm.Printf("Runtime Driver discovered.");
3085  strm.EOL();
3086  }
3087  if (m_libRSCpuRef) {
3088  strm.Printf("CPU Reference Implementation discovered.");
3089  strm.EOL();
3090  }
3091 
3092  if (m_runtimeHooks.size()) {
3093  strm.Printf("Runtime functions hooked:");
3094  strm.EOL();
3095  for (auto b : m_runtimeHooks) {
3096  strm.Indent(b.second->defn->name);
3097  strm.EOL();
3098  }
3099  } else {
3100  strm.Printf("Runtime is not hooked.");
3101  strm.EOL();
3102  }
3103 }
3104 
3105 void RenderScriptRuntime::DumpContexts(Stream &strm) const {
3106  strm.Printf("Inferred RenderScript Contexts:");
3107  strm.EOL();
3108  strm.IndentMore();
3109 
3110  std::map<addr_t, uint64_t> contextReferences;
3111 
3112  // Iterate over all of the currently discovered scripts. Note: We cant push
3113  // or pop from m_scripts inside this loop or it may invalidate script.
3114  for (const auto &script : m_scripts) {
3115  if (!script->context.isValid())
3116  continue;
3117  lldb::addr_t context = *script->context;
3118 
3119  if (contextReferences.find(context) != contextReferences.end()) {
3120  contextReferences[context]++;
3121  } else {
3122  contextReferences[context] = 1;
3123  }
3124  }
3125 
3126  for (const auto &cRef : contextReferences) {
3127  strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances",
3128  cRef.first, cRef.second);
3129  strm.EOL();
3130  }
3131  strm.IndentLess();
3132 }
3133 
3134 void RenderScriptRuntime::DumpKernels(Stream &strm) const {
3135  strm.Printf("RenderScript Kernels:");
3136  strm.EOL();
3137  strm.IndentMore();
3138  for (const auto &module : m_rsmodules) {
3139  strm.Printf("Resource '%s':", module->m_resname.c_str());
3140  strm.EOL();
3141  for (const auto &kernel : module->m_kernels) {
3142  strm.Indent(kernel.m_name.GetStringRef());
3143  strm.EOL();
3144  }
3145  }
3146  strm.IndentLess();
3147 }
3148 
3150 RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id) {
3151  AllocationDetails *alloc = nullptr;
3152 
3153  // See if we can find allocation using id as an index;
3154  if (alloc_id <= m_allocations.size() && alloc_id != 0 &&
3155  m_allocations[alloc_id - 1]->id == alloc_id) {
3156  alloc = m_allocations[alloc_id - 1].get();
3157  return alloc;
3158  }
3159 
3160  // Fallback to searching
3161  for (const auto &a : m_allocations) {
3162  if (a->id == alloc_id) {
3163  alloc = a.get();
3164  break;
3165  }
3166  }
3167 
3168  if (alloc == nullptr) {
3169  strm.Printf("Error: Couldn't find allocation with id matching %" PRIu32,
3170  alloc_id);
3171  strm.EOL();
3172  }
3173 
3174  return alloc;
3175 }
3176 
3177 // Prints the contents of an allocation to the output stream, which may be a
3178 // file
3179 bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr,
3180  const uint32_t id) {
3182 
3183  // Check we can find the desired allocation
3184  AllocationDetails *alloc = FindAllocByID(strm, id);
3185  if (!alloc)
3186  return false; // FindAllocByID() will print error message for us here
3187 
3188  LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64, __FUNCTION__,
3189  *alloc->address.get());
3190 
3191  // Check we have information about the allocation, if not calculate it
3192  if (alloc->ShouldRefresh()) {
3193  LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.",
3194  __FUNCTION__);
3195 
3196  // JIT all the allocation information
3197  if (!RefreshAllocation(alloc, frame_ptr)) {
3198  strm.Printf("Error: Couldn't JIT allocation details");
3199  strm.EOL();
3200  return false;
3201  }
3202  }
3203 
3204  // Establish format and size of each data element
3205  const uint32_t vec_size = *alloc->element.type_vec_size.get();
3206  const Element::DataType type = *alloc->element.type.get();
3207 
3208  assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT &&
3209  "Invalid allocation type");
3210 
3211  lldb::Format format;
3212  if (type >= Element::RS_TYPE_ELEMENT)
3213  format = eFormatHex;
3214  else
3215  format = vec_size == 1
3216  ? static_cast<lldb::Format>(
3217  AllocationDetails::RSTypeToFormat[type][eFormatSingle])
3218  : static_cast<lldb::Format>(
3219  AllocationDetails::RSTypeToFormat[type][eFormatVector]);
3220 
3221  const uint32_t data_size = *alloc->element.datum_size.get();
3222 
3223  LLDB_LOGF(log, "%s - element size %" PRIu32 " bytes, including padding",
3224  __FUNCTION__, data_size);
3225 
3226  // Allocate a buffer to copy data into
3227  std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
3228  if (!buffer) {
3229  strm.Printf("Error: Couldn't read allocation data");
3230  strm.EOL();
3231  return false;
3232  }
3233 
3234  // Calculate stride between rows as there may be padding at end of rows since
3235  // allocated memory is 16-byte aligned
3236  if (!alloc->stride.isValid()) {
3237  if (alloc->dimension.get()->dim_2 == 0) // We only have one dimension
3238  alloc->stride = 0;
3239  else if (!JITAllocationStride(alloc, frame_ptr)) {
3240  strm.Printf("Error: Couldn't calculate allocation row stride");
3241  strm.EOL();
3242  return false;
3243  }
3244  }
3245  const uint32_t stride = *alloc->stride.get();
3246  const uint32_t size = *alloc->size.get(); // Size of whole allocation
3247  const uint32_t padding =
3248  alloc->element.padding.isValid() ? *alloc->element.padding.get() : 0;
3249  LLDB_LOGF(log,
3250  "%s - stride %" PRIu32 " bytes, size %" PRIu32
3251  " bytes, padding %" PRIu32,
3252  __FUNCTION__, stride, size, padding);
3253 
3254  // Find dimensions used to index loops, so need to be non-zero
3255  uint32_t dim_x = alloc->dimension.get()->dim_1;
3256  dim_x = dim_x == 0 ? 1 : dim_x;
3257 
3258  uint32_t dim_y = alloc->dimension.get()->dim_2;
3259  dim_y = dim_y == 0 ? 1 : dim_y;
3260 
3261  uint32_t dim_z = alloc->dimension.get()->dim_3;
3262  dim_z = dim_z == 0 ? 1 : dim_z;
3263 
3264  // Use data extractor to format output
3265  const uint32_t target_ptr_size =
3266  GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
3267  DataExtractor alloc_data(buffer.get(), size, GetProcess()->GetByteOrder(),
3268  target_ptr_size);
3269 
3270  uint32_t offset = 0; // Offset in buffer to next element to be printed
3271  uint32_t prev_row = 0; // Offset to the start of the previous row
3272 
3273  // Iterate over allocation dimensions, printing results to user
3274  strm.Printf("Data (X, Y, Z):");
3275  for (uint32_t z = 0; z < dim_z; ++z) {
3276  for (uint32_t y = 0; y < dim_y; ++y) {
3277  // Use stride to index start of next row.
3278  if (!(y == 0 && z == 0))
3279  offset = prev_row + stride;
3280  prev_row = offset;
3281 
3282  // Print each element in the row individually
3283  for (uint32_t x = 0; x < dim_x; ++x) {
3284  strm.Printf("\n(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ") = ", x, y, z);
3285  if ((type == Element::RS_TYPE_NONE) &&
3286  (alloc->element.children.size() > 0) &&
3287  (alloc->element.type_name != Element::GetFallbackStructName())) {
3288  // Here we are dumping an Element of struct type. This is done using
3289  // expression evaluation with the name of the struct type and pointer
3290  // to element. Don't print the name of the resulting expression,
3291  // since this will be '$[0-9]+'
3292  DumpValueObjectOptions expr_options;
3293  expr_options.SetHideName(true);
3294 
3295  // Setup expression as dereferencing a pointer cast to element
3296  // address.
3297  char expr_char_buffer[jit_max_expr_size];
3298  int written =
3299  snprintf(expr_char_buffer, jit_max_expr_size, "*(%s*) 0x%" PRIx64,
3300  alloc->element.type_name.AsCString(),
3301  *alloc->data_ptr.get() + offset);
3302 
3303  if (written < 0 || written >= jit_max_expr_size) {
3304  LLDB_LOGF(log, "%s - error in snprintf().", __FUNCTION__);
3305  continue;
3306  }
3307 
3308  // Evaluate expression
3309  ValueObjectSP expr_result;
3310  GetProcess()->GetTarget().EvaluateExpression(expr_char_buffer,
3311  frame_ptr, expr_result);
3312 
3313  // Print the results to our stream.
3314  expr_result->Dump(strm, expr_options);
3315  } else {
3316  DumpDataExtractor(alloc_data, &strm, offset, format,
3317  data_size - padding, 1, 1, LLDB_INVALID_ADDRESS, 0,
3318  0);
3319  }
3320  offset += data_size;
3321  }
3322  }
3323  }
3324  strm.EOL();
3325 
3326  return true;
3327 }
3328 
3329 // Function recalculates all our cached information about allocations by
3330 // jitting the RS runtime regarding each allocation we know about. Returns true
3331 // if all allocations could be recomputed, false otherwise.
3332 bool RenderScriptRuntime::RecomputeAllAllocations(Stream &strm,
3333  StackFrame *frame_ptr) {
3334  bool success = true;
3335  for (auto &alloc : m_allocations) {
3336  // JIT current allocation information
3337  if (!RefreshAllocation(alloc.get(), frame_ptr)) {
3338  strm.Printf("Error: Couldn't evaluate details for allocation %" PRIu32
3339  "\n",
3340  alloc->id);
3341  success = false;
3342  }
3343  }
3344 
3345  if (success)
3346  strm.Printf("All allocations successfully recomputed");
3347  strm.EOL();
3348 
3349  return success;
3350 }
3351 
3352 // Prints information regarding currently loaded allocations. These details are
3353 // gathered by jitting the runtime, which has as latency. Index parameter
3354 // specifies a single allocation ID to print, or a zero value to print them all
3355 void RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame *frame_ptr,
3356  const uint32_t index) {
3357  strm.Printf("RenderScript Allocations:");
3358  strm.EOL();
3359  strm.IndentMore();
3360 
3361  for (auto &alloc : m_allocations) {
3362  // index will only be zero if we want to print all allocations
3363  if (index != 0 && index != alloc->id)
3364  continue;
3365 
3366  // JIT current allocation information
3367  if (alloc->ShouldRefresh() && !RefreshAllocation(alloc.get(), frame_ptr)) {
3368  strm.Printf("Error: Couldn't evaluate details for allocation %" PRIu32,
3369  alloc->id);
3370  strm.EOL();
3371  continue;
3372  }
3373 
3374  strm.Printf("%" PRIu32 ":", alloc->id);
3375  strm.EOL();
3376  strm.IndentMore();
3377 
3378  strm.Indent("Context: ");
3379  if (!alloc->context.isValid())
3380  strm.Printf("unknown\n");
3381  else
3382  strm.Printf("0x%" PRIx64 "\n", *alloc->context.get());
3383 
3384  strm.Indent("Address: ");
3385  if (!alloc->address.isValid())
3386  strm.Printf("unknown\n");
3387  else
3388  strm.Printf("0x%" PRIx64 "\n", *alloc->address.get());
3389 
3390  strm.Indent("Data pointer: ");
3391  if (!alloc->data_ptr.isValid())
3392  strm.Printf("unknown\n");
3393  else
3394  strm.Printf("0x%" PRIx64 "\n", *alloc->data_ptr.get());
3395 
3396  strm.Indent("Dimensions: ");
3397  if (!alloc->dimension.isValid())
3398  strm.Printf("unknown\n");
3399  else
3400  strm.Printf("(%" PRId32 ", %" PRId32 ", %" PRId32 ")\n",
3401  alloc->dimension.get()->dim_1, alloc->dimension.get()->dim_2,
3402  alloc->dimension.get()->dim_3);
3403 
3404  strm.Indent("Data Type: ");
3405  if (!alloc->element.type.isValid() ||
3406  !alloc->element.type_vec_size.isValid())
3407  strm.Printf("unknown\n");
3408  else {
3409  const int vector_size = *alloc->element.type_vec_size.get();
3410  Element::DataType type = *alloc->element.type.get();
3411 
3412  if (!alloc->element.type_name.IsEmpty())
3413  strm.Printf("%s\n", alloc->element.type_name.AsCString());
3414  else {
3415  // Enum value isn't monotonous, so doesn't always index
3416  // RsDataTypeToString array
3417  if (type >= Element::RS_TYPE_ELEMENT && type <= Element::RS_TYPE_FONT)
3418  type =
3419  static_cast<Element::DataType>((type - Element::RS_TYPE_ELEMENT) +
3420  Element::RS_TYPE_MATRIX_2X2 + 1);
3421 
3422  if (type >= (sizeof(AllocationDetails::RsDataTypeToString) /
3423  sizeof(AllocationDetails::RsDataTypeToString[0])) ||
3424  vector_size > 4 || vector_size < 1)
3425  strm.Printf("invalid type\n");
3426  else
3427  strm.Printf(
3428  "%s\n",
3429  AllocationDetails::RsDataTypeToString[static_cast<uint32_t>(type)]
3430  [vector_size - 1]);
3431  }
3432  }
3433 
3434  strm.Indent("Data Kind: ");
3435  if (!alloc->element.type_kind.isValid())
3436  strm.Printf("unknown\n");
3437  else {
3438  const Element::DataKind kind = *alloc->element.type_kind.get();
3439  if (kind < Element::RS_KIND_USER || kind > Element::RS_KIND_PIXEL_YUV)
3440  strm.Printf("invalid kind\n");
3441  else
3442  strm.Printf(
3443  "%s\n",
3444  AllocationDetails::RsDataKindToString[static_cast<uint32_t>(kind)]);
3445  }
3446 
3447  strm.EOL();
3448  strm.IndentLess();
3449  }
3450  strm.IndentLess();
3451 }
3452 
3453 // Set breakpoints on every kernel found in RS module
3454 void RenderScriptRuntime::BreakOnModuleKernels(
3455  const RSModuleDescriptorSP rsmodule_sp) {
3456  for (const auto &kernel : rsmodule_sp->m_kernels) {
3457  // Don't set breakpoint on 'root' kernel
3458  if (strcmp(kernel.m_name.AsCString(), "root") == 0)
3459  continue;
3460 
3461  CreateKernelBreakpoint(kernel.m_name);
3462  }
3463 }
3464 
3465 // Method is internally called by the 'kernel breakpoint all' command to enable
3466 // or disable breaking on all kernels. When do_break is true we want to enable
3467 // this functionality. When do_break is false we want to disable it.
3468 void RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target) {
3469  Log *log(
3471 
3472  InitSearchFilter(target);
3473 
3474  // Set breakpoints on all the kernels
3475  if (do_break && !m_breakAllKernels) {
3476  m_breakAllKernels = true;
3477 
3478  for (const auto &module : m_rsmodules)
3479  BreakOnModuleKernels(module);
3480 
3481  LLDB_LOGF(log,
3482  "%s(True) - breakpoints set on all currently loaded kernels.",
3483  __FUNCTION__);
3484  } else if (!do_break &&
3485  m_breakAllKernels) // Breakpoints won't be set on any new kernels.
3486  {
3487  m_breakAllKernels = false;
3488 
3489  LLDB_LOGF(log, "%s(False) - breakpoints no longer automatically set.",
3490  __FUNCTION__);
3491  }
3492 }
3493 
3494 // Given the name of a kernel this function creates a breakpoint using our own
3495 // breakpoint resolver, and returns the Breakpoint shared pointer.
3496 BreakpointSP
3497 RenderScriptRuntime::CreateKernelBreakpoint(ConstString name) {
3498  Log *log(
3500 
3501  if (!m_filtersp) {
3502  LLDB_LOGF(log, "%s - error, no breakpoint search filter set.",
3503  __FUNCTION__);
3504  return nullptr;
3505  }
3506 
3507  BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
3508  Target &target = GetProcess()->GetTarget();
3509  BreakpointSP bp = target.CreateBreakpoint(
3510  m_filtersp, resolver_sp, false, false, false);
3511 
3512  // Give RS breakpoints a specific name, so the user can manipulate them as a
3513  // group.
3514  Status err;
3515  target.AddNameToBreakpoint(bp, "RenderScriptKernel", err);
3516  if (err.Fail() && log)
3517  LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__,
3518  err.AsCString());
3519 
3520  return bp;
3521 }
3522 
3523 BreakpointSP
3524 RenderScriptRuntime::CreateReductionBreakpoint(ConstString name,
3525  int kernel_types) {
3526  Log *log(
3528 
3529  if (!m_filtersp) {
3530  LLDB_LOGF(log, "%s - error, no breakpoint search filter set.",
3531  __FUNCTION__);
3532  return nullptr;
3533  }
3534 
3535  BreakpointResolverSP resolver_sp(new RSReduceBreakpointResolver(
3536  nullptr, name, &m_rsmodules, kernel_types));
3537  Target &target = GetProcess()->GetTarget();
3538  BreakpointSP bp = target.CreateBreakpoint(
3539  m_filtersp, resolver_sp, false, false, false);
3540 
3541  // Give RS breakpoints a specific name, so the user can manipulate them as a
3542  // group.
3543  Status err;
3544  target.AddNameToBreakpoint(bp, "RenderScriptReduction", err);
3545  if (err.Fail() && log)
3546  LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__,
3547  err.AsCString());
3548 
3549  return bp;
3550 }
3551 
3552 // Given an expression for a variable this function tries to calculate the
3553 // variable's value. If this is possible it returns true and sets the uint64_t
3554 // parameter to the variables unsigned value. Otherwise function returns false.
3555 bool RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp,
3556  const char *var_name,
3557  uint64_t &val) {
3559  Status err;
3560  VariableSP var_sp;
3561 
3562  // Find variable in stack frame
3563  ValueObjectSP value_sp(frame_sp->GetValueForVariableExpressionPath(
3564  var_name, eNoDynamicValues,
3565  StackFrame::eExpressionPathOptionCheckPtrVsMember |
3566  StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
3567  var_sp, err));
3568  if (!err.Success()) {
3569  LLDB_LOGF(log, "%s - error, couldn't find '%s' in frame", __FUNCTION__,
3570  var_name);
3571  return false;
3572  }
3573 
3574  // Find the uint32_t value for the variable
3575  bool success = false;
3576  val = value_sp->GetValueAsUnsigned(0, &success);
3577  if (!success) {
3578  LLDB_LOGF(log, "%s - error, couldn't parse '%s' as an uint32_t.",
3579  __FUNCTION__, var_name);
3580  return false;
3581  }
3582 
3583  return true;
3584 }
3585 
3586 // Function attempts to find the current coordinate of a kernel invocation by
3587 // investigating the values of frame variables in the .expand function. These
3588 // coordinates are returned via the coord array reference parameter. Returns
3589 // true if the coordinates could be found, and false otherwise.
3590 bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord,
3591  Thread *thread_ptr) {
3592  static const char *const x_expr = "rsIndex";
3593  static const char *const y_expr = "p->current.y";
3594  static const char *const z_expr = "p->current.z";
3595 
3597 
3598  if (!thread_ptr) {
3599  LLDB_LOGF(log, "%s - Error, No thread pointer", __FUNCTION__);
3600 
3601  return false;
3602  }
3603 
3604  // Walk the call stack looking for a function whose name has the suffix
3605  // '.expand' and contains the variables we're looking for.
3606  for (uint32_t i = 0; i < thread_ptr->GetStackFrameCount(); ++i) {
3607  if (!thread_ptr->SetSelectedFrameByIndex(i))
3608  continue;
3609 
3610  StackFrameSP frame_sp = thread_ptr->GetSelectedFrame();
3611  if (!frame_sp)
3612  continue;
3613 
3614  // Find the function name
3615  const SymbolContext sym_ctx =
3616  frame_sp->GetSymbolContext(eSymbolContextFunction);
3617  const ConstString func_name = sym_ctx.GetFunctionName();
3618  if (!func_name)
3619  continue;
3620 
3621  LLDB_LOGF(log, "%s - Inspecting function '%s'", __FUNCTION__,
3622  func_name.GetCString());
3623 
3624  // Check if function name has .expand suffix
3625  if (!func_name.GetStringRef().endswith(".expand"))
3626  continue;
3627 
3628  LLDB_LOGF(log, "%s - Found .expand function '%s'", __FUNCTION__,
3629  func_name.GetCString());
3630 
3631  // Get values for variables in .expand frame that tell us the current
3632  // kernel invocation
3633  uint64_t x, y, z;
3634  bool found = GetFrameVarAsUnsigned(frame_sp, x_expr, x) &&
3635  GetFrameVarAsUnsigned(frame_sp, y_expr, y) &&
3636  GetFrameVarAsUnsigned(frame_sp, z_expr, z);
3637 
3638  if (found) {
3639  // The RenderScript runtime uses uint32_t for these vars. If they're not
3640  // within bounds, our frame parsing is garbage
3641  assert(x <= UINT32_MAX && y <= UINT32_MAX && z <= UINT32_MAX);
3642  coord.x = (uint32_t)x;
3643  coord.y = (uint32_t)y;
3644  coord.z = (uint32_t)z;
3645  return true;
3646  }
3647  }
3648  return false;
3649 }
3650 
3651 // Callback when a kernel breakpoint hits and we're looking for a specific
3652 // coordinate. Baton parameter contains a pointer to the target coordinate we
3653 // want to break on. Function then checks the .expand frame for the current
3654 // coordinate and breaks to user if it matches. Parameter 'break_id' is the id
3655 // of the Breakpoint which made the callback. Parameter 'break_loc_id' is the
3656 // id for the BreakpointLocation which was hit, a single logical breakpoint can
3657 // have multiple addresses.
3658 bool RenderScriptRuntime::KernelBreakpointHit(void *baton,
3660  user_id_t break_id,
3661  user_id_t break_loc_id) {
3662  Log *log(
3664 
3665  assert(baton &&
3666  "Error: null baton in conditional kernel breakpoint callback");
3667 
3668  // Coordinate we want to stop on
3669  RSCoordinate target_coord = *static_cast<RSCoordinate *>(baton);
3670 
3671  LLDB_LOGF(log, "%s - Break ID %" PRIu64 ", " FMT_COORD, __FUNCTION__,
3672  break_id, target_coord.x, target_coord.y, target_coord.z);
3673 
3674  // Select current thread
3675  ExecutionContext context(ctx->exe_ctx_ref);
3676  Thread *thread_ptr = context.GetThreadPtr();
3677  assert(thread_ptr && "Null thread pointer");
3678 
3679  // Find current kernel invocation from .expand frame variables
3680  RSCoordinate current_coord{};
3681  if (!GetKernelCoordinate(current_coord, thread_ptr)) {
3682  LLDB_LOGF(log, "%s - Error, couldn't select .expand stack frame",
3683  __FUNCTION__);
3684  return false;
3685  }
3686 
3687  LLDB_LOGF(log, "%s - " FMT_COORD, __FUNCTION__, current_coord.x,
3688  current_coord.y, current_coord.z);
3689 
3690  // Check if the current kernel invocation coordinate matches our target
3691  // coordinate
3692  if (target_coord == current_coord) {
3693  LLDB_LOGF(log, "%s, BREAKING " FMT_COORD, __FUNCTION__, current_coord.x,
3694  current_coord.y, current_coord.z);
3695 
3696  BreakpointSP breakpoint_sp =
3697  context.GetTargetPtr()->GetBreakpointByID(break_id);
3698  assert(breakpoint_sp != nullptr &&
3699  "Error: Couldn't find breakpoint matching break id for callback");
3700  breakpoint_sp->SetEnabled(false); // Optimise since conditional breakpoint
3701  // should only be hit once.
3702  return true;
3703  }
3704 
3705  // No match on coordinate
3706  return false;
3707 }
3708 
3709 void RenderScriptRuntime::SetConditional(BreakpointSP bp, Stream &messages,
3710  const RSCoordinate &coord) {
3711  messages.Printf("Conditional kernel breakpoint on coordinate " FMT_COORD,
3712  coord.x, coord.y, coord.z);
3713  messages.EOL();
3714 
3715  // Allocate memory for the baton, and copy over coordinate
3716  RSCoordinate *baton = new RSCoordinate(coord);
3717 
3718  // Create a callback that will be invoked every time the breakpoint is hit.
3719  // The baton object passed to the handler is the target coordinate we want to
3720  // break on.
3721  bp->SetCallback(KernelBreakpointHit, baton, true);
3722 
3723  // Store a shared pointer to the baton, so the memory will eventually be
3724  // cleaned up after destruction
3725  m_conditional_breaks[bp->GetID()] = std::unique_ptr<RSCoordinate>(baton);
3726 }
3727 
3728 // Tries to set a breakpoint on the start of a kernel, resolved using the
3729 // kernel name. Argument 'coords', represents a three dimensional coordinate
3730 // which can be used to specify a single kernel instance to break on. If this
3731 // is set then we add a callback to the breakpoint.
3732 bool RenderScriptRuntime::PlaceBreakpointOnKernel(TargetSP target,
3733  Stream &messages,
3734  const char *name,
3735  const RSCoordinate *coord) {
3736  if (!name)
3737  return false;
3738 
3739  InitSearchFilter(target);
3740 
3741  ConstString kernel_name(name);
3742  BreakpointSP bp = CreateKernelBreakpoint(kernel_name);
3743  if (!bp)
3744  return false;
3745 
3746  // We have a conditional breakpoint on a specific coordinate
3747  if (coord)
3748  SetConditional(bp, messages, *coord);
3749 
3750  bp->GetDescription(&messages, lldb::eDescriptionLevelInitial, false);
3751 
3752  return true;
3753 }
3754 
3755 BreakpointSP
3756 RenderScriptRuntime::CreateScriptGroupBreakpoint(ConstString name,
3757  bool stop_on_all) {
3758  Log *log(
3760 
3761  if (!m_filtersp) {
3762  LLDB_LOGF(log, "%s - error, no breakpoint search filter set.",
3763  __FUNCTION__);
3764  return nullptr;
3765  }
3766 
3767  BreakpointResolverSP resolver_sp(new RSScriptGroupBreakpointResolver(
3768  nullptr, name, m_scriptGroups, stop_on_all));
3769  Target &target = GetProcess()->GetTarget();
3770  BreakpointSP bp = target.CreateBreakpoint(
3771  m_filtersp, resolver_sp, false, false, false);
3772  // Give RS breakpoints a specific name, so the user can manipulate them as a
3773  // group.
3774  Status err;
3775  target.AddNameToBreakpoint(bp, name.GetCString(), err);
3776  if (err.Fail() && log)
3777  LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__,
3778  err.AsCString());
3779  // ask the breakpoint to resolve itself
3780  bp->ResolveBreakpoint();
3781  return bp;
3782 }
3783 
3784 bool RenderScriptRuntime::PlaceBreakpointOnScriptGroup(TargetSP target,
3785  Stream &strm,
3786  ConstString name,
3787  bool multi) {
3788  InitSearchFilter(target);
3789  BreakpointSP bp = CreateScriptGroupBreakpoint(name, multi);
3790  if (bp)
3791  bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
3792  return bool(bp);
3793 }
3794 
3795 bool RenderScriptRuntime::PlaceBreakpointOnReduction(TargetSP target,
3796  Stream &messages,
3797  const char *reduce_name,
3798  const RSCoordinate *coord,
3799  int kernel_types) {
3800  if (!reduce_name)
3801  return false;
3802 
3803  InitSearchFilter(target);
3804  BreakpointSP bp =
3805  CreateReductionBreakpoint(ConstString(reduce_name), kernel_types);
3806  if (!bp)
3807  return false;
3808 
3809  if (coord)
3810  SetConditional(bp, messages, *coord);
3811 
3812  bp->GetDescription(&messages, lldb::eDescriptionLevelInitial, false);
3813 
3814  return true;
3815 }
3816 
3817 void RenderScriptRuntime::DumpModules(Stream &strm) const {
3818  strm.Printf("RenderScript Modules:");
3819  strm.EOL();
3820  strm.IndentMore();
3821  for (const auto &module : m_rsmodules) {
3822  module->Dump(strm);
3823  }
3824  strm.IndentLess();
3825 }
3826 
3828 RenderScriptRuntime::LookUpScript(addr_t address, bool create) {
3829  for (const auto &s : m_scripts) {
3830  if (s->script.isValid())
3831  if (*s->script == address)
3832  return s.get();
3833  }
3834  if (create) {
3835  std::unique_ptr<ScriptDetails> s(new ScriptDetails);
3836  s->script = address;
3837  m_scripts.push_back(std::move(s));
3838  return m_scripts.back().get();
3839  }
3840  return nullptr;
3841 }
3842 
3844 RenderScriptRuntime::LookUpAllocation(addr_t address) {
3845  for (const auto &a : m_allocations) {
3846  if (a->address.isValid())
3847  if (*a->address == address)
3848  return a.get();
3849  }
3850  return nullptr;
3851 }
3852 
3854 RenderScriptRuntime::CreateAllocation(addr_t address) {
3856 
3857  // Remove any previous allocation which contains the same address
3858  auto it = m_allocations.begin();
3859  while (it != m_allocations.end()) {
3860  if (*((*it)->address) == address) {
3861  LLDB_LOGF(log, "%s - Removing allocation id: %d, address: 0x%" PRIx64,
3862  __FUNCTION__, (*it)->id, address);
3863 
3864  it = m_allocations.erase(it);
3865  } else {
3866  it++;
3867  }
3868  }
3869 
3870  std::unique_ptr<AllocationDetails> a(new AllocationDetails);
3871  a->address = address;
3872  m_allocations.push_back(std::move(a));
3873  return m_allocations.back().get();
3874 }
3875 
3876 bool RenderScriptRuntime::ResolveKernelName(lldb::addr_t kernel_addr,
3877  ConstString &name) {
3879 
3880  Target &target = GetProcess()->GetTarget();
3881  Address resolved;
3882  // RenderScript module
3883  if (!target.GetSectionLoadList().ResolveLoadAddress(kernel_addr, resolved)) {
3884  LLDB_LOGF(log, "%s: unable to resolve 0x%" PRIx64 " to a loaded symbol",
3885  __FUNCTION__, kernel_addr);
3886  return false;
3887  }
3888 
3889  Symbol *sym = resolved.CalculateSymbolContextSymbol();
3890  if (!sym)
3891  return false;
3892 
3893  name = sym->GetName();
3894  assert(IsRenderScriptModule(resolved.CalculateSymbolContextModule()));
3895  LLDB_LOGF(log, "%s: 0x%" PRIx64 " resolved to the symbol '%s'", __FUNCTION__,
3896  kernel_addr, name.GetCString());
3897  return true;
3898 }
3899 
3900 void RSModuleDescriptor::Dump(Stream &strm) const {
3901  int indent = strm.GetIndentLevel();
3902 
3903  strm.Indent();
3904  m_module->GetFileSpec().Dump(strm.AsRawOstream());
3905  strm.Indent(m_module->GetNumCompileUnits() ? "Debug info loaded."
3906  : "Debug info does not exist.");
3907  strm.EOL();
3908  strm.IndentMore();
3909 
3910  strm.Indent();
3911  strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size()));
3912  strm.EOL();
3913  strm.IndentMore();
3914  for (const auto &global : m_globals) {
3915  global.Dump(strm);
3916  }
3917  strm.IndentLess();
3918 
3919  strm.Indent();
3920  strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size()));
3921  strm.EOL();
3922  strm.IndentMore();
3923  for (const auto &kernel : m_kernels) {
3924  kernel.Dump(strm);
3925  }
3926  strm.IndentLess();
3927 
3928  strm.Indent();
3929  strm.Printf("Pragmas: %" PRIu64, static_cast<uint64_t>(m_pragmas.size()));
3930  strm.EOL();
3931  strm.IndentMore();
3932  for (const auto &key_val : m_pragmas) {
3933  strm.Indent();
3934  strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str());
3935  strm.EOL();
3936  }
3937  strm.IndentLess();
3938 
3939  strm.Indent();
3940  strm.Printf("Reductions: %" PRIu64,
3941  static_cast<uint64_t>(m_reductions.size()));
3942  strm.EOL();
3943  strm.IndentMore();
3944  for (const auto &reduction : m_reductions) {
3945  reduction.Dump(strm);
3946  }
3947 
3948  strm.SetIndentLevel(indent);
3949 }
3950 
3951 void RSGlobalDescriptor::Dump(Stream &strm) const {
3952  strm.Indent(m_name.GetStringRef());
3953  VariableList var_list;
3954  m_module->m_module->FindGlobalVariables(m_name, CompilerDeclContext(), 1U,
3955  var_list);
3956  if (var_list.GetSize() == 1) {
3957  auto var = var_list.GetVariableAtIndex(0);
3958  auto type = var->GetType();
3959  if (type) {
3960  strm.Printf(" - ");
3961  type->DumpTypeName(&strm);
3962  } else {
3963  strm.Printf(" - Unknown Type");
3964  }
3965  } else {
3966  strm.Printf(" - variable identified, but not found in binary");
3967  const Symbol *s = m_module->m_module->FindFirstSymbolWithNameAndType(
3968  m_name, eSymbolTypeData);
3969  if (s) {
3970  strm.Printf(" (symbol exists) ");
3971  }
3972  }
3973 
3974  strm.EOL();
3975 }
3976 
3977 void RSKernelDescriptor::Dump(Stream &strm) const {
3978  strm.Indent(m_name.GetStringRef());
3979  strm.EOL();
3980 }
3981 
3982 void RSReductionDescriptor::Dump(lldb_private::Stream &stream) const {
3983  stream.Indent(m_reduce_name.GetStringRef());
3984  stream.IndentMore();
3985  stream.EOL();
3986  stream.Indent();
3987  stream.Printf("accumulator: %s", m_accum_name.AsCString());
3988  stream.EOL();
3989  stream.Indent();
3990  stream.Printf("initializer: %s", m_init_name.AsCString());
3991  stream.EOL();
3992  stream.Indent();
3993  stream.Printf("combiner: %s", m_comb_name.AsCString());
3994  stream.EOL();
3995  stream.Indent();
3996  stream.Printf("outconverter: %s", m_outc_name.AsCString());
3997  stream.EOL();
3998  // XXX This is currently unspecified by RenderScript, and unused
3999  // stream.Indent();
4000  // stream.Printf("halter: '%s'", m_init_name.AsCString());
4001  // stream.EOL();
4002  stream.IndentLess();
4003 }
4004 
4006 public:
4009  interpreter, "renderscript module dump",
4010  "Dumps renderscript specific information for all modules.",
4011  "renderscript module dump",
4012  eCommandRequiresProcess | eCommandProcessMustBeLaunched) {}
4013 
4014  ~CommandObjectRenderScriptRuntimeModuleDump() override = default;
4015 
4016  bool DoExecute(Args &command, CommandReturnObject &result) override {
4017  RenderScriptRuntime *runtime = llvm::cast<RenderScriptRuntime>(
4018  m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4020  runtime->DumpModules(result.GetOutputStream());
4022  return true;
4023  }
4024 };
4025 
4027 public:
4029  : CommandObjectMultiword(interpreter, "renderscript module",
4030  "Commands that deal with RenderScript modules.",
4031  nullptr) {
4032  LoadSubCommand(
4033  "dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(
4034  interpreter)));
4035  }
4036 
4037  ~CommandObjectRenderScriptRuntimeModule() override = default;
4038 };
4039 
4041 public:
4044  interpreter, "renderscript kernel list",
4045  "Lists renderscript kernel names and associated script resources.",
4046  "renderscript kernel list",
4047  eCommandRequiresProcess | eCommandProcessMustBeLaunched) {}
4048 
4049  ~CommandObjectRenderScriptRuntimeKernelList() override = default;
4050 
4051  bool DoExecute(Args &command, CommandReturnObject &result) override {
4052  RenderScriptRuntime *runtime = llvm::cast<RenderScriptRuntime>(
4053  m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4055  runtime->DumpKernels(result.GetOutputStream());
4057  return true;
4058  }
4059 };
4060 
4062  {LLDB_OPT_SET_1, false, "function-role", 't',
4063  OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner,
4064  "Break on a comma separated set of reduction kernel types "
4065  "(accumulator,outcoverter,combiner,initializer"},
4066  {LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument,
4067  nullptr, {}, 0, eArgTypeValue,
4068  "Set a breakpoint on a single invocation of the kernel with specified "
4069  "coordinate.\n"
4070  "Coordinate takes the form 'x[,y][,z] where x,y,z are positive "
4071  "integers representing kernel dimensions. "
4072  "Any unset dimensions will be defaulted to zero."}};
4073 
4075  : public CommandObjectParsed {
4076 public:
4078  CommandInterpreter &interpreter)
4080  interpreter, "renderscript reduction breakpoint set",
4081  "Set a breakpoint on named RenderScript general reductions",
4082  "renderscript reduction breakpoint set <kernel_name> [-t "
4083  "<reduction_kernel_type,...>]",
4084  eCommandRequiresProcess | eCommandProcessMustBeLaunched |
4085  eCommandProcessMustBePaused),
4086  m_options(){};
4087 
4088  class CommandOptions : public Options {
4089  public:
4091 
4092  ~CommandOptions() override = default;
4093 
4094  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4095  ExecutionContext *exe_ctx) override {
4096  Status err;
4097  StreamString err_str;
4098  const int short_option = m_getopt_table[option_idx].val;
4099  switch (short_option) {
4100  case 't':
4101  if (!ParseReductionTypes(option_arg, err_str))
4103  "Unable to deduce reduction types for %s: %s",
4104  option_arg.str().c_str(), err_str.GetData());
4105  break;
4106  case 'c': {
4107  auto coord = RSCoordinate{};
4108  if (!ParseCoordinate(option_arg, coord))
4109  err.SetErrorStringWithFormat("unable to parse coordinate for %s",
4110  option_arg.str().c_str());
4111  else {
4112  m_have_coord = true;
4113  m_coord = coord;
4114  }
4115  break;
4116  }
4117  default:
4118  err.SetErrorStringWithFormat("Invalid option '-%c'", short_option);
4119  }
4120  return err;
4121  }
4122 
4123  void OptionParsingStarting(ExecutionContext *exe_ctx) override {
4124  m_have_coord = false;
4125  }
4126 
4127  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4128  return llvm::makeArrayRef(g_renderscript_reduction_bp_set_options);
4129  }
4130 
4131  bool ParseReductionTypes(llvm::StringRef option_val,
4132  StreamString &err_str) {
4133  m_kernel_types = RSReduceBreakpointResolver::eKernelTypeNone;
4134  const auto reduce_name_to_type = [](llvm::StringRef name) -> int {
4135  return llvm::StringSwitch<int>(name)
4136  .Case("accumulator", RSReduceBreakpointResolver::eKernelTypeAccum)
4137  .Case("initializer", RSReduceBreakpointResolver::eKernelTypeInit)
4138  .Case("outconverter", RSReduceBreakpointResolver::eKernelTypeOutC)
4139  .Case("combiner", RSReduceBreakpointResolver::eKernelTypeComb)
4140  .Case("all", RSReduceBreakpointResolver::eKernelTypeAll)
4141  // Currently not exposed by the runtime
4142  // .Case("halter", RSReduceBreakpointResolver::eKernelTypeHalter)
4143  .Default(0);
4144  };
4145 
4146  // Matching a comma separated list of known words is fairly
4147  // straightforward with PCRE, but we're using ERE, so we end up with a
4148  // little ugliness...
4149  RegularExpression match_type_list(
4150  llvm::StringRef("^([[:alpha:]]+)(,[[:alpha:]]+){0,4}$"));
4151 
4152  assert(match_type_list.IsValid());
4153 
4154  if (!match_type_list.Execute(option_val)) {
4155  err_str.PutCString(
4156  "a comma-separated list of kernel types is required");
4157  return false;
4158  }
4159 
4160  // splitting on commas is much easier with llvm::StringRef than regex
4161  llvm::SmallVector<llvm::StringRef, 5> type_names;
4162  llvm::StringRef(option_val).split(type_names, ',');
4163 
4164  for (const auto &name : type_names) {
4165  const int type = reduce_name_to_type(name);
4166  if (!type) {
4167  err_str.Printf("unknown kernel type name %s", name.str().c_str());
4168  return false;
4169  }
4170  m_kernel_types |= type;
4171  }
4172 
4173  return true;
4174  }
4175 
4176  int m_kernel_types = RSReduceBreakpointResolver::eKernelTypeAll;
4177  llvm::StringRef m_reduce_name;
4180  };
4181 
4182  Options *GetOptions() override { return &m_options; }
4183 
4184  bool DoExecute(Args &command, CommandReturnObject &result) override {
4185  const size_t argc = command.GetArgumentCount();
4186  if (argc < 1) {
4187  result.AppendErrorWithFormat("'%s' takes 1 argument of reduction name, "
4188  "and an optional kernel type list",
4189  m_cmd_name.c_str());
4190  return false;
4191  }
4192 
4193  RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
4194  m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4196 
4197  auto &outstream = result.GetOutputStream();
4198  auto name = command.GetArgumentAtIndex(0);
4199  auto &target = m_exe_ctx.GetTargetSP();
4200  auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr;
4201  if (!runtime->PlaceBreakpointOnReduction(target, outstream, name, coord,
4202  m_options.m_kernel_types)) {
4203  result.AppendError("Error: unable to place breakpoint on reduction");
4204  return false;
4205  }
4206  result.AppendMessage("Breakpoint(s) created");
4208  return true;
4209  }
4210 
4211 private:
4213 };
4214 
4216  {LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument,
4217  nullptr, {}, 0, eArgTypeValue,
4218  "Set a breakpoint on a single invocation of the kernel with specified "
4219  "coordinate.\n"
4220  "Coordinate takes the form 'x[,y][,z] where x,y,z are positive "
4221  "integers representing kernel dimensions. "
4222  "Any unset dimensions will be defaulted to zero."}};
4223 
4225  : public CommandObjectParsed {
4226 public:
4228  CommandInterpreter &interpreter)
4230  interpreter, "renderscript kernel breakpoint set",
4231  "Sets a breakpoint on a renderscript kernel.",
4232  "renderscript kernel breakpoint set <kernel_name> [-c x,y,z]",
4233  eCommandRequiresProcess | eCommandProcessMustBeLaunched |
4234  eCommandProcessMustBePaused),
4235  m_options() {}
4236 
4238 
4239  Options *GetOptions() override { return &m_options; }
4240 
4241  class CommandOptions : public Options {
4242  public:
4244 
4245  ~CommandOptions() override = default;
4246 
4247  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4248  ExecutionContext *exe_ctx) override {
4249  Status err;
4250  const int short_option = m_getopt_table[option_idx].val;
4251 
4252  switch (short_option) {
4253  case 'c': {
4254  auto coord = RSCoordinate{};
4255  if (!ParseCoordinate(option_arg, coord))
4257  "Couldn't parse coordinate '%s', should be in format 'x,y,z'.",
4258  option_arg.str().c_str());
4259  else {
4260  m_have_coord = true;
4261  m_coord = coord;
4262  }
4263  break;
4264  }
4265  default:
4266  err.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
4267  break;
4268  }
4269  return err;
4270  }
4271 
4272  void OptionParsingStarting(ExecutionContext *exe_ctx) override {
4273  m_have_coord = false;
4274  }
4275 
4276  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4277  return llvm::makeArrayRef(g_renderscript_kernel_bp_set_options);
4278  }
4279 
4282  };
4283 
4284  bool DoExecute(Args &command, CommandReturnObject &result) override {
4285  const size_t argc = command.GetArgumentCount();
4286  if (argc < 1) {
4287  result.AppendErrorWithFormat(
4288  "'%s' takes 1 argument of kernel name, and an optional coordinate.",
4289  m_cmd_name.c_str());
4290  return false;
4291  }
4292 
4293  RenderScriptRuntime *runtime = llvm::cast<RenderScriptRuntime>(
4294  m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4296 
4297  auto &outstream = result.GetOutputStream();
4298  auto &target = m_exe_ctx.GetTargetSP();
4299  auto name = command.GetArgumentAtIndex(0);
4300  auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr;
4301  if (!runtime->PlaceBreakpointOnKernel(target, outstream, name, coord)) {
4302  result.AppendErrorWithFormat(
4303  "Error: unable to set breakpoint on kernel '%s'", name);
4304  return false;
4305  }
4306 
4307  result.AppendMessage("Breakpoint(s) created");
4309  return true;
4310  }
4311 
4312 private:
4314 };
4315 
4317  : public CommandObjectParsed {
4318 public:
4320  CommandInterpreter &interpreter)
4322  interpreter, "renderscript kernel breakpoint all",
4323  "Automatically sets a breakpoint on all renderscript kernels that "
4324  "are or will be loaded.\n"
4325  "Disabling option means breakpoints will no longer be set on any "
4326  "kernels loaded in the future, "
4327  "but does not remove currently set breakpoints.",
4328  "renderscript kernel breakpoint all <enable/disable>",
4329  eCommandRequiresProcess | eCommandProcessMustBeLaunched |
4330  eCommandProcessMustBePaused) {}
4331 
4333 
4334  bool DoExecute(Args &command, CommandReturnObject &result) override {
4335  const size_t argc = command.GetArgumentCount();
4336  if (argc != 1) {
4337  result.AppendErrorWithFormat(
4338  "'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
4339  return false;
4340  }
4341 
4342  RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
4343  m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4345 
4346  bool do_break = false;
4347  const char *argument = command.GetArgumentAtIndex(0);
4348  if (strcmp(argument, "enable") == 0) {
4349  do_break = true;
4350  result.AppendMessage("Breakpoints will be set on all kernels.");
4351  } else if (strcmp(argument, "disable") == 0) {
4352  do_break = false;
4353  result.AppendMessage("Breakpoints will not be set on any new kernels.");
4354  } else {
4355  result.AppendErrorWithFormat(
4356  "Argument must be either 'enable' or 'disable'");
4357  return false;
4358  }
4359 
4360  runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP());
4361 
4363  return true;
4364  }
4365 };
4366 
4368  : public CommandObjectMultiword {
4369 public:
4371  CommandInterpreter &interpreter)
4372  : CommandObjectMultiword(interpreter, "renderscript reduction breakpoint",
4373  "Commands that manipulate breakpoints on "
4374  "renderscript general reductions.",
4375  nullptr) {
4376  LoadSubCommand(
4377  "set", CommandObjectSP(
4379  interpreter)));
4380  }
4381 
4383 };
4384 
4386  : public CommandObjectParsed {
4387 public:
4389  CommandInterpreter &interpreter)
4391  interpreter, "renderscript kernel coordinate",
4392  "Shows the (x,y,z) coordinate of the current kernel invocation.",
4393  "renderscript kernel coordinate",
4394  eCommandRequiresProcess | eCommandProcessMustBeLaunched |
4395  eCommandProcessMustBePaused) {}
4396 
4398 
4399  bool DoExecute(Args &command, CommandReturnObject &result) override {
4400  RSCoordinate coord{};
4401  bool success = RenderScriptRuntime::GetKernelCoordinate(
4402  coord, m_exe_ctx.GetThreadPtr());
4403  Stream &stream = result.GetOutputStream();
4404 
4405  if (success) {
4406  stream.Printf("Coordinate: " FMT_COORD, coord.x, coord.y, coord.z);
4407  stream.EOL();
4409  } else {
4410  stream.Printf("Error: Coordinate could not be found.");
4411  stream.EOL();
4413  }
4414  return true;
4415  }
4416 };
4417 
4419  : public CommandObjectMultiword {
4420 public:
4422  CommandInterpreter &interpreter)
4424  interpreter, "renderscript kernel",
4425  "Commands that generate breakpoints on renderscript kernels.",
4426  nullptr) {
4427  LoadSubCommand(
4428  "set",
4430  interpreter)));
4431  LoadSubCommand(
4432  "all",
4434  interpreter)));
4435  }
4436 
4438 };
4439 
4441 public:
4443  : CommandObjectMultiword(interpreter, "renderscript kernel",
4444  "Commands that deal with RenderScript kernels.",
4445  nullptr) {
4446  LoadSubCommand(
4447  "list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(
4448  interpreter)));
4449  LoadSubCommand(
4450  "coordinate",
4451  CommandObjectSP(
4453  LoadSubCommand(
4454  "breakpoint",
4455  CommandObjectSP(
4457  }
4458 
4459  ~CommandObjectRenderScriptRuntimeKernel() override = default;
4460 };
4461 
4463 public:
4465  : CommandObjectParsed(interpreter, "renderscript context dump",
4466  "Dumps renderscript context information.",
4467  "renderscript context dump",
4468  eCommandRequiresProcess |
4469  eCommandProcessMustBeLaunched) {}
4470 
4471  ~CommandObjectRenderScriptRuntimeContextDump() override = default;
4472 
4473  bool DoExecute(Args &command, CommandReturnObject &result) override {
4474  RenderScriptRuntime *runtime = llvm::cast<RenderScriptRuntime>(
4475  m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4477  runtime->DumpContexts(result.GetOutputStream());
4479  return true;
4480  }
4481 };
4482 
4484  {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument,
4485  nullptr, {}, 0, eArgTypeFilename,
4486  "Print results to specified file instead of command line."}};
4487 
4489 public:
4491  : CommandObjectMultiword(interpreter, "renderscript context",
4492  "Commands that deal with RenderScript contexts.",
4493  nullptr) {
4494  LoadSubCommand(
4495  "dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(
4496  interpreter)));
4497  }
4498 
4499  ~CommandObjectRenderScriptRuntimeContext() override = default;
4500 };
4501 
4503  : public CommandObjectParsed {
4504 public:
4506  CommandInterpreter &interpreter)
4507  : CommandObjectParsed(interpreter, "renderscript allocation dump",
4508  "Displays the contents of a particular allocation",
4509  "renderscript allocation dump <ID>",
4510  eCommandRequiresProcess |
4511  eCommandProcessMustBeLaunched),
4512  m_options() {}
4513 
4514  ~CommandObjectRenderScriptRuntimeAllocationDump() override = default;
4515 
4516  Options *GetOptions() override { return &m_options; }
4517 
4518  class CommandOptions : public Options {
4519  public:
4521 
4522  ~CommandOptions() override = default;
4523 
4524  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4525  ExecutionContext *exe_ctx) override {
4526  Status err;
4527  const int short_option = m_getopt_table[option_idx].val;
4528 
4529  switch (short_option) {
4530  case 'f':
4531  m_outfile.SetFile(option_arg, FileSpec::Style::native);
4532  FileSystem::Instance().Resolve(m_outfile);
4533  if (FileSystem::Instance().Exists(m_outfile)) {
4534  m_outfile.Clear();
4535  err.SetErrorStringWithFormat("file already exists: '%s'",
4536  option_arg.str().c_str());
4537  }
4538  break;
4539  default:
4540  err.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
4541  break;
4542  }
4543  return err;
4544  }
4545 
4546  void OptionParsingStarting(ExecutionContext *exe_ctx) override {
4547  m_outfile.Clear();
4548  }
4549 
4550  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4551  return llvm::makeArrayRef(g_renderscript_runtime_alloc_dump_options);
4552  }
4553 
4555  };
4556 
4557  bool DoExecute(Args &command, CommandReturnObject &result) override {
4558  const size_t argc = command.GetArgumentCount();
4559  if (argc < 1) {
4560  result.AppendErrorWithFormat("'%s' takes 1 argument, an allocation ID. "
4561  "As well as an optional -f argument",
4562  m_cmd_name.c_str());
4563  return false;
4564  }
4565 
4566  RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
4567  m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4569 
4570  const char *id_cstr = command.GetArgumentAtIndex(0);
4571  bool success = false;
4572  const uint32_t id =
4573  StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &success);
4574  if (!success) {
4575  result.AppendErrorWithFormat("invalid allocation id argument '%s'",
4576  id_cstr);
4577  return false;
4578  }
4579 
4580  Stream *output_stream_p = nullptr;
4581  std::unique_ptr<Stream> output_stream_storage;
4582 
4583  const FileSpec &outfile_spec =
4584  m_options.m_outfile; // Dump allocation to file instead
4585  if (outfile_spec) {
4586  // Open output file
4587  std::string path = outfile_spec.GetPath();
4588  auto file = FileSystem::Instance().Open(
4589  outfile_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate);
4590  if (file) {
4591  output_stream_storage =
4592  std::make_unique<StreamFile>(std::move(file.get()));
4593  output_stream_p = output_stream_storage.get();
4594  result.GetOutputStream().Printf("Results written to '%s'",
4595  path.c_str());
4596  result.GetOutputStream().EOL();
4597  } else {
4598  std::string error = llvm::toString(file.takeError());
4599  result.AppendErrorWithFormat("Couldn't open file '%s': %s",
4600  path.c_str(), error.c_str());
4601  return false;
4602  }
4603  } else
4604  output_stream_p = &result.GetOutputStream();
4605 
4606  assert(output_stream_p != nullptr);
4607  bool dumped =
4608  runtime->DumpAllocation(*output_stream_p, m_exe_ctx.GetFramePtr(), id);
4609 
4610  if (dumped)
4612  else
4614 
4615  return true;
4616  }
4617 
4618 private:
4620 };
4621 
4623  {LLDB_OPT_SET_1, false, "id", 'i', OptionParser::eRequiredArgument, nullptr,
4624  {}, 0, eArgTypeIndex,
4625  "Only show details of a single allocation with specified id."}};
4626 
4628  : public CommandObjectParsed {
4629 public:
4631  CommandInterpreter &interpreter)
4633  interpreter, "renderscript allocation list",
4634  "List renderscript allocations and their information.",
4635  "renderscript allocation list",
4636  eCommandRequiresProcess | eCommandProcessMustBeLaunched),
4637  m_options() {}
4638 
4639  ~CommandObjectRenderScriptRuntimeAllocationList() override = default;
4640 
4641  Options *GetOptions() override { return &m_options; }
4642 
4643  class CommandOptions : public Options {
4644  public:
4646 
4647  ~CommandOptions() override = default;
4648 
4649  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4650  ExecutionContext *exe_ctx) override {
4651  Status err;
4652  const int short_option = m_getopt_table[option_idx].val;
4653 
4654  switch (short_option) {
4655  case 'i':
4656  if (option_arg.getAsInteger(0, m_id))
4657  err.SetErrorStringWithFormat("invalid integer value for option '%c'",
4658  short_option);
4659  break;
4660  default:
4661  err.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
4662  break;
4663  }
4664  return err;
4665  }
4666 
4667  void OptionParsingStarting(ExecutionContext *exe_ctx) override { m_id = 0; }
4668 
4669  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4670  return llvm::makeArrayRef(g_renderscript_runtime_alloc_list_options);
4671  }
4672 
4673  uint32_t m_id = 0;
4674  };
4675 
4676  bool DoExecute(Args &command, CommandReturnObject &result) override {
4677  RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
4678  m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4680  runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(),
4681  m_options.m_id);
4683  return true;
4684  }
4685 
4686 private:
4688 };
4689 
4691  : public CommandObjectParsed {
4692 public:
4694  CommandInterpreter &interpreter)
4696  interpreter, "renderscript allocation load",
4697  "Loads renderscript allocation contents from a file.",
4698  "renderscript allocation load <ID> <filename>",
4699  eCommandRequiresProcess | eCommandProcessMustBeLaunched) {}
4700 
4701  ~CommandObjectRenderScriptRuntimeAllocationLoad() override = default;
4702 
4703  bool DoExecute(Args &command, CommandReturnObject &result) override {
4704  const size_t argc = command.GetArgumentCount();
4705  if (argc != 2) {
4706  result.AppendErrorWithFormat(
4707  "'%s' takes 2 arguments, an allocation ID and filename to read from.",
4708  m_cmd_name.c_str());
4709  return false;
4710  }
4711 
4712  RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
4713  m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4715 
4716  const char *id_cstr = command.GetArgumentAtIndex(0);
4717  bool success = false;
4718  const uint32_t id =
4719  StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &success);
4720  if (!success) {
4721  result.AppendErrorWithFormat("invalid allocation id argument '%s'",
4722  id_cstr);
4723  return false;
4724  }
4725 
4726  const char *path = command.GetArgumentAtIndex(1);
4727  bool loaded = runtime->LoadAllocation(result.GetOutputStream(), id, path,
4728  m_exe_ctx.GetFramePtr());
4729 
4730  if (loaded)
4732  else
4734 
4735  return true;
4736  }
4737 };
4738 
4740  : public CommandObjectParsed {
4741 public:
4743  CommandInterpreter &interpreter)
4744  : CommandObjectParsed(interpreter, "renderscript allocation save",
4745  "Write renderscript allocation contents to a file.",
4746  "renderscript allocation save <ID> <filename>",
4747  eCommandRequiresProcess |
4748  eCommandProcessMustBeLaunched) {}
4749 
4750  ~CommandObjectRenderScriptRuntimeAllocationSave() override = default;
4751 
4752  bool DoExecute(Args &command, CommandReturnObject &result) override {
4753  const size_t argc = command.GetArgumentCount();
4754  if (argc != 2) {
4755  result.AppendErrorWithFormat(
4756  "'%s' takes 2 arguments, an allocation ID and filename to read from.",
4757  m_cmd_name.c_str());
4758  return false;
4759  }
4760 
4761  RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
4762  m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4764 
4765  const char *id_cstr = command.GetArgumentAtIndex(0);
4766  bool success = false;
4767  const uint32_t id =
4768  StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &success);
4769  if (!success) {
4770  result.AppendErrorWithFormat("invalid allocation id argument '%s'",
4771  id_cstr);
4772  return false;
4773  }
4774 
4775  const char *path = command.GetArgumentAtIndex(1);
4776  bool saved = runtime->SaveAllocation(result.GetOutputStream(), id, path,
4777  m_exe_ctx.GetFramePtr());
4778 
4779  if (saved)
4781  else
4783 
4784  return true;
4785  }
4786 };
4787 
4789  : public CommandObjectParsed {
4790 public:
4792  CommandInterpreter &interpreter)
4793  : CommandObjectParsed(interpreter, "renderscript allocation refresh",
4794  "Recomputes the details of all allocations.",
4795  "renderscript allocation refresh",
4796  eCommandRequiresProcess |
4797  eCommandProcessMustBeLaunched) {}
4798 
4800 
4801  bool DoExecute(Args &command, CommandReturnObject &result) override {
4802  RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>(
4803  m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4805 
4806  bool success = runtime->RecomputeAllAllocations(result.GetOutputStream(),
4807  m_exe_ctx.GetFramePtr());
4808 
4809  if (success) {
4811  return true;
4812  } else {
4814  return false;
4815  }
4816  }
4817 };
4818 
4820  : public CommandObjectMultiword {
4821 public:
4824  interpreter, "renderscript allocation",
4825  "Commands that deal with RenderScript allocations.", nullptr) {
4826  LoadSubCommand(
4827  "list",
4828  CommandObjectSP(
4830  LoadSubCommand(
4831  "dump",
4832  CommandObjectSP(
4834  LoadSubCommand(
4835  "save",
4836  CommandObjectSP(
4838  LoadSubCommand(
4839  "load",
4840  CommandObjectSP(
4842  LoadSubCommand(
4843  "refresh",
4845  interpreter)));
4846  }
4847 
4848  ~CommandObjectRenderScriptRuntimeAllocation() override = default;
4849 };
4850 
4852 public:
4854  : CommandObjectParsed(interpreter, "renderscript status",
4855  "Displays current RenderScript runtime status.",
4856  "renderscript status",
4857  eCommandRequiresProcess |
4858  eCommandProcessMustBeLaunched) {}
4859 
4860  ~CommandObjectRenderScriptRuntimeStatus() override = default;
4861 
4862  bool DoExecute(Args &command, CommandReturnObject &result) override {
4863  RenderScriptRuntime *runtime = llvm::cast<RenderScriptRuntime>(
4864  m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(
4866  runtime->DumpStatus(result.GetOutputStream());
4868  return true;
4869  }
4870 };
4871 
4873  : public CommandObjectMultiword {
4874 public:
4876  : CommandObjectMultiword(interpreter, "renderscript reduction",
4877  "Commands that handle general reduction kernels",
4878  nullptr) {
4879  LoadSubCommand(
4880  "breakpoint",
4882  interpreter)));
4883  }
4884  ~CommandObjectRenderScriptRuntimeReduction() override = default;
4885 };
4886 
4888 public:
4891  interpreter, "renderscript",
4892  "Commands for operating on the RenderScript runtime.",
4893  "renderscript <subcommand> [<subcommand-options>]") {
4894  LoadSubCommand(
4895  "module", CommandObjectSP(
4896  new CommandObjectRenderScriptRuntimeModule(interpreter)));
4897  LoadSubCommand(
4898  "status", CommandObjectSP(
4899  new CommandObjectRenderScriptRuntimeStatus(interpreter)));
4900  LoadSubCommand(
4901  "kernel", CommandObjectSP(
4902  new CommandObjectRenderScriptRuntimeKernel(interpreter)));
4903  LoadSubCommand("context",
4904  CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(
4905  interpreter)));
4906  LoadSubCommand(
4907  "allocation",
4908  CommandObjectSP(
4909  new CommandObjectRenderScriptRuntimeAllocation(interpreter)));
4910  LoadSubCommand("scriptgroup",
4912  LoadSubCommand(
4913  "reduction",
4914  CommandObjectSP(
4915  new CommandObjectRenderScriptRuntimeReduction(interpreter)));
4916  }
4917 
4918  ~CommandObjectRenderScriptRuntime() override = default;
4919 };
4920 
4921 void RenderScriptRuntime::Initiate() { assert(!m_initiated); }
4922 
4923 RenderScriptRuntime::RenderScriptRuntime(Process *process)
4924  : lldb_private::CPPLanguageRuntime(process), m_initiated(false),
4925  m_debuggerPresentFlagged(false), m_breakAllKernels(false),
4926  m_ir_passes(nullptr) {
4927  ModulesDidLoad(process->GetTarget().GetImages());
4928 }
4929 
4931  lldb_private::CommandInterpreter &interpreter) {
4932  return CommandObjectSP(new CommandObjectRenderScriptRuntime(interpreter));
4933 }
4934 
lldb_private::RenderScriptRuntime::AllocationDetails::ElementHeader
Definition: RenderScriptRuntime.cpp:627
RegularExpression.h
CommandObjectRenderScriptRuntimeAllocationList::GetOptions
Options * GetOptions() override
Definition: RenderScriptRuntime.cpp:4641
lldb_private::RenderScriptRuntime::AllocationDetails::data_ptr
empirical_type< lldb::addr_t > data_ptr
Definition: RenderScriptRuntime.cpp:659
lldb_private::Stream::IndentLess
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
Definition: Stream.cpp:171
lldb_private::CommandObjectParsed
Definition: CommandObject.h:378
lldb::eFormatVectorOfUInt64
@ eFormatVectorOfUInt64
Definition: lldb-enumerations.h:187
lldb_private::RenderScriptRuntime::ScriptDetails::res_name
empirical_type< std::string > res_name
Definition: RenderScriptRuntime.cpp:498
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
lldb_private::RenderScriptRuntime::AllocationDetails::ElementHeader::kind
uint32_t kind
Definition: RenderScriptRuntime.cpp:629
lldb_private::RenderScriptRuntime::Element::RS_KIND_PIXEL_LA
@ RS_KIND_PIXEL_LA
Definition: RenderScriptRuntime.cpp:517
CommandObjectRenderScriptRuntimeKernelBreakpoint
Definition: RenderScriptRuntime.cpp:4418
lldb_private::RenderScriptRuntime::Element::RS_KIND_PIXEL_A
@ RS_KIND_PIXEL_A
Definition: RenderScriptRuntime.cpp:516
lldb_private::BreakpointList
General Outline: Allows adding and removing breakpoints and find by ID and index.
Definition: BreakpointList.h:25
lldb_private::RenderScriptRuntime::Element::RS_TYPE_FLOAT_32
@ RS_TYPE_FLOAT_32
Definition: RenderScriptRuntime.cpp:529
lldb_private::RenderScriptRuntime::Element
Definition: RenderScriptRuntime.cpp:511
lldb_private::RegularExpression
Definition: RegularExpression.h:18
lldb_private::RenderScriptRuntime::AllocationDetails::FileHeader::ident
uint8_t ident[4]
Definition: RenderScriptRuntime.cpp:622
lldb_private::RenderScriptRuntime::HookCallback
static bool HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
Definition: RenderScriptRuntime.cpp:1103
CommandObjectRenderScriptRuntimeKernelBreakpoint::CommandObjectRenderScriptRuntimeKernelBreakpoint
CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4421
lldb_private::StoppointCallbackContext
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
Definition: StoppointCallbackContext.h:26
lldb::eSymbolTypeCode
@ eSymbolTypeCode
Definition: lldb-enumerations.h:616
lldb_private::SearchFilter::AddressPasses
virtual bool AddressPasses(Address &addr)
Call this method with a Address to see if address passes the filter.
Definition: SearchFilter.cpp:141
lldb_private::RenderScriptRuntime::Element::type
empirical_type< DataType > type
Definition: RenderScriptRuntime.cpp:568
lldb::Format
Format
Display format definitions.
Definition: lldb-enumerations.h:155
lldb_private::ArchSpec::GetMachine
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:667
lldb_private::EvaluateExpressionOptions::SetLanguage
void SetLanguage(lldb::LanguageType language)
Definition: Target.h:281
lldb_private::RegisterValue
Definition: RegisterValue.h:28
CommandObjectRenderScriptRuntimeKernelBreakpointAll::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: RenderScriptRuntime.cpp:4334
lldb_private::RenderScriptRuntime::AllocationDetails
Definition: RenderScriptRuntime.cpp:594
CommandObjectRenderScriptRuntimeContext::CommandObjectRenderScriptRuntimeContext
CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4490
lldb_private::RenderScriptRuntime::Element::GetFallbackStructName
static ConstString GetFallbackStructName()
Definition: RenderScriptRuntime.cpp:680
lldb_private::Symbol
Definition: Symbol.h:20
lldb::eNoDynamicValues
@ eNoDynamicValues
Definition: lldb-enumerations.h:495
lldb_private::ExecutionContext::GetProcessPtr
Process * GetProcessPtr() const
Returns a pointer to the process object.
Definition: ExecutionContext.cpp:208
CommandObjectRenderScriptRuntimeAllocationSave
Definition: RenderScriptRuntime.cpp:4739
lldb_private::RenderScriptRuntime::Element::RS_TYPE_UNSIGNED_64
@ RS_TYPE_UNSIGNED_64
Definition: RenderScriptRuntime.cpp:538
CommandObjectRenderScriptRuntimeKernelBreakpointSet::CommandOptions::SetOptionValue
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *exe_ctx) override
Set the value of an option.
Definition: RenderScriptRuntime.cpp:4247
lldb_private::lldb_renderscript::RSCoordinate
Definition: RenderScriptRuntime.h:46
CommandObjectRenderScriptRuntimeReductionBreakpoint
Definition: RenderScriptRuntime.cpp:4367
CommandObjectRenderScriptRuntimeKernelBreakpointAll::CommandObjectRenderScriptRuntimeKernelBreakpointAll
CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4319
CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::OptionParsingStarting
void OptionParsingStarting(ExecutionContext *exe_ctx) override
Definition: RenderScriptRuntime.cpp:4667
lldb_private::RenderScriptRuntime::AllocationDetails::stride
empirical_type< uint32_t > stride
Definition: RenderScriptRuntime.cpp:667
lldb_private::RenderScriptRuntime::AllocationDetails::Dimension::cube_map
uint32_t cube_map
Definition: RenderScriptRuntime.cpp:599
lldb_private::Stream::SetIndentLevel
void SetIndentLevel(unsigned level)
Set the current indentation level.
Definition: Stream.cpp:163
CommandObjectRenderScriptRuntimeAllocation::CommandObjectRenderScriptRuntimeAllocation
CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4822
lldb_private::lldb_renderscript::RSScriptGroupDescriptor::Kernel::m_addr
lldb::addr_t m_addr
Definition: RenderScriptRuntime.h:243
JIT_TEMPLATE_CONTEXT
#define JIT_TEMPLATE_CONTEXT
Definition: RenderScriptRuntime.cpp:1759
CommandObjectRenderScriptRuntimeKernelList
Definition: RenderScriptRuntime.cpp:4040
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:249
CommandObjectRenderScriptRuntimeAllocationDump
Definition: RenderScriptRuntime.cpp:4502
eElementSize
@ eElementSize
Definition: RenderScriptRuntime.cpp:734
lldb_private::Process
Definition: Process.h:341
lldb_private::lldb_renderscript::RSScriptGroupBreakpointResolver
Definition: RenderScriptRuntime.h:251
lldb_private::ModuleList::GetMutex
std::recursive_mutex & GetMutex() const
Definition: ModuleList.h:198
lldb_private::RenderScriptRuntime::Element::array_size
empirical_type< uint32_t > array_size
Definition: RenderScriptRuntime.cpp:577
CommandObjectRenderScriptRuntimeReductionBreakpointSet::CommandOptions::m_have_coord
bool m_have_coord
Definition: RenderScriptRuntime.cpp:4179
g_renderscript_kernel_bp_set_options
static constexpr OptionDefinition g_renderscript_kernel_bp_set_options[]
Definition: RenderScriptRuntime.cpp:4215
lldb_private::RenderScriptRuntime
Definition: RenderScriptRuntime.h:298
lldb_private::RenderScriptRuntime::AllocationDetails::RsDataKindToString
static const char * RsDataKindToString[]
Definition: RenderScriptRuntime.cpp:643
lldb_private::RenderScriptRuntime::AllocationDetails::address
empirical_type< lldb::addr_t > address
Definition: RenderScriptRuntime.cpp:657
lldb_private::RenderScriptRuntime::AllocationDetails::FileHeader
Definition: RenderScriptRuntime.cpp:621
lldb_private::RenderScriptRuntime::PlaceBreakpointOnKernel
bool PlaceBreakpointOnKernel(lldb::TargetSP target, Stream &messages, const char *name, const lldb_renderscript::RSCoordinate *coords=nullptr)
Definition: RenderScriptRuntime.cpp:3732
lldb_private::RenderScriptRuntime::Element::element_ptr
empirical_type< lldb::addr_t > element_ptr
Definition: RenderScriptRuntime.cpp:566
lldb_private::Process::GetTarget
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1194
lldb_private::StoppointCallbackContext::exe_ctx_ref
ExecutionContextRef exe_ctx_ref
Definition: StoppointCallbackContext.h:43
lldb_private::EvaluateExpressionOptions
Definition: Target.h:253
NewCommandObjectRenderScriptScriptGroup
lldb::CommandObjectSP NewCommandObjectRenderScriptScriptGroup(lldb_private::CommandInterpreter &interpreter)
Definition: RenderScriptScriptGroup.cpp:157
CommandObjectRenderScriptRuntimeAllocationDump::CommandObjectRenderScriptRuntimeAllocationDump
CommandObjectRenderScriptRuntimeAllocationDump(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4505
StoppointCallbackContext.h
CommandObjectRenderScriptRuntimeAllocationRefresh::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: RenderScriptRuntime.cpp:4801
lldb::eFormatVectorOfSInt16
@ eFormatVectorOfSInt16
Definition: lldb-enumerations.h:182
lldb::eFormatVectorOfSInt32
@ eFormatVectorOfSInt32
Definition: lldb-enumerations.h:184
lldb_private::RenderScriptRuntime::RecomputeAllAllocations
bool RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr)
Definition: RenderScriptRuntime.cpp:3332
lldb_private::VariableList::GetSize
size_t GetSize() const
Definition: VariableList.cpp:165
CommandObjectRenderScriptRuntimeAllocationList
Definition: RenderScriptRuntime.cpp:4627
lldb::LanguageType
LanguageType
Programming language type.
Definition: lldb-enumerations.h:436
lldb_private::Log::Warning
void void void void Warning(const char *fmt,...) __attribute__((format(printf
Definition: Log.cpp:172
lldb_private::RenderScriptRuntime::AllocationDetails::type_ptr
empirical_type< lldb::addr_t > type_ptr
Definition: RenderScriptRuntime.cpp:661
CommandObjectRenderScriptRuntimeKernelBreakpointSet::CommandOptions::OptionParsingStarting
void OptionParsingStarting(ExecutionContext *exe_ctx) override
Definition: RenderScriptRuntime.cpp:4272
CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions
Definition: RenderScriptRuntime.cpp:4518
lldb::eFormatBoolean
@ eFormatBoolean
Definition: lldb-enumerations.h:158
lldb::eSymbolTypeData
@ eSymbolTypeData
Definition: lldb-enumerations.h:618
lldb_private::ConstString::SetCString
void SetCString(const char *cstr)
Set the C string value.
Definition: ConstString.cpp:302
CommandObjectRenderScriptRuntimeContextDump::CommandObjectRenderScriptRuntimeContextDump
CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4464
SectionLoadList.h
CommandObjectRenderScriptRuntimeReductionBreakpointSet::GetOptions
Options * GetOptions() override
Definition: RenderScriptRuntime.cpp:4182
lldb_private::ConstString::AsCString
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
Definition: ConstString.h:193
CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::CommandOptions
CommandOptions()
Definition: RenderScriptRuntime.cpp:4645
lldb_private::Address::CalculateSymbolContextModule
lldb::ModuleSP CalculateSymbolContextModule() const
Definition: Address.cpp:814
UserExpression.h
lldb::eArgTypeFilename
@ eArgTypeFilename
Definition: lldb-enumerations.h:537
RegisterValue.h
lldb_private::lldb_renderscript::RSCoordinate::x
uint32_t x
Definition: RenderScriptRuntime.h:47
CommandObjectRenderScriptRuntimeReductionBreakpointSet::CommandOptions::SetOptionValue
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *exe_ctx) override
Set the value of an option.
Definition: RenderScriptRuntime.cpp:4094
lldb_private::RenderScriptRuntime::HookDefn::symbol_name_m64
const char * symbol_name_m64
Definition: RenderScriptRuntime.h:463
CommandObjectRenderScriptRuntimeReduction::CommandObjectRenderScriptRuntimeReduction
CommandObjectRenderScriptRuntimeReduction(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4875
lldb_private::RenderScriptRuntime::Element::RS_TYPE_ALLOCATION
@ RS_TYPE_ALLOCATION
Definition: RenderScriptRuntime.cpp:551
CommandObjectRenderScriptRuntimeAllocationDump::GetOptions
Options * GetOptions() override
Definition: RenderScriptRuntime.cpp:4516
lldb::eArgTypeValue
@ eArgTypeValue
Definition: lldb-enumerations.h:593
lldb_private::RenderScriptRuntime::AllocationDetails::RSTypeToFormat
static const uint32_t RSTypeToFormat[][3]
Definition: RenderScriptRuntime.cpp:646
lldb_private::RenderScriptRuntime::Element::type_kind
empirical_type< DataKind > type_kind
Definition: RenderScriptRuntime.cpp:570
lldb_private::Stream
Definition: Stream.h:28
lldb_private::Process::ReadCStringFromMemory
size_t ReadCStringFromMemory(lldb::addr_t vm_addr, char *cstr, size_t cstr_max_len, Status &error)
Read a NULL terminated C string from memory.
Definition: Process.cpp:1992
lldb_private::Args
Definition: Args.h:33
lldb_private::Target::CreateBreakpoint
lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, uint32_t column, lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool request_hardware, LazyBool move_to_nearest_code)
Definition: Target.cpp:331
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
CommandObjectRenderScriptRuntimeKernelCoordinate::CommandObjectRenderScriptRuntimeKernelCoordinate
CommandObjectRenderScriptRuntimeKernelCoordinate(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4388
lldb_private::Target::GetBreakpointList
BreakpointList & GetBreakpointList(bool internal=false)
Definition: Target.cpp:289
CommandObjectRenderScriptRuntimeAllocation
Definition: RenderScriptRuntime.cpp:4819
CommandReturnObject.h
CommandObjectRenderScriptRuntimeStatus
Definition: RenderScriptRuntime.cpp:4851
LIBLLDB_LOG_SYMBOLS
#define LIBLLDB_LOG_SYMBOLS
Definition: Logging.h:34
Debugger.h
lldb_private::SymbolContext
Definition: SymbolContext.h:33
lldb_private::Target
Definition: Target.h:445
CommandObjectRenderScriptRuntimeKernelBreakpointSet::GetOptions
Options * GetOptions() override
Definition: RenderScriptRuntime.cpp:4239
lldb_private::ExecutionContext::GetThreadPtr
Thread * GetThreadPtr() const
Returns a pointer to the thread object.
Definition: ExecutionContext.h:399
lldb_private::RenderScriptRuntime::LoadAllocation
bool LoadAllocation(Stream &strm, const uint32_t alloc_id, const char *filename, StackFrame *frame_ptr)
Definition: RenderScriptRuntime.cpp:2409
LLDB_LOGV
#define LLDB_LOGV(log,...)
Definition: Log.h:256
CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions::SetOptionValue
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *exe_ctx) override
Set the value of an option.
Definition: RenderScriptRuntime.cpp:4524
lldb_private::Target::GetImages
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:919
lldb_private::RenderScriptRuntime::Element::RS_KIND_PIXEL_RGBA
@ RS_KIND_PIXEL_RGBA
Definition: RenderScriptRuntime.cpp:519
CommandObjectRenderScriptRuntimeKernelList::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: RenderScriptRuntime.cpp:4051
lldb_private::VariableList
Definition: VariableList.h:18
lldb_private::StreamString::GetString
llvm::StringRef GetString() const
Definition: StreamString.cpp:51
lldb_private::RenderScriptRuntime::AllocationDetails::id
const uint32_t id
Definition: RenderScriptRuntime.cpp:650
CommandObjectRenderScriptRuntimeAllocationLoad::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: RenderScriptRuntime.cpp:4703
lldb_private::RenderScriptRuntime::Element::RS_TYPE_SIGNED_32
@ RS_TYPE_SIGNED_32
Definition: RenderScriptRuntime.cpp:533
lldb_private::RenderScriptRuntime::ListAllocations
void ListAllocations(Stream &strm, StackFrame *frame_ptr, const uint32_t index)
Definition: RenderScriptRuntime.cpp:3355
Process.h
CommandObjectRenderScriptRuntimeModule
Definition: RenderScriptRuntime.cpp:4026
lldb_private::RegisterValue::GetAsUInt64
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
Definition: RegisterValue.cpp:563
lldb_private::lldb_renderscript::RSBreakpointResolver
Definition: RenderScriptRuntime.h:59
lldb_private::RenderScriptRuntime::RuntimeHook
Definition: RenderScriptRuntime.h:469
lldb_private::RenderScriptRuntime::DumpModules
void DumpModules(Stream &strm) const
Definition: RenderScriptRuntime.cpp:3817
CommandObjectRenderScriptRuntimeKernelBreakpointAll
Definition: RenderScriptRuntime.cpp:4316
lldb_private::VariableList::GetVariableAtIndex
lldb::VariableSP GetVariableAtIndex(size_t idx) const
Definition: VariableList.cpp:47
lldb_private::DumpValueObjectOptions::SetHideName
DumpValueObjectOptions & SetHideName(bool hide_name=false)
Definition: DumpValueObjectOptions.cpp:145
lldb_private::lldb_renderscript::RSGlobalDescriptor
Definition: RenderScriptRuntime.h:155
CommandObjectRenderScriptRuntimeReductionBreakpointSet
Definition: RenderScriptRuntime.cpp:4074
lldb::eFormatVectorOfSInt8
@ eFormatVectorOfSInt8
Definition: lldb-enumerations.h:180
lldb_private::RenderScriptRuntime::CaptureAllocationDestroy
void CaptureAllocationDestroy(RuntimeHook *hook_info, ExecutionContext &context)
Definition: RenderScriptRuntime.cpp:1443
Target.h
CommandObjectRenderScriptRuntimeAllocationSave::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: RenderScriptRuntime.cpp:4752
lldb_private::RenderScriptRuntime::HookDefn::symbol_name_m32
const char * symbol_name_m32
Definition: RenderScriptRuntime.h:462
CommandObjectRenderScriptRuntimeAllocationList::m_options
CommandOptions m_options
Definition: RenderScriptRuntime.cpp:4687
CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions::GetDefinitions
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Definition: RenderScriptRuntime.cpp:4550
lldb_private::RenderScriptRuntime::CaptureScriptInit
void CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context)
Definition: RenderScriptRuntime.cpp:1480
eFormatSingle
@ eFormatSingle
Definition: RenderScriptRuntime.cpp:734
lldb_private::FileSpec
Definition: FileSpec.h:56
lldb_private::CommandObjectMultiword
Definition: CommandObjectMultiword.h:19
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
LIBLLDB_LOG_LANGUAGE
#define LIBLLDB_LOG_LANGUAGE
Definition: Logging.h:42
Options.h
lldb_private::RenderScriptRuntime::Element::type_vec_size
empirical_type< uint32_t > type_vec_size
Definition: RenderScriptRuntime.cpp:572
lldb::eFormatVectorOfFloat64
@ eFormatVectorOfFloat64
Definition: lldb-enumerations.h:190
lldb_private::RenderScriptRuntime::Element::DataKind
DataKind
Definition: RenderScriptRuntime.cpp:513
CommandObjectRenderScriptRuntimeContextDump::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: RenderScriptRuntime.cpp:4473
lldb_private::RenderScriptRuntime::AllocationDetails::FileHeader::dims
uint32_t dims[3]
Definition: RenderScriptRuntime.cpp:623
lldb_private::Status::Success
bool Success() const
Test for success condition.
Definition: Status.cpp:288
lldb_private::ModuleList::GetSize
size_t GetSize() const
Gets the size of the module list.
Definition: ModuleList.cpp:595
lldb::eFormatVectorOfUInt32
@ eFormatVectorOfUInt32
Definition: lldb-enumerations.h:185
lldb_private::lldb_renderscript::RSCoordinate::z
uint32_t z
Definition: RenderScriptRuntime.h:47
StringConvert.h
CommandObjectRenderScriptRuntimeAllocationDump::m_options
CommandOptions m_options
Definition: RenderScriptRuntime.cpp:4619
lldb_private::ExecutionContext::GetRegisterContext
RegisterContext * GetRegisterContext() const
Definition: ExecutionContext.cpp:192
lldb_private::Options
Definition: Options.h:57
ID
static char ID
Definition: IRDynamicChecks.cpp:32
lldb_private::Stream::Indent
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition: Stream.cpp:130
lldb_private::RenderScriptRuntime::Element::RS_KIND_USER
@ RS_KIND_USER
Definition: RenderScriptRuntime.cpp:514
lldb_private::breakpad::toString
llvm::StringRef toString(Record::Kind K)
Definition: BreakpadRecords.cpp:483
CommandObjectRenderScriptRuntimeKernel
Definition: RenderScriptRuntime.cpp:4440
lldb_private::DataExtractor
Definition: DataExtractor.h:48
lldb_private::ConstString::GetStringRef
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:202
lldb_private::ModuleList
Definition: ModuleList.h:71
CommandObjectRenderScriptRuntimeAllocationRefresh::CommandObjectRenderScriptRuntimeAllocationRefresh
CommandObjectRenderScriptRuntimeAllocationRefresh(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4791
lldb_private::RenderScriptRuntime::DumpAllocation
bool DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id)
Definition: RenderScriptRuntime.cpp:3179
lldb_private::SearchFilter
General Outline: Provides the callback and search depth for the SearchFilter search.
Definition: SearchFilter.h:83
CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::GetDefinitions
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Definition: RenderScriptRuntime.cpp:4669
Log.h
Args.h
CommandObjectRenderScriptRuntimeModuleDump::CommandObjectRenderScriptRuntimeModuleDump
CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4007
lldb_private::ConstString::IsEmpty
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:304
CommandObjectRenderScriptRuntimeKernel::CommandObjectRenderScriptRuntimeKernel
CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4442
lldb_private::Status::GetError
ValueType GetError() const
Access the error value.
Definition: Status.cpp:175
lldb_private::RenderScriptRuntime::CaptureDebugHintScriptGroup2
void CaptureDebugHintScriptGroup2(RuntimeHook *hook_info, ExecutionContext &context)
Definition: RenderScriptRuntime.cpp:1130
CommandObjectRenderScriptRuntimeKernelCoordinate::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: RenderScriptRuntime.cpp:4399
lldb_private::RenderScriptRuntime::Element::RS_TYPE_SIGNED_64
@ RS_TYPE_SIGNED_64
Definition: RenderScriptRuntime.cpp:534
lldb_private::Thread
Definition: Thread.h:62
CommandObjectRenderScriptRuntimeAllocationList::CommandObjectRenderScriptRuntimeAllocationList
CommandObjectRenderScriptRuntimeAllocationList(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4630
LLDB_OPT_SET_1
#define LLDB_OPT_SET_1
Definition: lldb-defines.h:113
lldb_private::CommandReturnObject::SetStatus
void SetStatus(lldb::ReturnStatus status)
Definition: CommandReturnObject.cpp:121
lldb_private::RenderScriptRuntime::DumpContexts
void DumpContexts(Stream &strm) const
Definition: RenderScriptRuntime.cpp:3105
lldb::eArgTypeIndex
@ eArgTypeIndex
Definition: lldb-enumerations.h:545
lldb_private::RenderScriptRuntime::ModulesDidLoad
static void ModulesDidLoad(const lldb::ProcessSP &process_sp, const ModuleList &module_list)
lldb_private::Status::Fail
bool Fail() const
Test for error condition.
Definition: Status.cpp:182
lldb_private::RenderScriptRuntime::Element::RS_TYPE_MATRIX_2X2
@ RS_TYPE_MATRIX_2X2
Definition: RenderScriptRuntime.cpp:547
CommandObjectRenderScriptRuntimeContextDump
Definition: RenderScriptRuntime.cpp:4462
lldb_private::StreamString::GetData
const char * GetData() const
Definition: StreamString.h:43
lldb_private::RenderScriptRuntime::CaptureAllocationInit
void CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context)
Definition: RenderScriptRuntime.cpp:1415
lldb_private::Status::SetErrorStringWithFormat
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:256
lldb_private::RenderScriptRuntime::Element::RS_TYPE_TYPE
@ RS_TYPE_TYPE
Definition: RenderScriptRuntime.cpp:550
lldb_private::SymbolContext::function
Function * function
The Function for a given query.
Definition: SymbolContext.h:320
lldb_private::Address::GetFileAddress
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:290
lldb_private::RenderScriptRuntime::AllocationDetails::size
empirical_type< uint32_t > size
Definition: RenderScriptRuntime.cpp:665
lldb_private::RenderScriptRuntime::HookDefn
Definition: RenderScriptRuntime.h:460
CommandObjectRenderScriptRuntimeAllocationRefresh
Definition: RenderScriptRuntime.cpp:4788
Type.h
lldb_private::Symbol::GetAddressRef
Address & GetAddressRef()
Definition: Symbol.h:57
CommandObjectRenderScriptRuntimeAllocationLoad
Definition: RenderScriptRuntime.cpp:4690
lldb_private::RenderScriptRuntime::HookDefn::version
uint32_t version
Definition: RenderScriptRuntime.h:464
lldb_private::CommandReturnObject::GetOutputStream
Stream & GetOutputStream()
Definition: CommandReturnObject.h:45
CommandObjectRenderScriptRuntimeAllocationList::CommandOptions
Definition: RenderScriptRuntime.cpp:4643
CommandObjectRenderScriptRuntimeKernelBreakpointSet::m_options
CommandOptions m_options
Definition: RenderScriptRuntime.cpp:4313
lldb_private::RenderScriptRuntime::Element::RS_TYPE_SIGNED_8
@ RS_TYPE_SIGNED_8
Definition: RenderScriptRuntime.cpp:531
lldb_private::RenderScriptRuntime::AllocationDetails::ElementHeader::vector_size
uint16_t vector_size
Definition: RenderScriptRuntime.cpp:631
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::Searcher::CallbackReturn
CallbackReturn
Definition: SearchFilter.h:44
lldb_private::RegularExpression::IsValid
bool IsValid() const
Test if this object contains a valid regular expression.
Definition: RegularExpression.cpp:31
lldb_private::StreamString
Definition: StreamString.h:23
lldb_private::RenderScriptRuntime::RuntimeHookSP
std::shared_ptr< RuntimeHook > RuntimeHookSP
Definition: RenderScriptRuntime.h:475
RenderScriptRuntime.h
lldb_private::RenderScriptRuntime::GetCommandObject
static lldb::CommandObjectSP GetCommandObject(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4930
lldb_private::Target::AddNameToBreakpoint
void AddNameToBreakpoint(BreakpointID &id, const char *name, Status &error)
Definition: Target.cpp:669
lldb_private::SymbolContext::GetFunctionName
ConstString GetFunctionName(Mangled::NamePreference preference=Mangled::ePreferDemangled) const
Find a name of the innermost function for the symbol context.
Definition: SymbolContext.cpp:654
lldb_private::RenderScriptRuntime::Element::RS_TYPE_PROGRAM_STORE
@ RS_TYPE_PROGRAM_STORE
Definition: RenderScriptRuntime.cpp:558
lldb_private::GetLogIfAllCategoriesSet
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:58
lldb_private::Thread::GetStackFrameCount
virtual uint32_t GetStackFrameCount()
Definition: Thread.h:395
CommandObjectRenderScriptRuntime::CommandObjectRenderScriptRuntime
CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4889
CommandObjectRenderScriptRuntimeReduction
Definition: RenderScriptRuntime.cpp:4872
lldb_private::Value::ValueType
ValueType
Type that describes Value::m_value.
Definition: Value.h:41
lldb_private::RenderScriptRuntime::AllocationDetails::ShouldRefresh
bool ShouldRefresh() const
Definition: RenderScriptRuntime.cpp:672
lldb_private::RenderScriptRuntime::Element::RS_TYPE_SAMPLER
@ RS_TYPE_SAMPLER
Definition: RenderScriptRuntime.cpp:552
lldb_private::CommandInterpreter
Definition: CommandInterpreter.h:214
CommandObjectRenderScriptRuntimeReductionBreakpointSet::CommandObjectRenderScriptRuntimeReductionBreakpointSet
CommandObjectRenderScriptRuntimeReductionBreakpointSet(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4077
lldb::eFormatDecimal
@ eFormatDecimal
Definition: lldb-enumerations.h:167
lldb_private::RenderScriptRuntime::AllocationDetails::FileHeader::hdr_size
uint16_t hdr_size
Definition: RenderScriptRuntime.cpp:624
CommandObjectMultiword.h
lldb_private::RenderScriptRuntime::ScriptDetails::cache_dir
empirical_type< std::string > cache_dir
Definition: RenderScriptRuntime.cpp:502
CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions::m_outfile
FileSpec m_outfile
Definition: RenderScriptRuntime.cpp:4554
lldb::eReturnStatusFailed
@ eReturnStatusFailed
Definition: lldb-enumerations.h:265
CommandObjectRenderScriptRuntimeReductionBreakpoint::CommandObjectRenderScriptRuntimeReductionBreakpoint
CommandObjectRenderScriptRuntimeReductionBreakpoint(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4370
lldb_private::RenderScriptRuntime::Element::RS_TYPE_MESH
@ RS_TYPE_MESH
Definition: RenderScriptRuntime.cpp:554
lldb_private::RenderScriptRuntime::Element::RS_TYPE_FLOAT_16
@ RS_TYPE_FLOAT_16
Definition: RenderScriptRuntime.cpp:528
lldb::DynamicValueType
DynamicValueType
Definition: lldb-enumerations.h:494
lldb_private::Stream::GetIndentLevel
unsigned GetIndentLevel() const
Get the current indentation level.
Definition: Stream.cpp:160
lldb_private::LanguageRuntime
Definition: LanguageRuntime.h:60
lldb_private::RenderScriptRuntime::Element::RS_TYPE_SCRIPT
@ RS_TYPE_SCRIPT
Definition: RenderScriptRuntime.cpp:553
lldb::eFormatVectorOfUInt16
@ eFormatVectorOfUInt16
Definition: lldb-enumerations.h:183
sp
@ sp
Definition: CompactUnwindInfo.cpp:1249
lldb_private::RenderScriptRuntime::DumpKernels
void DumpKernels(Stream &strm) const
Definition: RenderScriptRuntime.cpp:3134
set
set(option_framework FRAMEWORK) endif() if(LLDB_ENABLE_PYTHON) get_target_property(python_bindings_dir swig_wrapper_python BINARY_DIR) set(lldb_python_wrapper $
Definition: API/CMakeLists.txt:9
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:38
CommandObjectRenderScriptRuntimeKernelBreakpointSet::CommandOptions
Definition: RenderScriptRuntime.cpp:4241
lldb_private::RenderScriptRuntime::AllocationDetails::element
RenderScriptRuntime::Element element
Definition: RenderScriptRuntime.cpp:653
lldb_private::RenderScriptRuntime::Element::DataType
DataType
Definition: RenderScriptRuntime.cpp:526
lldb_private::lldb_renderscript::RSReduceBreakpointResolver
Definition: RenderScriptRuntime.h:90
lldb_private::RenderScriptRuntime::Element::RS_TYPE_UNSIGNED_16
@ RS_TYPE_UNSIGNED_16
Definition: RenderScriptRuntime.cpp:536
lldb_private::RenderScriptRuntime::AllocationDetails::Dimension::dim_2
uint32_t dim_2
Definition: RenderScriptRuntime.cpp:597
lldb_private::RenderScriptRuntime::Element::RS_TYPE_MATRIX_3X3
@ RS_TYPE_MATRIX_3X3
Definition: RenderScriptRuntime.cpp:546
Thread.h
lldb_private::Address::CalculateSymbolContextSymbol
Symbol * CalculateSymbolContextSymbol() const
Definition: Address.cpp:863
CommandObjectRenderScriptRuntimeReductionBreakpointSet::CommandOptions::OptionParsingStarting
void OptionParsingStarting(ExecutionContext *exe_ctx) override
Definition: RenderScriptRuntime.cpp:4123
CommandObjectRenderScriptRuntimeModuleDump::DoExecute
bool DoExecute(Args &command, CommandReturnObject &result) override
Definition: RenderScriptRuntime.cpp:4016
lldb_private::SectionLoadList::ResolveLoadAddress
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, bool allow_section_end=false) const
Definition: SectionLoadList.cpp:208
lldb::eArgTypeOneLiner
@ eArgTypeOneLiner
Definition: lldb-enumerations.h:557
DumpDataExtractor.h
VariableList.h
lldb_private::RenderScriptRuntime::AllocationDetails::RsDataTypeToString
static const char * RsDataTypeToString[][4]
Definition: RenderScriptRuntime.cpp:640
lldb_private::RegisterContext
Definition: RegisterContext.h:17
CommandObjectRenderScriptRuntimeKernelBreakpointSet
Definition: RenderScriptRuntime.cpp:4224
lldb_private::CompilerDeclContext
Represents a generic declaration context in a program.
Definition: CompilerDeclContext.h:30
lldb_private::ArchSpec::GetAddressByteSize
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:683
lldb_private::RenderScriptRuntime::Element::children
std::vector< Element > children
Definition: RenderScriptRuntime.cpp:564
lldb_private::RenderScriptRuntime::Element::RS_TYPE_UNSIGNED_32
@ RS_TYPE_UNSIGNED_32
Definition: RenderScriptRuntime.cpp:537
lldb::eFormatVectorOfFloat16
@ eFormatVectorOfFloat16
Definition: lldb-enumerations.h:188
lldb_private::RenderScriptRuntime::AllocationDetails::ElementHeader::type
uint16_t type
Definition: RenderScriptRuntime.cpp:628
lldb_private::RenderScriptRuntime::Element::datum_size
empirical_type< uint32_t > datum_size
Definition: RenderScriptRuntime.cpp:574
lldb_private::RenderScriptRuntime::AllocationDetails::ElementHeader::array_size
uint32_t array_size
Definition: RenderScriptRuntime.cpp:632
g_renderscript_reduction_bp_set_options
static constexpr OptionDefinition g_renderscript_reduction_bp_set_options[]
Definition: RenderScriptRuntime.cpp:4061
Symbol.h
lldb_private::Symbol::GetName
ConstString GetName() const
Definition: Symbol.cpp:498
CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::SetOptionValue
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *exe_ctx) override
Set the value of an option.
Definition: RenderScriptRuntime.cpp:4649
lldb_private::RenderScriptRuntime::ModuleKind
ModuleKind
Definition: RenderScriptRuntime.h:300
lldb_private::RenderScriptRuntime::Element::RS_TYPE_PROGRAM_RASTER
@ RS_TYPE_PROGRAM_RASTER
Definition: RenderScriptRuntime.cpp:557
lldb_private::RenderScriptRuntime::Element::RS_TYPE_BOOLEAN
@ RS_TYPE_BOOLEAN
Definition: RenderScriptRuntime.cpp:539
lldb_private::lldb_renderscript::RSKernelDescriptor
Definition: RenderScriptRuntime.h:142
CommandObjectRenderScriptRuntimeAllocationLoad::CommandObjectRenderScriptRuntimeAllocationLoad
CommandObjectRenderScriptRuntimeAllocationLoad(CommandInterpreter &interpreter)
Definition: RenderScriptRuntime.cpp:4693
lldb_private::Log::Error
void void Error(const char *fmt,...) __attribute__((format(printf
Definition: Log.cpp:146
lldb_private::Target::GetArchitecture
const ArchSpec & GetArchitecture() const
Definition: Target.h:961
CommandObjectRenderScriptRuntimeKernelBreakpointSet::CommandOptions::GetDefinitions