/* Convenience wrapper around get_btf_kind for the common case. */
-static uint32_t
+uint32_t
btf_dtd_kind (ctf_dtdef_ref dtd)
{
if (!dtd)
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);
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 */
--- /dev/null
+/* 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 } } */