btf: change encoding of forward-declared enums [PR111735]
The BTF specification does not formally define a representation for forward-declared enum types such as: enum Foo; Forward-declarations for struct and union types are represented by BTF_KIND_FWD, which has a 1-bit flag distinguishing the two. The de-facto standard format used by other tools like clang and pahole is to represent forward-declared enums as BTF_KIND_ENUM with vlen=0, i.e. as a regular enum type with no enumerators. This patch changes GCC to adopt that format, and makes a couple of minor cleanups in btf_asm_type (). gcc/ PR debug/111735 * btfout.cc (btf_fwd_to_enum_p): New. (btf_asm_type_ref): Special case references to enum forwards. (btf_asm_type): Special case enum forwards. Rename btf_size_type to btf_size, and change chained ifs switching on btf_kind into else ifs. gcc/testsuite/ PR debug/111735 * gcc.dg/debug/btf/btf-forward-2.c: New test.
This commit is contained in:
parent
0a37463758
commit
1502d724df
2 changed files with 53 additions and 11 deletions
|
@ -268,6 +268,17 @@ btf_emit_id_p (ctf_id_t id)
|
|||
&& (btf_id_map[id] <= BTF_MAX_TYPE));
|
||||
}
|
||||
|
||||
/* Return true if DTD is a forward-declared enum. The BTF representation
|
||||
of forward declared enums is not formally defined. */
|
||||
|
||||
static bool
|
||||
btf_fwd_to_enum_p (ctf_dtdef_ref dtd)
|
||||
{
|
||||
uint32_t btf_kind = get_btf_kind (CTF_V2_INFO_KIND (dtd->dtd_data.ctti_info));
|
||||
|
||||
return (btf_kind == BTF_KIND_FWD && dtd->dtd_data.ctti_type == CTF_K_ENUM);
|
||||
}
|
||||
|
||||
/* Each BTF type can be followed additional, variable-length information
|
||||
completing the description of the type. Calculate the number of bytes
|
||||
of variable information required to encode a given type. */
|
||||
|
@ -753,8 +764,12 @@ btf_asm_type_ref (const char *prefix, ctf_container_ref ctfc, ctf_id_t ref_id)
|
|||
uint32_t ref_kind
|
||||
= get_btf_kind (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info));
|
||||
|
||||
const char *kind_name = btf_fwd_to_enum_p (ref_type)
|
||||
? btf_kind_name (BTF_KIND_ENUM)
|
||||
: btf_kind_name (ref_kind);
|
||||
|
||||
dw2_asm_output_data (4, ref_id, "%s: (BTF_KIND_%s '%s')",
|
||||
prefix, btf_kind_name (ref_kind),
|
||||
prefix, kind_name,
|
||||
get_btf_type_name (ref_type));
|
||||
}
|
||||
}
|
||||
|
@ -765,11 +780,11 @@ btf_asm_type_ref (const char *prefix, ctf_container_ref ctfc, ctf_id_t ref_id)
|
|||
static void
|
||||
btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
|
||||
{
|
||||
uint32_t btf_kind, btf_kflag, btf_vlen, btf_size_type;
|
||||
uint32_t btf_kind, btf_kflag, btf_vlen, btf_size;
|
||||
uint32_t ctf_info = dtd->dtd_data.ctti_info;
|
||||
|
||||
btf_kind = get_btf_kind (CTF_V2_INFO_KIND (ctf_info));
|
||||
btf_size_type = dtd->dtd_data.ctti_type;
|
||||
btf_size = dtd->dtd_data.ctti_size;
|
||||
btf_vlen = CTF_V2_INFO_VLEN (ctf_info);
|
||||
|
||||
/* By now any unrepresentable types have been removed. */
|
||||
|
@ -777,7 +792,7 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
|
|||
|
||||
/* Size 0 integers are redundant definitions of void. None should remain
|
||||
in the types list by this point. */
|
||||
gcc_assert (btf_kind != BTF_KIND_INT || btf_size_type >= 1);
|
||||
gcc_assert (btf_kind != BTF_KIND_INT || btf_size >= 1);
|
||||
|
||||
/* Re-encode the ctti_info to BTF. */
|
||||
/* kflag is 1 for structs/unions with a bitfield member.
|
||||
|
@ -810,16 +825,26 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
|
|||
structs and forwards to unions. The dwarf2ctf conversion process stores
|
||||
the kind of the forward in ctti_type, but for BTF this must be 0 for
|
||||
forwards, with only the KIND_FLAG to distinguish.
|
||||
At time of writing, BTF forwards to enums are unspecified. */
|
||||
if (btf_kind == BTF_KIND_FWD)
|
||||
Forwards to enum types are special-cased below. */
|
||||
else if (btf_kind == BTF_KIND_FWD)
|
||||
{
|
||||
if (dtd->dtd_data.ctti_type == CTF_K_UNION)
|
||||
btf_kflag = 1;
|
||||
|
||||
btf_size_type = 0;
|
||||
/* PR debug/111735. Encode foward-declared enums as BTF_KIND_ENUM
|
||||
with vlen=0. A representation for these is not formally defined;
|
||||
this is the de-facto standard used by other tools like clang
|
||||
and pahole. */
|
||||
else if (dtd->dtd_data.ctti_type == CTF_K_ENUM)
|
||||
{
|
||||
btf_kind = BTF_KIND_ENUM;
|
||||
btf_vlen = 0;
|
||||
}
|
||||
|
||||
btf_size = 0;
|
||||
}
|
||||
|
||||
if (btf_kind == BTF_KIND_ENUM)
|
||||
else if (btf_kind == BTF_KIND_ENUM)
|
||||
{
|
||||
btf_kflag = dtd->dtd_enum_unsigned
|
||||
? BTF_KF_ENUM_UNSIGNED
|
||||
|
@ -829,7 +854,7 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
|
|||
}
|
||||
|
||||
/* PR debug/112656. BTF_KIND_FUNC_PROTO is always anonymous. */
|
||||
if (btf_kind == BTF_KIND_FUNC_PROTO)
|
||||
else if (btf_kind == BTF_KIND_FUNC_PROTO)
|
||||
dtd->dtd_data.ctti_name = 0;
|
||||
|
||||
dw2_asm_output_data (4, dtd->dtd_data.ctti_name,
|
||||
|
@ -848,8 +873,7 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
|
|||
case BTF_KIND_ENUM:
|
||||
case BTF_KIND_DATASEC:
|
||||
case BTF_KIND_ENUM64:
|
||||
dw2_asm_output_data (4, dtd->dtd_data.ctti_size, "btt_size: %uB",
|
||||
dtd->dtd_data.ctti_size);
|
||||
dw2_asm_output_data (4, btf_size, "btt_size: %uB", btf_size);
|
||||
return;
|
||||
case BTF_KIND_ARRAY:
|
||||
case BTF_KIND_FWD:
|
||||
|
|
18
gcc/testsuite/gcc.dg/debug/btf/btf-forward-2.c
Normal file
18
gcc/testsuite/gcc.dg/debug/btf/btf-forward-2.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* PR111735. Test BTF generation for forward-declared enum.
|
||||
|
||||
The BTF representation for forward-declared enums is not formally
|
||||
defined, but the de-facto representation used by various tools is
|
||||
to encode them as a BTF_KIND_ENUM type with vlen=0 and size=0. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O0 -gbtf -dA" } */
|
||||
|
||||
enum Foo;
|
||||
enum Foo *pfoo;
|
||||
|
||||
/* Check that there is one BTF_KIND_ENUM with vlen=0, and no BTF_KIND_FWD. */
|
||||
/* { dg-final { scan-assembler-times "\[\t \]0x6000000\[\t \]+\[^\n\]*btt_info" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "\[\t \]0x7000000\[\t \]+\[^\n\]*btt_info" 0 } } */
|
||||
|
||||
/* Verify the reference to the enum-forward. */
|
||||
/* { dg-final { scan-assembler-times "btt_type: \\(BTF_KIND_ENUM 'Foo'\\)" 1 } } */
|
Loading…
Add table
Reference in a new issue