btf: refactor and simplify implementation

This patch heavily refactors btfout.cc to take advantage of the
structural changes in the prior commits.

Now that inter-type references are internally stored as simply pointers,
all the painful, brittle, confusing infrastructure that was used in the
process of converting CTF type IDs to BTF type IDs can be thrown out.
This greatly simplifies the entire process of converting from CTF to
BTF, making the code cleaner, easier to read, and easier to maintain.

In addition, we no longer need to worry about destructive changes in
internal data structures used commonly by CTF and BTF, which allows
deleting several ancillary data structures previously used in btfout.cc.

This is nearly transparent, but a few improvements have also been made:

 1) BTF_KIND_FUNC records are now _always_ constructed at early_finish,
    allowing us to construct records even for functions which are later
    inlined by optimizations. DATASEC entries for functions are only
    constructed at late_finish, to avoid incorrectly generating entries
    for functions which get inlined.

 2) BTF_KIND_VAR records and DATASEC entries for them are now always
    constructed at (late) finish, which avoids cases where we could
    incorrectly create records for variables which were completely
    optimized away.  This fixes PR debug/113566 for non-LTO builds.
    In LTO builds, BTF must be emitted at early_finish, so some VAR
    records may be emitted for variables which are later optimized away.

 3) Some additional assembler comments have been added with more
    information for debugging.

gcc/
	* btfout.cc (struct btf_datasec_entry): New.
	(struct btf_datasec): Add `id' member.  Change `entries' to use
	new struct btf_datasec_entry.
	(func_map): New hash_map.
	(max_translated_id): New.
	(btf_var_ids, btf_id_map, holes, voids, num_vars_added)
	(num_types_added, num_types_created): Delete.
	(btf_absolute_var_id, btf_relative_var_id, btf_absolute_func_id)
	(btf_relative_func_id, btf_absolute_datasec_id, init_btf_id_map)
	(get_btf_id, set_btf_id, btf_emit_id_p): Delete.
	(btf_removed_type_p): Delete.
	(btf_dtd_kind, btf_emit_type_p): New helpers.
	(btf_fwd_to_enum_p, btf_calc_num_vbytes): Use them.
	(btf_collect_datasec): Delete.
	(btf_dtd_postprocess_cb, btf_dvd_emit_preprocess_cb)
	(btf_dtd_emit_preprocess_cb, btf_emit_preprocess): Delete.
	(btf_dmd_representable_bitfield_p): Adapt to type reference changes
	and delete now-unused ctfc argument.
	(btf_asm_datasec_type_ref): Delete.
	(btf_asm_type_ref): Adapt to type reference changes, simplify.
	(btf_asm_type): Likewise. Mark struct/union types with bitfield
	members.
	(btf_asm_array): Adapt to data structure changes.
	(btf_asm_varent): Likewise.
	(btf_asm_sou_member): Likewise. Ensure non-bitfield members are
	correctly re-encoded if struct or union contains any bitfield.
	(btf_asm_func_arg, btf_asm_func_type, btf_asm_datasec_entry)
	(btf_asm_datasec_type): Adapt to data structure changes.
	(output_btf_header): Adapt to other changes, simplify type
	length calculation, add info to assembler comments.
	(output_btf_vars): Adapt to other changes.
	(output_btf_strs): Fix overlong lines.
	(output_asm_btf_sou_fields, output_asm_btf_enum_list)
	(output_asm_btf_func_args_list, output_asm_btf_vlen_bytes)
	(output_asm_btf_type, output_btf_types, output_btf_func_types)
	(output_btf_datasec_types): Adapt to other changes.
	(btf_init_postprocess): Delete.
	(btf_output): Change to only perform output.
	(btf_add_const_void, btf_add_func_records): New.
	(btf_early_finish): Use them here. New.
	(btf_datasec_push_entry): Adapt to data structure changes.
	(btf_datasec_add_func, btf_datasec_add_var): New.
	(btf_add_func_datasec_entries): New.
	(btf_emit_variable_p): New helper.
	(btf_add_vars): Use it here. New.
	(btf_type_list_cb, btf_collect_translated_types): New.
	(btf_assign_func_ids, btf_late_assign_var_ids)
	(btf_assign_datasec_ids): New.
	(btf_finish): Remove unused argument. Call new btf_late*
	functions and btf_output.
	(btf_finalize): Adapt to data structure changes.
	* ctfc.h (struct ctf_dtdef): Convert existing boolean flags to
	BOOL_BITFIELD and reorder.
	(struct ctf_dvdef): Add dvd_id member.
	(btf_finish): Remove argument from prototype.
	(get_btf_id): Delete prototype.
	(funcs_traverse_callback, traverse_btf_func_types): Add an
	explanatory comment.
	* dwarf2ctf.cc (ctf_debug_finish): Remove unused argument.
	* dwarf2ctf.h: Analogous change.
	* dwarf2out.cc: Likewise.
This commit is contained in:
David Faust 2024-05-30 14:06:27 -07:00
parent 36774cec1f
commit 616c44f02b
5 changed files with 556 additions and 756 deletions

File diff suppressed because it is too large Load diff

View file

@ -164,10 +164,14 @@ struct GTY ((for_user)) ctf_dtdef
ctf_id_t dtd_type; /* Type identifier for this definition. */
ctf_dtdef_ref ref_type; /* Type referred to by this type (if any). */
ctf_itype_t dtd_data; /* Type node. */
bool from_global_func; /* Whether this type was added from a global
function. */
uint32_t linkage; /* Used in function types. 0=local, 1=global. */
bool dtd_enum_unsigned; /* Enum signedness. */
/* Whether this type was added from a global function. */
BOOL_BITFIELD from_global_func : 1;
/* Enum signedness. */
BOOL_BITFIELD dtd_enum_unsigned : 1;
/* Lots of spare bits. */
union GTY ((desc ("ctf_dtu_d_union_selector (&%1)")))
{
/* struct, union, or enum. */
@ -194,6 +198,7 @@ struct GTY ((for_user)) ctf_dvdef
uint32_t dvd_name_offset; /* Offset of the name in str table. */
unsigned int dvd_visibility; /* External visibility. 0=static,1=global. */
ctf_dtdef_ref dvd_type; /* Type of variable. */
ctf_id_t dvd_id; /* ID of this variable. Only used for BTF. */
};
typedef struct ctf_dvdef ctf_dvdef_t;
@ -388,7 +393,7 @@ extern void ctf_output (const char * filename);
extern void ctf_finalize (void);
extern void btf_early_finish (void);
extern void btf_finish (const char * filename);
extern void btf_finish (void);
extern void btf_finalize (void);
extern ctf_container_ref ctf_get_tu_ctfc (void);
@ -443,7 +448,9 @@ extern int ctf_add_variable (ctf_container_ref, const char *, ctf_dtdef_ref,
dw_die_ref, unsigned int, dw_die_ref);
extern ctf_dtdef_ref ctf_lookup_tree_type (ctf_container_ref, const tree);
extern ctf_id_t get_btf_id (ctf_id_t);
/* Callback and traversal function for BTF_KIND_FUNC records. Used by BPF
target for BPF CO-RE implementation. */
typedef bool (*funcs_traverse_callback) (ctf_dtdef_ref, void *);
bool traverse_btf_func_types (funcs_traverse_callback, void *);

View file

@ -979,7 +979,7 @@ ctf_debug_early_finish (const char * filename)
/* For LTO builds, also emit BTF now. */
if (flag_lto && !in_lto_p)
btf_finish (filename);
btf_finish ();
}
else
/* Otherwise, done with the CTF container. */
@ -989,12 +989,12 @@ ctf_debug_early_finish (const char * filename)
/* Finish CTF/BTF debug info emission. */
void
ctf_debug_finish (const char * filename)
ctf_debug_finish ()
{
/* Emit BTF late, unless this is an LTO build in which case it was
already done early. */
if (btf_debuginfo_p () && !flag_lto)
btf_finish (filename);
btf_finish ();
}
#include "gt-dwarf2ctf.h"

View file

@ -32,7 +32,7 @@ extern void ctf_debug_init (void);
extern void ctf_debug_init_postprocess (bool);
extern bool ctf_do_die (dw_die_ref);
extern void ctf_debug_early_finish (const char *);
extern void ctf_debug_finish (const char *);
extern void ctf_debug_finish (void);
/* Wrappers for CTF/BTF to fetch information from GCC DWARF DIE. Used in
ctfc.cc.

View file

@ -32348,7 +32348,7 @@ dwarf2out_finish (const char *filename)
/* Generate CTF/BTF debug info. */
if ((ctf_debug_info_level > CTFINFO_LEVEL_NONE
|| btf_debuginfo_p ()) && lang_GNU_C ())
ctf_debug_finish (filename);
ctf_debug_finish ();
#ifdef CODEVIEW_DEBUGGING_INFO
if (codeview_debuginfo_p ())