Skip to content

Commit 6ebaa3f

Browse files
eddyz87anakryiko
authored andcommitted
libbpf: Rewrite btf datasec names starting from '?'
Optional struct_ops maps are defined using question mark at the start of the section name, e.g.: SEC("?.struct_ops") struct test_ops optional_map = { ... }; This commit teaches libbpf to detect if kernel allows '?' prefix in datasec names, and if it doesn't then to rewrite such names by replacing '?' with '_', e.g.: DATASEC ?.struct_ops -> DATASEC _.struct_ops Signed-off-by: Eduard Zingerman <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 5ad0ecb commit 6ebaa3f

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

tools/lib/bpf/features.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,25 @@ static int probe_kern_btf_datasec(int token_fd)
147147
strs, sizeof(strs), token_fd));
148148
}
149149

150+
static int probe_kern_btf_qmark_datasec(int token_fd)
151+
{
152+
static const char strs[] = "\0x\0?.data";
153+
/* static int a; */
154+
__u32 types[] = {
155+
/* int */
156+
BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
157+
/* VAR x */ /* [2] */
158+
BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1),
159+
BTF_VAR_STATIC,
160+
/* DATASEC ?.data */ /* [3] */
161+
BTF_TYPE_ENC(3, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4),
162+
BTF_VAR_SECINFO_ENC(2, 0, 4),
163+
};
164+
165+
return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types),
166+
strs, sizeof(strs), token_fd));
167+
}
168+
150169
static int probe_kern_btf_float(int token_fd)
151170
{
152171
static const char strs[] = "\0float";
@@ -534,6 +553,9 @@ static struct kern_feature_desc {
534553
[FEAT_ARG_CTX_TAG] = {
535554
"kernel-side __arg_ctx tag", probe_kern_arg_ctx_tag,
536555
},
556+
[FEAT_BTF_QMARK_DATASEC] = {
557+
"BTF DATASEC names starting from '?'", probe_kern_btf_qmark_datasec,
558+
},
537559
};
538560

539561
bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id)

tools/lib/bpf/libbpf.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2869,6 +2869,11 @@ static bool section_have_execinstr(struct bpf_object *obj, int idx)
28692869
return sh->sh_flags & SHF_EXECINSTR;
28702870
}
28712871

2872+
static bool starts_with_qmark(const char *s)
2873+
{
2874+
return s && s[0] == '?';
2875+
}
2876+
28722877
static bool btf_needs_sanitization(struct bpf_object *obj)
28732878
{
28742879
bool has_func_global = kernel_supports(obj, FEAT_BTF_GLOBAL_FUNC);
@@ -2878,9 +2883,10 @@ static bool btf_needs_sanitization(struct bpf_object *obj)
28782883
bool has_decl_tag = kernel_supports(obj, FEAT_BTF_DECL_TAG);
28792884
bool has_type_tag = kernel_supports(obj, FEAT_BTF_TYPE_TAG);
28802885
bool has_enum64 = kernel_supports(obj, FEAT_BTF_ENUM64);
2886+
bool has_qmark_datasec = kernel_supports(obj, FEAT_BTF_QMARK_DATASEC);
28812887

28822888
return !has_func || !has_datasec || !has_func_global || !has_float ||
2883-
!has_decl_tag || !has_type_tag || !has_enum64;
2889+
!has_decl_tag || !has_type_tag || !has_enum64 || !has_qmark_datasec;
28842890
}
28852891

28862892
static int bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
@@ -2892,6 +2898,7 @@ static int bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
28922898
bool has_decl_tag = kernel_supports(obj, FEAT_BTF_DECL_TAG);
28932899
bool has_type_tag = kernel_supports(obj, FEAT_BTF_TYPE_TAG);
28942900
bool has_enum64 = kernel_supports(obj, FEAT_BTF_ENUM64);
2901+
bool has_qmark_datasec = kernel_supports(obj, FEAT_BTF_QMARK_DATASEC);
28952902
int enum64_placeholder_id = 0;
28962903
struct btf_type *t;
28972904
int i, j, vlen;
@@ -2918,7 +2925,7 @@ static int bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
29182925

29192926
name = (char *)btf__name_by_offset(btf, t->name_off);
29202927
while (*name) {
2921-
if (*name == '.')
2928+
if (*name == '.' || *name == '?')
29222929
*name = '_';
29232930
name++;
29242931
}
@@ -2933,6 +2940,14 @@ static int bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
29332940
vt = (void *)btf__type_by_id(btf, v->type);
29342941
m->name_off = vt->name_off;
29352942
}
2943+
} else if (!has_qmark_datasec && btf_is_datasec(t) &&
2944+
starts_with_qmark(btf__name_by_offset(btf, t->name_off))) {
2945+
/* replace '?' prefix with '_' for DATASEC names */
2946+
char *name;
2947+
2948+
name = (char *)btf__name_by_offset(btf, t->name_off);
2949+
if (name[0] == '?')
2950+
name[0] = '_';
29362951
} else if (!has_func && btf_is_func_proto(t)) {
29372952
/* replace FUNC_PROTO with ENUM */
29382953
vlen = btf_vlen(t);

tools/lib/bpf/libbpf_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ enum kern_feature_id {
374374
FEAT_UPROBE_MULTI_LINK,
375375
/* Kernel supports arg:ctx tag (__arg_ctx) for global subprogs natively */
376376
FEAT_ARG_CTX_TAG,
377+
/* Kernel supports '?' at the front of datasec names */
378+
FEAT_BTF_QMARK_DATASEC,
377379
__FEAT_CNT,
378380
};
379381

0 commit comments

Comments
 (0)