Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libbpf: Parse usdt args without offset on x86 (e.g. 8@(%rsp))

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

authored by

Timo Hunziker and committed by
Andrii Nakryiko
c21dc529 aa67961f

+8
+8
tools/lib/bpf/usdt.c
··· 1233 1233 if (reg_off < 0) 1234 1234 return reg_off; 1235 1235 arg->reg_off = reg_off; 1236 + } else if (sscanf(arg_str, " %d @ ( %%%15[^)] ) %n", &arg_sz, reg_name, &len) == 2) { 1237 + /* Memory dereference case without offset, e.g., 8@(%rsp) */ 1238 + arg->arg_type = USDT_ARG_REG_DEREF; 1239 + arg->val_off = 0; 1240 + reg_off = calc_pt_regs_off(reg_name); 1241 + if (reg_off < 0) 1242 + return reg_off; 1243 + arg->reg_off = reg_off; 1236 1244 } else if (sscanf(arg_str, " %d @ %%%15s %n", &arg_sz, reg_name, &len) == 2) { 1237 1245 /* Register read case, e.g., -4@%eax */ 1238 1246 arg->arg_type = USDT_ARG_REG;