libbpf: Parse usdt args without offset on x86 (e.g. 8@(%rsp))
authorTimo Hunziker <timo.hunziker@gmx.ch>
Sat, 3 Dec 2022 12:37:46 +0000 (12:37 +0000)
committerAndrii Nakryiko <andrii@kernel.org>
Wed, 7 Dec 2022 00:16:50 +0000 (16:16 -0800)
Parse USDT arguments like "8@(%rsp)" on x86. These are emmited by
SystemTap. The argument syntax is similar to the existing "memory
dereference case" but the offset left out as it's zero (i.e. read
the value from the address in the register). We treat it the same
as the the "memory dereference case", but set the offset to 0.

I've tested that this fixes the "unrecognized arg #N spec: 8@(%rsp).."
error I've run into when attaching to a probe with such an argument.
Attaching and reading the correct argument values works.

Something similar might be needed for the other supported
architectures.

  [0] Closes: https://github.com/libbpf/libbpf/issues/559

Signed-off-by: Timo Hunziker <timo.hunziker@gmx.ch>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20221203123746.2160-1-timo.hunziker@eclipso.ch
tools/lib/bpf/usdt.c

index b8daae265f996b5b2bcd22e089ee290e87b5f36b..75b411fc2c77b60ba81633838668101cbd1e7ff9 100644 (file)
@@ -1233,6 +1233,14 @@ static int parse_usdt_arg(const char *arg_str, int arg_num, struct usdt_arg_spec
                if (reg_off < 0)
                        return reg_off;
                arg->reg_off = reg_off;
+       } else if (sscanf(arg_str, " %d @ ( %%%15[^)] ) %n", &arg_sz, reg_name, &len) == 2) {
+               /* Memory dereference case without offset, e.g., 8@(%rsp) */
+               arg->arg_type = USDT_ARG_REG_DEREF;
+               arg->val_off = 0;
+               reg_off = calc_pt_regs_off(reg_name);
+               if (reg_off < 0)
+                       return reg_off;
+               arg->reg_off = reg_off;
        } else if (sscanf(arg_str, " %d @ %%%15s %n", &arg_sz, reg_name, &len) == 2) {
                /* Register read case, e.g., -4@%eax */
                arg->arg_type = USDT_ARG_REG;