Message ID | 20231113223739.11844-1-cupertino.miranda@oracle.com |
---|---|
State | New |
Headers | show |
Series | Fixed problem with BTF defining smaller enums. | expand |
Hi Cupertino, A couple of comments inline. On 11/13/23 14:37, Cupertino Miranda wrote: > This patch fixes a BTF, which would become invalid when having > smaller then 4 byte definitions of enums. > For example, when using the __attribute__((mode(byte))) in the enum > definition. Please add a test for this case in the BTF testsuite. > > Two problems were identified: > - it would incorrectly create an entry for enum64 when the size of the > enum was different then 4. > - it would allocate less then 4 bytes for the value entry in BTF, in > case the type was smaller. > > BTF generated was validated against clang. > > gcc/ChangeLog: > * bpfout.cc (btf_calc_num_vbytes): Fixed logic for enum64. > (btf_asm_enum_const): Corrected logic for enum64 and smaller > than 4 bytes values. > --- > gcc/btfout.cc | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > > diff --git a/gcc/btfout.cc b/gcc/btfout.cc > index e07fed302c24..d2263ec6eec3 100644 > --- a/gcc/btfout.cc > +++ b/gcc/btfout.cc > @@ -299,7 +299,7 @@ btf_calc_num_vbytes (ctf_dtdef_ref dtd) > break; > > case BTF_KIND_ENUM: > - vlen_bytes += (dtd->dtd_data.ctti_size == 0x8) > + vlen_bytes += (dtd->dtd_data.ctti_size > 4) > ? vlen * sizeof (struct btf_enum64) > : vlen * sizeof (struct btf_enum); > break; > @@ -914,13 +914,13 @@ btf_asm_enum_const (unsigned int size, ctf_dmdef_t * dmd, unsigned int idx) > { > dw2_asm_output_data (4, dmd->dmd_name_offset, "ENUM_CONST '%s' idx=%u", > dmd->dmd_name, idx); > - if (size == 4) > - dw2_asm_output_data (size, dmd->dmd_value, "bte_value"); > - else > + if (size > 4) > { > - dw2_asm_output_data (4, dmd->dmd_value & 0xffffffff, "bte_value_lo32"); > + dw2_asm_output_data (4, dmd->dmd_value & 0xfffffffe, "bte_value_lo32"); I don't understand the mask change here. Why clear the low bit of the enum value? > dw2_asm_output_data (4, (dmd->dmd_value >> 32) & 0xffffffff, "bte_value_hi32"); > } > + else > + dw2_asm_output_data (size < 4 ? 4 : size, dmd->dmd_value, "bte_value"); In the else case isn't size guaranteed <= 4? In which case, 'size < 4 ? 4 : size' always evaluates to 4. So I would suggest to just write a literal 4 to keep it simple. > } > > /* Asm'out a function parameter description following a BTF_KIND_FUNC_PROTO. */
diff --git a/gcc/btfout.cc b/gcc/btfout.cc index e07fed302c24..d2263ec6eec3 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -299,7 +299,7 @@ btf_calc_num_vbytes (ctf_dtdef_ref dtd) break; case BTF_KIND_ENUM: - vlen_bytes += (dtd->dtd_data.ctti_size == 0x8) + vlen_bytes += (dtd->dtd_data.ctti_size > 4) ? vlen * sizeof (struct btf_enum64) : vlen * sizeof (struct btf_enum); break; @@ -914,13 +914,13 @@ btf_asm_enum_const (unsigned int size, ctf_dmdef_t * dmd, unsigned int idx) { dw2_asm_output_data (4, dmd->dmd_name_offset, "ENUM_CONST '%s' idx=%u", dmd->dmd_name, idx); - if (size == 4) - dw2_asm_output_data (size, dmd->dmd_value, "bte_value"); - else + if (size > 4) { - dw2_asm_output_data (4, dmd->dmd_value & 0xffffffff, "bte_value_lo32"); + dw2_asm_output_data (4, dmd->dmd_value & 0xfffffffe, "bte_value_lo32"); dw2_asm_output_data (4, (dmd->dmd_value >> 32) & 0xffffffff, "bte_value_hi32"); } + else + dw2_asm_output_data (size < 4 ? 4 : size, dmd->dmd_value, "bte_value"); } /* Asm'out a function parameter description following a BTF_KIND_FUNC_PROTO. */