https://gcc.gnu.org/g:d30def000abbc8d254a128751ac87a079cd10202
commit r15-6918-gd30def000abbc8d254a128751ac87a079cd10202 Author: Cupertino Miranda <cupertino.mira...@oracle.com> Date: Wed Jan 15 14:25:44 2025 +0000 bpf: make sure CO-RE relocs are typed with struct BTF_KIND_STRUCT Based on observation within bpf-next selftests and comparisson of GCC and clang compiled code, the BPF loader expects all CO-RE relocations to point to BTF non const and non volatile type nodes. gcc/ChangeLog: * btfout.cc (get_btf_kind): Remove static from function definition. * config/bpf/btfext-out.cc (bpf_code_reloc_add): Check if CO-RE type is not a const or volatile. * ctfc.h (btf_dtd_kind): Add prototype for function. gcc/testsuite/ChangeLog: * gcc.target/bpf/core-attr-const.c: New test. Diff: --- gcc/btfout.cc | 2 +- gcc/config/bpf/btfext-out.cc | 7 +++++ gcc/ctfc.h | 2 ++ gcc/testsuite/gcc.target/bpf/core-attr-const.c | 40 ++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 16d5b7f97cc4..ff7ea42a9614 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -148,7 +148,7 @@ get_btf_kind (uint32_t ctf_kind) /* Convenience wrapper around get_btf_kind for the common case. */ -static uint32_t +uint32_t btf_dtd_kind (ctf_dtdef_ref dtd) { if (!dtd) diff --git a/gcc/config/bpf/btfext-out.cc b/gcc/config/bpf/btfext-out.cc index ad5ce9655a7c..7cab59bb5400 100644 --- a/gcc/config/bpf/btfext-out.cc +++ b/gcc/config/bpf/btfext-out.cc @@ -298,6 +298,13 @@ bpf_core_reloc_add (const tree type, const char * section_name, ctf_container_ref ctfc = ctf_get_tu_ctfc (); ctf_dtdef_ref dtd = ctf_lookup_tree_type (ctfc, type); + /* Make sure CO-RE type is never the const or volatile version. */ + if ((btf_dtd_kind (dtd) == BTF_KIND_CONST + || btf_dtd_kind (dtd) == BTF_KIND_VOLATILE) + && kind >= BPF_RELO_FIELD_BYTE_OFFSET + && kind <= BPF_RELO_FIELD_RSHIFT_U64) + dtd = dtd->ref_type; + /* Buffer the access string in the auxiliary strtab. */ bpfcr->bpfcr_astr_off = 0; gcc_assert (accessor != NULL); diff --git a/gcc/ctfc.h b/gcc/ctfc.h index 6a9baa56194c..32c73be6a412 100644 --- a/gcc/ctfc.h +++ b/gcc/ctfc.h @@ -465,4 +465,6 @@ extern void btf_mark_type_used (tree); extern int ctfc_get_dtd_srcloc (ctf_dtdef_ref, ctf_srcloc_ref); extern int ctfc_get_dvd_srcloc (ctf_dvdef_ref, ctf_srcloc_ref); +extern uint32_t btf_dtd_kind (ctf_dtdef_ref dtd); + #endif /* GCC_CTFC_H */ diff --git a/gcc/testsuite/gcc.target/bpf/core-attr-const.c b/gcc/testsuite/gcc.target/bpf/core-attr-const.c new file mode 100644 index 000000000000..da6113a3faf1 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/core-attr-const.c @@ -0,0 +1,40 @@ +/* Test to make sure CO-RE access relocs point to non const versions of the + type. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -dA -gbtf -mco-re -masm=normal" } */ + +struct S { + int a; + int b; + int c; +} __attribute__((preserve_access_index)); + +void +func (struct S * s) +{ + int *x; + int *y; + int *z; + struct S tmp; + const struct S *cs = s; + volatile struct S *vs = s; + + /* 0:2 */ + x = &(s->c); + + /* 0:1 */ + y = (int *) &(cs->b); + + /* 0:1 */ + z = (int *) &(vs->b); + + *x = 4; + *y = 4; + *z = 4; +} + +/* Both const and non const struct type should have the same bpfcr_type. */ +/* { dg-final { scan-assembler-times "0x1\t# bpfcr_type \\(struct S\\)" 1 } } */ +/* { dg-final { scan-assembler-times "0x1\t# bpfcr_type \\(const struct S\\)" 1 } } */ +/* { dg-final { scan-assembler-times "0x1\t# bpfcr_type \\(volatile struct S\\)" 1 } } */