0001
0002
0003
0004
0005
0006 static nokprobe_inline void
0007 fetch_store_raw(unsigned long val, struct fetch_insn *code, void *buf)
0008 {
0009 switch (code->size) {
0010 case 1:
0011 *(u8 *)buf = (u8)val;
0012 break;
0013 case 2:
0014 *(u16 *)buf = (u16)val;
0015 break;
0016 case 4:
0017 *(u32 *)buf = (u32)val;
0018 break;
0019 case 8:
0020
0021 *(u64 *)buf = (u64)val;
0022 break;
0023 default:
0024 *(unsigned long *)buf = val;
0025 }
0026 }
0027
0028 static nokprobe_inline void
0029 fetch_apply_bitfield(struct fetch_insn *code, void *buf)
0030 {
0031 switch (code->basesize) {
0032 case 1:
0033 *(u8 *)buf <<= code->lshift;
0034 *(u8 *)buf >>= code->rshift;
0035 break;
0036 case 2:
0037 *(u16 *)buf <<= code->lshift;
0038 *(u16 *)buf >>= code->rshift;
0039 break;
0040 case 4:
0041 *(u32 *)buf <<= code->lshift;
0042 *(u32 *)buf >>= code->rshift;
0043 break;
0044 case 8:
0045 *(u64 *)buf <<= code->lshift;
0046 *(u64 *)buf >>= code->rshift;
0047 break;
0048 }
0049 }
0050
0051
0052
0053
0054
0055
0056 static int
0057 process_fetch_insn(struct fetch_insn *code, void *rec,
0058 void *dest, void *base);
0059 static nokprobe_inline int fetch_store_strlen(unsigned long addr);
0060 static nokprobe_inline int
0061 fetch_store_string(unsigned long addr, void *dest, void *base);
0062 static nokprobe_inline int fetch_store_strlen_user(unsigned long addr);
0063 static nokprobe_inline int
0064 fetch_store_string_user(unsigned long addr, void *dest, void *base);
0065 static nokprobe_inline int
0066 probe_mem_read(void *dest, void *src, size_t size);
0067 static nokprobe_inline int
0068 probe_mem_read_user(void *dest, void *src, size_t size);
0069
0070
0071 static nokprobe_inline int
0072 process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val,
0073 void *dest, void *base)
0074 {
0075 struct fetch_insn *s3 = NULL;
0076 int total = 0, ret = 0, i = 0;
0077 u32 loc = 0;
0078 unsigned long lval = val;
0079
0080 stage2:
0081
0082 do {
0083 if (code->op == FETCH_OP_DEREF) {
0084 lval = val;
0085 ret = probe_mem_read(&val, (void *)val + code->offset,
0086 sizeof(val));
0087 } else if (code->op == FETCH_OP_UDEREF) {
0088 lval = val;
0089 ret = probe_mem_read_user(&val,
0090 (void *)val + code->offset, sizeof(val));
0091 } else
0092 break;
0093 if (ret)
0094 return ret;
0095 code++;
0096 } while (1);
0097
0098 s3 = code;
0099 stage3:
0100
0101 if (unlikely(!dest)) {
0102 if (code->op == FETCH_OP_ST_STRING) {
0103 ret = fetch_store_strlen(val + code->offset);
0104 code++;
0105 goto array;
0106 } else if (code->op == FETCH_OP_ST_USTRING) {
0107 ret += fetch_store_strlen_user(val + code->offset);
0108 code++;
0109 goto array;
0110 } else
0111 return -EILSEQ;
0112 }
0113
0114 switch (code->op) {
0115 case FETCH_OP_ST_RAW:
0116 fetch_store_raw(val, code, dest);
0117 break;
0118 case FETCH_OP_ST_MEM:
0119 probe_mem_read(dest, (void *)val + code->offset, code->size);
0120 break;
0121 case FETCH_OP_ST_UMEM:
0122 probe_mem_read_user(dest, (void *)val + code->offset, code->size);
0123 break;
0124 case FETCH_OP_ST_STRING:
0125 loc = *(u32 *)dest;
0126 ret = fetch_store_string(val + code->offset, dest, base);
0127 break;
0128 case FETCH_OP_ST_USTRING:
0129 loc = *(u32 *)dest;
0130 ret = fetch_store_string_user(val + code->offset, dest, base);
0131 break;
0132 default:
0133 return -EILSEQ;
0134 }
0135 code++;
0136
0137
0138 if (code->op == FETCH_OP_MOD_BF) {
0139 fetch_apply_bitfield(code, dest);
0140 code++;
0141 }
0142
0143 array:
0144
0145 if (code->op == FETCH_OP_LP_ARRAY) {
0146 total += ret;
0147 if (++i < code->param) {
0148 code = s3;
0149 if (s3->op != FETCH_OP_ST_STRING &&
0150 s3->op != FETCH_OP_ST_USTRING) {
0151 dest += s3->size;
0152 val += s3->size;
0153 goto stage3;
0154 }
0155 code--;
0156 val = lval + sizeof(char *);
0157 if (dest) {
0158 dest += sizeof(u32);
0159 *(u32 *)dest = update_data_loc(loc, ret);
0160 }
0161 goto stage2;
0162 }
0163 code++;
0164 ret = total;
0165 }
0166
0167 return code->op == FETCH_OP_END ? ret : -EILSEQ;
0168 }
0169
0170
0171 static nokprobe_inline int
0172 __get_data_size(struct trace_probe *tp, struct pt_regs *regs)
0173 {
0174 struct probe_arg *arg;
0175 int i, len, ret = 0;
0176
0177 for (i = 0; i < tp->nr_args; i++) {
0178 arg = tp->args + i;
0179 if (unlikely(arg->dynamic)) {
0180 len = process_fetch_insn(arg->code, regs, NULL, NULL);
0181 if (len > 0)
0182 ret += len;
0183 }
0184 }
0185
0186 return ret;
0187 }
0188
0189
0190 static nokprobe_inline void
0191 store_trace_args(void *data, struct trace_probe *tp, void *rec,
0192 int header_size, int maxlen)
0193 {
0194 struct probe_arg *arg;
0195 void *base = data - header_size;
0196 void *dyndata = data + tp->size;
0197 u32 *dl;
0198 int ret, i;
0199
0200 for (i = 0; i < tp->nr_args; i++) {
0201 arg = tp->args + i;
0202 dl = data + arg->offset;
0203
0204 if (unlikely(arg->dynamic))
0205 *dl = make_data_loc(maxlen, dyndata - base);
0206 ret = process_fetch_insn(arg->code, rec, dl, base);
0207 if (unlikely(ret < 0 && arg->dynamic)) {
0208 *dl = make_data_loc(0, dyndata - base);
0209 } else {
0210 dyndata += ret;
0211 maxlen -= ret;
0212 }
0213 }
0214 }
0215
0216 static inline int
0217 print_probe_args(struct trace_seq *s, struct probe_arg *args, int nr_args,
0218 u8 *data, void *field)
0219 {
0220 void *p;
0221 int i, j;
0222
0223 for (i = 0; i < nr_args; i++) {
0224 struct probe_arg *a = args + i;
0225
0226 trace_seq_printf(s, " %s=", a->name);
0227 if (likely(!a->count)) {
0228 if (!a->type->print(s, data + a->offset, field))
0229 return -ENOMEM;
0230 continue;
0231 }
0232 trace_seq_putc(s, '{');
0233 p = data + a->offset;
0234 for (j = 0; j < a->count; j++) {
0235 if (!a->type->print(s, p, field))
0236 return -ENOMEM;
0237 trace_seq_putc(s, j == a->count - 1 ? '}' : ',');
0238 p += a->type->size;
0239 }
0240 }
0241 return 0;
0242 }