Skip to content

Commit 43de622

Browse files
iii-iKernel Patches Daemon
authored andcommitted
libbpf: Add s390-specific USDT arg spec parsing logic
The logic is superficially similar to that of x86, but the small differences (no need for register table and dynamic allocation of register names, no $ sign before constants) make maintaining a common implementation too burdensome. Therefore simply add a s390x-specific version of parse_usdt_arg(). Note that while bcc supports index registers, this patch does not. This should not be a problem in most cases, since s390 uses a default value "nor" for STAP_SDT_ARG_CONSTRAINT. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
1 parent 23308d0 commit 43de622

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

tools/lib/bpf/usdt.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,6 +1326,63 @@ static int parse_usdt_arg(const char *arg_str, int arg_num,
13261326
return len;
13271327
}
13281328

1329+
#elif defined(__s390x__)
1330+
1331+
/* Do not support __s390__ for now, since user_pt_regs is broken with -m31. */
1332+
1333+
static int parse_usdt_arg(const char *arg_str, int arg_num,
1334+
struct usdt_arg_spec *arg)
1335+
{
1336+
unsigned int reg;
1337+
int sz, len;
1338+
long off;
1339+
1340+
if (sscanf(arg_str, " %d @ %ld ( %%r%u ) %n", &sz, &off, &reg, &len) == 3) {
1341+
/* Memory dereference case, e.g., -2@-28(%r15) */
1342+
arg->arg_type = USDT_ARG_REG_DEREF;
1343+
arg->val_off = off;
1344+
if (reg > 15) {
1345+
pr_warn("usdt: unrecognized register '%%r%u'\n", reg);
1346+
return -EINVAL;
1347+
}
1348+
arg->reg_off = offsetof(user_pt_regs, gprs[reg]);
1349+
} else if (sscanf(arg_str, " %d @ %%r%u %n", &sz, &reg, &len) == 2) {
1350+
/* Register read case, e.g., -8@%r0 */
1351+
arg->arg_type = USDT_ARG_REG;
1352+
arg->val_off = 0;
1353+
if (reg > 15) {
1354+
pr_warn("usdt: unrecognized register '%%r%u'\n", reg);
1355+
return -EINVAL;
1356+
}
1357+
arg->reg_off = offsetof(user_pt_regs, gprs[reg]);
1358+
} else if (sscanf(arg_str, " %d @ %ld %n", &sz, &off, &len) == 2) {
1359+
/* Constant value case, e.g., 4@71 */
1360+
arg->arg_type = USDT_ARG_CONST;
1361+
arg->val_off = off;
1362+
arg->reg_off = -1;
1363+
} else {
1364+
pr_warn("usdt: unrecognized arg #%d spec '%s'\n", arg_num,
1365+
arg_str);
1366+
return -EINVAL;
1367+
}
1368+
1369+
arg->arg_signed = sz < 0;
1370+
if (sz < 0)
1371+
sz = -sz;
1372+
1373+
switch (sz) {
1374+
case 1: case 2: case 4: case 8:
1375+
arg->arg_bitshift = 64 - sz * 8;
1376+
break;
1377+
default:
1378+
pr_warn("usdt: unsupported arg #%d (spec '%s') size: %d\n",
1379+
arg_num, arg_str, sz);
1380+
return -EINVAL;
1381+
}
1382+
1383+
return len;
1384+
}
1385+
13291386
#else
13301387

13311388
static int parse_usdt_arg(const char *arg_str, int arg_num, struct usdt_arg_spec *arg)

0 commit comments

Comments
 (0)