|
@@ -178,3 +178,51 @@ extern ssize_t traceprobe_probes_write(struct file *file,
|
|
|
int (*createfn)(int, char**));
|
|
|
|
|
|
extern int traceprobe_command(const char *buf, int (*createfn)(int, char**));
|
|
|
+
|
|
|
+/* Sum up total data length for dynamic arraies (strings) */
|
|
|
+static inline __kprobes int
|
|
|
+__get_data_size(struct trace_probe *tp, struct pt_regs *regs)
|
|
|
+{
|
|
|
+ int i, ret = 0;
|
|
|
+ u32 len;
|
|
|
+
|
|
|
+ for (i = 0; i < tp->nr_args; i++)
|
|
|
+ if (unlikely(tp->args[i].fetch_size.fn)) {
|
|
|
+ call_fetch(&tp->args[i].fetch_size, regs, &len);
|
|
|
+ ret += len;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/* Store the value of each argument */
|
|
|
+static inline __kprobes void
|
|
|
+store_trace_args(int ent_size, struct trace_probe *tp, struct pt_regs *regs,
|
|
|
+ u8 *data, int maxlen)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ u32 end = tp->size;
|
|
|
+ u32 *dl; /* Data (relative) location */
|
|
|
+
|
|
|
+ for (i = 0; i < tp->nr_args; i++) {
|
|
|
+ if (unlikely(tp->args[i].fetch_size.fn)) {
|
|
|
+ /*
|
|
|
+ * First, we set the relative location and
|
|
|
+ * maximum data length to *dl
|
|
|
+ */
|
|
|
+ dl = (u32 *)(data + tp->args[i].offset);
|
|
|
+ *dl = make_data_rloc(maxlen, end - tp->args[i].offset);
|
|
|
+ /* Then try to fetch string or dynamic array data */
|
|
|
+ call_fetch(&tp->args[i].fetch, regs, dl);
|
|
|
+ /* Reduce maximum length */
|
|
|
+ end += get_rloc_len(*dl);
|
|
|
+ maxlen -= get_rloc_len(*dl);
|
|
|
+ /* Trick here, convert data_rloc to data_loc */
|
|
|
+ *dl = convert_rloc_to_loc(*dl,
|
|
|
+ ent_size + tp->args[i].offset);
|
|
|
+ } else
|
|
|
+ /* Just fetching data normally */
|
|
|
+ call_fetch(&tp->args[i].fetch, regs,
|
|
|
+ data + tp->args[i].offset);
|
|
|
+ }
|
|
|
+}
|