Re: [PATCH v4 4/6] btf: add -gprune-btf option
On 6/24/24 09:11, David Faust wrote: Ping. Richard: I changed the option name as you asked but forgot to CC you on the updated patch. Is the new option OK? Indu: You had some minor comments on the prior version which I have addressed, not sure whether you meant the rest of the patch was OK or not, or if you had a chance to review it. Hi David, Thanks for making the change in the commit message to clearly state the behavior of the option -gprune-btf with and without LTO build. I did take a look at the V3 version of the patch, had tested it a bit too. While there are still remain some gaps in my understanding of the algorithm, but overall I think this patch as such looks good and makes forward progress. So, LGTM. Thanks Indu Thanks! archive:https://gcc.gnu.org/pipermail/gcc-patches/2024-June/654252.html
Re: [PATCH v3 6/6] opts: allow any combination of DWARF, CTF, BTF
On 5/30/24 14:32, David Faust wrote: Previously it was not supported to generate both CTF and BTF debug info in the same compiler run, as both formats made incompatible changes to the same internal data structures. With the structural change in the prior patches, in particular the guarantee that CTF will always be fully emitted before any BTF translation occurs, there is no longer anything preventing generation of both CTF and BTF at the same time. This patch changes option parsing to allow any combination of -gdwarf, -gctf, and -gbtf at the same time. I am not an approver for this change, but I have a comment below. gcc/ * opts.cc (set_debug_level): Allow any combination of -gdwarf, -gctf and -gbtf at the same time. --- gcc/opts.cc | 20 +++- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/gcc/opts.cc b/gcc/opts.cc index f80d5d4ba8f9..d58bea096a5f 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -3505,21 +3505,15 @@ set_debug_level (uint32_t dinfo, int extended, const char *arg, } else { - /* Make and retain the choice if both CTF and DWARF debug info are to -be generated. */ - if (((dinfo == DWARF2_DEBUG) || (dinfo == CTF_DEBUG)) + /* Any combination of DWARF, CTF and BTF is allowed together. */ + if (((dinfo == DWARF2_DEBUG) || (dinfo == CTF_DEBUG) + || (dinfo == BTF_DEBUG)) && ((opts->x_write_symbols == (DWARF2_DEBUG|CTF_DEBUG)) + || (opts->x_write_symbols == (DWARF2_DEBUG|BTF_DEBUG)) + || (opts->x_write_symbols == (CTF_DEBUG|BTF_DEBUG)) || (opts->x_write_symbols == DWARF2_DEBUG) - || (opts->x_write_symbols == CTF_DEBUG))) - { - opts->x_write_symbols |= dinfo; - opts_set->x_write_symbols |= dinfo; - } - /* However, CTF and BTF are not allowed together at this time. */ - else if (((dinfo == DWARF2_DEBUG) || (dinfo == BTF_DEBUG)) - && ((opts->x_write_symbols == (DWARF2_DEBUG|BTF_DEBUG)) - || (opts->x_write_symbols == DWARF2_DEBUG) - || (opts->x_write_symbols == BTF_DEBUG))) + || (opts->x_write_symbols == CTF_DEBUG) + || (opts->x_write_symbols == BTF_DEBUG))) I realised that this check will cause failures on double occurrences of the command line flags: $ gcc -c sort.c -g3 -gctf -flto -gbtf -gctf gcc: error: debug format ‘ctf’ conflicts with prior selection What do you think about the following check instead ? if ((dinfo == DWARF2_DEBUG || dinfo == CTF_DEBUG || dinfo == BTF_DEBUG) && ((opts->x_write_symbols | (DWARF2_DEBUG|CTF_DEBUG|BTF_DEBUG)) == (DWARF2_DEBUG|CTF_DEBUG|BTF_DEBUG))) { We have some testcases for checking -gctf -gdwarf (in debug/ctf/ctf-debug*), adding something for -gctf -gbtf will be great. { opts->x_write_symbols |= dinfo; opts_set->x_write_symbols |= dinfo;
Re: [PATCH v3 5/6] bpf,btf: enable BTF pruning by default for BPF
On 5/30/24 14:32, David Faust wrote: This patch enables -fprune-btf by default in the BPF backend when generating BTF information, and fixes BPF CO-RE generation when using -fprune-btf. When generating BPF CO-RE information, we must ensure that types used in CO-RE relocations always have sufficient BTF information emited so that the CO-RE relocations can be processed by a BPF loader. The BTF pruning algorithm on its own does not have sufficient information to determine which types are used in a BPF CO-RE relocation, so this information must be supplied by the BPF backend, using a new btf_mark_type_used function. Co-authored-by: Cupertino Miranda gcc/ * btfout.cc (btf_mark_type_used): New. * ctfc.h (btf_mark_type_used): Declare it here. * config/bpf/bpf.cc (bpf_option_override): Enable -fprune-btf by default if -gbtf is enabled. * config/bpf/core-builtins.cc (extra_fn): New typedef. (compute_field_expr): Add callback parameter, and call it if supplied. Fix computation for MEM_REF. (mark_component_type_as_used): New. (bpf_mark_types_as_used): Likewise. (bpf_expand_core_builtin): Call here. * doc/invoke.texi (Debugging Options): Note that -fprune-btf is enabled by default for BPF target when generating BTF. gcc/testsuite/ * gcc.dg/debug/btf/btf-variables-5.c: Add -fno-prune-btf to dg-options. OK for the CTF/BTF generic parts in btfout.cc/ctfc.h. One minor comment below. --- gcc/btfout.cc | 22 ++ gcc/config/bpf/bpf.cc | 5 ++ gcc/config/bpf/core-builtins.cc | 71 +-- gcc/ctfc.h| 1 + gcc/doc/invoke.texi | 3 + .../gcc.dg/debug/btf/btf-variables-5.c| 6 +- 6 files changed, 100 insertions(+), 8 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index a7da164f6b31..35d2875e3f61 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -1501,6 +1501,28 @@ btf_late_assign_datasec_ids (ctf_container_ref ctfc) } } + +/* Manually mark that type T is used to ensure it will not be pruned. + Used by the BPF backend when generating BPF CO-RE to mark types used + in CO-RE relocations. */ + +void +btf_mark_type_used (tree t) +{ + /* If we are not going to prune anyway, this is a no-op. */ + if (!flag_prune_btf) +return; + + gcc_assert (TYPE_P (t)); + ctf_container_ref ctfc = ctf_get_tu_ctfc (); + ctf_dtdef_ref dtd = ctf_lookup_tree_type (ctfc, t); + + if (!dtd) +return; + + btf_add_used_type (ctfc, dtd, false, false, true); +} + /* Callback used for assembling the only-used-types list. Note that this is the same as btf_type_list_cb above, but the hash_set traverse requires a different function signature. */ diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc index dd1bfe38d29b..775730700eba 100644 --- a/gcc/config/bpf/bpf.cc +++ b/gcc/config/bpf/bpf.cc @@ -221,6 +221,11 @@ bpf_option_override (void) && !(target_flags_explicit & MASK_BPF_CORE)) target_flags |= MASK_BPF_CORE; + /* -gbtf implies -fprune-btf for BPF target. */ -g also will imply -fprune-btf for BPF target now. So perhaps "BTF, if generated, for BPF target is pruned by default" or something similar ? + if (btf_debuginfo_p ()) +SET_OPTION_IF_UNSET (_options, _options_set, +flag_prune_btf, true); + /* Determine available features from ISA setting (-mcpu=). */ if (bpf_has_jmpext == -1) bpf_has_jmpext = (bpf_isa >= ISA_V2); diff --git a/gcc/config/bpf/core-builtins.cc b/gcc/config/bpf/core-builtins.cc index 232bebcadbd5..86e2e9d6e39f 100644 --- a/gcc/config/bpf/core-builtins.cc +++ b/gcc/config/bpf/core-builtins.cc @@ -624,13 +624,20 @@ bpf_core_get_index (const tree node, bool *valid) ALLOW_ENTRY_CAST is an input arguments and specifies if the function should consider as valid expressions in which NODE entry is a cast expression (or - tree code nop_expr). */ + tree code nop_expr). + + EXTRA_FN is a callback function to allow extra functionality with this + function traversal. Currently used for marking used type during expand + pass. */ + +typedef void (*extra_fn) (tree); static unsigned char compute_field_expr (tree node, unsigned int *accessors, bool *valid, tree *access_node, - bool allow_entry_cast = true) + bool allow_entry_cast = true, + extra_fn callback = NULL) { unsigned char n = 0; unsigned int fake_accessors[MAX_NR_ACCESSORS]; @@ -647,6 +654,9 @@ compute_field_expr (tree node, unsigned int *accessors, *access_node = node; + if (callback != NULL) +callback (node); + switch (TREE_CODE (node)) { case INDIRECT_REF: @@ -664,17 +674,19 @@ compute_field_expr (tree node, unsigned int
Re: [PATCH v3 4/6] btf: add -fprune-btf option
On 5/30/24 14:32, David Faust wrote: This patch adds a new option, -fprune-btf, to control BTF debug info generation. As the name implies, this option enables a kind of "pruning" of the BTF information before it is emitted. When enabled, rather than emitting all type information translated from DWARF, only information for types directly used in the source program is emitted. The primary purpose of this pruning is to reduce the amount of unnecessary BTF information emitted, especially for BPF programs. It is very common for BPF programs to incldue Linux kernel internal headers in typo: incldue order to have access to kernel data structures. However, doing so often has the side effect of also adding type definitions for a large number of types which are not actually used by nor relevant to the program. In these cases, -fprune-btf commonly reduces the size of the resulting BTF information by 10x or more, as seen on average when compiling Linux kernel BPF selftests. This both slims down the size of the resulting object and reduces the time required by the BPF loader to verify the program and its BTF information. Note that the pruning implemented in this patch follows the same rules as the BTF pruning performed unconditionally by LLVM's BPF backend when generating BTF. In particular, the main sources of pruning are: 1) Only generate BTF for types used by variables and functions at the file scope. Note that with or without pruning, BTF_KIND_VAR entries are only generated for variables present in the final object - unused static variables or variables completely optimized away must not have VAR entries in BTF. This needs adjusting. I think you mean to convey that the above is expected behavior of -fprune-btf (-gprune-btf) for BPF backend. But the option as such is also available for non-BPF backends, where its behavior will not be the one stated here (due to BTF creation, pruning and output work being at the time of early_finish () when LTO is enabled) Perhaps we clearly specify the behavior of -fprune-btf for BPF and non-BPF backends ? I wonder if the right approach is to instead disallow -fprune-btf with -flto, however until it is clear what that effectively means. One nit below. 2) Avoid emitting full BTF for struct and union types which are only pointed-to by members of other struct/union types. In these cases, the full BTF_KIND_STRUCT or BTF_KIND_UNION which would normally be emitted is replaced with a BTF_KIND_FWD, as though the underlying type was a forward-declared struct or union type. gcc/ * btfout.cc (btf_used_types): New hash set. (struct btf_fixup): New. (fixups, forwards): New vecs. (btf_output): Calculate num_types depending on flag_prune_btf. (btf_early_finsih): New initialization for flag_prune_btf. (btf_add_used_type): New function. (btf_used_type_list_cb): Likewise. (btf_late_collect_pruned_types): Likewise. (btf_late_add_vars): Handle special case for variables in ".maps" section when generating BTF for BPF CO-RE target. (btf_late_finish): Use btf_late_collect_pruned_types when flag_prune_btf in effect. Move some initialization to btf_early_finish. (btf_finalize): Additional deallocation for flag_prune_btf. * common.opt (fprune-btf): New flag. * ctfc.cc (init_ctf_strtable): Make non-static. * ctfc.h (struct ctf_dtdef): Add visited_children_p boolean flag. (init_ctf_strtable, ctfc_delete_strtab): Make extern. * doc/invoke.texi (Debugging Options): Document -fprune-btf. gcc/testsuite/ * gcc.dg/debug/btf/btf-prune-1.c: New test. * gcc.dg/debug/btf/btf-prune-2.c: Likewise. * gcc.dg/debug/btf/btf-prune-3.c: Likewise. * gcc.dg/debug/btf/btf-prune-maps.c: Likewise. --- gcc/btfout.cc | 359 +- gcc/common.opt| 4 + gcc/ctfc.cc | 2 +- gcc/ctfc.h| 3 + gcc/doc/invoke.texi | 20 + gcc/testsuite/gcc.dg/debug/btf/btf-prune-1.c | 25 ++ gcc/testsuite/gcc.dg/debug/btf/btf-prune-2.c | 33 ++ gcc/testsuite/gcc.dg/debug/btf/btf-prune-3.c | 35 ++ .../gcc.dg/debug/btf/btf-prune-maps.c | 20 + 9 files changed, 494 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-prune-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-prune-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-prune-3.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-prune-maps.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 32fda14f704b..a7da164f6b31 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -828,7 +828,10 @@ output_btf_types (ctf_container_ref ctfc) { size_t i; size_t num_types; - num_types =
Re: [PATCH v3 3/6] btf: refactor and simplify implementation
On 5/30/24 14:32, David Faust wrote: 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. I find this aspect of the BTF specification "interesting": Neither BTF_KIND_VAR record, nor DATASEC entry must be emitted for optimized away variables. But for functions, OTH, BTF_KIND_FUNC (and BTF_KIND_FUNC_PROTO (albeit anon) ?) are expected for inlined functions, but no DATASEC. Anayway, that aside, I have one comment below. Other than that, this looks OK to me. Thanks 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_early_add_const_void, btf_early_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_late_add_func_datasec_entries): New. (btf_emit_variable_p): New helper. (btf_late_add_vars): Use it here. New. (btf_type_list_cb, btf_late_collect_translated_types): New. (btf_late_assign_func_ids, btf_late_assign_var_ids) (btf_late_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.
Re: [PATCH v3 2/6] ctf: use pointers instead of IDs internally
On 5/30/24 14:32, David Faust wrote: This patch replaces all inter-type references in the ctfc internal data structures with pointers, rather than the references-by-ID which were used previously. A couple of small updates in the BPF backend are included to make it compatible with the change. This change is only to the in-memory representation of various CTF structures to make them easier to work with in various cases. It is outwardly transparent; there is no change in emitted CTF. gcc/ * btfout.cc (BTF_VOID_TYPEID, BTF_INIT_TYPEID): Move defines to include/btf.h. (btf_dvd_emit_preprocess_cb, btf_emit_preprocess) (btf_dmd_representable_bitfield_p, btf_asm_array, btf_asm_varent) (btf_asm_sou_member, btf_asm_func_arg, btf_init_postprocess): Adapt to structural changes in ctf_* structs. * ctfc.h (struct ctf_dtdef): Add forward declaration. (ctf_dtdef_t, ctf_dtdef_ref): Move typedefs earlier. (struct ctf_arinfo, struct ctf_funcinfo, struct ctf_sliceinfo) (struct ctf_itype, struct ctf_dmdef, struct ctf_func_arg) (struct ctf_dvdef): Use pointers instead of type IDs for references to other types and use typedefs where appropriate. (struct ctf_dtdef): Add ref_type member. (ctf_type_exists): Use pointer instead of type ID. (ctf_add_reftype, ctf_add_enum, ctf_add_slice, ctf_add_float) (ctf_add_integer, ctf_add_unknown, ctf_add_pointer) (ctf_add_array, ctf_add_forward, ctf_add_typedef) (ctf_add_function, ctf_add_sou, ctf_add_enumerator) (ctf_add_variable): Likewise. Return pointer instead of ID. (ctf_lookup_tree_type): Return pointer to type instead of ID. * ctfc.cc: Analogous changes. * ctfout.cc (ctf_asm_type, ctf_asm_slice, ctf_asm_varent) (ctf_asm_sou_lmember, ctf_asm_sou_member, ctf_asm_func_arg) (output_ctf_objt_info): Adapt to changes. * dwarf2ctf.cc (gen_ctf_type, gen_ctf_void_type) (gen_ctf_unknown_type, gen_ctf_base_type, gen_ctf_pointer_type) (gen_ctf_subrange_type, gen_ctf_array_type, gen_ctf_typedef) (gen_ctf_modifier_type, gen_ctf_sou_type, gen_ctf_function_type) (gen_ctf_enumeration_type, gen_ctf_variable, gen_ctf_function) (gen_ctf_type, ctf_do_die): Likewise. * config/bpf/btfext-out.cc (struct btf_ext_core_reloc): Use pointer instead of type ID. (bpf_core_reloc_add, bpf_core_get_sou_member_index) (output_btfext_core_sections): Adapt to above changes. * config/bpf/core-builtins.cc (process_type): Likewise. include/ * btf.h (BTF_VOID_TYPEID, BTF_INIT_TYPEID): Move defines here, from gcc/btfout.cc. The patch looks OK overall. Few updates to code comments for function description or in the body of the function were missed. I have pointed them out below. OK with those addressed. Thanks --- gcc/btfout.cc | 40 +++--- gcc/config/bpf/btfext-out.cc| 14 +- gcc/config/bpf/core-builtins.cc | 3 +- gcc/ctfc.cc | 139 +- gcc/ctfc.h | 90 ++-- gcc/ctfout.cc | 22 +-- gcc/dwarf2ctf.cc| 244 +++- include/btf.h | 5 + 8 files changed, 278 insertions(+), 279 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 1b6a9ed811f0..40e8d8c5c01b 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -61,11 +61,6 @@ static char btf_info_section_label[MAX_BTF_LABEL_BYTES]; #define BTF_INFO_SECTION_LABEL "Lbtf" #endif -/* BTF encodes void as type id 0. */ - -#define BTF_VOID_TYPEID 0 -#define BTF_INIT_TYPEID 1 - #define BTF_INVALID_TYPEID 0x /* Mapping of CTF variables to the IDs they will be assigned when they are @@ -626,7 +621,8 @@ btf_dvd_emit_preprocess_cb (ctf_dvdef_ref *slot, ctf_container_ref arg_ctfc) return 1; /* Do not add variables which refer to unsupported types. */ - if (!voids.contains (var->dvd_type) && btf_removed_type_p (var->dvd_type)) + if (!voids.contains (var->dvd_type->dtd_type) + && btf_removed_type_p (var->dvd_type->dtd_type)) return 1; arg_ctfc->ctfc_vars_list[num_vars_added] = var; @@ -716,7 +712,7 @@ btf_emit_preprocess (ctf_container_ref ctfc) static bool btf_dmd_representable_bitfield_p (ctf_container_ref ctfc, ctf_dmdef_t *dmd) { - ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[dmd->dmd_type]; + ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[dmd->dmd_type->dtd_type]; if (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info) == CTF_K_SLICE) { @@ -913,8 +909,8 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) static void btf_asm_array (ctf_container_ref ctfc, ctf_arinfo_t arr) { - btf_asm_type_ref ("bta_elem_type", ctfc, arr.ctr_contents); - btf_asm_type_ref ("bta_index_type", ctfc, arr.ctr_index); +
Re: [PATCH v3 1/6] ctf, btf: restructure CTF/BTF emission
On 5/30/24 14:32, David Faust wrote: This commit makes some structural changes to the CTF/BTF debug info emission. In particular: a) CTF is new always fully generated and emitted before any BTF-related procedures are run. This means that BTF-related functions can change, even irreversibly, the shared in-memory representation used by the two formats without issue. b) BTF generation has fewer entry points, and is cleanly divided into early_finish and finish. c) BTF is now always emitted at finish (called from dwarf2out_finish), for all targets in non-LTO builds, rather than being emitted at early_finish for targets other than BPF CO-RE. In LTO builds, BTF is emitted at early_finish as before. Note that this change alone does not alter the contents of BTF at all, regardless of whether it would have previously been emitted at early_finish or finish, because the calculation of the BTF to be emitted is not moved by this patch, only the write-out. The changes are transparent to both CTF and BTF emission. OK. This will work to keep supporting -flto with BTF (for non-BPF targets) and of course -flto with CTF. One question/nit below. gcc/ * btfout.cc (btf_init_postprocess): Rename to... (btf_early_finish): ...this. (btf_output): Rename to... (btf_finish): ...this. * ctfc.h: Analogous changes. * dwarf2ctf.cc (ctf_debug_early_finish): Conditionally call btf_early_finish, or ctf_finalize as appropriate. Emit BTF here for LTO builds. (ctf_debug_finish): Always call btf_finish here if generating BTF info in non-LTO builds. (ctf_debug_finalize, ctf_debug_init_postprocess): Delete. * dwarf2out.cc (dwarf2out_early_finish): Remove call to ctf_debug_init_postprocess. --- gcc/btfout.cc| 28 + gcc/ctfc.h | 4 +-- gcc/dwarf2ctf.cc | 65 +++- gcc/dwarf2out.cc | 2 -- 4 files changed, 50 insertions(+), 49 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 07f066a47068..1b6a9ed811f0 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -1491,6 +1491,34 @@ btf_finalize (void) tu_ctfc = NULL; } +/* Initial entry point of BTF generation, called at early_finish () after + CTF information has possibly been output. Translate all CTF information + to BTF, and do any processing that must be done early, such as creating + BTF_KIND_FUNC records. */ + +void +btf_early_finish (void) +{ + btf_init_postprocess (); +} + +/* Late entry point for BTF generation, called from dwarf2out_finish (). + Complete and emit BTF information. */ + +void +btf_finish (const char * filename) +{ + btf_output (filename); + + /* If compiling for BPF with CO-RE info, we cannot deallocate until after + CO-RE information is created, which happens very late in BPF backend. I am wondering if it is more precise to say that "until after contents for the .BTF.ext section are finalized" ? We have already called the btf_output () above, which means _some_ CO-RE information is already created (like the accessor strings for CO-RE relocs that go in the .BTF section). + Therefore, the deallocation (i.e. btf_finalize ()) is delayed until + TARGET_ASM_FILE_END for BPF CO-RE. */ + if (!btf_with_core_debuginfo_p ()) +btf_finalize (); +} + + /* Traversal function for all BTF_KIND_FUNC type records. */ bool diff --git a/gcc/ctfc.h b/gcc/ctfc.h index fa188bf2f5a4..e7bd93901cfa 100644 --- a/gcc/ctfc.h +++ b/gcc/ctfc.h @@ -384,8 +384,8 @@ extern void ctf_init (void); extern void ctf_output (const char * filename); extern void ctf_finalize (void); -extern void btf_output (const char * filename); -extern void btf_init_postprocess (void); +extern void btf_early_finish (void); +extern void btf_finish (const char * filename); extern void btf_finalize (void); extern ctf_container_ref ctf_get_tu_ctfc (void); diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc index dc59569fe560..8f9e2fada9e3 100644 --- a/gcc/dwarf2ctf.cc +++ b/gcc/dwarf2ctf.cc @@ -933,30 +933,6 @@ gen_ctf_type (ctf_container_ref ctfc, dw_die_ref die) return type_id; } -/* Prepare for output and write out the CTF debug information. */ - -static void -ctf_debug_finalize (const char *filename, bool btf) -{ - if (btf) -{ - btf_output (filename); - /* btf_finalize when compiling BPF applciations gets deallocated by the -BPF target in bpf_file_end. */ - if (btf_debuginfo_p () && !btf_with_core_debuginfo_p ()) - btf_finalize (); -} - - else -{ - /* Emit the collected CTF information. */ - ctf_output (filename); - - /* Reset the CTF state. */ - ctf_finalize (); -} -} - bool ctf_do_die (dw_die_ref die) { @@ -996,27 +972,27 @@ ctf_debug_init (void) add_name_attribute (ctf_unknown_die, "unknown"); } -/*
Re: [PATCH v2 6/6] bpf,btf: enable BTF pruning by default for BPF
On 5/2/24 10:11, David Faust wrote: This patch enables -fprune-btf by default in the BPF backend when generating BTF information, and fixes BPF CO-RE generation when using -fprune-btf. When generating BPF CO-RE information, we must ensure that types used in CO-RE relocations always have sufficient BTF information emited so that the CO-RE relocations can be processed by a BPF loader. The BTF pruning algorithm on its own does not have sufficient information to determine which types are used in a BPF CO-RE relocation, so this information must be supplied by the BPF backend, using a new btf_mark_type_used function. Co-authored-by: Cupertino Miranda gcc/ * btfout.cc (btf_mark_type_used): New. * ctfc.h (btf_mark_type_used): Declare it here. * config/bpf/bpf.cc (bpf_option_override): Enable -fprune-btf by default if -gbtf is enabled. * config/bpf/bcore-builtins.cc (extra_fn): New typedef. (compute_field_expr): Add callback parameter, and call it if supplied. Fix computation for MEM_REF. (mark_component_type_as_used): New. (bpf_mark_types_as_used): Likewise. (bpf_expand_core_builtin): Call here. * doc/invoke.texi (Debugging Options): Note that -fprune-btf is enabled by default for BPF target when generating BTF. gcc/testsuite/ * gcc.dg/debug/btf/btf-variables-5.c: Add -fno-prune-btf to dg-options. --- gcc/btfout.cc | 22 ++ gcc/config/bpf/bpf.cc | 5 ++ gcc/config/bpf/core-builtins.cc | 70 +-- gcc/ctfc.h| 1 + gcc/doc/invoke.texi | 3 + .../gcc.dg/debug/btf/btf-variables-5.c| 2 +- 6 files changed, 96 insertions(+), 7 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 93d56492bbe..da2c9d35be9 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -1539,6 +1539,28 @@ btf_late_assign_datasec_ids (ctf_container_ref ctfc) } } + +/* Manually mark that type T is used to ensure it will not be pruned. + Used by the BPF backend when generating BPF CO-RE to mark types used + in CO-RE relocations. */ + +void +btf_mark_type_used (tree t) +{ + /* If we are not going to prune anyway, this is a no-op. */ + if (!flag_prune_btf) +return; + + gcc_assert (TYPE_P (t)); + ctf_container_ref ctfc = ctf_get_tu_ctfc (); + ctf_dtdef_ref dtd = ctf_lookup_tree_type (ctfc, t); + + if (!dtd) +return; + + btf_minimal_add_type (ctfc, dtd, false, false); +} + /* Callback used for assembling the only-used-types list. Note that this is the same as btf_type_list_cb above, but the hash_set traverse requires a different function signature. */ diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc index e6ea211a2c6..75303ce8f46 100644 --- a/gcc/config/bpf/bpf.cc +++ b/gcc/config/bpf/bpf.cc @@ -221,6 +221,11 @@ bpf_option_override (void) && !(target_flags_explicit & MASK_BPF_CORE)) target_flags |= MASK_BPF_CORE; + /* -gbtf implies -fprune-btf for BPF target. */ + if (btf_debuginfo_p ()) +SET_OPTION_IF_UNSET (_options, _options_set, +flag_prune_btf, true); + /* Determine available features from ISA setting (-mcpu=). */ if (bpf_has_jmpext == -1) bpf_has_jmpext = (bpf_isa >= ISA_V2); diff --git a/gcc/config/bpf/core-builtins.cc b/gcc/config/bpf/core-builtins.cc index d5a7de825ad..1b91b1c0d25 100644 --- a/gcc/config/bpf/core-builtins.cc +++ b/gcc/config/bpf/core-builtins.cc @@ -624,13 +624,20 @@ bpf_core_get_index (const tree node, bool *valid) ALLOW_ENTRY_CAST is an input arguments and specifies if the function should consider as valid expressions in which NODE entry is a cast expression (or - tree code nop_expr). */ + tree code nop_expr). + + EXTRA_FN is a callback function to allow extra functionality with this + function traversal. Currently used for marking used type during expand + pass. */ + +typedef void (*extra_fn) (tree); static unsigned char compute_field_expr (tree node, unsigned int *accessors, bool *valid, tree *access_node, - bool allow_entry_cast = true) + bool allow_entry_cast = true, + extra_fn callback = NULL) { unsigned char n = 0; unsigned int fake_accessors[MAX_NR_ACCESSORS]; @@ -647,6 +654,9 @@ compute_field_expr (tree node, unsigned int *accessors, *access_node = node; + if (callback != NULL) +callback (node); + switch (TREE_CODE (node)) { case INDIRECT_REF: @@ -664,17 +674,19 @@ compute_field_expr (tree node, unsigned int *accessors, case COMPONENT_REF: n = compute_field_expr (TREE_OPERAND (node, 0), accessors, valid, - access_node, false); + access_node, false,
Re: [PATCH v2 5/6] btf: add -fprune-btf option
On 5/2/24 10:11, David Faust wrote: This patch adds a new option, -fprune-btf, to control BTF debug info generation. As the name implies, this option enables a kind of "pruning" of the BTF information before it is emitted. When enabled, rather than emitting all type information translated from DWARF, only information for types directly used in the source program is emitted. The primary purpose of this pruning is to reduce the amount of unnecessary BTF information emitted, especially for BPF programs. It is very common for BPF programs to incldue Linux kernel internal headers in order to have access to kernel data structures. However, doing so often has the side effect of also adding type definitions for a large number of types which are not actually used by nor relevant to the program. In these cases, -fprune-btf commonly reduces the size of the resulting BTF information by approximately 10x. This both slims down the size of the resulting object and reduces the time required by the BPF loader to verify the program and its BTF information. The 10x reduction is substantial. Do you think its is worthwhile to mention alongside that this data is the average observed for the kernel self-tests (I assume it is) ? Just useful info when parsing the commit logs, especially when some data is specified... Note that the pruning implemented in this patch follows the same rules as the BTF pruning performed unconditionally by LLVM's BPF backend when generating BTF. In particular, the main sources of pruning are: 1) Only generate BTF for types used by variables and functions at the file scope. I dont recollect anymore if BTF_KIND_VAR for unused static vars is also a correctness issue for BTF. (With PR debug/113566, we know having BTF_KIND_DATASEC entries for optimized away vars is an issue). It will be great to add some text here or elsewhere for posterity around this. 2) Avoid emitting full BTF for struct and union types which are only pointed-to by members of other struct/union types. In these cases, the full BTF_KIND_STRUCT or BTF_KIND_UNION which would normally be emitted is replaced with a BTF_KIND_FWD, as though the underlying type was a forward-declared struct or union type. gcc/ * btfout.cc (btf_minimal_types): New hash set. (struct btf_fixup): New. (fixups, forwards): New vecs. (btf_output): Calculate num_types depending on flag_prune_btf. (btf_early_finsih): New initialization for flag_prune_btf. (btf_mark_full_type_used): Likewise. (btf_minimal_add_type): New function. (btf_minimal_type_list_cb): Likewise. (btf_late_collect_pruned_types): Likewise. (btf_late_add_vars): Handle special case for variables in ".maps" section when generating BTF for BPF CO-RE target. (btf_late_finish): Use btf_late_collect_pruned_types when flag_prune_btf in effect. Move some initialization to btf_early_finish. (btf_finalize): Additional deallocation for flag_prune_btf. * common.opt (fprune-btf): New flag. * ctfc.cc (init_ctf_strtable): Make non-static. * ctfc.h (struct ctf_dtdef): Add visited_children_p boolean flag. (init_ctf_strtable, ctfc_delete_strtab): Make extern. * doc/invoke.texi (Debugging Options): Document -fprune-btf. gcc/testsuite/ * gcc.dg/debug/btf/btf-prune-1.c: New test. * gcc.dg/debug/btf/btf-prune-2.c: Likewise. * gcc.dg/debug/btf/btf-prune-3.c: Likewise. --- gcc/btfout.cc| 394 ++- gcc/common.opt | 4 + gcc/ctfc.cc | 2 +- gcc/ctfc.h | 5 + gcc/doc/invoke.texi | 20 + gcc/testsuite/gcc.dg/debug/btf/btf-prune-1.c | 25 ++ gcc/testsuite/gcc.dg/debug/btf/btf-prune-2.c | 33 ++ gcc/testsuite/gcc.dg/debug/btf/btf-prune-3.c | 35 ++ 8 files changed, 511 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-prune-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-prune-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-prune-3.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 0af0bd39fc7..93d56492bbe 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -833,7 +833,10 @@ output_btf_types (ctf_container_ref ctfc) { size_t i; size_t num_types; - num_types = ctfc->ctfc_types->elements (); + if (flag_prune_btf) +num_types = max_translated_id; + else +num_types = ctfc->ctfc_types->elements (); if (num_types) { @@ -962,6 +965,211 @@ btf_early_add_func_records (ctf_container_ref ctfc) } } +/* The set of types used directly in the source program, and any types manually + marked as used. This is the set of types which will be emitted when + pruning (-fprune-btf) is enabled. */ Nit: emitted when
Re: [PATCH v2 4/6] btf: refactor and simplify implementation
On 5/2/24 10:11, David Faust wrote: 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. I am a bit unsure ATM, how this commit will look like once we revisit where the BTF is generated for BPF and non-BPF backends. Since patch 1/6 moved everything to (late)finish, but that will be problematic, I would like to defer reviewing this until the approach for afore-mentioned patch is pinned. 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_early_add_const_void, btf_early_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_late_add_func_datasec_entries): New. (btf_emit_variable_p): New helper. (btf_late_add_vars): Use it here. New. (btf_type_list_cb, btf_late_collect_translated_types): New. (btf_late_assign_func_ids, btf_late_assign_var_ids) (btf_late_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. *
Re: [PATCH v2 3/6] ctf: use pointers instead of IDs internally
On 5/2/24 10:11, David Faust wrote: This patch replaces all inter-type references in the ctfc internal data structures with pointers, rather than the references-by-ID which were used previously. A couple of small updates in the BPF backend are included to make it compatible with the change. This change is only to the in-memory representation of various CTF structures to make them easier to work with in various cases. It is outwardly transparent; there is no change in emitted CTF. gcc/ * btfout.cc (btf_dvd_emit_preprocess_cb, btf_emit_preprocess) (btf_dmd_representable_bitfield_p, btf_asm_array, btf_asm_varent) (btf_asm_sou_member, btf_asm_func_arg, btf_init_postprocess): Adapt to structural changes in ctf_* structs. * ctfc.h (struct ctf_dtdef): Add forward declaration. (struct ctf_arinfo, struct ctf_funcinfo, struct ctf_sliceinfo) (struct ctf_itype, struct ctf_dmdef, struct ctf_func_arg) (struct ctf_dvdef): Use pointers instead of type IDs for references to other types. (struct ctf_dtdef): Add ref_type member. (ctf_type_exists): Use pointer instead of type ID. (ctf_add_reftype, ctf_add_enum, ctf_add_slice, ctf_add_float) (ctf_add_integer, ctf_add_unknown, ctf_add_pointer) (ctf_add_array, ctf_add_forward, ctf_add_typedef) (ctf_add_function, ctf_add_sou, ctf_add_enumerator) (ctf_add_variable): Likewise. Return pointer instead of ID. (ctf_lookup_tree_type): Return pointer to type instead of ID. * ctfc.cc: Analogous changes. * ctfout.cc (ctf_asm_type, ctf_asm_slice, ctf_asm_varent) (ctf_asm_sou_lmember, ctf_asm_sou_member, ctf_asm_func_arg) (output_ctf_objt_info): Adapt to changes. * dwarf2ctf.cc (gen_ctf_type, gen_ctf_void_type) (gen_ctf_unknown_type, gen_ctf_base_type, gen_ctf_pointer_type) (gen_ctf_subrange_type, gen_ctf_array_type, gen_ctf_typedef) (gen_ctf_modifier_type, gen_ctf_sou_type, gen_ctf_function_type) (gen_ctf_enumeration_type, gen_ctf_variable, gen_ctf_function) (gen_ctf_type, ctf_do_die): Likewise. * config/bpf/btfext-out.cc (struct btf_ext_core_reloc): Use pointer instead of type ID. (bpf_core_reloc_add, bpf_core_get_sou_member_index) (output_btfext_core_sections): Adapt to above changes. * config/bpf/core-builtins.cc (process_type): Likewise. --- gcc/btfout.cc | 35 ++--- gcc/config/bpf/btfext-out.cc| 12 +- gcc/config/bpf/core-builtins.cc | 3 +- gcc/ctfc.cc | 137 +- gcc/ctfc.h | 61 gcc/ctfout.cc | 19 +-- gcc/dwarf2ctf.cc| 244 +++- 7 files changed, 252 insertions(+), 259 deletions(-) diff --git a/gcc/config/bpf/btfext-out.cc b/gcc/config/bpf/btfext-out.cc index 7ec438fd1d1..ce596e33643 100644 --- a/gcc/config/bpf/btfext-out.cc +++ b/gcc/config/bpf/btfext-out.cc @@ -134,7 +134,7 @@ struct GTY ((chain_next ("%h.next"))) btf_ext_lineinfo /* Internal representation of a BPF CO-RE relocation record. */ struct GTY ((chain_next ("%h.next"))) btf_ext_core_reloc { - unsigned int bpfcr_type; /* BTF type ID of container. */ + ctf_dtdef_ref bpfcr_type;/* BTF type of container. */ I find the comment "BTF type of container" associated with the member confusing. May be we say " BTF type involved with the reloc " or something like that ? unsigned int bpfcr_astr_off; /* Offset of access string in .BTF string table. */ rtx_code_label * bpfcr_insn_label; /* RTX label attached to instruction @@ -296,13 +296,14 @@ bpf_core_reloc_add (const tree type, const char * section_name, struct btf_ext_core_reloc *bpfcr = bpf_create_core_reloc (section_name, ); ctf_container_ref ctfc = ctf_get_tu_ctfc (); + ctf_dtdef_ref dtd = ctf_lookup_tree_type (ctfc, type); /* Buffer the access string in the auxiliary strtab. */ bpfcr->bpfcr_astr_off = 0; gcc_assert (accessor != NULL); bpfcr->bpfcr_astr_off = btf_ext_add_string (accessor); - bpfcr->bpfcr_type = get_btf_id (ctf_lookup_tree_type (ctfc, type)); + bpfcr->bpfcr_type = dtd; bpfcr->bpfcr_insn_label = label; bpfcr->bpfcr_kind = kind; @@ -341,7 +342,7 @@ bpf_core_get_sou_member_index (ctf_container_ref ctfc, const tree node) for (dmd = dtd->dtd_u.dtu_members; dmd != NULL; dmd = (ctf_dmdef_t *) ctf_dmd_list_next (dmd)) { - bool field_has_btf = get_btf_id (dmd->dmd_type) <= BTF_MAX_TYPE; + bool field_has_btf = (dmd->dmd_type && dmd->dmd_type->dtd_type <= BTF_MAX_TYPE); if (field == node) return field_has_btf ? i : -1; @@ -574,8 +575,9 @@ output_btfext_core_sections (void) false);
Re: [PATCH v2 1/6] ctf, btf: restructure CTF/BTF emission
On 5/2/24 10:11, David Faust wrote: This commit makes some structural changes to the CTF/BTF debug info emission. In particular: a) CTF is new always fully generated and emitted before any BTF-related procedures are run. This means that BTF-related functions can change, even irreversibly, the shared in-memory representation used by the two formats without issue. b) BTF generation has fewer entry points, and is cleanly divided into early_finish and finish. c) BTF is now always emitted at finish (called from dwarf2out_finish), rather than being emitted at early_finish for targets other than BPF CO-RE. Note that this change alone does not alter the contents of BTF at all, regardless of whether it would have previously been emitted at early_finish or finish. This will necessitate that we disallow -gbtf with -flto for non-BPF targets. Emitting BTF always at dwarf2out_finish will not work with LTO. The changes are transparent to both CTF and BTF emission. gcc/ * btfout.cc (btf_init_postprocess): Rename to... (btf_early_finish): ...this. (btf_output): Rename to... (btf_finish): ...this. * ctfc.h: Analogous changes. * dwarf2ctf.cc (ctf_debug_early_finish): Conditionally call btf_early_finish or ctf_finalize as appropriate. (ctf_debug_finish): Always call btf_finish here if generating BTF info. (ctf_debug_finalize, ctf_debug_init_postprocess): Delete. * dwarf2out.cc (dwarf2out_early_finish): Remove call to ctf_debug_init_postprocess. --- gcc/btfout.cc| 28 + gcc/ctfc.h | 4 ++-- gcc/dwarf2ctf.cc | 54 +++- gcc/dwarf2out.cc | 2 -- 4 files changed, 42 insertions(+), 46 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 07f066a4706..1b6a9ed811f 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -1491,6 +1491,34 @@ btf_finalize (void) tu_ctfc = NULL; } +/* Initial entry point of BTF generation, called at early_finish () after + CTF information has possibly been output. Translate all CTF information + to BTF, and do any processing that must be done early, such as creating + BTF_KIND_FUNC records. */ + +void +btf_early_finish (void) +{ + btf_init_postprocess (); +} + +/* Late entry point for BTF generation, called from dwarf2out_finish (). + Complete and emit BTF information. */ + +void +btf_finish (const char * filename) +{ + btf_output (filename); + + /* If compiling for BPF with CO-RE info, we cannot deallocate until after + CO-RE information is created, which happens very late in BPF backend. + Therefore, the deallocation (i.e. btf_finalize ()) is delayed until + TARGET_ASM_FILE_END for BPF CO-RE. */ + if (!btf_with_core_debuginfo_p ()) +btf_finalize (); +} + + /* Traversal function for all BTF_KIND_FUNC type records. */ bool diff --git a/gcc/ctfc.h b/gcc/ctfc.h index fa188bf2f5a..e7bd93901cf 100644 --- a/gcc/ctfc.h +++ b/gcc/ctfc.h @@ -384,8 +384,8 @@ extern void ctf_init (void); extern void ctf_output (const char * filename); extern void ctf_finalize (void); -extern void btf_output (const char * filename); -extern void btf_init_postprocess (void); +extern void btf_early_finish (void); +extern void btf_finish (const char * filename); extern void btf_finalize (void); extern ctf_container_ref ctf_get_tu_ctfc (void); diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc index dc59569fe56..ec94982e4b1 100644 --- a/gcc/dwarf2ctf.cc +++ b/gcc/dwarf2ctf.cc @@ -933,30 +933,6 @@ gen_ctf_type (ctf_container_ref ctfc, dw_die_ref die) return type_id; } -/* Prepare for output and write out the CTF debug information. */ - -static void -ctf_debug_finalize (const char *filename, bool btf) -{ - if (btf) -{ - btf_output (filename); - /* btf_finalize when compiling BPF applciations gets deallocated by the -BPF target in bpf_file_end. */ - if (btf_debuginfo_p () && !btf_with_core_debuginfo_p ()) - btf_finalize (); -} - - else -{ - /* Emit the collected CTF information. */ - ctf_output (filename); - - /* Reset the CTF state. */ - ctf_finalize (); -} -} - bool ctf_do_die (dw_die_ref die) { @@ -996,27 +972,21 @@ ctf_debug_init (void) add_name_attribute (ctf_unknown_die, "unknown"); } -/* Preprocess the CTF debug information after initialization. */ - -void -ctf_debug_init_postprocess (bool btf) -{ - /* Only BTF requires postprocessing right after init. */ - if (btf) -btf_init_postprocess (); -} - /* Early finish CTF/BTF debug info. */ void ctf_debug_early_finish (const char * filename) { - /* Emit CTF debug info early always. */ - if (ctf_debug_info_level > CTFINFO_LEVEL_NONE - /* Emit BTF debug info early if CO-RE relocations are not -required. */ - || (btf_debuginfo_p () &&
Re: [PATCH] btf: fix a possibly misleading asm debug comment
On 4/11/24 14:02, David Faust wrote: This patch fixes a small error that could occur in the debug comment when emitting a type reference with btf_asm_type_ref. While working on a previous patch, I noticed the following in the asm output for the test btf-bitfields-4.c: ... .long 0x39# MEMBER 'c' idx=3 .long 0x6 # btm_type: (BTF_KIND_UNKN '') ... .long 0x34# TYPE 6 BTF_KIND_INT 'char' The type for member 'c' is correct, but the comment for the member incorrectly reads "BTF_KIND_UNKN ''". This was caused by an incorrect type lookup in btf_asm_type_ref that could happen if the source file has types which can be represented in CTF but not in BTF. This patch fixes the issue by changing btf_asm_type_ref to work fully in the CTF ID space until writing out the final BTF ID. That ensures types are correctly identified when writing the asm debug comments, like the following fixed comment for the above case. ... .long 0x39# MEMBER 'c' idx=3 .long 0x6 # btm_type: (BTF_KIND_INT 'char') ... Note that there was no problem with the actual BTF information, the only error was in the comment. This patch does not change the output BTF information, and no tests were affected. Tested on x86_64-linux-gnu and x86_64-linux-gnu host for bpf-unknown-none target. Sanity checked by compiling kernel BPF selftests. Thanks. The code is easier to follow now too. LGTM. gcc/ * btfout.cc (btf_asm_type_ref): Convert IDs to BTF internally and fix potentially looking up wrong type for asm debug comment info. Split into... (btf_asm_datasec_type_ref): ... This. New. (btf_asm_datasec_entry): Call it here, instead of btf_asm_type_ref. (btf_asm_type, btf_asm_array, btf_asm_varent, btf_asm_sou_member) (btf_asm_func_arg, btf_asm_func_type): Adapt btf_asm_type_ref call. --- gcc/btfout.cc | 84 ++- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index e1ada41b1f4..24bef3acfd1 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -738,36 +738,22 @@ btf_dmd_representable_bitfield_p (ctf_container_ref ctfc, ctf_dmdef_t *dmd) /* Asm'out a reference to another BTF type. */ static void -btf_asm_type_ref (const char *prefix, ctf_container_ref ctfc, ctf_id_t ref_id) +btf_asm_type_ref (const char *prefix, ctf_container_ref ctfc, ctf_id_t ctf_id) { - if (ref_id == BTF_VOID_TYPEID || ref_id == BTF_INVALID_TYPEID) + ctf_id_t btf_id = get_btf_id (ctf_id); + if (btf_id == BTF_VOID_TYPEID || btf_id == BTF_INVALID_TYPEID) { /* There is no explicit void type. Also handle any invalid refs that made it this far, just in case. */ - dw2_asm_output_data (4, ref_id, "%s: void", prefix); -} - else if (ref_id >= num_types_added + 1 - && ref_id < num_types_added + num_vars_added + 1) -{ - /* Ref to a variable. Should only appear in DATASEC entries. */ - ctf_id_t var_id = btf_relative_var_id (ref_id); - ctf_dvdef_ref dvd = ctfc->ctfc_vars_list[var_id]; - dw2_asm_output_data (4, ref_id, "%s: (BTF_KIND_VAR '%s')", - prefix, dvd->dvd_name); - -} - else if (ref_id >= num_types_added + num_vars_added + 1) -{ - /* Ref to a FUNC record. */ - size_t func_id = btf_relative_func_id (ref_id); - ctf_dtdef_ref ref_type = (*funcs)[func_id]; - dw2_asm_output_data (4, ref_id, "%s: (BTF_KIND_FUNC '%s')", - prefix, get_btf_type_name (ref_type)); + dw2_asm_output_data (4, btf_id, "%s: void", prefix); } else { - /* Ref to a standard type in the types list. */ - ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[ref_id]; + gcc_assert (btf_id <= num_types_added); + + /* Ref to a standard type in the types list. Note: take care that we +must index the type list by the original CTF id, not the BTF id. */ + ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[ctf_id]; uint32_t ref_kind = get_btf_kind (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info)); @@ -775,12 +761,43 @@ btf_asm_type_ref (const char *prefix, ctf_container_ref ctfc, ctf_id_t ref_id) ? btf_kind_name (BTF_KIND_ENUM) : btf_kind_name (ref_kind); - dw2_asm_output_data (4, ref_id, "%s: (BTF_KIND_%s '%s')", + dw2_asm_output_data (4, btf_id, "%s: (BTF_KIND_%s '%s')", prefix, kind_name, get_btf_type_name (ref_type)); } } +/* Asm'out a reference to a BTF_KIND_VAR or BTF_KIND_FUNC type. These type + kinds are BTF-specific, and should only be referred to by entries in + BTF_KIND_DATASEC records. */ + +static void +btf_asm_datasec_type_ref (const char *prefix, ctf_container_ref ctfc, + ctf_id_t btf_id) +{ + if (btf_id >=
Re: [PATCH v2] btf: emit non-representable bitfield as void
On 4/11/24 14:01, David Faust wrote: [Changes from v1: use btf_dmd_representable_bitfield_p in btf_asm_sou_member, instead of a slightly incorrect equivalent check.] This patch fixes an issue with mangled BTF that could occur when a struct type contains a bitfield member which cannot be represented in BTF. It is undefined what should happen in such cases, but we can at least do something reasonable. Commit 936dd627cd9 "btf: do not skip members of data type with type id BTF_VOID_TYPEID" made a similar change for un-representable non-bitfield members, but had an unintended side-effect of mangling BTF for un-representable bitfields: the struct (or union) would account for the offending bitfield in its member count but the bitfield member itself was not emitted, making the member count incorrect. This change ensures that non-representable bitfield members of struct and union types are always emitted with BTF_VOID_TYPEID. This avoids corrupting the BTF information for the entire struct or union type. Tested on x86_64-linux-gnu and x86_64-linux-gnu host for bpf-unknown-none target. gcc/ * btfout.cc (btf_asm_sou_member): Always emit non-representable bitfield members as having 'void' type. Refactor slightly. gcc/testsuite/ * gcc.dg/debug/btf/btf-bitfields-4.c: Add two new checks. LGTM. Thanks --- gcc/btfout.cc | 54 +-- .../gcc.dg/debug/btf/btf-bitfields-4.c| 2 + 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index ab491f0297f..a1510574a93 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -922,41 +922,39 @@ static void btf_asm_sou_member (ctf_container_ref ctfc, ctf_dmdef_t * dmd, unsigned int idx) { ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[dmd->dmd_type]; + ctf_id_t base_type = get_btf_id (dmd->dmd_type); + uint64_t sou_offset = dmd->dmd_offset; + + dw2_asm_output_data (4, dmd->dmd_name_offset, + "MEMBER '%s' idx=%u", + dmd->dmd_name, idx); /* Re-encode bitfields to BTF representation. */ if (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info) == CTF_K_SLICE) { - ctf_id_t base_type = ref_type->dtd_u.dtu_slice.cts_type; - unsigned short word_offset = ref_type->dtd_u.dtu_slice.cts_offset; - unsigned short bits = ref_type->dtd_u.dtu_slice.cts_bits; - uint64_t sou_offset = dmd->dmd_offset; - - /* Pack the bit offset and bitfield size together. */ - sou_offset += word_offset; - - /* If this bitfield cannot be represented, do not output anything. -The parent struct/union 'vlen' field has already been updated. */ - if ((bits > 0xff) || (sou_offset > 0xff)) - return; + if (btf_dmd_representable_bitfield_p (ctfc, dmd)) + { + unsigned short word_offset = ref_type->dtd_u.dtu_slice.cts_offset; + unsigned short bits = ref_type->dtd_u.dtu_slice.cts_bits; - sou_offset &= 0x00ff; - sou_offset |= ((bits & 0xff) << 24); + /* Pack the bit offset and bitfield size together. */ + sou_offset += word_offset; + sou_offset &= 0x00ff; + sou_offset |= ((bits & 0xff) << 24); - dw2_asm_output_data (4, dmd->dmd_name_offset, - "MEMBER '%s' idx=%u", - dmd->dmd_name, idx); - /* Refer to the base type of the slice. */ - btf_asm_type_ref ("btm_type", ctfc, get_btf_id (base_type)); - dw2_asm_output_data (4, sou_offset, "btm_offset"); -} - else -{ - dw2_asm_output_data (4, dmd->dmd_name_offset, - "MEMBER '%s' idx=%u", - dmd->dmd_name, idx); - btf_asm_type_ref ("btm_type", ctfc, get_btf_id (dmd->dmd_type)); - dw2_asm_output_data (4, dmd->dmd_offset, "btm_offset"); + /* Refer to the base type of the slice. */ + base_type = get_btf_id (ref_type->dtd_u.dtu_slice.cts_type); + } + else + { + /* Bitfield cannot be represented in BTF. Emit the member as having +'void' type. */ + base_type = BTF_VOID_TYPEID; + } } + + btf_asm_type_ref ("btm_type", ctfc, base_type); + dw2_asm_output_data (4, sou_offset, "btm_offset"); } /* Asm'out an enum constant following a BTF_KIND_ENUM{,64}. */ diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c index d4a6ef6a1eb..20cdfaa057a 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c @@ -14,6 +14,8 @@ /* Struct with 4 members and no bitfield (kind_flag not set). */ /* { dg-final { scan-assembler-times "\[\t \]0x404\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times " MEMBER" 4 } } */ +/* { dg-final { scan-assembler-times " MEMBER 'unsup'
Re: [PATCH] btf: emit non-representable bitfield as void
On 4/11/24 11:53, David Faust wrote: This patch fixes an issue with mangled BTF that could occur when a struct type contains a bitfield member which cannot be represented in BTF. It is undefined what should happen in such cases, but we can at least do something reasonable. Commit 936dd627cd9 "btf: do not skip members of data type with type id BTF_VOID_TYPEID" made a similar change for un-representable non-bitfield members, but had an unintended side-effect of mangling BTF for un-representable bitfields: the struct (or union) would account for the offending bitfield in its member count but the bitfield member itself was not emitted, making the member count incorrect. This change ensures that non-representable bitfield members of struct and union types are always emitted with BTF_VOID_TYPEID. This avoids corrupting the BTF information for the entire struct or union type. Tested on x86_64-linux-gnu and x86_64-linux-gnu host for bpf-unknown-none target. Hi David, Thanks for fixing this. One comment below. gcc/ * btfout.cc (btf_asm_sou_member): Always emit non-representable bitfield members as having 'void' type. Refactor slightly. gcc/testsuite/ * gcc.dg/debug/btf/btf-bitfields-4.c: Add two new checks. --- gcc/btfout.cc | 48 +-- .../gcc.dg/debug/btf/btf-bitfields-4.c| 2 + 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index ab491f0297f..e1ada41b1f4 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -922,41 +922,39 @@ static void btf_asm_sou_member (ctf_container_ref ctfc, ctf_dmdef_t * dmd, unsigned int idx) { ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[dmd->dmd_type]; + ctf_id_t base_type = get_btf_id (dmd->dmd_type); + uint64_t sou_offset = dmd->dmd_offset; + + dw2_asm_output_data (4, dmd->dmd_name_offset, + "MEMBER '%s' idx=%u", + dmd->dmd_name, idx); /* Re-encode bitfields to BTF representation. */ if (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info) == CTF_K_SLICE) { - ctf_id_t base_type = ref_type->dtd_u.dtu_slice.cts_type; unsigned short word_offset = ref_type->dtd_u.dtu_slice.cts_offset; unsigned short bits = ref_type->dtd_u.dtu_slice.cts_bits; - uint64_t sou_offset = dmd->dmd_offset; - - /* Pack the bit offset and bitfield size together. */ - sou_offset += word_offset; - /* If this bitfield cannot be represented, do not output anything. -The parent struct/union 'vlen' field has already been updated. */ if ((bits > 0xff) || (sou_offset > 0xff)) Why dont we reuse the btf_dmd_representable_bitfield_p () function here? This one here checks for sou_off > 0xff, while that in btf_dmd_representable_bitfield_p checks for sou_offset + word_offset > 0xff. The latter is more precise. - return; - - sou_offset &= 0x00ff; - sou_offset |= ((bits & 0xff) << 24); + { + /* Bitfield cannot be represented in BTF. Emit the member as having +'void' type. */ + base_type = BTF_VOID_TYPEID; + } + else + { + /* Pack the bit offset and bitfield size together. */ + sou_offset += word_offset; + sou_offset &= 0x00ff; + sou_offset |= ((bits & 0xff) << 24); - dw2_asm_output_data (4, dmd->dmd_name_offset, - "MEMBER '%s' idx=%u", - dmd->dmd_name, idx); - /* Refer to the base type of the slice. */ - btf_asm_type_ref ("btm_type", ctfc, get_btf_id (base_type)); - dw2_asm_output_data (4, sou_offset, "btm_offset"); -} - else -{ - dw2_asm_output_data (4, dmd->dmd_name_offset, - "MEMBER '%s' idx=%u", - dmd->dmd_name, idx); - btf_asm_type_ref ("btm_type", ctfc, get_btf_id (dmd->dmd_type)); - dw2_asm_output_data (4, dmd->dmd_offset, "btm_offset"); + /* Refer to the base type of the slice. */ + base_type = get_btf_id (ref_type->dtd_u.dtu_slice.cts_type); + } } + + btf_asm_type_ref ("btm_type", ctfc, base_type); + dw2_asm_output_data (4, sou_offset, "btm_offset"); } /* Asm'out an enum constant following a BTF_KIND_ENUM{,64}. */ diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c index d4a6ef6a1eb..20cdfaa057a 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c @@ -14,6 +14,8 @@ /* Struct with 4 members and no bitfield (kind_flag not set). */ /* { dg-final { scan-assembler-times "\[\t \]0x404\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times " MEMBER" 4 } } */ +/* { dg-final { scan-assembler-times " MEMBER 'unsup' idx=2\[\\r\\n\]+\[^\\r\\n\]*0\[\t \]+\[^\n\]*btm_type: void" 1 } }
[PATCH 1/2] ctf: fix PR debug/112878
PR debug/112878: ICE: in ctf_add_slice, at ctfc.cc:499 with _BitInt > 255 in a struct and -gctf1 The CTF generation in GCC does not have a mechanism to roll-back an already added type. In this testcase presented in the PR, we hit a representation limit in CTF slices (for a member of a struct) and ICE, after the type for struct (CTF_K_STRUCT) has already been added to the container. To exit gracefully instead, we now check for both the offset and size of the bitfield to be explicitly <= 255. If the check fails, we emit the member with type CTF_K_UNKNOWN. Note that, the value 255 stems from the existing binutils libctf checks which were motivated to guard against malformed inputs. Although it is not accurate to say that this is a CTF representation limit, mark the code with TBD_CTF_REPRESENTATION_LIMIT for now so that this can be taken care of with the next format version bump, when libctf's checks for the slice data can be lifted as well. gcc/ChangeLog: PR debug/112878 * dwarf2ctf.cc (gen_ctf_sou_type): Check for conditions before call to ctf_add_slice. Use CTF_K_UNKNOWN type if fail. gcc/testsuite/ChangeLog: PR debug/112878 * gcc.dg/debug/ctf/ctf-bitfields-5.c: New test. --- gcc/dwarf2ctf.cc| 15 ++- .../gcc.dg/debug/ctf/ctf-bitfields-5.c | 17 + 2 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc index 77d6bf89689..dc59569fe56 100644 --- a/gcc/dwarf2ctf.cc +++ b/gcc/dwarf2ctf.cc @@ -606,11 +606,16 @@ gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, uint32_t kind) if (attr) bitpos += AT_unsigned (attr); - field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT, -field_type_id, -bitpos - field_location, -bitsize, -c); + /* This is not precisely a TBD_CTF_REPRESENTATION_LIMIT, but +surely something to look at for the next format version bump +for CTF. */ + if (bitsize <= 255 && (bitpos - field_location) <= 255) + field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT, + field_type_id, + bitpos - field_location, + bitsize, c); + else + field_type_id = gen_ctf_unknown_type (ctfc); } /* Add the field type to the struct or union type. */ diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c new file mode 100644 index 000..fee8228647c --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c @@ -0,0 +1,17 @@ +/* Bitfield where the bit offset is > 255 is not allowed in CTF. + + PR debug/112878. + This testcase is to ensure graceful handling. No slices are expected. */ + +/* { dg-do compile { target bitint } } */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* No slices are expected, but a struct with one member is expected. + CTF_K_UNKNOWN is also expected. */ +/* { dg-final { scan-assembler-times "cts_type" 0 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x1a01\[\t \]+\[^\n\]*ctt_info" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \"unknown.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ + +struct { + _BitInt(282) a : 280; +} b; -- 2.43.0
[PATCH 0/2] Fix PR debug/112878 and a BTF issue
Hi, The patch series includes two patches: first one is a fix for PR debug/112878 and the second one is for an existing BTF generation issue. Testing Notes: - Regression tested on x86_64-linux-gnu - Tested btf.exp, ctf.exp, bpf.exp for --target=bpf-unknown-none Thanks, Indu Bhagat (2): ctf: fix PR debug/112878 btf: do not skip members of data type with type id BTF_VOID_TYPEID gcc/btfout.cc | 5 - gcc/dwarf2ctf.cc| 15 ++- .../gcc.dg/debug/btf/btf-bitfields-4.c | 6 +++--- gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c | 9 + .../gcc.dg/debug/ctf/ctf-bitfields-5.c | 17 + 5 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-bitfields-5.c -- 2.43.0
[PATCH 2/2] btf: do not skip members of data type with type id BTF_VOID_TYPEID
Testing the previous fix in gen_ctf_sou_type () reveals an issue in BTF generation, however: BTF emission was currently decrementing the vlen (indicating the number of members) to skip members of type CTF_K_UNKNOWN altogether, but still emitting the BTF for the corresponding member (in output_asm_btf_sou_fields ()). One can see malformed BTF by executing the newly added CTF testcase (gcc.dg/debug/ctf/ctf-bitfields-5.c) with -gbtf instead or even existing btf-struct-2.c without this patch. To fix the issue, it makes sense to rather _not_ skip members of data type of type id BTF_VOID_TYPEID. gcc/ChangeLog: * btfout.cc (btf_asm_type): Do not skip emitting members of unknown type. gcc/testsuite/ChangeLog: * btf-bitfields-4.c: Update the vlen check. * btf-struct-2.c: Check that member named 'f' with void data type is emitted. --- gcc/btfout.cc| 5 - gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c | 6 +++--- gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c| 9 + 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 4a8ec4d1ff0..ab491f0297f 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -820,11 +820,6 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) /* Set kflag if this member is a representable bitfield. */ if (btf_dmd_representable_bitfield_p (ctfc, dmd)) btf_kflag = 1; - - /* Struct members that refer to unsupported types or bitfield formats -shall be skipped. These are marked during preprocessing. */ - else if (!btf_emit_id_p (dmd->dmd_type)) - btf_vlen -= 1; } } diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c index c00c8b3d87f..d4a6ef6a1eb 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c @@ -6,14 +6,14 @@ In this test, we construct a structure such that the bitfield will have an offset so large as to be unrepresentable in BTF. We expect that the resulting BTF will describe the rest of the structure, ignoring the - non-representable bitfield. */ + non-representable bitfield by simply using void data type for the same. */ /* { dg-do compile } */ /* { dg-options "-O0 -gbtf -dA" } */ /* { dg-require-effective-target size32plus } */ -/* Struct with 3 members and no bitfield (kind_flag not set). */ -/* { dg-final { scan-assembler-times "\[\t \]0x403\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* Struct with 4 members and no bitfield (kind_flag not set). */ +/* { dg-final { scan-assembler-times "\[\t \]0x404\[\t \]+\[^\n\]*btt_info" 1 } } */ struct bigly { diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c index e9ff06883db..fa7231be75c 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c @@ -2,14 +2,15 @@ unsupported type. BTF does not support vector types (among other things). When - generating BTF for a struct (or union) type, members which refer to - unsupported types should be skipped. */ + generating BTF for a struct (or union) type. Members which refer to + unsupported types should not be skipped, however. */ /* { dg-do compile } */ /* { dg-options "-O0 -gbtf -dA" } */ -/* Expect a struct with only 2 members - 'f' should not be present. */ -/* { dg-final { scan-assembler-times "\[\t \]0x402\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* Expect a struct with 3 members - 'f' is present but is of data type void. */ +/* { dg-final { scan-assembler-times "\[\t \]0x403\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* { dg-final { scan-assembler-times " MEMBER 'f' idx=1\[\\r\\n\]+\[^\\r\\n\]*0\[\t \]+\[^\n\]*btm_type: void" 1 } } */ struct with_float { -- 2.43.0
Re: [PATCH] btf: improve btf-datasec-3.c test [PR 114642]
On 4/8/24 2:01 PM, David Faust wrote: This test failed on powerpc --target_board=unix'{-m32}' because two variables were not placed in sections where the test silently (and incorrectly) assumed they would be. The important thing for the test is only that BTF_KIND_DATASEC entries are NOT generated for the extern variable declarations without an explicit section attribute. Make the test more robust by placing the non-extern variables in explicit sections, and invert the checks to more accurately verify what we care about in this test. Tested on x86_64-linux-gnu and x86_64-linux-gnu host for powerpc64-linux-gnu and bpf-unkown-none targets. OK? Hi David, LGTM. I see that we have btf-datasec-1.c testcase for checking the case when vars are in sections .rodata/.bss/.data. Thanks gcc/testsuite/ PR testsuite/114642 * gcc.dg/debug/btf/btf-datasec-3.c: Make test more robust on different architectures. --- gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c index 297340cabfa..6b127aa14da 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c @@ -7,22 +7,22 @@ extern int VERSION __attribute__((section (".version"))); -extern int test_bss1; -extern int test_data1; +extern int ext1; +extern int ext2; -int test_bss2; -int test_data2 = 2; +int var1 __attribute__((section (".sec_a"))); +int var2 __attribute__((section (".sec_b"))) = 2; int foo (void) { - test_bss2 = VERSION; - return test_bss1 + test_data1 + test_data2; + ext2 = VERSION; + return ext1 + var1 + var2; } /* There should be 3 DATASEC entries total. Of the extern decls, only VERSION has a known section; entries are not created for the other two. */ /* { dg-final { scan-assembler-times "bts_type" 3 } } */ -/* { dg-final { scan-assembler-times "bts_type: \\(BTF_KIND_VAR 'test_data2'\\)" 1 } } */ -/* { dg-final { scan-assembler-times "bts_type: \\(BTF_KIND_VAR 'test_bss2'\\)" 1 } } */ /* { dg-final { scan-assembler-times "bts_type: \\(BTF_KIND_VAR 'VERSION'\\)" 1 } } */ +/* { dg-final { scan-assembler-not "bts_type: \\(BTF_KIND_VAR 'ext1'\\)" } } */ +/* { dg-final { scan-assembler-not "bts_type: \\(BTF_KIND_VAR 'ext2'\\)" } } */
Re: [PATCH] btf: emit symbol refs in DATASEC entries only for BPF [PR114608]
On 4/8/24 12:26, David Faust wrote: The behavior introduced in fa60ac54964 btf: Emit labels in DATASEC bts_offset entries. is only fully correct when compiling for the BPF target with BPF CO-RE enabled. In other cases, depending on optimizations, it can result in an incorrect symbol reference in the entry bts_offset field for a symbol which may not be emitted at all, causing link-time undefined symbol reference errors like in PR114608. The offending bts_offset field of BTF_KIND_DATASEC entries is in reality only currently useful to consumers of BTF information for BPF programs anyway. Correct the regression by only emitting symbol references in these entries when compiling for the BPF target. For other targets, the behavior returns to that prior to fa60ac54964. The underlying cause is related to PR 113566 "btf: incorrect BTF_KIND_DATASEC entries for variables which are optimized out." A complete fix for 113566 is more involved and unsuitable for stage 4, but will be addressed in the near future. Tested on x86_64-linux-gnu and on x86_64-linux-gnu host for bpf-unknown-none target. OK? Thanks. LGTM. I think adding a comment in the bugzilla for 114431 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114431 indicating a further patch would not hurt either. Thanks gcc/ PR debug/114608 * btfout.cc (btf_asm_datasec_entry): Only emit a symbol reference when generating BTF for BPF CO-RE target. gcc/testsuite/ PR debug/114608 * gcc.dg/debug/btf/btf-datasec-1.c: Check bts_offset symbol references only for BPF target. * gcc.dg/debug/btf/btf-datasec-2.c: Likewise. * gcc.dg/debug/btf/btf-pr106773.c: Likewise. --- gcc/btfout.cc | 2 +- gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c | 10 ++ gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c | 7 --- gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c | 3 ++- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 2e2b3524e83..4a8ec4d1ff0 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -1045,7 +1045,7 @@ btf_asm_datasec_entry (ctf_container_ref ctfc, struct btf_var_secinfo info) { const char *symbol_name = get_name_for_datasec_entry (ctfc, info.type); btf_asm_type_ref ("bts_type", ctfc, info.type); - if (symbol_name == NULL) + if (!btf_with_core_debuginfo_p () || symbol_name == NULL) dw2_asm_output_data (4, info.offset, "bts_offset"); else dw2_asm_output_offset (4, symbol_name, NULL, "bts_offset"); diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c index c8ebe5d07ca..15b76259218 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c @@ -19,10 +19,12 @@ /* { dg-final { scan-assembler-times "0xf03\[\t \]+\[^\n\]*btt_info" 2 } } */ /* { dg-final { scan-assembler-times "0xf01\[\t \]+\[^\n\]*btt_info" 1 } } */ -/* The offset entry for each variable in a DATSEC should contain a label. */ -/* { dg-final { scan-assembler-times "(?:(?:\\.4byte|\\.long|data4\\.ua|\\.ualong|\\.uaword|\\.dword|long|dc\\.l|\\.word)\[\t \]|\\.vbyte\t4,\[\t \]?)_?\[a-e\]\[\t \]+\[^\n\]*bts_offset" 5 } } */ -/* { dg-final { scan-assembler-times "my_cstruct\[\t \]+\[^\n\]*bts_offset" 1 } } */ -/* { dg-final { scan-assembler-times "bigarr\[\t \]+\[^\n\]*bts_offset" 1 } } */ +/* { dg-final { scan-assembler-times "0\[\t \]+\[^\n\]*bts_offset" 7 { target { ! bpf-*-* } } } } */ + +/* For BPF target the offset entry for each variable in a DATSEC should contain a label. */ +/* { dg-final { scan-assembler-times ".4byte\[\t \]\[a-e\]\[\t \]+\[^\n\]*bts_offset" 5 { target bpf-*-* } } } */ +/* { dg-final { scan-assembler-times "my_cstruct\[\t \]+\[^\n\]*bts_offset" 1 { target bpf-*-* } } } */ +/* { dg-final { scan-assembler-times "bigarr\[\t \]+\[^\n\]*bts_offset" 1 { target bpf-*-* } } } */ /* Check that strings for each DATASEC have been added to the BTF string table. */ /* { dg-final { scan-assembler-times "ascii \".data.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c index 857d830e446..a89a239a504 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c @@ -10,9 +10,10 @@ /* { dg-final { scan-assembler-times " BTF_KIND_DATASEC '.bar_sec'\[\\r\\n\]+\[^\\r\\n\]*0xf02\[\t \]+\[^\n\]*btt_info" 1 } } */ /* Function entries should have offset with a label and size of 0 at compile time. */ -/* { dg-final { scan-assembler-times "chacha\[\t \]+\[^\n\]*bts_offset" 1 } } */ -/* { dg-final { scan-assembler-times "bar\[\t \]+\[^\n\]*bts_offset" 1 } } */ -/* { dg-final { scan-assembler-times "foo\[\t \]+\[^\n\]*bts_offset" 1 } } */ +/* { dg-final { scan-assembler-times "chacha\[\t
[PATCH, V3] ctf: fix incorrect CTF for multi-dimensional array types
From: Cupertino Miranda [Changes from V2] - Fixed aarch64 new FAILs reported by Linaro CI. - Fixed typos and other nits pointed out in V2. [End of changes from V2] PR debug/114186 DWARF DIEs of type DW_TAG_subrange_type are linked together to represent the information about the subsequent dimensions. The CTF processing was so far working through them in the opposite (incorrect) order. While fixing the issue, refactor the code a bit for readability. co-authored-By: Indu Bhagat gcc/ PR debug/114186 * dwarf2ctf.cc (gen_ctf_array_type): Invoke the ctf_add_array () in the correct order of the dimensions. (gen_ctf_subrange_type): Refactor out handling of DW_TAG_subrange_type DIE to here. gcc/testsuite/ PR debug/114186 * gcc.dg/debug/ctf/ctf-array-6.c: Add test. --- Testing notes: - Linaro CI reported three new FAILs introduced by ctf-array-6.c due to presence of char '#' on aarch64 where the ASM_COMMENT_START differs. Fixed and regression tested on aarch64. - Regression tested on x86_64-linux-gnu default target. - Regression tested for target bpf-unknown-none (btf.exp, ctf.exp, bpf.exp). - Kernel build with -gctf shows healthier CTF types for arrays. --- gcc/dwarf2ctf.cc | 158 +-- gcc/testsuite/gcc.dg/debug/ctf/ctf-array-6.c | 14 ++ 2 files changed, 89 insertions(+), 83 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-array-6.c diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc index dca86edfffa9..77d6bf896893 100644 --- a/gcc/dwarf2ctf.cc +++ b/gcc/dwarf2ctf.cc @@ -349,105 +349,97 @@ gen_ctf_pointer_type (ctf_container_ref ctfc, dw_die_ref ptr_type) return ptr_type_id; } -/* Generate CTF for an array type. */ +/* Recursively generate CTF for array dimensions starting at DIE C (of type + DW_TAG_subrange_type) until DIE LAST (of type DW_TAG_subrange_type) is + reached. ARRAY_ELEMS_TYPE_ID is base type for the array. */ static ctf_id_t -gen_ctf_array_type (ctf_container_ref ctfc, dw_die_ref array_type) +gen_ctf_subrange_type (ctf_container_ref ctfc, ctf_id_t array_elems_type_id, + dw_die_ref c, dw_die_ref last) { - dw_die_ref c; - ctf_id_t array_elems_type_id = CTF_NULL_TYPEID; + ctf_arinfo_t arinfo; + ctf_id_t array_node_type_id = CTF_NULL_TYPEID; - int vector_type_p = get_AT_flag (array_type, DW_AT_GNU_vector); - if (vector_type_p) -return array_elems_type_id; + dw_attr_node *upper_bound_at; + dw_die_ref array_index_type; + uint32_t array_num_elements; - dw_die_ref array_elems_type = ctf_get_AT_type (array_type); + if (dw_get_die_tag (c) == DW_TAG_subrange_type) +{ + /* When DW_AT_upper_bound is used to specify the size of an +array in DWARF, it is usually an unsigned constant +specifying the upper bound index of the array. However, +for unsized arrays, such as foo[] or bar[0], +DW_AT_upper_bound is a signed integer constant +instead. */ + + upper_bound_at = get_AT (c, DW_AT_upper_bound); + if (upper_bound_at + && AT_class (upper_bound_at) == dw_val_class_unsigned_const) + /* This is the upper bound index. */ + array_num_elements = get_AT_unsigned (c, DW_AT_upper_bound) + 1; + else if (get_AT (c, DW_AT_count)) + array_num_elements = get_AT_unsigned (c, DW_AT_count); + else + { + /* This is a VLA of some kind. */ + array_num_elements = 0; + } +} + else +gcc_unreachable (); - /* First, register the type of the array elements if needed. */ - array_elems_type_id = gen_ctf_type (ctfc, array_elems_type); + /* Ok, mount and register the array type. Note how the array + type we register here is the type of the elements in + subsequent "dimensions", if there are any. */ + arinfo.ctr_nelems = array_num_elements; - /* DWARF array types pretend C supports multi-dimensional arrays. - So for the type int[N][M], the array type DIE contains two - subrange_type children, the first with upper bound N-1 and the - second with upper bound M-1. + array_index_type = ctf_get_AT_type (c); + arinfo.ctr_index = gen_ctf_type (ctfc, array_index_type); - CTF, on the other hand, just encodes each array type in its own - array type CTF struct. Therefore we have to iterate on the - children and create all the needed types. */ + if (c == last) +arinfo.ctr_contents = array_elems_type_id; + else +arinfo.ctr_contents = gen_ctf_subrange_type (ctfc, array_elems_type_id, +dw_get_die_sib (c), last); - c = dw_get_die_child (array_type); - gcc_assert (c); - do -{ - ctf_arinfo_t arinfo; - dw_die_ref array_index_type; - uint32_t array_num_elements; + if (!ctf_type_exists (ctfc, c, _node_type_id)) +array_node_type_id = ctf_add_array (ctfc, CTF_ADD_ROOT, , c); -
[PATCH,V2] ctf: fix incorrect CTF for multi-dimensional array types
From: Cupertino Miranda [Changes from V1] - Refactor the code a bit. [End of changes from V1] PR debug/114186 DWARF DIEs of type DW_TAG_subrange_type are linked together to represent the information about the subsequent dimensions. The CTF processing was so far working through them in the opposite (incorrect) order. While fixing the issue, refactor the code a bit for readability. co-authored-By: Indu Bhagat gcc/ PR debug/114186 * dwarf2ctf.cc (gen_ctf_array_type): Invoke the ctf_add_array () in the correct order of the dimensions. (gen_ctf_subrange_type): Refactor out handling of DW_TAG_subrange_type DIE to here. gcc/testsuite/ PR debug/114186 * gcc.dg/debug/ctf/ctf-array-6.c: Add test. --- Testing notes: Regression tested on x86_64-linux-gnu default target. Regression tested for target bpf-unknown-none (btf.exp, ctf.exp, bpf.exp). --- gcc/dwarf2ctf.cc | 153 +-- gcc/testsuite/gcc.dg/debug/ctf/ctf-array-6.c | 14 ++ 2 files changed, 84 insertions(+), 83 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-array-6.c diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc index dca86edfffa9..3985de115a79 100644 --- a/gcc/dwarf2ctf.cc +++ b/gcc/dwarf2ctf.cc @@ -349,105 +349,92 @@ gen_ctf_pointer_type (ctf_container_ref ctfc, dw_die_ref ptr_type) return ptr_type_id; } -/* Generate CTF for an array type. */ +/* Recursively generate CTF for array dimensions starting at DIE C (of type + DW_TAG_subrange_type) until DIE LAST (of type DW_TAG_subrange_type) is + reached. ARRAY_ELEMS_TYPE_ID is base type for the array. */ static ctf_id_t -gen_ctf_array_type (ctf_container_ref ctfc, dw_die_ref array_type) +gen_ctf_subrange_type (ctf_container_ref ctfc, ctf_id_t array_elems_type_id, + dw_die_ref c, dw_die_ref last) { - dw_die_ref c; - ctf_id_t array_elems_type_id = CTF_NULL_TYPEID; + ctf_arinfo_t arinfo; + ctf_id_t array_node_type_id = CTF_NULL_TYPEID; + + dw_attr_node *upper_bound_at; + dw_die_ref array_index_type; + uint32_t array_num_elements; + + /* When DW_AT_upper_bound is used to specify the size of an + array in DWARF, it is usually an unsigned constant + specifying the upper bound index of the array. However, + for unsized arrays, such as foo[] or bar[0], + DW_AT_upper_bound is a signed integer constant + instead. */ + + upper_bound_at = get_AT (c, DW_AT_upper_bound); + if (upper_bound_at + && AT_class (upper_bound_at) == dw_val_class_unsigned_const) +/* This is the ound index. */ +array_num_elements = get_AT_unsigned (c, DW_AT_upper_bound) + 1; + else if (get_AT (c, DW_AT_count)) +array_num_elements = get_AT_unsigned (c, DW_AT_count); + else +{ + /* This is a VLA of some kind. */ + array_num_elements = 0; +} - int vector_type_p = get_AT_flag (array_type, DW_AT_GNU_vector); - if (vector_type_p) -return array_elems_type_id; + /* Ok, mount and register the array type. Note how the array + type we register here is the type of the elements in + subsequent "dimensions", if there are any. */ + arinfo.ctr_nelems = array_num_elements; - dw_die_ref array_elems_type = ctf_get_AT_type (array_type); + array_index_type = ctf_get_AT_type (c); + arinfo.ctr_index = gen_ctf_type (ctfc, array_index_type); - /* First, register the type of the array elements if needed. */ - array_elems_type_id = gen_ctf_type (ctfc, array_elems_type); + if (c == last) +arinfo.ctr_contents = array_elems_type_id; + else +arinfo.ctr_contents = gen_ctf_subrange_type (ctfc, array_elems_type_id, +dw_get_die_sib (c), last); - /* DWARF array types pretend C supports multi-dimensional arrays. - So for the type int[N][M], the array type DIE contains two - subrange_type children, the first with upper bound N-1 and the - second with upper bound M-1. + if (!ctf_type_exists (ctfc, c, _node_type_id)) +array_node_type_id = ctf_add_array (ctfc, CTF_ADD_ROOT, , c); - CTF, on the other hand, just encodes each array type in its own - array type CTF struct. Therefore we have to iterate on the - children and create all the needed types. */ + return array_node_type_id; +} - c = dw_get_die_child (array_type); - gcc_assert (c); - do -{ - ctf_arinfo_t arinfo; - dw_die_ref array_index_type; - uint32_t array_num_elements; +/* Generate CTF for an ARRAY_TYPE. */ - c = dw_get_die_sib (c); +static ctf_id_t +gen_ctf_array_type (ctf_container_ref ctfc, + dw_die_ref array_type) +{ + dw_die_ref first, last, array_elems_type; + ctf_id_t array_elems_type_id = CTF_NULL_TYPEID; + ctf_id_t array_type_id = CTF_NULL_TYPEID; - if (dw_get_die_tag (c) == DW_TAG_subrange_type) - { - dw_attr_node *upper_bound_at; - - array_index_type =
Re: [PATCH] testsuite: ctf: make array in ctf-file-scope-1 fixed length
On 3/1/24 11:01, David Faust wrote: The array member of struct SFOO in the ctf-file-scope-1 caused the test to fail for the BPF target, since BPF does not support dynamic stack allocation. The array does not need to variable length for the sake of the test, so make it fixed length instead to allow the test to run successfully for the bpf-unknown-none target. Tested on x86_64-linux-gnu, and on x86_64-linux-gnu host for bpf-unknown-none target. LGTM. Thanks! gcc/testsuite/ * gcc.dg/debug/ctf/ctf-file-scope-1.c (SFOO): Make array member fixed-length. --- gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c index a683113e505..ddfb31da405 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c @@ -9,7 +9,7 @@ int foo (int n) { - typedef struct { int a[n]; } SFOO; + typedef struct { int a[6]; } SFOO; SFOO a; __attribute__ ((noinline)) SFOO gfoo (void) { return a; }
Re: [PATCH] btf: change encoding of forward-declared enums [PR111735]
On 12/12/23 14:35, David Faust wrote: 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 (). Bootstrapped and tested on x86_64-linux-gnu. Also tested on x86_64-linux-gnu host for bpf-unknown-none target. LGTM. Thanks 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. --- gcc/btfout.cc | 46 ++- .../gcc.dg/debug/btf/btf-forward-2.c | 18 2 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-forward-2.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index db4f1084f85..3ec938874b6 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -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 @@
Re: [[PATCH][GCC13] 0/2] Fix combined tree build of GCC 13 with Binutils 2.41
On 12/5/23 13:45, Jakub Jelinek wrote: On Tue, Dec 05, 2023 at 01:36:30PM -0800, Indu Bhagat wrote: To resolve the issue of combined Binutils (2.41) + GCC (13) failing to install (https://sourceware.org/bugzilla/show_bug.cgi?id=31108), we will need some backports. This specific issue is with using --enable-shared in the combined tree build; it arises due to missing install-* dependencies in the top-level makefiles. I think it makes sense to bring both of the following two commits (from the trunk) to the GCC13 branch: commit eff0e7a4ae31d1e4e64ae37bbc10d073d8579255 Author: Indu Bhagat Date: Wed Jan 18 23:17:49 2023 -0800 toplevel: Makefile.def: add install-strip dependency on libsframe commit dab58c93634bef06fd289f49109b5c370cd5c380 Author: Indu Bhagat Date: Tue Nov 15 15:07:04 2022 -0800 bfd: linker: merge .sframe sections This patch set cherry-picks the above two commits to GCC13 branch. The patches apply cleanly with no conflicts. Won't this break building gcc 13 with in-tree older binutils which don't have libsframe at all? I think binutils 2.39 and older don't have it. I tested with binutils-2_39-branch and releases/gcc-13 as well (with --enable-shared --disable-bootstrap). It builds and installs fine. Indu
[[PATCH][GCC13] 2/2] toplevel: Makefile.def: add install-strip dependency on libsframe
As noted in PR libsframe/30014 - FTBFS: install-strip fails because bfdlib relinks and fails to find libsframe, the install time dependencies of libbfd need to be updated. ChangeLog: * Makefile.def: Reflect that libsframe needs to installed before libbfd. Reorder a bit to better track libsframe dependencies. * Makefile.in: Regenerate. (cherry picked from commit eff0e7a4ae31d1e4e64ae37bbc10d073d8579255) --- Makefile.def | 5 - Makefile.in | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile.def b/Makefile.def index 41512475042..0c107cae128 100644 --- a/Makefile.def +++ b/Makefile.def @@ -490,7 +490,6 @@ dependencies = { module=install-binutils; on=install-opcodes; }; dependencies = { module=install-strip-binutils; on=install-strip-opcodes; }; // Likewise for ld, libctf, and bfd. -dependencies = { module=install-bfd; on=install-libsframe; }; dependencies = { module=install-libctf; on=install-bfd; }; dependencies = { module=install-ld; on=install-bfd; }; dependencies = { module=install-ld; on=install-libctf; }; @@ -498,6 +497,10 @@ dependencies = { module=install-strip-libctf; on=install-strip-bfd; }; dependencies = { module=install-strip-ld; on=install-strip-bfd; }; dependencies = { module=install-strip-ld; on=install-strip-libctf; }; +// libbfd depends on libsframe +dependencies = { module=install-bfd; on=install-libsframe; }; +dependencies = { module=install-strip-bfd; on=install-strip-libsframe; }; + // libopcodes depends on libbfd dependencies = { module=configure-opcodes; on=configure-bfd; hard=true; }; dependencies = { module=install-opcodes; on=install-bfd; }; diff --git a/Makefile.in b/Makefile.in index 076a48944b8..c1a607ac564 100644 --- a/Makefile.in +++ b/Makefile.in @@ -65991,13 +65991,14 @@ all-stageautoprofile-binutils: maybe-all-stageautoprofile-libsframe all-stageautofeedback-binutils: maybe-all-stageautofeedback-libsframe install-binutils: maybe-install-opcodes install-strip-binutils: maybe-install-strip-opcodes -install-bfd: maybe-install-libsframe install-libctf: maybe-install-bfd install-ld: maybe-install-bfd install-ld: maybe-install-libctf install-strip-libctf: maybe-install-strip-bfd install-strip-ld: maybe-install-strip-bfd install-strip-ld: maybe-install-strip-libctf +install-bfd: maybe-install-libsframe +install-strip-bfd: maybe-install-strip-libsframe configure-opcodes: configure-bfd configure-stage1-opcodes: configure-stage1-bfd configure-stage2-opcodes: configure-stage2-bfd -- 2.41.0
[[PATCH][GCC13] 1/2] bfd: linker: merge .sframe sections
The linker merges all the input .sframe sections. When merging, the linker verifies that all the input .sframe sections have the same abi/arch. The linker uses libsframe library to perform key actions on the .sframe sections - decode, read, and create output data. This implies buildsystem changes to make and install libsframe before libbfd. The linker places the output .sframe section in a new segment of its own: PT_GNU_SFRAME. A new segment is not added, however, if the generated .sframe section is empty. When a section is discarded from the final link, the corresponding entries in the .sframe section for those functions are also deleted. The linker sorts the SFrame FDEs on start address by default and sets the SFRAME_F_FDE_SORTED flag in the .sframe section. This patch also adds support for generation of SFrame unwind information for the .plt* sections on x86_64. SFrame unwind info is generated for IBT enabled PLT, lazy/non-lazy PLT. The existing linker option --no-ld-generated-unwind-info has been adapted to include the control of whether .sframe unwind information will be generated for the linker generated sections like PLT. Changes to the linker script have been made as necessary. ChangeLog: * Makefile.def: Add install dependency on libsframe for libbfd. * Makefile.in: Regenerated. (cherry picked from commit dab58c93634bef06fd289f49109b5c370cd5c380) --- Makefile.def | 4 Makefile.in | 11 +++ 2 files changed, 15 insertions(+) diff --git a/Makefile.def b/Makefile.def index 35e994eb77e..41512475042 100644 --- a/Makefile.def +++ b/Makefile.def @@ -457,11 +457,14 @@ dependencies = { module=all-gdbsupport; on=all-gnulib; }; dependencies = { module=all-gdbsupport; on=all-intl; }; // Host modules specific to binutils. +// build libsframe before bfd for encoder/decoder support for linking +// SFrame sections dependencies = { module=configure-bfd; on=configure-libiberty; hard=true; }; dependencies = { module=configure-bfd; on=configure-intl; }; dependencies = { module=all-bfd; on=all-libiberty; }; dependencies = { module=all-bfd; on=all-intl; }; dependencies = { module=all-bfd; on=all-zlib; }; +dependencies = { module=all-bfd; on=all-libsframe; }; dependencies = { module=configure-opcodes; on=configure-libiberty; hard=true; }; dependencies = { module=all-opcodes; on=all-libiberty; }; @@ -487,6 +490,7 @@ dependencies = { module=install-binutils; on=install-opcodes; }; dependencies = { module=install-strip-binutils; on=install-strip-opcodes; }; // Likewise for ld, libctf, and bfd. +dependencies = { module=install-bfd; on=install-libsframe; }; dependencies = { module=install-libctf; on=install-bfd; }; dependencies = { module=install-ld; on=install-bfd; }; dependencies = { module=install-ld; on=install-libctf; }; diff --git a/Makefile.in b/Makefile.in index 06a9398e172..076a48944b8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -65849,6 +65849,16 @@ all-stagetrain-bfd: maybe-all-stagetrain-zlib all-stagefeedback-bfd: maybe-all-stagefeedback-zlib all-stageautoprofile-bfd: maybe-all-stageautoprofile-zlib all-stageautofeedback-bfd: maybe-all-stageautofeedback-zlib +all-bfd: maybe-all-libsframe +all-stage1-bfd: maybe-all-stage1-libsframe +all-stage2-bfd: maybe-all-stage2-libsframe +all-stage3-bfd: maybe-all-stage3-libsframe +all-stage4-bfd: maybe-all-stage4-libsframe +all-stageprofile-bfd: maybe-all-stageprofile-libsframe +all-stagetrain-bfd: maybe-all-stagetrain-libsframe +all-stagefeedback-bfd: maybe-all-stagefeedback-libsframe +all-stageautoprofile-bfd: maybe-all-stageautoprofile-libsframe +all-stageautofeedback-bfd: maybe-all-stageautofeedback-libsframe configure-opcodes: configure-libiberty configure-stage1-opcodes: configure-stage1-libiberty configure-stage2-opcodes: configure-stage2-libiberty @@ -65981,6 +65991,7 @@ all-stageautoprofile-binutils: maybe-all-stageautoprofile-libsframe all-stageautofeedback-binutils: maybe-all-stageautofeedback-libsframe install-binutils: maybe-install-opcodes install-strip-binutils: maybe-install-strip-opcodes +install-bfd: maybe-install-libsframe install-libctf: maybe-install-bfd install-ld: maybe-install-bfd install-ld: maybe-install-libctf -- 2.41.0
[[PATCH][GCC13] 0/2] Fix combined tree build of GCC 13 with Binutils 2.41
Hello, To resolve the issue of combined Binutils (2.41) + GCC (13) failing to install (https://sourceware.org/bugzilla/show_bug.cgi?id=31108), we will need some backports. This specific issue is with using --enable-shared in the combined tree build; it arises due to missing install-* dependencies in the top-level makefiles. I think it makes sense to bring both of the following two commits (from the trunk) to the GCC13 branch: commit eff0e7a4ae31d1e4e64ae37bbc10d073d8579255 Author: Indu Bhagat Date: Wed Jan 18 23:17:49 2023 -0800 toplevel: Makefile.def: add install-strip dependency on libsframe commit dab58c93634bef06fd289f49109b5c370cd5c380 Author: Indu Bhagat Date: Tue Nov 15 15:07:04 2022 -0800 bfd: linker: merge .sframe sections This patch set cherry-picks the above two commits to GCC13 branch. The patches apply cleanly with no conflicts. --- Testing notes: - Combined tree with GCC 13 (releases/gcc-13 branch) with binutils 2.41 (binutils-2_41-release-point branch) with "--enable-shared --disable-bootstrap" builds and installs. - Bootstrapped and regression tested releases/gcc-13 branch (make check-gcc in a NOT combined tree build). --- Thanks, Indu Bhagat (2): bfd: linker: merge .sframe sections toplevel: Makefile.def: add install-strip dependency on libsframe Makefile.def | 7 +++ Makefile.in | 12 2 files changed, 19 insertions(+) -- 2.41.0
Re: [PATCH] btf: avoid wrong DATASEC entries for extern vars [PR112849]
On 12/4/23 15:47, David Faust wrote: The process of creating BTF_KIND_DATASEC records involves iterating through variable declarations, determining which section they will be placed in, and creating an entry in the appropriate DATASEC record accordingly. For variables without e.g. an explicit __attribute__((section)), we use categorize_decl_for_section () to identify the appropriate named section and corresponding BTF_KIND_DATASEC record. This was incorrectly being done for 'extern' variable declarations as well as non-extern ones, which meant that extern variable declarations could result in BTF_KIND_DATASEC entries claiming the variable is allocated in some section such as '.bss' without any knowledge whether that is actually true. That resulted in errors building the Linux kernel BPF selftests. This patch corrects btf_collect_datasec () to avoid assuming a section for extern variables, and only emit BTF_KIND_DATASEC entries for them if they have a known section. Bootstrapped + tested on x86_64-linux-gnu. Tested on x86_64-linux-gnu host for bpf-unknown-none. One comment below. LGTM, otherwise. Thanks gcc/ PR debug/112849 * btfout.cc (btf_collect_datasec): Avoid incorrectly creating an entry in a BTF_KIND_DATASEC record for extern variable decls without a known section. gcc/testsuite/ PR debug/112849 * gcc.dg/debug/btf/btf-datasec-3.c: New test. --- gcc/btfout.cc | 10 ++- .../gcc.dg/debug/btf/btf-datasec-3.c | 27 +++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index a5e0d640e19..db4f1084f85 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -486,7 +486,15 @@ btf_collect_datasec (ctf_container_ref ctfc) /* Mark extern variables. */ if (DECL_EXTERNAL (node->decl)) - dvd->dvd_visibility = BTF_VAR_GLOBAL_EXTERN; + { + dvd->dvd_visibility = BTF_VAR_GLOBAL_EXTERN; + + /* PR112849: avoid assuming a section for extern decls without +an explicit section, which would result in incorrectly +emitting a BTF_KIND_DATASEC entry for them. */ + if (node->get_section () == NULL) + continue; + } const char *section_name = get_section_name (node); if (section_name == NULL) diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c new file mode 100644 index 000..3c1c7a28c2a --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c @@ -0,0 +1,27 @@ +/* PR debug/112849 + Test that we do not incorrectly create BTF_KIND_DATASEC entries for + extern decls with no known section. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +extern int VERSION __attribute__((section (".version"))); + +extern int test_bss1; +extern int test_data1; + +int test_bss2; +int test_data2 = 2; + +int +foo (void) +{ + test_bss2 = VERSION; + return test_bss1 + test_data1 + test_data2; +} + +/* There should only be a DATASEC entries for VERSION out of the extern decls. */ The statement is unclear as is. Perhaps you wanted to say "There should only be 3 DATASEC entries; including one for VERSION even though it is extern decl" ? +/* { dg-final { scan-assembler-times "bts_type" 3 } } */ +/* { dg-final { scan-assembler-times "bts_type: \\(BTF_KIND_VAR 'test_data2'\\)" 1 } } */ +/* { dg-final { scan-assembler-times "bts_type: \\(BTF_KIND_VAR 'test_bss2'\\)" 1 } } */ +/* { dg-final { scan-assembler-times "bts_type: \\(BTF_KIND_VAR 'VERSION'\\)" 1 } } */
[PATCH] btf: fix PR debug/112656
PR debug/112656 - btf: function prototypes generated with name With this patch, all BTF_KIND_FUNC_PROTO will appear anonymous in the generated BTF section. As noted in the discussion in the bugzilla, the number of BTF_KIND_FUNC_PROTO types output varies across targets (BPF with -mco-re vs non-BPF targets). Hence the check in the test case merely checks that all BTF_KIND_FUNC_PROTO appear anonymous. gcc/ChangeLog: PR debug/112656 * btfout.cc (btf_asm_type): Fixup ctti_name for all BTF types of kind BTF_KIND_FUNC_PROTO. gcc/testsuite/ChangeLog: PR debug/112656 * gcc.dg/debug/btf/btf-function-7.c: New test. Testing notes: - bootstrapped and reg tested on x86_64 - No regressions in btf.exp on BPF target --- gcc/btfout.cc | 4 .../gcc.dg/debug/btf/btf-function-7.c | 19 +++ 2 files changed, 23 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-function-7.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 1c25404b2c0..a5e0d640e19 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -820,6 +820,10 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) btf_kind = BTF_KIND_ENUM64; } + /* PR debug/112656. BTF_KIND_FUNC_PROTO is always anonymous. */ + if (btf_kind == BTF_KIND_FUNC_PROTO) +dtd->dtd_data.ctti_name = 0; + dw2_asm_output_data (4, dtd->dtd_data.ctti_name, "TYPE %" PRIu64 " BTF_KIND_%s '%s'", get_btf_id (dtd->dtd_type), btf_kind_name (btf_kind), diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-function-7.c b/gcc/testsuite/gcc.dg/debug/btf/btf-function-7.c new file mode 100644 index 000..b560dc75650 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-function-7.c @@ -0,0 +1,19 @@ +/* Test BTF for inlined functions. + + See PR/112656 - btf: function prototypes generated with name + BTF_KIND_FUNC_PROTO must be anonymous. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -gbtf -dA" } */ + +/* { dg-final { scan-assembler-times "BTF_KIND_FUNC_PROTO ''\\(\[0-9a-z\]*\\)'" 0 } } */ + +static int log_event(const char *event_name, void *dev_ptr) +{ + return 666; +} + +int foo () +{ + return log_event ("foobar", ((void *)0)); +} -- 2.41.0
[PATCH] btf: fix PR debug/112768
PR debug/112768 - btf: fix asm comment output for BTF_KIND_FUNC* kinds The patch adds a small function to abstract out the detail and return the name of the type. The patch also fixes the issue of BTF_KIND_FUNC appearing in the comments with a 'null' string. For btf-function-6.c testcase, after the patch: .long 0 # TYPE 2 BTF_KIND_FUNC_PROTO '' .long 0xd02 # btt_info: kind=13, kflag=0, vlen=2 .long 0x1 # btt_type: (BTF_KIND_INT 'int') .long 0 # farg_name .long 0x1 # farg_type: (BTF_KIND_INT 'int') .long 0 # farg_name .long 0x1 # farg_type: (BTF_KIND_INT 'int') .long 0 # TYPE 3 BTF_KIND_FUNC_PROTO '' .long 0xd01 # btt_info: kind=13, kflag=0, vlen=1 .long 0x1 # btt_type: (BTF_KIND_INT 'int') .long 0x68# farg_name .long 0x1 # farg_type: (BTF_KIND_INT 'int') .long 0x5 # TYPE 4 BTF_KIND_FUNC 'extfunc' .long 0xc02 # btt_info: kind=12, kflag=0, linkage=2 .long 0x2 # btt_type: (BTF_KIND_FUNC_PROTO '') .long 0xd # TYPE 5 BTF_KIND_FUNC 'foo' .long 0xc01 # btt_info: kind=12, kflag=0, linkage=1 .long 0x3 # btt_type: (BTF_KIND_FUNC_PROTO '') gcc/ChangeLog: PR debug/112768 * btfout.cc (get_btf_type_name): New definition. (btf_collect_datasec): Update dtd_name to the original type name string. (btf_asm_type_ref): Use the new get_btf_type_name function instead. (btf_asm_type): Likewise. (btf_asm_func_type): Likewise. gcc/testsuite/ChangeLog: PR debug/112768 * gcc.dg/debug/btf/btf-function-6.c: Empty string expected with BTF_KIND_FUNC_PROTO. Testing notes: - bootstrapped and reg tested on x86_64 - No regressions in btf.exp on BPF target --- gcc/btfout.cc | 22 +++ .../gcc.dg/debug/btf/btf-function-6.c | 4 ++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 5f2e99ce472..1c25404b2c0 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -158,6 +158,19 @@ get_btf_kind (uint32_t ctf_kind) return BTF_KIND_UNKN; } +/* Some BTF types, like BTF_KIND_FUNC_PROTO, are anonymous. The machinery + in btfout to emit BTF, may reset dtd_data->ctti_name, but does not update + the name in the ctf_dtdef_ref type object (deliberate choice). This + interface helps abstract out that state of affairs, while giving access to + the name of the type as intended. */ + +static const char * +get_btf_type_name (ctf_dtdef_ref dtd) +{ + const char *anon = ""; + return (dtd->dtd_data.ctti_name) ? dtd->dtd_name : anon; +} + /* Helper routines to map between 'relative' and 'absolute' IDs. In BTF all records (including variables) are output in one long list, and all @@ -425,6 +438,7 @@ btf_collect_datasec (ctf_container_ref ctfc) func_dtd->dtd_data = dtd->dtd_data; func_dtd->dtd_data.ctti_type = dtd->dtd_type; func_dtd->linkage = dtd->linkage; + func_dtd->dtd_name = dtd->dtd_name; func_dtd->dtd_type = num_types_added + num_types_created; /* Only the BTF_KIND_FUNC type actually references the name. The @@ -722,7 +736,7 @@ btf_asm_type_ref (const char *prefix, ctf_container_ref ctfc, ctf_id_t ref_id) size_t func_id = btf_relative_func_id (ref_id); ctf_dtdef_ref ref_type = (*funcs)[func_id]; dw2_asm_output_data (4, ref_id, "%s: (BTF_KIND_FUNC '%s')", - prefix, ref_type->dtd_name); + prefix, get_btf_type_name (ref_type)); } else { @@ -733,7 +747,7 @@ btf_asm_type_ref (const char *prefix, ctf_container_ref ctfc, ctf_id_t ref_id) dw2_asm_output_data (4, ref_id, "%s: (BTF_KIND_%s '%s')", prefix, btf_kind_name (ref_kind), - ref_type->dtd_name); + get_btf_type_name (ref_type)); } } @@ -809,7 +823,7 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) dw2_asm_output_data (4, dtd->dtd_data.ctti_name, "TYPE %" PRIu64 " BTF_KIND_%s '%s'", get_btf_id (dtd->dtd_type), btf_kind_name (btf_kind), - dtd->dtd_name); + get_btf_type_name (dtd)); dw2_asm_output_data (4, BTF_TYPE_INFO (btf_kind, btf_kflag, btf_vlen), "btt_info: kind=%u, kflag=%u, vlen=%u", btf_kind, btf_kflag, btf_vlen); @@ -950,7 +964,7 @@ btf_asm_func_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd, ctf_id_t id) ctf_id_t ref_id = dtd->dtd_data.ctti_type; dw2_asm_output_data (4, dtd->dtd_data.ctti_name, "TYPE %" PRIu64 " BTF_KIND_FUNC '%s'", - btf_absolute_func_id (id), dtd->dtd_name); +
Re: [PATCH 2/2] btf: improve -dA comments for testsuite
On 5/30/23 11:27, David Faust wrote: [Changes from v1: - Fix typos. - Split unrelated change into separate commit. - Improve asm comment for enum constants, update btf-enum-1 test. - Improve asm comment for DATASEC records, update btf-datasec-2 test.] Many BTF type kinds refer to other types via index to the final types list. However, the order of the final types list is not guaranteed to remain the same for the same source program between different runs of the compiler, making it difficult to test inter-type references. This patch updates the assembler comments output when writing a given BTF record to include minimal information about the referenced type, if any. This allows for the regular expressions used in the gcc testsuite to do some basic integrity checks on inter-type references. For example, for the type unsigned int * Assembly comments like the following are written with -dA: .4byte 0 ; TYPE 2 BTF_KIND_PTR '' .4byte 0x200 ; btt_info: kind=2, kflag=0, vlen=0 .4byte 0x1 ; btt_type: (BTF_KIND_INT 'unsigned int') Several BTF tests which can immediately be made more robust with this change are updated. It will also be useful in new tests for the upcoming btf_type_tag support. Re-tested on BPF and x86_64, no known regressions. Thanks. LGTM. Thanks gcc/ * btfout.cc (btf_kind_names): New. (btf_kind_name): New. (btf_absolute_var_id): New utility function. (btf_relative_var_id): Likewise. (btf_relative_func_id): Likewise. (btf_absolute_datasec_id): Likewise. (btf_asm_type_ref): New. (btf_asm_type): Update asm comments and use btf_asm_type_ref (). (btf_asm_array): Likewise. Accept ctf_container_ref parameter. (btf_asm_varent): Likewise. (btf_asm_func_arg): Likewise. (btf_asm_datasec_entry): Likewise. (btf_asm_datasec_type): Likewise. (btf_asm_func_type): Likewise. Add index parameter. (btf_asm_enum_const): Likewise. (btf_asm_sou_member): Likewise. (output_btf_vars): Update btf_asm_* call accordingly. (output_asm_btf_sou_fields): Likewise. (output_asm_btf_enum_list): Likewise. (output_asm_btf_func_args_list): Likewise. (output_asm_btf_vlen_bytes): Likewise. (output_btf_func_types): Add ctf_container_ref parameter. Pass it to btf_asm_func_type. (output_btf_datasec_types): Update btf_asm_datsec_type call similarly. (btf_output): Update output_btf_func_types call similarly. gcc/testsuite/ * gcc.dg/debug/btf/btf-array-1.c: Use new BTF asm comments in scan-assembler expressions where useful. * gcc.dg/debug/btf/btf-anonymous-struct-1.c: Likewise. * gcc.dg/debug/btf/btf-anonymous-union-1.c: Likewise. * gcc.dg/debug/btf/btf-bitfields-2.c: Likewise. * gcc.dg/debug/btf/btf-bitfields-3.c: Likewise. * gcc.dg/debug/btf/btf-datasec-2.c: Likewise. * gcc.dg/debug/btf/btf-enum-1.c: Likewise. * gcc.dg/debug/btf/btf-function-6.c: Likewise. * gcc.dg/debug/btf/btf-pointers-1.c: Likewise. * gcc.dg/debug/btf/btf-struct-1.c: Likewise. * gcc.dg/debug/btf/btf-struct-2.c: Likewise. * gcc.dg/debug/btf/btf-typedef-1.c: Likewise. * gcc.dg/debug/btf/btf-union-1.c: Likewise. * gcc.dg/debug/btf/btf-variables-1.c: Likewise. * gcc.dg/debug/btf/btf-variables-2.c: Likewise. Update outdated comment. * gcc.dg/debug/btf/btf-function-3.c: Update outdated comment. --- gcc/btfout.cc | 227 ++ .../gcc.dg/debug/btf/btf-anonymous-struct-1.c | 3 +- .../gcc.dg/debug/btf/btf-anonymous-union-1.c | 4 +- gcc/testsuite/gcc.dg/debug/btf/btf-array-1.c | 3 + .../gcc.dg/debug/btf/btf-bitfields-2.c| 2 +- .../gcc.dg/debug/btf/btf-bitfields-3.c| 2 +- .../gcc.dg/debug/btf/btf-datasec-2.c | 4 +- gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c | 4 + .../gcc.dg/debug/btf/btf-function-3.c | 2 +- .../gcc.dg/debug/btf/btf-function-6.c | 4 +- .../gcc.dg/debug/btf/btf-pointers-1.c | 3 + gcc/testsuite/gcc.dg/debug/btf/btf-struct-1.c | 4 +- gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c | 2 +- .../gcc.dg/debug/btf/btf-typedef-1.c | 14 +- gcc/testsuite/gcc.dg/debug/btf/btf-union-1.c | 2 +- .../gcc.dg/debug/btf/btf-variables-1.c| 6 + .../gcc.dg/debug/btf/btf-variables-2.c| 7 +- 17 files changed, 224 insertions(+), 69 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index ae9855716eb..f51ccf73242 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -114,6 +114,23 @@ static unsigned int num_types_added = 0; CTF types. */ static unsigned int num_types_created = 0; +/* Name strings for BTF kinds. + Note: the indices here must match the type defines in btf.h. */
Re: [PATCH 1/2] btf: be clear when record size/type is not used
On 5/30/23 11:27, David Faust wrote: [Changes from v1: split this change into own commit.] All BTF type records have a 4-byte field used to encode a size or link to another type, depending on the type kind. But BTF_KIND_ARRAY and BTF_KIND_FWD do not use this field at all, and should write zero. GCC already correctly writes zero in this field for these type kinds, but the process is not straightforward and results in the -dA comment claiming the field is a reference to another type. This patch makes the behavior explicit and updates the assembler comment to state clearly that the field is unused. LGTM. Thanks gcc/ * btfout.cc (btf_asm_type): Add dedicated cases for BTF_KIND_ARRAY and BTF_KIND_FWD which do not use the size/type field at all. --- gcc/btfout.cc | 6 ++ 1 file changed, 6 insertions(+) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 497c1ca06e6..ae9855716eb 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -705,6 +705,12 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) dw2_asm_output_data (4, dtd->dtd_data.ctti_size, "btt_size: %uB", dtd->dtd_data.ctti_size); return; +case BTF_KIND_ARRAY: +case BTF_KIND_FWD: + /* These types do not encode any information in the size/type field +and should write 0. */ + dw2_asm_output_data (4, 0, "(unused)"); + return; default: break; }
Re: [PATCH] btf: improve -dA comments for testsuite
On 5/30/23 09:08, David Faust wrote: @@ -793,7 +917,8 @@ btf_asm_enum_const (unsigned int size, ctf_dmdef_t * dmd) /* Asm'out a function parameter description following a BTF_KIND_FUNC_PROTO. */ static void -btf_asm_func_arg (ctf_func_arg_t * farg, size_t stroffset) +btf_asm_func_arg (ctf_container_ref ctfc, ctf_func_arg_t * farg, + size_t stroffset) { /* If the function arg does not have a name, refer to the null string at the start of the string table. This ensures correct encoding for varargs @@ -803,31 +928,33 @@ btf_asm_func_arg (ctf_func_arg_t * farg, size_t stroffset) else dw2_asm_output_data (4, 0, "farg_name"); - dw2_asm_output_data (4, (btf_removed_type_p (farg->farg_type) - ? BTF_VOID_TYPEID - : get_btf_id (farg->farg_type)), - "farg_type"); + btf_asm_type_ref ("farg_type", ctfc, (btf_removed_type_p (farg->farg_type) + ? BTF_VOID_TYPEID + : get_btf_id (farg->farg_type))); } /* Asm'out a BTF_KIND_FUNC type. */ Lets keep the function level comments updated. Apart from btf_asm_func_type, this comment applies to other functions touched in this commit, like btf_asm_datasec_type. I don't follow. All those functions are still doing the same thing. What needs to be updated exactly? I meant updating the function-level comments for the additional args that are added. I saw that in this patch, the new functions added follow the style of explaining the args, like, +/* Return the relative index of the variable with final BTF ID ABS. */ + +static ctf_id_t +btf_relative_var_id (ctf_id_t abs) Hence, my comment. But on second look, however, I see that the file keeps a mix of different styles. This one is up to you then. It makes sense to leave out the self-explanatory args. static void -btf_asm_func_type (ctf_dtdef_ref dtd) +btf_asm_func_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd, size_t i) { - dw2_asm_output_data (4, dtd->dtd_data.ctti_name, "btt_name"); - dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_FUNC, 0, - dtd->linkage), - "btt_info: kind=%u, kflag=%u, linkage=%u", - BTF_KIND_FUNC, 0, dtd->linkage); - dw2_asm_output_data (4, get_btf_id (dtd->dtd_data.ctti_type), "btt_type"); + ctf_id_t ref_id = dtd->dtd_data.ctti_type; + dw2_asm_output_data (4, dtd->dtd_data.ctti_name, + "TYPE %lu BTF_KIND_FUNC '%s'", + num_types_added + num_vars_added + 1 + i, + dtd->dtd_name); + dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_FUNC, 0, dtd->linkage), + "btt_info: kind=%u, kflag=%u, linkage=%u", + BTF_KIND_FUNC, 0, dtd->linkage); + btf_asm_type_ref ("btt_type", ctfc, get_btf_id (ref_id)); } /* Asm'out a variable entry following a BTF_KIND_DATASEC. */ static void -btf_asm_datasec_entry (struct btf_var_secinfo info) +btf_asm_datasec_entry (ctf_container_ref ctfc, struct btf_var_secinfo info) { - dw2_asm_output_data (4, info.type, "bts_type"); + btf_asm_type_ref ("bts_type", ctfc, info.type); dw2_asm_output_data (4, info.offset, "bts_offset"); dw2_asm_output_data (4, info.size, "bts_size"); } @@ -835,9 +962,12 @@ btf_asm_datasec_entry (struct btf_var_secinfo info) /* Asm'out a whole BTF_KIND_DATASEC, including its variable entries. */ static void -btf_asm_datasec_type (btf_datasec_t ds, size_t stroffset) +btf_asm_datasec_type (ctf_container_ref ctfc, btf_datasec_t ds, ctf_id_t id, + size_t stroffset) { - dw2_asm_output_data (4, ds.name_offset + stroffset, "btt_name"); + dw2_asm_output_data (4, ds.name_offset + stroffset, + "TYPE %lu BTF_KIND_DATASEC '%s'", + btf_absolute_datasec_id (id), ds.name); dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_DATASEC, 0, ds.entries.length ()), "btt_info"); @@ -845,7 +975,7 @@ btf_asm_datasec_type (btf_datasec_t ds, size_t stroffset) loaders such as libbpf. */ dw2_asm_output_data (4, 0, "btt_size"); for (size_t i = 0; i < ds.entries.length (); i++) -btf_asm_datasec_entry (ds.entries[i]); +btf_asm_datasec_entry (ctfc, ds.entries[i]); }
Re: [PATCH] btf: improve -dA comments for testsuite
On 5/25/23 9:37 AM, David Faust via Gcc-patches wrote: Many BTF type kinds refer to other types via index to the final types list. However, the order of the final types list is not guaranteed to remain the same for the same source program between different runs of the compiler, making it difficult to test inter-type references. This patch updates the assembler comments output when writing a given BTF record to include minimal information about the referenced type, if any. This allows for the regular expressions used in the gcc testsuite to do some basic integrity checks on inter-type references. For example, for the type unsigned int * Assembly comments like the following are written with -dA: .4byte 0 ; TYPE 2 BTF_KIND_PTR '' .4byte 0x200 ; btt_info: kind=2, kflag=0, vlen=0 .4byte 0x1 ; btt_type: (BTF_KIND_INT 'unsigned int') Several BTF tests which can immediately be made more robust with this change are updated. It will also be useful in new tests for the upcoming btf_type_tag support. Thanks for working on this, David. It will be nice to use these enhanced assembler comments in the output for some of CTF testing as well sometime. But we can get to that later after this comit. Some comments inlined below. Tested on BPF and x86_64, no known regressions. OK for trunk? Thanks. gcc/ * btfout.cc (btf_kind_names): New. (btf_kind_name): New. (btf_absolute_var_id): New utility function. (btf_relative_var_id): Likewise. (btf_relative_func_id): Likewise. (btf_absolute_datasec_id): Likewise. (btf_asm_type_ref): New. (btf_asm_type): Update asm comments and use btf_asm_type_ref (). (btf_asm_array): Likewise. Accept ctf_container_ref parameter. (btf_asm_varent): Likewise. (btf_asm_func_arg): Likewise. (btf_asm_datasec_entry): Likewise. (btf_asm_datasec_type): Likewise. (btf_asm_func_type): Likewise. Add index parameter. (btf_asm_sou_member): Likewise. (output_btf_vars): Update btf_asm_* call accordingly. (output_asm_btf_sou_fields): Likewise. (output_asm_btf_func_args_list): Likewise. (output_asm_btf_vlen_bytes): Likewise. (output_btf_func_types): Add ctf_container_ref parameter. Pass it to btf_asm_func_type. (output_btf_datasec_types): Update btf_asm_datsec_type call similarly. (btf_output): Update output_btf_func_types call similarly. gcc/testsuite/ * gcc.dg/debug/btf/btf-array-1.c: Use new BTF asm comments in scan-assembler expressions where useful. * gcc.dg/debug/btf/btf-anonymous-struct-1.c: Likewise. * gcc.dg/debug/btf/btf-anonymous-union-1.c: Likewise. * gcc.dg/debug/btf/btf-bitfields-2.c: Likewise. * gcc.dg/debug/btf/btf-bitfields-3.c: Likewise. * gcc.dg/debug/btf/btf-function-6.c: Likewise. * gcc.dg/debug/btf/btf-pointers-1.c: Likewise. * gcc.dg/debug/btf/btf-struct-1.c: Likewise. * gcc.dg/debug/btf/btf-struct-2.c: Likewise. * gcc.dg/debug/btf/btf-typedef-1.c: Likewise. * gcc.dg/debug/btf/btf-union-1.c: Likewise. * gcc.dg/debug/btf/btf-variables-1.c: Likewise. * gcc.dg/debug/btf/btf-variables-2.c: Likewise. Update outdated comment. * gcc.dg/debug/btf/btf-function-3.c: Update outdated comment. --- gcc/btfout.cc | 220 ++ .../gcc.dg/debug/btf/btf-anonymous-struct-1.c | 3 +- .../gcc.dg/debug/btf/btf-anonymous-union-1.c | 4 +- gcc/testsuite/gcc.dg/debug/btf/btf-array-1.c | 3 + .../gcc.dg/debug/btf/btf-bitfields-2.c| 2 +- .../gcc.dg/debug/btf/btf-bitfields-3.c| 2 +- .../gcc.dg/debug/btf/btf-function-3.c | 2 +- .../gcc.dg/debug/btf/btf-function-6.c | 4 +- .../gcc.dg/debug/btf/btf-pointers-1.c | 3 + gcc/testsuite/gcc.dg/debug/btf/btf-struct-1.c | 4 +- gcc/testsuite/gcc.dg/debug/btf/btf-struct-2.c | 2 +- .../gcc.dg/debug/btf/btf-typedef-1.c | 14 +- gcc/testsuite/gcc.dg/debug/btf/btf-union-1.c | 2 +- .../gcc.dg/debug/btf/btf-variables-1.c| 6 + .../gcc.dg/debug/btf/btf-variables-2.c| 7 +- 15 files changed, 215 insertions(+), 63 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 497c1ca06e6..8960acfbbaa 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -114,6 +114,23 @@ static unsigned int num_types_added = 0; CTF types. */ static unsigned int num_types_created = 0; +/* Name strings for BTF kinds. + Note: the indices here must match the type defines in btf.h. */ +static const char *const btf_kind_names[] = + { +"UNKN", "INT", "PTR", "ARRAY", "STRUCT", "UNION", "ENUM", "FWD", +"TYPEDEF", "VOLATILE", "CONST", "RESTRICT", "FUNC", "FUNC_PROTO", +"VAR", "DATASEC", "FLOAT", "DECL_TAG", "TYPE_TAG", "ENUM64" + }; + +/* Return a name string
[Committed] MAINTAINERS: Add myself as CTF and BTF reviewer
Looks like I did this only in my head back then. Finally pushed. Thanks! ChangeLog: * MAINTAINERS: Add myself. --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index c8045d49861..cebf45d49e5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -271,6 +271,7 @@ check in changes outside of the parts of the compiler they maintain. arc port Claudiu Zissulescu callgraph Martin Jambor C front endMarek Polacek +CTF, BTF Indu Bhagat CTF, BTF David Faust dataflow Paolo Bonzini dataflow Seongbae Park @@ -340,7 +341,6 @@ Andrew Benson Daniel Berlin Pat Bernardi Jan Beulich -Indu Bhagat David Billinghurst Tomas Bily Laurynas Biveinis -- 2.39.2
Re: [PATCH v2 0/3] btf: fix BTF for extern items [PR106773]
On 12/13/22 10:44, David Faust wrote: [Changes from v1: - Remove #defines for LINKAGE_* values, instead mirror enums from linux/btf.h to include/btf.h and use those. - Fix BTF generation for extern variable with both non-defining and defining decls in the same CU. Add a test for this. - Update several comments per review feedback. ] Hi, This series fixes the issues reported in target/PR106773. I decided to split it into three commits, as there are ultimately three distinct issues and fixes. See each patch for details. Tested on bpf-unknown-none and x86_64-linux-gnu, no known regressions. OK to push? Thanks. Hi David, LGTM. Thanks David Faust (3): btf: add 'extern' linkage for variables [PR106773] btf: fix 'extern const void' variables [PR106773] btf: correct generation for extern funcs [PR106773] gcc/btfout.cc | 184 +- .../gcc.dg/debug/btf/btf-datasec-2.c | 28 +++ .../gcc.dg/debug/btf/btf-function-6.c | 19 ++ gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c | 25 +++ .../gcc.dg/debug/btf/btf-variables-4.c| 24 +++ .../gcc.dg/debug/btf/btf-variables-5.c| 19 ++ include/btf.h | 29 ++- 7 files changed, 276 insertions(+), 52 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-function-6.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-variables-4.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-variables-5.c
Re: [PATCH 1/3] btf: add 'extern' linkage for variables [PR106773]
On 12/12/22 12:47, David Faust wrote: On 12/8/22 22:55, Indu Bhagat wrote: Hi David, On 12/7/22 12:57, David Faust wrote: Add support for the 'extern' linkage value for BTF_KIND_VAR records, which is used for variables declared as extern in the source file. PR target/106773 gcc/ * btfout.cc (BTF_LINKAGE_STATIC): New define. (BTF_LINKAGE_GLOBAL): Likewise. (BTF_LINKAGE_EXTERN): Likewise. (btf_collect_datasec): Mark extern variables as such. (btf_asm_varent): Accomodate 'extern' linkage. gcc/testsuite/ * gcc.dg/debug/btf/btf-variables-4.c: New test. include/ * btf.h (struct btf_var): Update comment to note 'extern' linkage. --- gcc/btfout.cc | 9 ++- .../gcc.dg/debug/btf/btf-variables-4.c| 24 +++ include/btf.h | 2 +- 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-variables-4.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index aef9fd70a28..a1c6266a7db 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -66,6 +66,10 @@ static char btf_info_section_label[MAX_BTF_LABEL_BYTES]; #define BTF_INVALID_TYPEID 0x +#define BTF_LINKAGE_STATIC 0 +#define BTF_LINKAGE_GLOBAL 1 +#define BTF_LINKAGE_EXTERN 2 + I was about to suggest to rename these to use the same name as used in the kernel btf.h. What is used there is: BTF_VAR_STATIC = 0, BTF_VAR_GLOBAL_ALLOCATED = 1, BTF_VAR_GLOBAL_EXTERN = 2, But after looking at the Patch 3/3, I see you reuse these definitions for functions as well. I just find the names confusing on the first look - "BTF_LINKAGE_STATIC". Naming aside, what do you think about adding the defines to include/btf.h instead ? Actually, I forgot these are defined (separately for both VARs and FUNCs) in the kernel uapi/linux/btf.h. It would probably be best to mirror that approach and use a separate enum for each, in include/btf.h. WDYT? Yes, mirroring in include/btf.h sounds good. /* Mapping of CTF variables to the IDs they will be assigned when they are converted to BTF_KIND_VAR type records. Strictly accounts for the index from the start of the variable type entries, does not include the number @@ -314,6 +318,9 @@ btf_collect_datasec (ctf_container_ref ctfc) continue; const char *section_name = node->get_section (); + /* Mark extern variables. */ + if (DECL_EXTERNAL (node->decl)) + dvd->dvd_visibility = BTF_LINKAGE_EXTERN; This made me think about the following case. extern const char a[]; const char a[] = "foo"; What is the expected BTF for this? Since BTF can differentiate between the non-defining extern variable declaration, I expected to see two variables with different "linkage". At this time I see, two variables with global linkage but different types: .long 0xe00 # btv_info .long 0x4 # btv_type .long 0x1 # btv_linkage .long 0x1f# btv_name .long 0xe00 # btv_info .long 0x7 # btv_type .long 0x1 # btv_linkage .long 0x60# btt_name The BTF documentation in the kernel does not clarify this case. Going off the implementation in clang as a reference, it looks like only one VAR record is expected, with 'global' linkage: $ cat extdef.c extern const char a[]; const char a[] = "foo"; $ clang -target bpf -c -g extdef.c -o extdef.o $ /usr/sbin/bpftool btf dump file extdef.o [1] CONST '(anon)' type_id=2 [2] INT 'char' size=1 bits_offset=0 nr_bits=8 encoding=SIGNED [3] ARRAY '(anon)' type_id=1 index_type_id=4 nr_elems=4 [4] INT '__ARRAY_SIZE_TYPE__' size=4 bits_offset=0 nr_bits=32 encoding=(none) [5] VAR 'a' type_id=3, linkage=global [6] DATASEC '.rodata' size=0 vlen=1 type_id=5 offset=0 size=4 (VAR 'a') In GCC we have two records since we have two DIEs for "a" in the DWARF. One has type "const char[4]" and the other has type "const char[]", so the BTF records point to two different types as well. I guess we should find a way in BTF to identify this and emit only the defining definition as clang does. CTF had a similar issue earlier. See PR105089. https://gcc.gnu.org/PR105089 if (section_name == NULL) { @@ -676,7 +683,7 @@ btf_asm_varent (ctf_dvdef_ref var) dw2_asm_output_data (4, var->dvd_name_offset, "btv_name"); dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_VAR, 0, 0), "btv_info"); dw2_asm_output_data (4, get_btf_id (var->dvd_type), "btv_type"); - dw2_asm_output_data (4, (var->dvd_visibility ? 1 : 0), "btv_linkage"); + dw2_asm_output_data (4, var->dvd_visibility, "btv_linkage"); } /* Asm'out a member description
Re: [PATCH 3/3] btf: correct generation for extern funcs [PR106773]
On 12/12/22 12:31, David Faust wrote: On 12/8/22 23:36, Indu Bhagat wrote: On 12/7/22 12:57, David Faust wrote: The eBPF loader expects to find entries for functions declared as extern in the corresponding BTF_KIND_DATASEC record, but we were not generating these entries. This patch adds support for the 'extern' linkage of function types in BTF, and creates entries for for them BTF_KIND_DATASEC records as needed. PR target/106773 gcc/ * btfout.cc (get_section_name): New function. (btf_collect_datasec): Use it here. Process functions, marking them 'extern' and generating DATASEC entries for them as appropriate. Move creation of BTF_KIND_FUNC records to here... (btf_dtd_emit_preprocess_cb): ... from here. gcc/testsuite/ * gcc.dg/debug/btf/btf-datasec-2.c: New test. * gcc.dg/debug/btf/btf-function-6.c: New test. include/ * btf.h (struct btf_var_secinfo): Update comments with notes about extern functions. --- gcc/btfout.cc | 129 -- .../gcc.dg/debug/btf/btf-datasec-2.c | 28 .../gcc.dg/debug/btf/btf-function-6.c | 19 +++ include/btf.h | 9 +- 4 files changed, 139 insertions(+), 46 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-function-6.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 05f3a3f9b6e..d7ead377ec5 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -294,7 +294,35 @@ btf_datasec_push_entry (ctf_container_ref ctfc, const char *secname, ds.entries.safe_push (info); datasecs.safe_push (ds); - num_types_created++; +} + + +/* Return the section name, as of interest to btf_collect_datasec, for the + given symtab node. Note that this deliberately returns NULL for objects + which do not go in a section btf_collect_datasec cares about. */ "Dot, space, space, new sentence." +static const char * +get_section_name (symtab_node *node) +{ + const char *section_name = node->get_section (); + + if (section_name == NULL) +{ + switch (categorize_decl_for_section (node->decl, 0)) + { + case SECCAT_BSS: + section_name = ".bss"; + break; + case SECCAT_DATA: + section_name = ".data"; + break; + case SECCAT_RODATA: + section_name = ".rodata"; + break; + default:; + } +} + + return section_name; } /* Construct all BTF_KIND_DATASEC records for CTFC. One such record is created @@ -305,7 +333,60 @@ btf_datasec_push_entry (ctf_container_ref ctfc, const char *secname, static void btf_collect_datasec (ctf_container_ref ctfc) { - /* See cgraph.h struct symtab_node, which varpool_node extends. */ + cgraph_node *func; + FOR_EACH_FUNCTION (func) +{ + dw_die_ref die = lookup_decl_die (func->decl); + if (die == NULL) + continue; + + ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, die); + if (dtd == NULL) + continue; + + /* Functions actually get two types: a BTF_KIND_FUNC_PROTO, and +also a BTF_KIND_FUNC. But the CTF container only allocates one +type per function, which matches closely with BTF_KIND_FUNC_PROTO. +For each such function, also allocate a BTF_KIND_FUNC entry. +These will be output later. */ "Dot, space, space, new sentence." + ctf_dtdef_ref func_dtd = ggc_cleared_alloc (); + func_dtd->dtd_data = dtd->dtd_data; + func_dtd->dtd_data.ctti_type = dtd->dtd_type; + func_dtd->linkage = dtd->linkage; + func_dtd->dtd_type = num_types_added + num_types_created; + + /* Only the BTF_KIND_FUNC type actually references the name. The +BTF_KIND_FUNC_PROTO is always anonymous. */ + dtd->dtd_data.ctti_name = 0; + + vec_safe_push (funcs, func_dtd); + num_types_created++; + + /* Mark any 'extern' funcs and add DATASEC entries for them. */ + if (DECL_EXTERNAL (func->decl)) + { + func_dtd->linkage = BTF_LINKAGE_EXTERN; + What is the expected BTF when both decl and definition are present: extern int extfunc(int x); int extfunc (int x) { int y = foo (); return y; } Using clang implementation as the reference, a single FUNC record for "extfunc" with "global" linkage: $ cat extfuncdef.c extern int extfunc (int x); int extfunc (int x) { int y = foo (); return y; } $ clang -target bpf -c -g extfuncdef.c -o extfuncdef.o $ /usr/sbin/bpftool btf dump file extfuncdef.o [1] FUNC_PROTO '(anon)' ret_type_id=2 vlen=1 '(anon)' type_id=2 [2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED [3] FUNC 'extfunc' type_id=1 linkage=global With this patch we do the same in GCC. OK. Thanks for confirming. +
Re: [PATCH 2/3] btf: fix 'extern const void' variables [PR106773]
On 12/12/22 12:59, David Faust wrote: On 12/8/22 23:34, Indu Bhagat wrote: Looks OK to me overall. Minor comments below. Thanks On 12/7/22 12:57, David Faust wrote: The eBPF loader expects to find BTF_KIND_VAR records for references to extern const void symbols. We were mistakenly identifing these as unsupported types, and as a result skipping emitting VAR records for them. In addition, the internal DWARF representation from which BTF is produced does not generate 'const' modifier DIEs for the void type, which meant in BTF the 'const' qualifier was dropped for 'extern const void' variables. This patch also adds support for generating a const void type in BTF to correct emission for these variables. PR target/106773 gcc/ * btfout.cc (btf_collect_datasec): Correct size of void entries. (btf_dvd_emit_preprocess_cb): Do not skip emitting variables which refer to void types. (btf_init_postprocess): Create 'const void' type record if needed and adjust variables to refer to it as appropriate. gcc/testsuite/ * gcc.dg/debug/btf/btf-pr106773.c: New test. --- gcc/btfout.cc | 44 +-- gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c | 25 +++ 2 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index a1c6266a7db..05f3a3f9b6e 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -354,6 +354,8 @@ btf_collect_datasec (ctf_container_ref ctfc) tree size = DECL_SIZE_UNIT (node->decl); if (tree_fits_uhwi_p (size)) info.size = tree_to_uhwi (size); + else if (VOID_TYPE_P (TREE_TYPE (node->decl))) + info.size = 1; /* Offset is left as 0 at compile time, to be filled in by loaders such as libbpf. */ @@ -439,7 +441,7 @@ btf_dvd_emit_preprocess_cb (ctf_dvdef_ref *slot, ctf_container_ref arg_ctfc) ctf_dvdef_ref var = (ctf_dvdef_ref) * slot; /* Do not add variables which refer to unsupported types. */ - if (btf_removed_type_p (var->dvd_type)) + if (!voids.contains (var->dvd_type) && btf_removed_type_p (var->dvd_type)) return 1; arg_ctfc->ctfc_vars_list[num_vars_added] = var; @@ -1073,15 +1075,49 @@ btf_init_postprocess (void) { ctf_container_ref tu_ctfc = ctf_get_tu_ctfc (); - size_t i; - size_t num_ctf_types = tu_ctfc->ctfc_types->elements (); - holes.create (0); voids.create (0); num_types_added = 0; num_types_created = 0; + /* Workaround for 'const void' variables. These variables are sometimes used + in eBPF programs to address kernel symbols. DWARF does not generate const + qualifier on void type, so we would incorrectly emit these variables + without the const qualifier. + Unfortunately we need the TREE node to know it was const, and we need + to create the const modifier type (if needed) now, before making the types + list. So we can't avoid iterating with FOR_EACH_VARIABLE here, and then + again when creating the DATASEC entries. */ "Dot, space, space, new sentence." in 3 places. + ctf_id_t constvoid_id = CTF_NULL_TYPEID; + varpool_node *var; + FOR_EACH_VARIABLE (var) +{ + if (!var->decl) + continue; + + tree type = TREE_TYPE (var->decl); + if (type && VOID_TYPE_P (type) && TYPE_READONLY (type)) + { + dw_die_ref die = lookup_decl_die (var->decl); + if (die == NULL) + continue; + + ctf_dvdef_ref dvd = ctf_dvd_lookup (tu_ctfc, die); + if (dvd == NULL) + continue; + + /* Create the 'const' modifier type for void. */ + if (constvoid_id == CTF_NULL_TYPEID) + constvoid_id = ctf_add_reftype (tu_ctfc, CTF_ADD_ROOT, + dvd->dvd_type, CTF_K_CONST, NULL); No de-duplication of the const void type. I assume libbpf will take care of this eventually. Hm, not sure I follow. Where is the duplication? The const void type is only created once here, for the first such variable which needs it, and reused for subsequent variables. And it does not already exist in the CTF which we are translating into BTF. You're right - you are reusing the const void type once generated for a CU for each usage. My bad - I didnt follow the code properly :) In any case, yes libbpf can handle duplicated types. Though it would still be good to minimize that where we can to not bloat the BTF info. + dvd->dvd_type = constvoid_id; + } +} + + size_t i; + size_t num_ctf_types = tu_ctfc->ctfc_types->elements (); + if (num_ctf_types) { init_btf_id_map (num_ctf_types + 1); diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c b/gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c new fi
Re: [PATCH 3/3] btf: correct generation for extern funcs [PR106773]
On 12/7/22 12:57, David Faust wrote: The eBPF loader expects to find entries for functions declared as extern in the corresponding BTF_KIND_DATASEC record, but we were not generating these entries. This patch adds support for the 'extern' linkage of function types in BTF, and creates entries for for them BTF_KIND_DATASEC records as needed. PR target/106773 gcc/ * btfout.cc (get_section_name): New function. (btf_collect_datasec): Use it here. Process functions, marking them 'extern' and generating DATASEC entries for them as appropriate. Move creation of BTF_KIND_FUNC records to here... (btf_dtd_emit_preprocess_cb): ... from here. gcc/testsuite/ * gcc.dg/debug/btf/btf-datasec-2.c: New test. * gcc.dg/debug/btf/btf-function-6.c: New test. include/ * btf.h (struct btf_var_secinfo): Update comments with notes about extern functions. --- gcc/btfout.cc | 129 -- .../gcc.dg/debug/btf/btf-datasec-2.c | 28 .../gcc.dg/debug/btf/btf-function-6.c | 19 +++ include/btf.h | 9 +- 4 files changed, 139 insertions(+), 46 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-function-6.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 05f3a3f9b6e..d7ead377ec5 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -294,7 +294,35 @@ btf_datasec_push_entry (ctf_container_ref ctfc, const char *secname, ds.entries.safe_push (info); datasecs.safe_push (ds); - num_types_created++; +} + + +/* Return the section name, as of interest to btf_collect_datasec, for the + given symtab node. Note that this deliberately returns NULL for objects + which do not go in a section btf_collect_datasec cares about. */ "Dot, space, space, new sentence." +static const char * +get_section_name (symtab_node *node) +{ + const char *section_name = node->get_section (); + + if (section_name == NULL) +{ + switch (categorize_decl_for_section (node->decl, 0)) + { + case SECCAT_BSS: + section_name = ".bss"; + break; + case SECCAT_DATA: + section_name = ".data"; + break; + case SECCAT_RODATA: + section_name = ".rodata"; + break; + default:; + } +} + + return section_name; } /* Construct all BTF_KIND_DATASEC records for CTFC. One such record is created @@ -305,7 +333,60 @@ btf_datasec_push_entry (ctf_container_ref ctfc, const char *secname, static void btf_collect_datasec (ctf_container_ref ctfc) { - /* See cgraph.h struct symtab_node, which varpool_node extends. */ + cgraph_node *func; + FOR_EACH_FUNCTION (func) +{ + dw_die_ref die = lookup_decl_die (func->decl); + if (die == NULL) + continue; + + ctf_dtdef_ref dtd = ctf_dtd_lookup (ctfc, die); + if (dtd == NULL) + continue; + + /* Functions actually get two types: a BTF_KIND_FUNC_PROTO, and +also a BTF_KIND_FUNC. But the CTF container only allocates one +type per function, which matches closely with BTF_KIND_FUNC_PROTO. +For each such function, also allocate a BTF_KIND_FUNC entry. +These will be output later. */ "Dot, space, space, new sentence." + ctf_dtdef_ref func_dtd = ggc_cleared_alloc (); + func_dtd->dtd_data = dtd->dtd_data; + func_dtd->dtd_data.ctti_type = dtd->dtd_type; + func_dtd->linkage = dtd->linkage; + func_dtd->dtd_type = num_types_added + num_types_created; + + /* Only the BTF_KIND_FUNC type actually references the name. The +BTF_KIND_FUNC_PROTO is always anonymous. */ + dtd->dtd_data.ctti_name = 0; + + vec_safe_push (funcs, func_dtd); + num_types_created++; + + /* Mark any 'extern' funcs and add DATASEC entries for them. */ + if (DECL_EXTERNAL (func->decl)) + { + func_dtd->linkage = BTF_LINKAGE_EXTERN; + What is the expected BTF when both decl and definition are present: extern int extfunc(int x); int extfunc (int x) { int y = foo (); return y; } + const char *section_name = get_section_name (func); + /* Note: get_section_name () returns NULL for functions in text +section. This is intentional, since we do not want to generate +DATASEC entries for them. */ "Dot, space, space, new sentence." + if (section_name == NULL) + continue; + + struct btf_var_secinfo info; + + /* +1 for the sentinel type not in the types map. */ + info.type = func_dtd->dtd_type + 1; + + /* Both zero at compile time. */ + info.size = 0; + info.offset = 0; + + btf_datasec_push_entry (ctfc, section_name, info); + } +} + varpool_node *node; FOR_EACH_VARIABLE (node) { @@ -317,28 +398,13 @@
Re: [PATCH 2/3] btf: fix 'extern const void' variables [PR106773]
Looks OK to me overall. Minor comments below. Thanks On 12/7/22 12:57, David Faust wrote: The eBPF loader expects to find BTF_KIND_VAR records for references to extern const void symbols. We were mistakenly identifing these as unsupported types, and as a result skipping emitting VAR records for them. In addition, the internal DWARF representation from which BTF is produced does not generate 'const' modifier DIEs for the void type, which meant in BTF the 'const' qualifier was dropped for 'extern const void' variables. This patch also adds support for generating a const void type in BTF to correct emission for these variables. PR target/106773 gcc/ * btfout.cc (btf_collect_datasec): Correct size of void entries. (btf_dvd_emit_preprocess_cb): Do not skip emitting variables which refer to void types. (btf_init_postprocess): Create 'const void' type record if needed and adjust variables to refer to it as appropriate. gcc/testsuite/ * gcc.dg/debug/btf/btf-pr106773.c: New test. --- gcc/btfout.cc | 44 +-- gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c | 25 +++ 2 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index a1c6266a7db..05f3a3f9b6e 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -354,6 +354,8 @@ btf_collect_datasec (ctf_container_ref ctfc) tree size = DECL_SIZE_UNIT (node->decl); if (tree_fits_uhwi_p (size)) info.size = tree_to_uhwi (size); + else if (VOID_TYPE_P (TREE_TYPE (node->decl))) + info.size = 1; /* Offset is left as 0 at compile time, to be filled in by loaders such as libbpf. */ @@ -439,7 +441,7 @@ btf_dvd_emit_preprocess_cb (ctf_dvdef_ref *slot, ctf_container_ref arg_ctfc) ctf_dvdef_ref var = (ctf_dvdef_ref) * slot; /* Do not add variables which refer to unsupported types. */ - if (btf_removed_type_p (var->dvd_type)) + if (!voids.contains (var->dvd_type) && btf_removed_type_p (var->dvd_type)) return 1; arg_ctfc->ctfc_vars_list[num_vars_added] = var; @@ -1073,15 +1075,49 @@ btf_init_postprocess (void) { ctf_container_ref tu_ctfc = ctf_get_tu_ctfc (); - size_t i; - size_t num_ctf_types = tu_ctfc->ctfc_types->elements (); - holes.create (0); voids.create (0); num_types_added = 0; num_types_created = 0; + /* Workaround for 'const void' variables. These variables are sometimes used + in eBPF programs to address kernel symbols. DWARF does not generate const + qualifier on void type, so we would incorrectly emit these variables + without the const qualifier. + Unfortunately we need the TREE node to know it was const, and we need + to create the const modifier type (if needed) now, before making the types + list. So we can't avoid iterating with FOR_EACH_VARIABLE here, and then + again when creating the DATASEC entries. */ "Dot, space, space, new sentence." in 3 places. + ctf_id_t constvoid_id = CTF_NULL_TYPEID; + varpool_node *var; + FOR_EACH_VARIABLE (var) +{ + if (!var->decl) + continue; + + tree type = TREE_TYPE (var->decl); + if (type && VOID_TYPE_P (type) && TYPE_READONLY (type)) + { + dw_die_ref die = lookup_decl_die (var->decl); + if (die == NULL) + continue; + + ctf_dvdef_ref dvd = ctf_dvd_lookup (tu_ctfc, die); + if (dvd == NULL) + continue; + + /* Create the 'const' modifier type for void. */ + if (constvoid_id == CTF_NULL_TYPEID) + constvoid_id = ctf_add_reftype (tu_ctfc, CTF_ADD_ROOT, + dvd->dvd_type, CTF_K_CONST, NULL); No de-duplication of the const void type. I assume libbpf will take care of this eventually. + dvd->dvd_type = constvoid_id; + } +} + + size_t i; + size_t num_ctf_types = tu_ctfc->ctfc_types->elements (); + if (num_ctf_types) { init_btf_id_map (num_ctf_types + 1); diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c b/gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c new file mode 100644 index 000..f90fa773a4b --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c @@ -0,0 +1,25 @@ +/* Test BTF generation for extern const void symbols. + BTF_KIND_VAR records should be emitted for such symbols if they are used, + as well as a corresponding entry in the appropriate DATASEC record. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* Expect 1 variable record only for foo, with 'extern' (2) linkage. */ +/* { dg-final { scan-assembler-times "\[\t \]0xe00\[\t \]+\[^\n\]*btv_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*btv_linkage" 1 } } */ + +/* { dg-final { scan-assembler-times "ascii \"foo.0\"\[\t
Re: [PATCH 1/3] btf: add 'extern' linkage for variables [PR106773]
Hi David, On 12/7/22 12:57, David Faust wrote: Add support for the 'extern' linkage value for BTF_KIND_VAR records, which is used for variables declared as extern in the source file. PR target/106773 gcc/ * btfout.cc (BTF_LINKAGE_STATIC): New define. (BTF_LINKAGE_GLOBAL): Likewise. (BTF_LINKAGE_EXTERN): Likewise. (btf_collect_datasec): Mark extern variables as such. (btf_asm_varent): Accomodate 'extern' linkage. gcc/testsuite/ * gcc.dg/debug/btf/btf-variables-4.c: New test. include/ * btf.h (struct btf_var): Update comment to note 'extern' linkage. --- gcc/btfout.cc | 9 ++- .../gcc.dg/debug/btf/btf-variables-4.c| 24 +++ include/btf.h | 2 +- 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-variables-4.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index aef9fd70a28..a1c6266a7db 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -66,6 +66,10 @@ static char btf_info_section_label[MAX_BTF_LABEL_BYTES]; #define BTF_INVALID_TYPEID 0x +#define BTF_LINKAGE_STATIC 0 +#define BTF_LINKAGE_GLOBAL 1 +#define BTF_LINKAGE_EXTERN 2 + I was about to suggest to rename these to use the same name as used in the kernel btf.h. What is used there is: BTF_VAR_STATIC = 0, BTF_VAR_GLOBAL_ALLOCATED = 1, BTF_VAR_GLOBAL_EXTERN = 2, But after looking at the Patch 3/3, I see you reuse these definitions for functions as well. I just find the names confusing on the first look - "BTF_LINKAGE_STATIC". Naming aside, what do you think about adding the defines to include/btf.h instead ? /* Mapping of CTF variables to the IDs they will be assigned when they are converted to BTF_KIND_VAR type records. Strictly accounts for the index from the start of the variable type entries, does not include the number @@ -314,6 +318,9 @@ btf_collect_datasec (ctf_container_ref ctfc) continue; const char *section_name = node->get_section (); + /* Mark extern variables. */ + if (DECL_EXTERNAL (node->decl)) + dvd->dvd_visibility = BTF_LINKAGE_EXTERN; This made me think about the following case. extern const char a[]; const char a[] = "foo"; What is the expected BTF for this? Since BTF can differentiate between the non-defining extern variable declaration, I expected to see two variables with different "linkage". At this time I see, two variables with global linkage but different types: .long 0xe00 # btv_info .long 0x4 # btv_type .long 0x1 # btv_linkage .long 0x1f# btv_name .long 0xe00 # btv_info .long 0x7 # btv_type .long 0x1 # btv_linkage .long 0x60# btt_name if (section_name == NULL) { @@ -676,7 +683,7 @@ btf_asm_varent (ctf_dvdef_ref var) dw2_asm_output_data (4, var->dvd_name_offset, "btv_name"); dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_VAR, 0, 0), "btv_info"); dw2_asm_output_data (4, get_btf_id (var->dvd_type), "btv_type"); - dw2_asm_output_data (4, (var->dvd_visibility ? 1 : 0), "btv_linkage"); + dw2_asm_output_data (4, var->dvd_visibility, "btv_linkage"); } /* Asm'out a member description following a BTF_KIND_STRUCT or diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-variables-4.c b/gcc/testsuite/gcc.dg/debug/btf/btf-variables-4.c new file mode 100644 index 000..d77600bae1c --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-variables-4.c @@ -0,0 +1,24 @@ +/* Test BTF generation for extern variables. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* Expect 4 variables. */ +/* { dg-final { scan-assembler-times "\[\t \]0xe00\[\t \]+\[^\n\]*btv_info" 4 } } */ + +/* 2 extern, 1 global, 1 static. */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*btv_linkage" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x1\[\t \]+\[^\n\]*btv_linkage" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*btv_linkage" 2 } } */ + +extern int a; +extern const int b; +int c; +static const int d = 5; + +int foo (int x) +{ + c = a + b + x; + + return c + d; +} diff --git a/include/btf.h b/include/btf.h index eba67f9d599..9a757ce5bc9 100644 --- a/include/btf.h +++ b/include/btf.h @@ -182,7 +182,7 @@ struct btf_param information about the variable. */ struct btf_var { - uint32_t linkage;/* Currently only 0=static or 1=global. */ + uint32_t linkage;/* 0=static, 1=global, 2=extern. */ }; /* BTF_KIND_DATASEC is followed by VLEN struct btf_var_secinfo entries,
Re: [PATCH v4] btf: Add support to BTF_KIND_ENUM64 type
On 10/21/22 2:28 AM, Indu Bhagat via Gcc-patches wrote: On 10/19/22 19:05, Guillermo E. Martinez wrote: Hello, The following is patch v4 to update BTF/CTF backend supporting BTF_KIND_ENUM64 type. Changes from v3: + Remove `ctf_enum_binfo' structure. + Remove -m{little,big}-endian from dg-options in testcase. Comments will be welcomed and appreciated!, Kind regards, guillermo -- Thanks Guillermo. LGTM. Pushed on behalf of Guillermo. Thanks BTF supports 64-bits enumerators with following encoding: struct btf_type: name_off: 0 or offset to a valid C identifier info.kind_flag: 0 for unsigned, 1 for signed info.kind: BTF_KIND_ENUM64 info.vlen: number of enum values size: 1/2/4/8 The btf_type is followed by info.vlen number of: struct btf_enum64 { uint32_t name_off; /* Offset in string section of enumerator name. */ uint32_t val_lo32; /* lower 32-bit value for a 64-bit value Enumerator */ uint32_t val_hi32; /* high 32-bit value for a 64-bit value Enumerator */ }; So, a new btf_enum64 structure was added to represent BTF_KIND_ENUM64 and a new field dtd_enum_unsigned in ctf_dtdef structure to distinguish when CTF enum is a signed or unsigned type, later that information is used to encode the BTF enum type. gcc/ChangeLog: * btfout.cc (btf_calc_num_vbytes): Compute enumeration size depending of enumerator type btf_enum{,64}. (btf_asm_type): Update btf_kflag according to enumeration type sign using dtd_enum_unsigned field for both: BTF_KIND_ENUM{,64}. (btf_asm_enum_const): New argument to represent the size of the BTF enum type, writing the enumerator constant value for 32 bits, if it's 64 bits then explicitly writes lower 32-bits value and higher 32-bits value. (output_asm_btf_enum_list): Add enumeration size argument. * ctfc.cc (ctf_add_enum): New argument to represent CTF enum basic information. (ctf_add_generic): Use of ei_{name. size, unsigned} to build the dtd structure containing enumeration information. (ctf_add_enumerator): Update comment mention support for BTF enumeration in 64-bits. * dwarf2ctf.cc (gen_ctf_enumeration_type): Extract signedness for enumeration type and use it in ctf_add_enum. * ctfc.h (ctf_dmdef): Update dmd_value to HOST_WIDE_INT to allow use 32/64 bits enumerators. information. (ctf_dtdef): New field to describe enum signedness. include/ * btf.h (btf_enum64): Add new definition and new symbolic constant to BTF_KIND_ENUM64 and BTF_KF_ENUM_{UN,}SIGNED. gcc/testsuite/ChangeLog: * gcc.dg/debug/btf/btf-enum-1.c: Update testcase, with correct info.kflags encoding. * gcc.dg/debug/btf/btf-enum64-1.c: New testcase. --- gcc/btfout.cc | 30 ++--- gcc/ctfc.cc | 13 +++--- gcc/ctfc.h | 5 ++- gcc/dwarf2ctf.cc | 5 ++- gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c | 2 +- gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c | 44 +++ include/btf.h | 19 ++-- 7 files changed, 100 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 997a33fa089..aef9fd70a28 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -223,7 +223,9 @@ btf_calc_num_vbytes (ctf_dtdef_ref dtd) break; case BTF_KIND_ENUM: - vlen_bytes += vlen * sizeof (struct btf_enum); + vlen_bytes += (dtd->dtd_data.ctti_size == 0x8) + ? vlen * sizeof (struct btf_enum64) + : vlen * sizeof (struct btf_enum); break; case BTF_KIND_FUNC_PROTO: @@ -622,6 +624,15 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) btf_size_type = 0; } + if (btf_kind == BTF_KIND_ENUM) + { + btf_kflag = dtd->dtd_enum_unsigned + ? BTF_KF_ENUM_UNSIGNED + : BTF_KF_ENUM_SIGNED; + if (dtd->dtd_data.ctti_size == 0x8) + btf_kind = BTF_KIND_ENUM64; + } + dw2_asm_output_data (4, dtd->dtd_data.ctti_name, "btt_name"); dw2_asm_output_data (4, BTF_TYPE_INFO (btf_kind, btf_kflag, btf_vlen), "btt_info: kind=%u, kflag=%u, vlen=%u", @@ -634,6 +645,7 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) case BTF_KIND_UNION: 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); return; @@ -707,13 +719,19 @@ btf_asm_sou_member (ctf_container_ref ctfc, ctf_dmdef_t * dmd) } } -/* Asm'out an enum constant following a BTF_KIND_ENUM. */ +/* Asm'out an enum constant following a BTF_KIND_ENUM{,64}. */ static void -btf_asm_enum_const (
Re: [PATCH v4] btf: Add support to BTF_KIND_ENUM64 type
On 10/19/22 19:05, Guillermo E. Martinez wrote: Hello, The following is patch v4 to update BTF/CTF backend supporting BTF_KIND_ENUM64 type. Changes from v3: + Remove `ctf_enum_binfo' structure. + Remove -m{little,big}-endian from dg-options in testcase. Comments will be welcomed and appreciated!, Kind regards, guillermo -- Thanks Guillermo. LGTM. BTF supports 64-bits enumerators with following encoding: struct btf_type: name_off: 0 or offset to a valid C identifier info.kind_flag: 0 for unsigned, 1 for signed info.kind: BTF_KIND_ENUM64 info.vlen: number of enum values size: 1/2/4/8 The btf_type is followed by info.vlen number of: struct btf_enum64 { uint32_t name_off; /* Offset in string section of enumerator name. */ uint32_t val_lo32; /* lower 32-bit value for a 64-bit value Enumerator */ uint32_t val_hi32; /* high 32-bit value for a 64-bit value Enumerator */ }; So, a new btf_enum64 structure was added to represent BTF_KIND_ENUM64 and a new field dtd_enum_unsigned in ctf_dtdef structure to distinguish when CTF enum is a signed or unsigned type, later that information is used to encode the BTF enum type. gcc/ChangeLog: * btfout.cc (btf_calc_num_vbytes): Compute enumeration size depending of enumerator type btf_enum{,64}. (btf_asm_type): Update btf_kflag according to enumeration type sign using dtd_enum_unsigned field for both: BTF_KIND_ENUM{,64}. (btf_asm_enum_const): New argument to represent the size of the BTF enum type, writing the enumerator constant value for 32 bits, if it's 64 bits then explicitly writes lower 32-bits value and higher 32-bits value. (output_asm_btf_enum_list): Add enumeration size argument. * ctfc.cc (ctf_add_enum): New argument to represent CTF enum basic information. (ctf_add_generic): Use of ei_{name. size, unsigned} to build the dtd structure containing enumeration information. (ctf_add_enumerator): Update comment mention support for BTF enumeration in 64-bits. * dwarf2ctf.cc (gen_ctf_enumeration_type): Extract signedness for enumeration type and use it in ctf_add_enum. * ctfc.h (ctf_dmdef): Update dmd_value to HOST_WIDE_INT to allow use 32/64 bits enumerators. information. (ctf_dtdef): New field to describe enum signedness. include/ * btf.h (btf_enum64): Add new definition and new symbolic constant to BTF_KIND_ENUM64 and BTF_KF_ENUM_{UN,}SIGNED. gcc/testsuite/ChangeLog: * gcc.dg/debug/btf/btf-enum-1.c: Update testcase, with correct info.kflags encoding. * gcc.dg/debug/btf/btf-enum64-1.c: New testcase. --- gcc/btfout.cc | 30 ++--- gcc/ctfc.cc | 13 +++--- gcc/ctfc.h| 5 ++- gcc/dwarf2ctf.cc | 5 ++- gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c | 2 +- gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c | 44 +++ include/btf.h | 19 ++-- 7 files changed, 100 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 997a33fa089..aef9fd70a28 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -223,7 +223,9 @@ btf_calc_num_vbytes (ctf_dtdef_ref dtd) break; case BTF_KIND_ENUM: - vlen_bytes += vlen * sizeof (struct btf_enum); + vlen_bytes += (dtd->dtd_data.ctti_size == 0x8) + ? vlen * sizeof (struct btf_enum64) + : vlen * sizeof (struct btf_enum); break; case BTF_KIND_FUNC_PROTO: @@ -622,6 +624,15 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) btf_size_type = 0; } + if (btf_kind == BTF_KIND_ENUM) +{ + btf_kflag = dtd->dtd_enum_unsigned + ? BTF_KF_ENUM_UNSIGNED + : BTF_KF_ENUM_SIGNED; + if (dtd->dtd_data.ctti_size == 0x8) + btf_kind = BTF_KIND_ENUM64; + } + dw2_asm_output_data (4, dtd->dtd_data.ctti_name, "btt_name"); dw2_asm_output_data (4, BTF_TYPE_INFO (btf_kind, btf_kflag, btf_vlen), "btt_info: kind=%u, kflag=%u, vlen=%u", @@ -634,6 +645,7 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) case BTF_KIND_UNION: 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); return; @@ -707,13 +719,19 @@ btf_asm_sou_member (ctf_container_ref ctfc, ctf_dmdef_t * dmd) } } -/* Asm'out an enum constant following a BTF_KIND_ENUM. */ +/* Asm'out an enum constant following a BTF_KIND_ENUM{,64}. */ static void
Re: [PATCH v3] btf: Add support to BTF_KIND_ENUM64 type
Hi Guillermo, On 10/14/22 8:55 PM, Guillermo E. Martinez wrote: Hello, The following is patch v3 to update BTF/CTF backend supporting BTF_KIND_ENUM64 type. Changes from v2: + Add a new `dtd_enum_unsigned' field in `ctf_dtdef' to indicate signedness of the enum type. + Fix endianness for representing BTF enum 64-bits enumerators. + Add {little,big}-endian testcases. Comments will be welcomed and appreciated!, Kind regards, guillermo -- BTF supports 64-bits enumerators with following encoding: struct btf_type: name_off: 0 or offset to a valid C identifier info.kind_flag: 0 for unsigned, 1 for signed info.kind: BTF_KIND_ENUM64 info.vlen: number of enum values size: 1/2/4/8 The btf_type is followed by info.vlen number of: struct btf_enum64 { uint32_t name_off; /* Offset in string section of enumerator name. */ uint32_t val_lo32; /* lower 32-bit value for a 64-bit value Enumerator */ uint32_t val_hi32; /* high 32-bit value for a 64-bit value Enumerator */ }; So, a new btf_enum64 structure was added to represent BTF_KIND_ENUM64 and a new field dtd_enum_unsigned in ctf_dtdef structure to distinguish when CTF enum is a signed or unsigned type, later that information is used to encode the BTF enum type. gcc/ChangeLog: * btfout.cc (btf_calc_num_vbytes): Compute enumeration size depending of enumerator type btf_enum{,64}. (btf_asm_type): Update btf_kflag according to enumeration type sign using dtd_enum_unsigned field for both: BTF_KIND_ENUM{,64}. (btf_asm_enum_const): New argument to represent the size of the BTF enum type, writing the enumerator constant value for 32 bits, if it's 64 bits then explicitly writes lower 32-bits value and higher 32-bits value. (output_asm_btf_enum_list): Add enumeration size argument. * ctfc.cc (ctf_add_enum): New argument to represent CTF enum basic information. (ctf_add_generic): Use of ei_{name. size, unsigned} to build the dtd structure containing enumeration information. (ctf_add_enumerator): Update comment mention support for BTF enumeration in 64-bits. * ctfc.h (ctf_dmdef): Update dmd_value to HOST_WIDE_INT to allow use 32/64 bits enumerators. (ctf_enum_binfo): New type to represent CTF basic enum type information. (ctf_dtdef): New field to describe enum signedness. * dwarf2ctf.cc (gen_ctf_enumeration_type): Use of ctf_enum_binfo type to pass information to ctf_add_enum to build the enum type. include/ * btf.h (btf_enum64): Add new definition and new symbolic constant to BTF_KIND_ENUM64 and BTF_KF_ENUM_{UN,}SIGNED. gcc/testsuite/ChangeLog: * gcc.dg/debug/btf/btf-enum-1.c: Update testcase, with correct info.kflags encoding. * gcc.dg/debug/btf/btf-enum64-be-1.c: New testcase. * gcc.dg/debug/btf/btf-enum64-le-1.c: New testcase. --- gcc/btfout.cc | 30 ++--- gcc/ctfc.cc | 22 +- gcc/ctfc.h| 15 +-- gcc/dwarf2ctf.cc | 8 +++- gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c | 2 +- .../gcc.dg/debug/btf/btf-enum64-be-1.c| 44 +++ .../gcc.dg/debug/btf/btf-enum64-le-1.c| 44 +++ include/btf.h | 19 ++-- 8 files changed, 160 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-enum64-be-1.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-enum64-le-1.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 997a33fa089..aef9fd70a28 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -223,7 +223,9 @@ btf_calc_num_vbytes (ctf_dtdef_ref dtd) break; case BTF_KIND_ENUM: - vlen_bytes += vlen * sizeof (struct btf_enum); + vlen_bytes += (dtd->dtd_data.ctti_size == 0x8) + ? vlen * sizeof (struct btf_enum64) + : vlen * sizeof (struct btf_enum); break; case BTF_KIND_FUNC_PROTO: @@ -622,6 +624,15 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) btf_size_type = 0; } + if (btf_kind == BTF_KIND_ENUM) +{ + btf_kflag = dtd->dtd_enum_unsigned + ? BTF_KF_ENUM_UNSIGNED + : BTF_KF_ENUM_SIGNED; + if (dtd->dtd_data.ctti_size == 0x8) + btf_kind = BTF_KIND_ENUM64; + } + dw2_asm_output_data (4, dtd->dtd_data.ctti_name, "btt_name"); dw2_asm_output_data (4, BTF_TYPE_INFO (btf_kind, btf_kflag, btf_vlen), "btt_info: kind=%u, kflag=%u, vlen=%u", @@ -634,6 +645,7 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) case BTF_KIND_UNION: case BTF_KIND_ENUM: case BTF_KIND_DATASEC: +case
Re: [PATCH v2] btf: Add support to BTF_KIND_ENUM64 type
Hi Guillermo, On 10/3/22 7:39 AM, Guillermo E. Martinez via Gcc-patches wrote: diff --git a/gcc/ctfc.cc b/gcc/ctfc.cc index 9773358a475..253c36b6a0a 100644 --- a/gcc/ctfc.cc +++ b/gcc/ctfc.cc @@ -604,6 +604,7 @@ ctf_add_enum (ctf_container_ref ctfc, uint32_t flag, const char * name, gcc_assert (size <= CTF_MAX_SIZE); dtd->dtd_data.ctti_size = size; + dtd->flags = CTF_ENUM_F_NONE; ctfc->ctfc_num_stypes++; @@ -612,7 +613,7 @@ ctf_add_enum (ctf_container_ref ctfc, uint32_t flag, const char * name, int ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name, - HOST_WIDE_INT value, dw_die_ref die) + HOST_WIDE_INT value, uint32_t flags, dw_die_ref die) { ctf_dmdef_t * dmd; uint32_t kind, vlen, root; @@ -630,10 +631,12 @@ ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name, gcc_assert (kind == CTF_K_ENUM && vlen < CTF_MAX_VLEN); - /* Enum value is of type HOST_WIDE_INT in the compiler, dmd_value is int32_t - on the other hand. Check bounds and skip adding this enum value if out of - bounds. */ - if ((value > INT_MAX) || (value < INT_MIN)) + /* Enum value is of type HOST_WIDE_INT in the compiler, CTF enumerators + values in ctf_enum_t is limited to int32_t, BTF supports signed and + unsigned enumerators values of 32 and 64 bits, for both debug formats + we use ctf_dmdef_t.dmd_value entry of HOST_WIDE_INT type. So check + CTF bounds and skip adding this enum value if out of bounds. */ + if (!btf_debuginfo_p() && ((value > INT_MAX) || (value < INT_MIN))) { /* FIXME - Note this TBD_CTF_REPRESENTATION_LIMIT. */ return (1); @@ -649,6 +652,7 @@ ctf_add_enumerator (ctf_container_ref ctfc, ctf_id_t enid, const char * name, dmd->dmd_value = value; dtd->dtd_data.ctti_info = CTF_TYPE_INFO (kind, root, vlen + 1); + dtd->flags |= flags; ctf_dmd_list_append (>dtd_u.dtu_members, dmd); if ((name != NULL) && strcmp (name, "")) diff --git a/gcc/ctfc.h b/gcc/ctfc.h index bcf3a43ae1b..a22342b2610 100644 --- a/gcc/ctfc.h +++ b/gcc/ctfc.h @@ -125,6 +125,10 @@ typedef struct GTY (()) ctf_itype #define CTF_FUNC_VARARG 0x1 +/* Enum specific flags. */ +#define CTF_ENUM_F_NONE (0) +#define CTF_ENUM_F_ENUMERATORS_SIGNED (1 << 0) + /* Struct/union/enum member definition for CTF generation. */ typedef struct GTY ((chain_next ("%h.dmd_next"))) ctf_dmdef @@ -133,7 +137,7 @@ typedef struct GTY ((chain_next ("%h.dmd_next"))) ctf_dmdef ctf_id_t dmd_type; /* Type of this member (for sou). */ uint32_t dmd_name_offset; /* Offset of the name in str table. */ uint64_t dmd_offset; /* Offset of this member in bits (for sou). */ - int dmd_value; /* Value of this member (for enum). */ + HOST_WIDE_INT dmd_value; /* Value of this member (for enum). */ struct ctf_dmdef * dmd_next; /* A list node. */ } ctf_dmdef_t; I am wondering if you considered adding a member here instead - something like- bool dmd_value_signed; /* Signedness for the enumerator. */. See comment below. @@ -162,6 +166,7 @@ struct GTY ((for_user)) ctf_dtdef bool from_global_func; /* Whether this type was added from a global function. */ uint32_t linkage; /* Used in function types. 0=local, 1=global. */ + uint32_t flags; /* Flags to describe specific type's properties. */ union GTY ((desc ("ctf_dtu_d_union_selector (&%1)"))) { /* struct, union, or enum. */ Instead of carrying this information in ctf_dtdef which is the data structure for each type in CTF, how about adding a new member in struct ctf_dmdef? The "flags" member is meant for only enum types, and hence it will be more appropriate to add to ctf_dmdef as say, dmd_value_signed. Yes, `ctf_dtdef' is structure for each type in CTF (including enumeration), and `ctf_dmdef' keeps information for enumerator, not for the enumeration type. Yes, please scrap my earlier suggestion of adding to ctf_dmdef_t. What do you think about adding something like 'dtd_enum_signedness' to ctf_dtdef, instead of uint32_t 'flags'; with two possible values of 0 (unsigned) and 1 (signed). I believe your intention of using the latter is to conserve some memory in the long run (by reusing the flags field for other types in future if need be)? I do, however, prefer an explicit member like dtd_enum_signedness at this time. My reasoning for keeping it explicit is that it helps code be more readable/maintainable. Thanks for your patience, Indu
Re: [PATCH v2] btf: Add support to BTF_KIND_ENUM64 type
On 9/28/22 2:15 PM, Guillermo E. Martinez via Gcc-patches wrote: Hello GCC team, The following is patch v2 to update BTF/CTF backend supporting BTF_KIND_ENUM64 type. Changes from v1: + Fix typo in commit message. + Fix changelog entries. Comments will be welcomed and appreciated!, Kind regards, guillermo -- Hi Guillermo, Thanks for your patch. Sorry for the delay in reviewing this patch. Please see my comments inlined. Indu BTF supports 64-bits enumerators with following encoding: struct btf_type: name_off: 0 or offset to a valid C identifier info.kind_flag: 0 for unsigned, 1 for signed info.kind: BTF_KIND_ENUM64 info.vlen: number of enum values size: 1/2/4/8 The btf_type is followed by info.vlen number of: struct btf_enum64 { uint32_t name_off; /* Offset in string section of enumerator name. */ uint32_t val_lo32; /* lower 32-bit value for a 64-bit value Enumerator */ uint32_t val_hi32; /* high 32-bit value for a 64-bit value Enumerator */ }; So, a new btf_enum64 structure was added to represent BTF_KIND_ENUM64 and a new field in ctf_dtdef to represent specific type's properties, in the particular case for CTF enums it helps to distinguish when its enumerators values are signed or unsigned, later that information is used to encode the BTF enum type. gcc/ChangeLog: * btfout.cc (btf_calc_num_vbytes): Compute enumeration size depending of enumerator type btf_enum{,64}. (btf_asm_type): Update btf_kflag according to enumerators sign, using correct BPF type in BTF_KIND_ENUMi{,64}. Typo : i after ENUM (btf_asm_enum_const): New argument to represent the size of the BTF enum type. * ctfc.cc (ctf_add_enum): Use and initialization of flag field to CTF_ENUM_F_NONE. (ctf_add_enumerator): New argument to represent CTF flags, updating the comment and flag vaue according to enumerators sing. * ctfc.h (ctf_dmdef): Update dmd_value to HOST_WIDE_INT to allow use 32/64 bits enumerators. (ctf_dtdef): Add flags to to describe specific type's properties. * dwarf2ctf.cc (gen_ctf_enumeration_type): Update flags field depending when a signed enumerator value is found. include/ * btf.h (btf_enum64): Add new definition and new symbolic constant to BTF_KIND_ENUM64 and BTF_KF_ENUM_{UN,}SIGNED. gcc/testsuite/ChangeLog: * gcc.dg/debug/btf/btf-enum-1.c: Update testcase, with correct info.kflags encoding. * gcc.dg/debug/btf/btf-enum64-1.c: New testcase. --- gcc/btfout.cc | 24 --- gcc/ctfc.cc | 14 --- gcc/ctfc.h| 9 +++- gcc/dwarf2ctf.cc | 9 +++- gcc/testsuite/gcc.dg/debug/btf/btf-enum-1.c | 2 +- gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c | 41 +++ include/btf.h | 19 +++-- 7 files changed, 99 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-enum64-1.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 997a33fa089..4b11c867c23 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -223,7 +223,9 @@ btf_calc_num_vbytes (ctf_dtdef_ref dtd) break; case BTF_KIND_ENUM: - vlen_bytes += vlen * sizeof (struct btf_enum); + vlen_bytes += (dtd->dtd_data.ctti_size == 0x8) + ? vlen * sizeof (struct btf_enum64) + : vlen * sizeof (struct btf_enum); break; case BTF_KIND_FUNC_PROTO: @@ -622,6 +624,15 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) btf_size_type = 0; } + if (btf_kind == BTF_KIND_ENUM) + { + btf_kflag = (dtd->flags & CTF_ENUM_F_ENUMERATORS_SIGNED) + ? BTF_KF_ENUM_SIGNED + : BTF_KF_ENUM_UNSIGNED; + if (dtd->dtd_data.ctti_size == 0x8) + btf_kind = BTF_KIND_ENUM64; + } + See below. If you do add a new member in ctf_dmdef instead (as I propose), you should ideally iterate over the enumerators (dtd->dtd_u.dtu_members) to make sure they are all the same signedness. dw2_asm_output_data (4, dtd->dtd_data.ctti_name, "btt_name"); dw2_asm_output_data (4, BTF_TYPE_INFO (btf_kind, btf_kflag, btf_vlen), "btt_info: kind=%u, kflag=%u, vlen=%u", @@ -634,6 +645,7 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd) case BTF_KIND_UNION: 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); return; @@ -707,13 +719,13 @@ btf_asm_sou_member (ctf_container_ref ctfc, ctf_dmdef_t * dmd) } } -/* Asm'out an enum constant following a BTF_KIND_ENUM. */ +/*
Re: [PATCH] btf: do not skip emitting void variables [PR106773]
On 9/1/22 12:53, David Faust wrote: The eBPF loader expects to find BTF_KIND_VAR records for references to extern const void symbols. We were mistakenly identifing these as unsupported types, and as a result skipping emitting VAR records for them. Tested on bpf-unknown-none and x86_64, no known regressions. OK? Hi David, LGTM. Thanks, Thanks. gcc/ChangeLog: PR target/106773 * btfout.cc (btf_dvd_emit_preprocess_cb): Do not skip emitting variables which refer to void types. gcc/testsuite/ChangeLog: PR target/106773 * gcc.dg/debug/btf/btf-pr106773.c: New test. --- gcc/btfout.cc | 2 +- gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c | 21 +++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 997a33fa089..37ec662c190 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -430,7 +430,7 @@ btf_dvd_emit_preprocess_cb (ctf_dvdef_ref *slot, ctf_container_ref arg_ctfc) ctf_dvdef_ref var = (ctf_dvdef_ref) * slot; /* Do not add variables which refer to unsupported types. */ - if (btf_removed_type_p (var->dvd_type)) + if (!voids.contains (var->dvd_type) && btf_removed_type_p (var->dvd_type)) return 1; arg_ctfc->ctfc_vars_list[num_vars_added] = var; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c b/gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c new file mode 100644 index 000..4de15f76546 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c @@ -0,0 +1,21 @@ +/* Test BTF generation for extern const void symbols. + BTF_KIND_VAR records should be emitted for such symbols if they are used. */ + +/* { dg-do compile } */ +/* { dg-options "-O0 -gbtf -dA" } */ + +/* Expect 1 variable record only for foo. */ +/* { dg-final { scan-assembler-times "\[\t \]0xe00\[\t \]+\[^\n\]*btv_info" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x1\[\t \]+\[^\n\]*btv_linkage" 1 } } */ + +/* { dg-final { scan-assembler-times "ascii \"foo.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ + +extern const void foo; +extern const void bar; + +unsigned long func () { + unsigned long x = (unsigned long) + + return x; +} +
Re: [PATCH] btf: do not use the CHAR `encoding' bit for BTF
On 7/22/22 4:23 AM, Jose E. Marchesi via Gcc-patches wrote: Contrary to CTF and our previous expectations, as per [1], turns out that in BTF: 1) The `encoding' field in integer types shall not be treated as a bitmap, but as an enumerated, i.e. these bits are exclusive to each other. 2) The CHAR bit in `encoding' shall _not_ be set when emitting types for char nor `unsigned char'. Hmm...well. At this time, I suggest we make a note of this in the btf.h for posterity that BTF_INT_CHAR is to not be used (i.e., BTF_INT_CHAR should not be set for char / unsigned char). Consequently this patch clears the CHAR bit before emitting the variable part of BTF integral types. It also updates the testsuite accordingly, expanding it to check for BOOL bits. [1] https://lore.kernel.org/bpf/a73586ad-f2dc-0401-1eba-2004357b7...@fb.com/T/#t gcc/ChangeLog: * btfout.cc (output_asm_btf_vlen_bytes): Do not use the CHAR encoding bit in BTF. gcc/testsuite/ChangeLog: * gcc.dg/debug/btf/btf-int-1.c: Do not check for char bits in bti_encoding and check for bool bits. --- gcc/btfout.cc | 4 gcc/testsuite/gcc.dg/debug/btf/btf-int-1.c | 18 +++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 31af50521da..576f73d47cf 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -914,6 +914,10 @@ output_asm_btf_vlen_bytes (ctf_container_ref ctfc, ctf_dtdef_ref dtd) if (dtd->dtd_data.ctti_size < 1) break; + /* In BTF the CHAR `encoding' seems to not be used, so clear it + here. */ + dtd->dtd_u.dtu_enc.cte_format &= ~BTF_INT_CHAR; + [Added David Faust] What do you think about doing this in btf_dtd_emit_preprocess_cb () for types where kind == BTF_KIND_INT. This is the place where BTF specific massaging of type info takes place. encoding = BTF_INT_DATA (dtd->dtd_u.dtu_enc.cte_format, dtd->dtd_u.dtu_enc.cte_offset, dtd->dtd_u.dtu_enc.cte_bits); diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-int-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-int-1.c index 2381decd6ff..87d9758e9cb 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-int-1.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-int-1.c @@ -4,7 +4,8 @@ | 0 | encoding | offset | 00 | bits | encoding: signed 1 << 24 - char2 << 24 + char2 << 24 (not used) + bool4 << 24 All offsets in this test should be 0. This test does _not_ check number of bits, as it may vary between targets. @@ -13,13 +14,14 @@ /* { dg-do compile } */ /* { dg-options "-O0 -gbtf -dA" } */ -/* Check for 8 BTF_KIND_INT types. */ -/* { dg-final { scan-assembler-times "\[\t \]0x100\[\t \]+\[^\n\]*btt_info" 8 } } */ +/* Check for 9 BTF_KIND_INT types. */ +/* { dg-final { scan-assembler-times "\[\t \]0x100\[\t \]+\[^\n\]*btt_info" 9 } } */ -/* Check the signed/char flags, but not bit size. */ -/* { dg-final { scan-assembler-times "\[\t \]0x1..\[\t \]+\[^\n\]*bti_encoding" 3 } } */ -/* { dg-final { scan-assembler-times "\[\t \]0x2..\[\t \]+\[^\n\]*bti_encoding" 1 } } */ -/* { dg-final { scan-assembler-times "\[\t \]0x3..\[\t \]+\[^\n\]*bti_encoding" 1 } } */ +/* Check the signed flags, but not bit size. */ +/* { dg-final { scan-assembler-times "\[\t \]0x1..\[\t \]+\[^\n\]*bti_encoding" 4 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x..\[\t \]+\[^\n\]*bti_encoding" 3 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x.\[\t \]+\[^\n\]*bti_encoding" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x4..\[\t \]+\[^\n\]*bti_encoding" 1 } } */ /* Check that there is a string entry for each type name. */ /* { dg-final { scan-assembler-times "ascii \"unsigned char.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ @@ -42,3 +44,5 @@ signed int f = -66; unsigned long int g = 77; signed long int h = 88; + +_Bool x = 1;
Re: [PATCH V2] btf: emit linkage information in BTF_KIND_FUNC entries
On 7/12/22 8:13 AM, Jose E. Marchesi via Gcc-patches wrote: The kernel bpftool expects BTF_KIND_FUNC entries in BTF to include an annotation reflecting the linkage of functions (static, global). For whatever reason they abuse the `vlen' field of the BTF_KIND_FUNC entry instead of adding a variable-part to the record like it is done with other entry kinds. This patch makes GCC to include this linkage info in BTF_KIND_FUNC entries. Tested in bpf-unknown-none target. I am not the maintainer of this functionality, but this version looks OK to me. Thanks gcc/ChangeLog: PR debug/106263 * ctfc.h (struct ctf_dtdef): Add field linkage. * ctfc.cc (ctf_add_function): Set ctti_linkage. * dwarf2ctf.cc (gen_ctf_function_type): Pass a linkage for function types and subprograms. * btfout.cc (btf_asm_func_type): Emit linkage information for the function. (btf_dtd_emit_preprocess_cb): Propagate the linkage information for functions. gcc/testsuite/ChangeLog: PR debug/106263 * gcc.dg/debug/btf/btf-function-4.c: New test. * gcc.dg/debug/btf/btf-function-5.c: Likewise. --- gcc/btfout.cc | 6 +- gcc/ctfc.cc | 3 ++- gcc/ctfc.h | 3 ++- gcc/dwarf2ctf.cc| 4 +++- gcc/testsuite/gcc.dg/debug/btf/btf-function-4.c | 14 ++ gcc/testsuite/gcc.dg/debug/btf/btf-function-5.c | 14 ++ 6 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-function-4.c create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-function-5.c diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 31af50521da..594cba84910 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -463,6 +463,7 @@ btf_dtd_emit_preprocess_cb (ctf_container_ref ctfc, ctf_dtdef_ref dtd) ctf_dtdef_ref func_dtd = ggc_cleared_alloc (); func_dtd->dtd_data = dtd->dtd_data; func_dtd->dtd_data.ctti_type = dtd->dtd_type; + func_dtd->linkage = dtd->linkage; vec_safe_push (funcs, func_dtd); num_types_created++; @@ -740,7 +741,10 @@ static void btf_asm_func_type (ctf_dtdef_ref dtd) { dw2_asm_output_data (4, dtd->dtd_data.ctti_name, "btt_name"); - dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_FUNC, 0, 0), "btt_info"); + dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_FUNC, 0, + dtd->linkage), + "btt_info: kind=%u, kflag=%u, linkage=%u", + BTF_KIND_FUNC, 0, dtd->linkage); dw2_asm_output_data (4, get_btf_id (dtd->dtd_data.ctti_type), "btt_type"); } diff --git a/gcc/ctfc.cc b/gcc/ctfc.cc index f24e7bff948..9773358a475 100644 --- a/gcc/ctfc.cc +++ b/gcc/ctfc.cc @@ -777,7 +777,7 @@ ctf_add_function_arg (ctf_container_ref ctfc, dw_die_ref func, ctf_id_t ctf_add_function (ctf_container_ref ctfc, uint32_t flag, const char * name, const ctf_funcinfo_t * ctc, dw_die_ref die, - bool from_global_func) + bool from_global_func, int linkage) { ctf_dtdef_ref dtd; ctf_id_t type; @@ -791,6 +791,7 @@ ctf_add_function (ctf_container_ref ctfc, uint32_t flag, const char * name, type = ctf_add_generic (ctfc, flag, name, , die); dtd->from_global_func = from_global_func; + dtd->linkage = linkage; dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen); /* Caller must make sure CTF types for ctc->ctc_return are already added. */ dtd->dtd_data.ctti_type = (uint32_t) ctc->ctc_return; diff --git a/gcc/ctfc.h b/gcc/ctfc.h index 001e544ef08..bcf3a43ae1b 100644 --- a/gcc/ctfc.h +++ b/gcc/ctfc.h @@ -161,6 +161,7 @@ struct GTY ((for_user)) ctf_dtdef 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. */ union GTY ((desc ("ctf_dtu_d_union_selector (&%1)"))) { /* struct, union, or enum. */ @@ -423,7 +424,7 @@ extern ctf_id_t ctf_add_forward (ctf_container_ref, uint32_t, const char *, extern ctf_id_t ctf_add_typedef (ctf_container_ref, uint32_t, const char *, ctf_id_t, dw_die_ref); extern ctf_id_t ctf_add_function (ctf_container_ref, uint32_t, const char *, - const ctf_funcinfo_t *, dw_die_ref, bool); + const ctf_funcinfo_t *, dw_die_ref, bool, int); extern ctf_id_t ctf_add_sou (ctf_container_ref, uint32_t, const char *, uint32_t, size_t, dw_die_ref); diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc index a6329ab6ee4..39714c2 100644 --- a/gcc/dwarf2ctf.cc +++ b/gcc/dwarf2ctf.cc @@ -644,6 +644,7 @@
Re: [PATCH] btf: emit linkage information in BTF_KIND_FUNC entries
On 7/8/22 11:30 AM, Jose E. Marchesi via Gcc-patches wrote: The kernel bpftool expects BTF_KIND_FUNC entries in BTF to include an annotation reflecting the linkage of functions (static, global). For whatever reason they (ab)use the `vlen' field of the BTF_KIND_FUNC entry instead of adding a variable-part to the record like it is done with other entry kinds. For BTF Variables, we have the linkage information in the output section as "btv_linkage". To propagate that information from DWARF to BTF, we have the dvd_visibility in struct ctf_dvdef (in ctfc.h). Now that the linkage information is needed for the BTF_KIND_FUNC entries, what do you think about - adding something like dtd_visibility to ctf_dtdef. Updating the BTF format documentation will be useful https://www.kernel.org/doc/Documentation/bpf/btf.rst. Let's see what can be done for that... Also, adding some testcases with the current patch will be great. I have created PR debug/106263 "BTF_KIND_FUNC type does not encode linkage" to track this. This patch makes GCC to include this linkage info in BTF_KIND_FUNC entries. Tested in bpf-unknown-none target. gcc/ChangeLog: * ctfc.h (struct ctf_itype): Add field ctti_linkage. * ctfc.cc (ctf_add_function): Set ctti_linkage. * dwarf2ctf.cc (gen_ctf_function_type): Pass a linkage for function types and subprograms. * btfout.cc (btf_asm_func_type): Emit linkage information for the function. --- gcc/btfout.cc| 3 ++- gcc/ctfc.cc | 3 ++- gcc/ctfc.h | 3 ++- gcc/dwarf2ctf.cc | 4 +++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/gcc/btfout.cc b/gcc/btfout.cc index 31af50521da..417d87cf519 100644 --- a/gcc/btfout.cc +++ b/gcc/btfout.cc @@ -740,7 +740,8 @@ static void btf_asm_func_type (ctf_dtdef_ref dtd) { dw2_asm_output_data (4, dtd->dtd_data.ctti_name, "btt_name"); - dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_FUNC, 0, 0), "btt_info"); + dw2_asm_output_data (4, BTF_TYPE_INFO (BTF_KIND_FUNC, 0, + dtd->dtd_data.ctti_linkage), "btt_info"); dw2_asm_output_data (4, get_btf_id (dtd->dtd_data.ctti_type), "btt_type"); } diff --git a/gcc/ctfc.cc b/gcc/ctfc.cc index f24e7bff948..ad7f8bb8e86 100644 --- a/gcc/ctfc.cc +++ b/gcc/ctfc.cc @@ -777,7 +777,7 @@ ctf_add_function_arg (ctf_container_ref ctfc, dw_die_ref func, ctf_id_t ctf_add_function (ctf_container_ref ctfc, uint32_t flag, const char * name, const ctf_funcinfo_t * ctc, dw_die_ref die, - bool from_global_func) + bool from_global_func, int linkage) { ctf_dtdef_ref dtd; ctf_id_t type; @@ -792,6 +792,7 @@ ctf_add_function (ctf_container_ref ctfc, uint32_t flag, const char * name, dtd->from_global_func = from_global_func; dtd->dtd_data.ctti_info = CTF_TYPE_INFO (CTF_K_FUNCTION, flag, vlen); + dtd->dtd_data.ctti_linkage = linkage; /* Caller must make sure CTF types for ctc->ctc_return are already added. */ dtd->dtd_data.ctti_type = (uint32_t) ctc->ctc_return; /* Caller must make sure CTF types for function arguments are already added diff --git a/gcc/ctfc.h b/gcc/ctfc.h index 001e544ef08..273997a2302 100644 --- a/gcc/ctfc.h +++ b/gcc/ctfc.h @@ -116,6 +116,7 @@ typedef struct GTY (()) ctf_itype } _u; uint32_t ctti_lsizehi; /* High 32 bits of type size in bytes. */ uint32_t ctti_lsizelo; /* Low 32 bits of type size in bytes. */ + uint32_t ctti_linkage; /* Linkage info for function types. */ } ctf_itype_t; #define ctti_size _u._size @@ -423,7 +424,7 @@ extern ctf_id_t ctf_add_forward (ctf_container_ref, uint32_t, const char *, extern ctf_id_t ctf_add_typedef (ctf_container_ref, uint32_t, const char *, ctf_id_t, dw_die_ref); extern ctf_id_t ctf_add_function (ctf_container_ref, uint32_t, const char *, - const ctf_funcinfo_t *, dw_die_ref, bool); + const ctf_funcinfo_t *, dw_die_ref, bool, int); extern ctf_id_t ctf_add_sou (ctf_container_ref, uint32_t, const char *, uint32_t, size_t, dw_die_ref); diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc index a6329ab6ee4..39714c2 100644 --- a/gcc/dwarf2ctf.cc +++ b/gcc/dwarf2ctf.cc @@ -644,6 +644,7 @@ gen_ctf_function_type (ctf_container_ref ctfc, dw_die_ref function, ctf_funcinfo_t func_info; uint32_t num_args = 0; + int linkage = get_AT_flag (function, DW_AT_external); ctf_id_t return_type_id; ctf_id_t function_type_id; @@ -687,7 +688,8 @@ gen_ctf_function_type (ctf_container_ref ctfc, dw_die_ref function, function_name, (const ctf_funcinfo_t *)_info, function, - from_global_func); +
Re: [PATCH 0/3] Fix PR debug/105089
ping On 3/30/22 4:31 PM, Indu Bhagat wrote: Hello, This patch set fixes PR debug/105089. [PS: The first patch in the series "ctfc: get rid of the static variable in ctf_list_add_ctf_vars" is unrelated to the PR and is combined here only for ease of review.] As noted in the PR debug/105089, gcc is emitting two CTF variable records where it sees an extern variable with declaration and definition in the same compilation unit. The CTF format format does not distinguish between the non-defining decl vs. the defining decl, so the correct behaviour wrt the compiler generating the type for such extern variables is to simply emit the type of the defining declaration. Testing Notes: -- bootstrapped and reg tested on x86_64 and aarch64 -- built binutils package with -gctf (with CTF-capable linker) on x86_64, no CTF errors reported. Thanks, Indu Bhagat (3): ctfc: get rid of the static variable in ctf_list_add_ctf_vars () CTF for extern variable fix [PR105089] Refactor and update CTF testcases [PR105089] gcc/ctfc.cc | 62 ++- gcc/ctfc.h| 8 ++- gcc/ctfout.cc | 28 ++--- gcc/dwarf2ctf.cc | 18 +- gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c | 22 +++ gcc/testsuite/gcc.dg/debug/ctf/ctf-array-5.c | 17 + .../gcc.dg/debug/ctf/ctf-variables-3.c| 22 +++ 7 files changed, 147 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-array-5.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-3.c
[PATCH 2/3] CTF for extern variable fix [PR105089]
The CTF format cannot differentiate between a non-defining extern variable declaration vs. a defining variable declaration (unlike DWARF). So, the correct behaviour wrt the compiler generating CTF for such extern variables (i.e., when both the defining and non-defining decl are present in the same CU) is to simply emit the CTF variable correspoding to the defining declaration. To carry out the above, following changes are introduced via the patch: 1. The CTF container (ctfc.h) now keeps track of the non-defining declarations (by noting the DWARF attribute DW_AT_specification) in a new ctfc_ignore_vars hashtable. Such book-keeping is necessary because the CTF container should not rely on the order of DWARF DIEs presented to it at generation time. 2. At the time of ctf_add_variable (), the DW_AT_specification DIE if present is added in the ctfc_ignore_vars hashtable. The CTF variable generation for the defining declaration continues as normal. 3. If the ctf_add_variable () is asked to generate CTF variable for a DIE present in the ctfc_ignore_vars, it skips generating CTF for it. 4. Recall that CTF variables are pre-processed before emission. Till now, the only pre-processing that was being done was to sort them in order of their names. Now an additional step is added: If the CTF variable which corresponds to the non-defining declaration is indeed present in the ctfc_vars hashtable (because the corresponding DWARF DIE was encountered first by the CTF generation engine), skip that CTF variable from output. An important side effect of such a workflow above is that CTF for the C type of the non-defining decl will remain in the CTF dictionary (and will be emitted in the output section as well). This type can, however, be pruned by the link-time de-duplicator as usual, if deemed unused. 2022-03-30 Indu Bhagat gcc/ChangeLog: PR debug/105089 * ctfc.cc (ctf_dvd_ignore_insert): New function. (ctf_dvd_ignore_lookup): Likewise. (ctf_add_variable): Keep track of non-defining decl DIEs. (new_ctf_container): Initialize the new hash-table. (ctfc_delete_container): Empty hash-table. * ctfc.h (struct ctf_container): Add new hash-table. (ctf_dvd_ignore_lookup): New declaration. (ctf_add_variable): Add additional argument. * ctfout.cc (ctf_dvd_preprocess_cb): Skip adding CTF variable record for non-defining decl for which a defining decl exists in the same TU. (ctf_preprocess): Defer updating the number of global objts until here. (output_ctf_header): Use ctfc_vars_list_count as some CTF variables may not make it to the final output. (output_ctf_vars): Likewise. * dwarf2ctf.cc (gen_ctf_variable): Skip generating CTF variable if this is known to be a non-defining decl DIE. --- gcc/ctfc.cc | 62 ++-- gcc/ctfc.h | 6 - gcc/ctfout.cc| 24 +-- gcc/dwarf2ctf.cc | 18 -- 4 files changed, 98 insertions(+), 12 deletions(-) diff --git a/gcc/ctfc.cc b/gcc/ctfc.cc index 6fe44d2e8d49..f24e7bff9487 100644 --- a/gcc/ctfc.cc +++ b/gcc/ctfc.cc @@ -179,6 +179,40 @@ ctf_dvd_lookup (const ctf_container_ref ctfc, dw_die_ref die) return NULL; } +/* Insert a dummy CTF variable into the list of variables to be ignored. */ + +static void +ctf_dvd_ignore_insert (ctf_container_ref ctfc, ctf_dvdef_ref dvd) +{ + bool existed = false; + ctf_dvdef_ref entry = dvd; + + ctf_dvdef_ref * item = ctfc->ctfc_ignore_vars->find_slot (entry, INSERT); + if (*item == NULL) + *item = dvd; + else +existed = true; + /* Duplicate variable records not expected to be inserted. */ + gcc_assert (!existed); +} + +/* Lookup the dummy CTF variable given the DWARF die for the non-defining + decl to be ignored. */ + +bool +ctf_dvd_ignore_lookup (const ctf_container_ref ctfc, dw_die_ref die) +{ + ctf_dvdef_t entry; + entry.dvd_key = die; + + ctf_dvdef_ref * slot = ctfc->ctfc_ignore_vars->find_slot (, NO_INSERT); + + if (slot) +return true; + + return false; +} + /* Append member definition to the list. Member list is a singly-linked list with list start pointing to the head. */ @@ -666,9 +700,10 @@ ctf_add_member_offset (ctf_container_ref ctfc, dw_die_ref sou, int ctf_add_variable (ctf_container_ref ctfc, const char * name, ctf_id_t ref, - dw_die_ref die, unsigned int external_vis) + dw_die_ref die, unsigned int external_vis, + dw_die_ref die_var_decl) { - ctf_dvdef_ref dvd; + ctf_dvdef_ref dvd, dvd_ignore; gcc_assert (name); @@ -680,6 +715,24 @@ ctf_add_variable (ctf_container_ref ctfc, const char * name, ctf_id_t ref, dvd->dvd_name = ctf_add_string (ctfc, name, &(dvd->dvd_name_offset)); dvd->dvd_visibility = external_vis; dvd->dvd_type = ref; + + /* If DW_AT_sp
[PATCH 3/3] Refactor and update CTF testcases [PR105089]
This commit splits the ctf-array-2.c into ctf-array-5.c and ctf-variables.c with the following responsibilities: [1] ctf-array-2.c: Test CTF generation for unsized arrays. [2] ctf-array-5.c: Test CTF generation for unsized but initialized array. [3] ctf-variables-3.c: Test CTF generation for extern variable with defining decl. Earlier all three tests above were being done in ctf-array-2.c. Further, the checks around [3] were very loose in the original version of ctf-array-2.c in that the testcase was only checking that the types are as expected. The compiler was emitting two CTF variable records as follows: Variables: _CTF_NEWSTR -> 5: const const char [0] (size 0x0) -> 4: const char [0] (size 0x0) _CTF_NEWSTR -> 8: const const char [8] (size 0x8) -> 7: const char [8] (size 0x8) This is incorrect behaviour as it creates ambiguity. The testcase ctf-variables-3.c now has added checks that only one CTF variable record is expected. 2022-03-30 Indu Bhagat gcc/testsuite/ChangeLog: PR debug/105089 * gcc.dg/debug/ctf/ctf-array-2.c: Refactor testcase. Move some checks ... * gcc.dg/debug/ctf/ctf-array-5.c: ... to here. * gcc.dg/debug/ctf/ctf-variables-3.c: ... and here. Add additional checks for one CTF variable and one CTF object info record. --- gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c | 22 ++- gcc/testsuite/gcc.dg/debug/ctf/ctf-array-5.c | 17 ++ .../gcc.dg/debug/ctf/ctf-variables-3.c| 22 +++ 3 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-array-5.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-3.c diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c index 2a19da050fe7..4721c4fb2f97 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c @@ -5,34 +5,26 @@ TBD_CTF_FORMAT_OPEN_ISSUES (1) - This testcase makes a note of the case of a probable misrepresentation. - See Note 1 and Note 2 below. + See Note 1 below. In the CTF section, these types are encoded as : Variables: - _CTF_NEWSTR -> 7: const char [0] (size 0x0) - _CTF_SECTION -> 6: const char [5] (size 0x5) - b1 -> 2: int [0] (size 0x0) - b2 -> 3: int [0] (size 0x0) + b1 -> 3: int [0] (size 0x0) + b2 -> 5: int [0] (size 0x0) Note 1 : There is misrepresentation in that b1 and b2 are specified differently by the user. -Note 2 : It is arguable though whether the representation for -_CTF_NEWSTR is incorrect. */ + +In this testcase, two CTF array records each of type int [0] is expected. */ /* { dg-do compile ) */ /* { dg-options "-O0 -gctf -dA" } */ -/* { dg-final { scan-assembler-times "0x1200\[\t \]+\[^\n\]*ctt_info" 5 } } */ +/* { dg-final { scan-assembler-times "0x1200\[\t \]+\[^\n\]*ctt_info" 2 } } */ -/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*cta_nelems" 3 } } */ -/* { dg-final { scan-assembler-times "\[\t \]0x5\[\t \]+\[^\n\]*cta_nelems" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*cta_nelems" 2 } } */ static int b1[] = {}; int b2[0]; - -const char _CTF_SECTION[] = ".ctf"; - -extern const char _CTF_NEWSTR[]; -const char _CTF_NEWSTR[] = "ctfinfo"; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-5.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-5.c new file mode 100644 index ..ec504412ef56 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-5.c @@ -0,0 +1,17 @@ +/* CTF generation for unsized (but initialized) arrays + + In this testcase, one CTF array type record of size 5 is expected. + + Variables: + _CTF_SECTION -> 5: const const char [5] (size 0x5) -> 4: const char [5] (size 0x5) + +*/ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "0x1200\[\t \]+\[^\n\]*ctt_info" 1 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x5\[\t \]+\[^\n\]*cta_nelems" 1 } } */ + +const char _CTF_SECTION[] = ".ctf"; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-3.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-3.c new file mode 100644 index ..8aea1e82749e --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-3.c @@ -0,0 +1,22 @@ +/* CTF generation for extern variable with defining and non-defining decl + in the same CU. + + This testcase checks the case when a non-defining decl is followed by + a defining decl for the same variable. See PR debug/105089. + + In this testcase, although two CTF array types are generated, only a + single CTF variable and a single entry in the CTF object
[PATCH 1/3] ctfc: get rid of the static variable in ctf_list_add_ctf_vars ()
2022-03-28 Indu Bhagat gcc/ChangeLog: * ctfc.h (struct ctf_container): Introduce a new member. * ctfout.cc (ctf_list_add_ctf_vars): Use it instead of static variable. --- gcc/ctfc.h| 2 ++ gcc/ctfout.cc | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gcc/ctfc.h b/gcc/ctfc.h index 18c93c802a06..4ce756c728a7 100644 --- a/gcc/ctfc.h +++ b/gcc/ctfc.h @@ -301,6 +301,8 @@ typedef struct GTY (()) ctf_container /* List of pre-processed CTF Variables. CTF requires that the variables appear in the sorted order of their names. */ ctf_dvdef_t ** GTY ((length ("0"))) ctfc_vars_list; + /* Count of pre-processed CTF Variables in the list. */ + uint64_t ctfc_vars_list_count; /* List of pre-processed CTF types. CTF requires that a shared type must appear before the type that uses it. For the compiler, this means types are emitted in sorted order of their type IDs. */ diff --git a/gcc/ctfout.cc b/gcc/ctfout.cc index a23d37758019..28a873b2027d 100644 --- a/gcc/ctfout.cc +++ b/gcc/ctfout.cc @@ -173,9 +173,7 @@ ctf_calc_num_vbytes (ctf_dtdef_ref ctftype) static void ctf_list_add_ctf_vars (ctf_container_ref ctfc, ctf_dvdef_ref var) { - /* FIXME - static may not fly with multiple CUs. */ - static int num_vars_added = 0; - ctfc->ctfc_vars_list[num_vars_added++] = var; + ctfc->ctfc_vars_list[ctfc->ctfc_vars_list_count++] = var; } /* Initialize the various sections and labels for CTF output. */ -- 2.31.1
[PATCH 0/3] Fix PR debug/105089
Hello, This patch set fixes PR debug/105089. [PS: The first patch in the series "ctfc: get rid of the static variable in ctf_list_add_ctf_vars" is unrelated to the PR and is combined here only for ease of review.] As noted in the PR debug/105089, gcc is emitting two CTF variable records where it sees an extern variable with declaration and definition in the same compilation unit. The CTF format format does not distinguish between the non-defining decl vs. the defining decl, so the correct behaviour wrt the compiler generating the type for such extern variables is to simply emit the type of the defining declaration. Testing Notes: -- bootstrapped and reg tested on x86_64 and aarch64 -- built binutils package with -gctf (with CTF-capable linker) on x86_64, no CTF errors reported. Thanks, Indu Bhagat (3): ctfc: get rid of the static variable in ctf_list_add_ctf_vars () CTF for extern variable fix [PR105089] Refactor and update CTF testcases [PR105089] gcc/ctfc.cc | 62 ++- gcc/ctfc.h| 8 ++- gcc/ctfout.cc | 28 ++--- gcc/dwarf2ctf.cc | 18 +- gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c | 22 +++ gcc/testsuite/gcc.dg/debug/ctf/ctf-array-5.c | 17 + .../gcc.dg/debug/ctf/ctf-variables-3.c| 22 +++ 7 files changed, 147 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-array-5.c create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-3.c -- 2.31.1
[COMMITTED] ctfout: use ctfc_get_num_ctf_vars instead
[Committed as obvious.] A minor cosmetic fix. 2022-03-28 Indu Bhagat gcc/ChangeLog: * ctfout.cc (ctf_preprocess): Use ctfc_get_num_ctf_vars instead. (output_ctf_vars): Likewise. --- gcc/ctfout.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/ctfout.cc b/gcc/ctfout.cc index 9bd918af53c..a23d3775801 100644 --- a/gcc/ctfout.cc +++ b/gcc/ctfout.cc @@ -287,7 +287,7 @@ ctf_preprocess (ctf_container_ref ctfc) ctfc->ctfc_gobjts_list = ggc_vec_alloc(num_global_objts); } - size_t num_ctf_vars = ctfc->ctfc_vars->elements (); + size_t num_ctf_vars = ctfc_get_num_ctf_vars (ctfc); if (num_ctf_vars) { ctf_dvd_preprocess_arg_t dvd_arg; @@ -597,7 +597,7 @@ static void output_ctf_vars (ctf_container_ref ctfc) { size_t i; - size_t num_ctf_vars = ctfc->ctfc_vars->elements (); + size_t num_ctf_vars = ctfc_get_num_ctf_vars (ctfc); if (num_ctf_vars) { /* Iterate over the list of sorted vars and output the asm. */ -- 2.31.1
Re: [PATCH] Testsuite: Add btf-dataset option for RISC-V.
On 12/30/21 8:59 AM, Palmer Dabbelt wrote: On Thu, 30 Dec 2021 08:28:34 PST (-0800), gcc-patches@gcc.gnu.org wrote: On 12/29/2021 8:02 PM, jiawei wrote: Add -msmall-data-limit option to put global and static data into right section and generate 'btt_info' on RISC-V target. BTF (BPF Type Format) is the metadata format which encodes the debug info related to BPF program/map, more details on: https://www.kernel.org/doc/html/latest/bpf/index.html#bpf-type-format-btf gcc/testsuite/ChangeLog: * gcc.dg/debug/btf/btf-datasec-1.c: Add riscv target support. Is the goal here to get the variable "d" out of the small data section and into the standard data section? It's not clear from your description . Neither an ACK nor a NAK at this point. I need to understand better what you're trying to accomplish. IIUC that's what this is doing, though the commit message isn't clear at all. That saind, it might be better to do something like diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c index dbb236bbda1..c0ad77d40aa 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c @@ -22,9 +22,9 @@ /* { dg-final { scan-assembler-times "0\[\t \]+\[^\n\]*bts_offset" 7 } } */ /* Check that strings for each DATASEC have been added to the BTF string table. */ -/* { dg-final { scan-assembler-times "ascii \".data.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ -/* { dg-final { scan-assembler-times "ascii \".rodata.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ -/* { dg-final { scan-assembler-times "ascii \".bss.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \".[s]?data.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \".[s]?rodata.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ +/* { dg-final { scan-assembler-times "ascii \".[s]?bss.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */ int a; long long b; as whether specific symbols end up in .data or .sdata is really just an optimization and either should be sufficiently correct. Yes, I would agree that the test case can be adapted as mentioned. The purpose of the test case is to check that BTF is correctly generated for whatever section the symbols end up in. Adding David Faust in CC for ACK. Thanks Indu IIRC some targets have other flavors of these, PPC's .sdata2 comes to mind. Not sure if we'd need that to drop their -msdata=none flag.
[COMMITTED] ctfc: remove redundant comma in enumerator list
This also helps get rid of warning ctfc.h:215:18: warning: comma at end of enumerator list [-Wpedantic] CTF_DTU_D_SLICE, gcc/ChangeLog: * ctfc.h (enum ctf_dtu_d_union_enum): Remove redundant comma. --- gcc/ctfc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/ctfc.h b/gcc/ctfc.h index a0b7e41..701c7ea 100644 --- a/gcc/ctfc.h +++ b/gcc/ctfc.h @@ -212,7 +212,7 @@ enum ctf_dtu_d_union_enum { CTF_DTU_D_ARRAY, CTF_DTU_D_ENCODING, CTF_DTU_D_ARGUMENTS, - CTF_DTU_D_SLICE, + CTF_DTU_D_SLICE }; enum ctf_dtu_d_union_enum -- 1.8.3.1
[PATCH] ctfc: Free CTF type and CTF variable objects in ctfc_delete_container ()
Hello, This patch fixes an outstanding issue with memory cleanup in the CTF container. Earlier the two hash tables in the CTF container were not cleaned up in ctfc_delete_container (). With this patch, we first free up the CTF type and CTF variable entries in the hash_table slots, followed by emptying of the hash tables. Bootstrapped and regression tested on x86_64. Thanks Free up the memory held by CTF type and CTF variable objects after CTF debug information has been emitted. In ctfc_delete_container (), traverse the hash_table of CTF types and CTF variables and free the memory held by the respective objects. gcc/ChangeLog: * ctfc.c (free_ctf_dtdef_cb): New function. (free_ctf_dvdef_cb): Likewise. (ctfc_delete_container): Free hash table contents. --- gcc/ctfc.c | 31 --- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/gcc/ctfc.c b/gcc/ctfc.c index 73c118e..1f961c9 100644 --- a/gcc/ctfc.c +++ b/gcc/ctfc.c @@ -179,6 +179,26 @@ ctf_dvd_lookup (const ctf_container_ref ctfc, dw_die_ref die) return NULL; } +/* Callback function to free the CTF type from hash table. */ + +static int +free_ctf_dtdef_cb (ctf_dtdef_ref * slot, void * arg ATTRIBUTE_UNUSED) +{ + if (slot && *slot) +ggc_free (*slot); + return 1; +} + +/* Callback function to free the CTF variable from hash table. */ + +static int +free_ctf_dvdef_cb (ctf_dvdef_ref * slot, void * arg ATTRIBUTE_UNUSED) +{ + if (slot && *slot) +ggc_free (*slot); + return 1; +} + /* Append member definition to the list. Member list is a singly-linked list with list start pointing to the head. */ @@ -944,11 +964,16 @@ ctfc_delete_strtab (ctf_strtable_t * strtab) void ctfc_delete_container (ctf_container_ref ctfc) { - /* FIXME - CTF container can be cleaned up now. - Will the ggc machinery take care of cleaning up the container structure - including the hash_map members etc. ? */ if (ctfc) { + ctfc->ctfc_types->traverse (NULL); + ctfc->ctfc_types->empty (); + ctfc->ctfc_types = NULL; + + ctfc->ctfc_vars->traverse (NULL); + ctfc->ctfc_vars->empty (); + ctfc->ctfc_types = NULL; + ctfc_delete_strtab (>ctfc_strtable); ctfc_delete_strtab (>ctfc_aux_strtable); if (ctfc->ctfc_vars_list) -- 1.8.3.1
Re: [PATCH] ctf: Do not warn for CTF not supported for GNU GIMPLE
On 9/29/21 12:14 AM, Richard Biener wrote: On Tue, Sep 28, 2021 at 8:52 PM Indu Bhagat via Gcc-patches wrote: CTF is supported for C only. Currently, a warning is emitted if the -gctf command line option is specified for a non-C frontend. This warning is also used by the GCC testsuite framework - it skips adding -gctf to the list of debug flags for automated testing, if CTF is not supported for the frontend. The following warning, however, is not useful in case of LTO: "lto1: note: CTF debug info requested, but not supported for ‘GNU GIMPLE’ frontend" This patch disables the generation of the above warning for GNU GIMPLE. Bootstrapped and regression tested on x86_64. gcc/ChangeLog: * toplev.c (process_options): Do not warn for GNU GIMPLE. --- gcc/toplev.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gcc/toplev.c b/gcc/toplev.c index e1688aa..511a343 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1416,14 +1416,16 @@ process_options (void) debug_info_level = DINFO_LEVEL_NONE; } - /* CTF is supported for only C at this time. - Compiling with -flto results in frontend language of GNU GIMPLE. */ + /* CTF is supported for only C at this time. */ if (!lang_GNU_C () && ctf_debug_info_level > CTFINFO_LEVEL_NONE) { - inform (UNKNOWN_LOCATION, - "CTF debug info requested, but not supported for %qs frontend", - language_string); + /* Compiling with -flto results in frontend language of GNU GIMPLE. It +is not useful to warn in that case. */ + if (!startswith (lang_hooks.name, "GNU GIMPLE")) please use in_lto_p instead OK with that change. in_lto_p is set later in lto_init () (when its time for do_compile ()). in_lto_p's updated value is not available at this point in process_options (). + inform (UNKNOWN_LOCATION, + "CTF debug info requested, but not supported for %qs frontend", + language_string); ctf_debug_info_level = CTFINFO_LEVEL_NONE; } -- 1.8.3.1
[PATCH] ctf: Do not warn for CTF not supported for GNU GIMPLE
CTF is supported for C only. Currently, a warning is emitted if the -gctf command line option is specified for a non-C frontend. This warning is also used by the GCC testsuite framework - it skips adding -gctf to the list of debug flags for automated testing, if CTF is not supported for the frontend. The following warning, however, is not useful in case of LTO: "lto1: note: CTF debug info requested, but not supported for ‘GNU GIMPLE’ frontend" This patch disables the generation of the above warning for GNU GIMPLE. Bootstrapped and regression tested on x86_64. gcc/ChangeLog: * toplev.c (process_options): Do not warn for GNU GIMPLE. --- gcc/toplev.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/gcc/toplev.c b/gcc/toplev.c index e1688aa..511a343 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1416,14 +1416,16 @@ process_options (void) debug_info_level = DINFO_LEVEL_NONE; } - /* CTF is supported for only C at this time. - Compiling with -flto results in frontend language of GNU GIMPLE. */ + /* CTF is supported for only C at this time. */ if (!lang_GNU_C () && ctf_debug_info_level > CTFINFO_LEVEL_NONE) { - inform (UNKNOWN_LOCATION, - "CTF debug info requested, but not supported for %qs frontend", - language_string); + /* Compiling with -flto results in frontend language of GNU GIMPLE. It +is not useful to warn in that case. */ + if (!startswith (lang_hooks.name, "GNU GIMPLE")) + inform (UNKNOWN_LOCATION, + "CTF debug info requested, but not supported for %qs frontend", + language_string); ctf_debug_info_level = CTFINFO_LEVEL_NONE; } -- 1.8.3.1
[PATCH] debug/102507: ICE in btf_finalize when compiling with -gbtf
Fix the free'up of btf_var_ids hash_map in btf_finalize (). Testing notes: - Bootstrapped GCC with -gbtf as an experiment. - Usual bootstrap and regression testing on x86_64. - BPF backend testing - make all-gcc, reg tested bpf.exp, btf.exp and ctf.exp. (tested using David Faust's config.gcc patch posted earlier https://gcc.gnu.org/pipermail/gcc-patches/2021-September/580422.html) gcc/ChangeLog: PR debug/102507 * btfout.c (GTY): Add GTY (()) albeit for cosmetic only purpose. (btf_finalize): Empty the hash_map btf_var_ids. --- gcc/btfout.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gcc/btfout.c b/gcc/btfout.c index cdc6c63..a787815 100644 --- a/gcc/btfout.c +++ b/gcc/btfout.c @@ -70,7 +70,7 @@ static char btf_info_section_label[MAX_BTF_LABEL_BYTES]; converted to BTF_KIND_VAR type records. Strictly accounts for the index from the start of the variable type entries, does not include the number of types emitted prior to the variable records. */ -static hash_map *btf_var_ids; +static GTY (()) hash_map *btf_var_ids; /* Mapping of type IDs from original CTF ID to BTF ID. Types do not map 1-to-1 from CTF to BTF. To avoid polluting the CTF container when updating @@ -1119,12 +1119,12 @@ btf_finalize (void) funcs = NULL; + btf_var_ids->empty (); + btf_var_ids = NULL; + free (btf_id_map); btf_id_map = NULL; - ggc_free (btf_var_ids); - btf_var_ids = NULL; - ctf_container_ref tu_ctfc = ctf_get_tu_ctfc (); ctfc_delete_container (tu_ctfc); tu_ctfc = NULL; -- 1.8.3.1
Re: [PATCH, V2 2/3] targhooks: New target hook for CTF/BTF debug info emission
On 8/26/21 11:12 PM, Richard Biener wrote: On Thu, Aug 26, 2021 at 8:55 PM Indu Bhagat wrote: On 8/26/21 3:03 AM, Richard Biener wrote: On Tue, Aug 24, 2021 at 7:07 PM Indu Bhagat wrote: On 8/18/21 12:00 AM, Richard Biener wrote: On Tue, Aug 17, 2021 at 7:26 PM Indu Bhagat wrote: On 8/17/21 1:04 AM, Richard Biener wrote: On Mon, Aug 16, 2021 at 7:39 PM Indu Bhagat wrote: On 8/10/21 4:54 AM, Richard Biener wrote: On Thu, Aug 5, 2021 at 2:52 AM Indu Bhagat via Gcc-patches wrote: This patch adds a new target hook to detect if the CTF container can allow the emission of CTF/BTF debug info at DWARF debug info early finish time. Some backends, e.g., BPF when generating code for CO-RE usecase, may need to emit the CTF/BTF debug info sections around the time when late DWARF debug is finalized (dwarf2out_finish). Without looking at the dwarf2out.c usage in the next patch - I think the CTF part should be always emitted from dwarf2out_early_finish, the "hooks" should somehow arrange for the alternate output specific data to be preserved until dwarf2out_finish time so the late BTF data can be emitted from there. Lumping everything together now just makes it harder to see what info is required to persist and thus make LTO support more intrusive than necessary. In principle, I agree the approach to split generate/emit CTF/BTF like you mention is ideal. But, the BTF CO-RE relocations format is such that the .BTF section cannot be finalized until .BTF.ext contents are all fully known (David Faust summarizes this issue in the other thread "[PATCH, V2 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase".) In summary, the .BTF.ext section refers to strings in the .BTF section. These strings are added at the time the CO-RE relocations are added. Recall that the .BTF section's header has information about the .BTF string table start offset and length. So, this means the "CTF part" (or the .BTF section) cannot simply be emitted in the dwarf2out_early_finish because it's not ready yet. If it is still unclear, please let me know. My judgement here is that the BTF format itself is not amenable to split early/late emission like DWARF. BTF has no linker support yet either. But are the strings used for the CO-RE relocations not all present already? Or does the "CTF part" have only "foo", "bar" and "baz" while the CO-RE part wants to output sth like "foo->bar.baz" (which IMHO would be quite stupid also for size purposes)? Yes, the latter ("foo->bar.baz") is closer to what the format does for CO-RE relocations! That said, fix the format. Alternatively hand the CO-RE part its own string table (what's the fuss with re-using the CTF string table if there's nothing to share ...) BTF and .BTF.ext formats are specified already by implementations in the kernel, libbpf, and LLVM. For that matter, I should add BPF CO-RE to the mix and say that BPF CO-RE capability _and_ .BTF/.BTF.ext debug formats have been defined already by the BPF kernel developers/associated entities. At this time, we as GCC developers simply extending the BPF backend/BTF generation support in GCC, cannot fix the format. That ship has sailed. Hmm, well. How about emitting .BTF.ext.string from GCC and have the linker merge the .BTF.ext.string section with the CTF string section then? You can't really say "the ship has sailed" if I read the CTF webpage - there seems to be many format changes planned. Well. Guess that was it from my side on the topic of ranting about the not well thought out debug format ;) Richard. Hello Richard, As we clarified in this thread, BTF/CO-RE format cannot be changed. What are your thoughts on this patch set now ? Is this OK ? Since the issue is intrinsic to BTF/CO-RE and not the actual target can we do w/o a target hook by just gating on BTF_WITH_CORE as debug format or so? Richard. The issue is intrinsic to BTF debug format *when* CO-RE is in effect, so it is not entirely target independent because the whole "Compile Once - Run Everywhere" scheme is BPF backend specific. I see. The debug information generation routines need to know if CO-RE is in effect (to finalize BTF debug info generation late and not early). Now, because it is the user who selects it via the -mco-re option, we need to have a way to detect this at run-time. Guarding it with a definition like BTF_WITH_CORE (is this what you meant?) will not work. I was thinking about having BTF_CORE_DEBUG in addition to BTF_DEBUG and thus have this part of the debug info format. That would be straight-forward in case the option to enable it were not backend specific but I guess it might be valid for the backend to alter ops->x_write_symbols in the backend option processing code. This is doable. I updated the patch series and have posted V3. Thanks Indu But, yes, we can do without a target h
Re: DWARF for extern variable
On 8/24/21 12:55 AM, Richard Biener wrote: On Mon, Aug 23, 2021 at 11:18 PM Indu Bhagat via Gcc-patches wrote: Hello, What is the expected DWARF for extern variable in the following cases? I am seeing that the DWARF generated is different with gcc8.4.1 vs gcc-trunk. Testcase 2 -- extern const char a[]; const char a[] = "testme"; Testcase 2 Behavior - Both gcc-trunk and gcc8.4.1 generate two DW_TAG_variable DIEs (the defining decl holds the reference to the non-defining decl via DW_AT_specification) - But gcc8.4.1 does not generate any DWARF for the type of the defining decl (const char[7]) but gcc-trunk does. ## DWARF for testcase 2 with gcc-trunk is as follows: <...> <1><22>: Abbrev Number: 2 (DW_TAG_array_type) <23> DW_AT_type: <0x39> <27> DW_AT_sibling : <0x2d> <2><2b>: Abbrev Number: 5 (DW_TAG_subrange_type) <2><2c>: Abbrev Number: 0 <1><2d>: Abbrev Number: 1 (DW_TAG_const_type) <2e> DW_AT_type: <0x22> <1><32>: Abbrev Number: 3 (DW_TAG_base_type) <33> DW_AT_byte_size : 1 <34> DW_AT_encoding: 6(signed char) <35> DW_AT_name: (indirect string, offset: 0x2035): char <1><39>: Abbrev Number: 1 (DW_TAG_const_type) <3a> DW_AT_type: <0x32> <1><3e>: Abbrev Number: 6 (DW_TAG_variable) <3f> DW_AT_name: a <41> DW_AT_decl_file : 1 <42> DW_AT_decl_line : 1 <43> DW_AT_decl_column : 19 <44> DW_AT_type: <0x2d> <48> DW_AT_external: 1 <48> DW_AT_declaration : 1 <1><48>: Abbrev Number: 2 (DW_TAG_array_type) <49> DW_AT_type: <0x39> <4d> DW_AT_sibling : <0x58> <2><51>: Abbrev Number: 7 (DW_TAG_subrange_type) <52> DW_AT_type: <0x5d> <56> DW_AT_upper_bound : 6 <2><57>: Abbrev Number: 0 <1><58>: Abbrev Number: 1 (DW_TAG_const_type) <59> DW_AT_type: <0x48> <1><5d>: Abbrev Number: 3 (DW_TAG_base_type) <5e> DW_AT_byte_size : 8 <5f> DW_AT_encoding: 7(unsigned) <60> DW_AT_name: (indirect string, offset: 0x2023): long unsigned int <1><64>: Abbrev Number: 8 (DW_TAG_variable) <65> DW_AT_specification: <0x3e> <69> DW_AT_decl_line : 2 <6a> DW_AT_decl_column : 12 <6b> DW_AT_type: <0x58> I suppose having both a DW_AT_specification and a DW_AT_type is somewhat at odds. It's likely because the definition specifies the size of the array while the specification does not. Not sure what should be best done here. Richard. Hmm..I thought the generated DWARF by gcc-trunk for testcase 2 is coherent and specifies the information in alignment with the source : DW_AT_type of the defining declaration correctly specifies the type to be const char[7] while the DW_AT_specification pointing to the non-defining decl (and with type const char[] with no size info). The DWARF generated by gcc-8.4.1, however, does seem to be missing information though. It should have the information for the defining decl and hence, the size info. i.e., DW_AT_type pointing to a array with DW_TAG_subrange_type with attribute DW_AT_upper_bound = 6 like above. Isn't it ? Indu <6f> DW_AT_location: 9 byte block: 3 0 0 0 0 0 0 0 0 (DW_OP_addr: 0) <1><79>: Abbrev Number: 0 ## DWARF for testcase 2 with gcc8.4.1 is as follows: <1><21>: Abbrev Number: 2 (DW_TAG_array_type) <22> DW_AT_type: <0x38> <26> DW_AT_sibling : <0x2c> <2><2a>: Abbrev Number: 3 (DW_TAG_subrange_type) <2><2b>: Abbrev Number: 0 <1><2c>: Abbrev Number: 4 (DW_TAG_const_type) <2d> DW_AT_type: <0x21> <1><31>: Abbrev Number: 5 (DW_TAG_base_type) <32> DW_AT_byte_size : 1 <33> DW_AT_encoding: 6(signed char) <34> DW_AT_name: (indirect string, offset: 0x1e04): char <1><38>: Abbrev Number: 4 (DW_TAG_const_type) <39> DW_AT_type: <0x31> <1><3d>: Abbrev Number: 6 (DW_TAG_variable) <3e> DW_AT_name: a <40> DW_AT_decl_file : 1 <41> DW_AT_decl_line : 1 <42> DW_AT_decl_column : 19 <43> DW_AT_type: <0x2c> <47> DW_AT_external: 1 <47> DW_AT_declaration : 1 <1><47>: Abbrev Number: 5 (DW_TAG_base_type) <48> DW_AT_byte_size : 8 <49> DW_AT_encoding: 7(unsigned) <4a> DW_AT_name: (indirect string, offset: 0x1df2): long unsigned int <1><4e>: Abbrev Number: 7 (DW_TAG_variable) <4f> DW_AT_specification: <0x3d> <53> DW_AT_decl_line : 2 <54> DW_AT_decl_column : 12 <55> DW_AT_location: 9 byte block: 3 0 0 0 0 0 0 0 0 (DW_OP_addr: 0) <1><5f>: Abbrev Number: 0 Thanks Indu
[PATCH, V3 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase
DWARF generation is split between early and late phases when LTO is in effect. This poses challenges for CTF/BTF generation especially if late debug info generation is desirable, as turns out to be the case for BPF CO-RE. The approach taken here in this patch is: 1. LTO is disabled for BPF CO-RE The reason to disable LTO for BPF CO-RE is that if LTO is in effect, BPF CO-RE relocations need to be generated in the LTO link phase _after_ the optimizations are done. This means we need to devise way to combine early and late BTF. At this time, in absence of linker support for BTF sections, it makes sense to steer clear of LTO for BPF CO-RE and bypass the issue. 2. The BPF backend updates the write_symbols with BPF_WITH_CORE_DEBUG to convey the case that BTF with CO-RE support needs to be generated. This information is used by the debug info emission routines to defer the emission of BTF/CO-RE until dwarf2out_finish. So, in other words, dwarf2out_early_finish - Always emit CTF here. - if (BTF && !BTF_WITH_CORE), emit BTF now. dwarf2out_finish - if (BTF_WITH_CORE) emit BTF now. gcc/ChangeLog: * dwarf2ctf.c (ctf_debug_finalize): Make it static. (ctf_debug_early_finish): New definition. (ctf_debug_finish): Likewise. * dwarf2ctf.h (ctf_debug_finalize): Remove declaration. (ctf_debug_early_finish): New declaration. (ctf_debug_finish): Likewise. * dwarf2out.c (dwarf2out_finish): Invoke ctf_debug_finish. (dwarf2out_early_finish): Invoke ctf_debug_early_finish. --- gcc/dwarf2ctf.c | 54 +- gcc/dwarf2ctf.h | 4 +++- gcc/dwarf2out.c | 9 +++-- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/gcc/dwarf2ctf.c b/gcc/dwarf2ctf.c index 5e8a725..b686baf 100644 --- a/gcc/dwarf2ctf.c +++ b/gcc/dwarf2ctf.c @@ -917,6 +917,27 @@ gen_ctf_type (ctf_container_ref ctfc, dw_die_ref die) return type_id; } +/* Prepare for output and write out the CTF debug information. */ + +static void +ctf_debug_finalize (const char *filename, bool btf) +{ + if (btf) +{ + btf_output (filename); + btf_finalize (); +} + + else +{ + /* Emit the collected CTF information. */ + ctf_output (filename); + + /* Reset the CTF state. */ + ctf_finalize (); +} +} + bool ctf_do_die (dw_die_ref die) { @@ -966,24 +987,31 @@ ctf_debug_init_postprocess (bool btf) btf_init_postprocess (); } -/* Prepare for output and write out the CTF debug information. */ +/* Early finish CTF/BTF debug info. */ void -ctf_debug_finalize (const char *filename, bool btf) +ctf_debug_early_finish (const char * filename) { - if (btf) -{ - btf_output (filename); - btf_finalize (); -} + /* Emit CTF debug info early always. */ + if (ctf_debug_info_level > CTFINFO_LEVEL_NONE + /* Emit BTF debug info early if CO-RE relocations are not +required. */ + || (btf_debuginfo_p () && !btf_with_core_debuginfo_p ())) +ctf_debug_finalize (filename, btf_debuginfo_p ()); +} - else -{ - /* Emit the collected CTF information. */ - ctf_output (filename); +/* Finish CTF/BTF debug info emission. */ - /* Reset the CTF state. */ - ctf_finalize (); +void +ctf_debug_finish (const char * filename) +{ + /* Emit BTF debug info here when CO-RE relocations need to be generated. + BTF with CO-RE relocations needs to be generated when CO-RE is in effect + for the BPF target. */ + if (btf_with_core_debuginfo_p ()) +{ + gcc_assert (btf_debuginfo_p ()); + ctf_debug_finalize (filename, btf_debuginfo_p ()); } } diff --git a/gcc/dwarf2ctf.h b/gcc/dwarf2ctf.h index a3cf567..9edbde0 100644 --- a/gcc/dwarf2ctf.h +++ b/gcc/dwarf2ctf.h @@ -24,13 +24,15 @@ along with GCC; see the file COPYING3. If not see #define GCC_DWARF2CTF_H 1 #include "dwarf2out.h" +#include "flags.h" /* Debug Format Interface. Used in dwarf2out.c. */ 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_finalize (const char *, bool); +extern void ctf_debug_early_finish (const char *); +extern void ctf_debug_finish (const char *); /* Wrappers for CTF/BTF to fetch information from GCC DWARF DIE. Used in ctfc.c. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 07a479f..3615e68 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -31913,6 +31913,11 @@ dwarf2out_finish (const char *filename) unsigned char checksum[16]; char dl_section_ref[MAX_ARTIFICIAL_LABEL_BYTES]; + /* Generate CTF/BTF debug info. */ + if ((ctf_debug_info_level > CTFINFO_LEVEL_NONE + || btf_debuginfo_p ()) && lang_GNU_C ()) +ctf_debug_finish (filename); + /* Skip emitting DWARF if not required. */ if (!dwarf_debuginfo_p ()) return; @@ -32817,8 +32822,8 @@ dwarf2out_early_finish (const char *filename) ctf_debug_do_cu
[PATCH,V3 2/3] bpf: Add new -mco-re option for BPF CO-RE
-mco-re in the BPF backend enables code generation for the CO-RE usecase. LTO is disabled for CO-RE compilations. gcc/ChangeLog: * config/bpf/bpf.c (bpf_option_override): For BPF backend, disable LTO support when compiling for CO-RE. * config/bpf/bpf.opt: Add new command line option -mco-re. gcc/testsuite/ChangeLog: * gcc.target/bpf/core-lto-1.c: New test. --- gcc/config/bpf/bpf.c | 25 + gcc/config/bpf/bpf.opt| 4 gcc/testsuite/gcc.target/bpf/core-lto-1.c | 9 + 3 files changed, 38 insertions(+) create mode 100644 gcc/testsuite/gcc.target/bpf/core-lto-1.c diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c index e635f9e..7228978 100644 --- a/gcc/config/bpf/bpf.c +++ b/gcc/config/bpf/bpf.c @@ -54,6 +54,7 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "predict.h" #include "langhooks.h" +#include "flags.h" /* Per-function machine data. */ struct GTY(()) machine_function @@ -158,6 +159,30 @@ bpf_option_override (void) { /* Set the initializer for the per-function status structure. */ init_machine_status = bpf_init_machine_status; + + /* BPF CO-RE support requires BTF debug info generation. */ + if (TARGET_BPF_CORE && !btf_debuginfo_p ()) +error ("BPF CO-RE requires BTF debugging information, use %<-gbtf%>"); + + /* To support the portability needs of BPF CO-RE approach, BTF debug + information includes the BPF CO-RE relocations. */ + if (TARGET_BPF_CORE) +write_symbols |= BTF_WITH_CORE_DEBUG; + + /* Unlike much of the other BTF debug information, the information necessary + for CO-RE relocations is added to the CTF container by the BPF backend. + Enabling LTO adds some complications in the generation of the BPF CO-RE + relocations because if LTO is in effect, the relocations need to be + generated late in the LTO link phase. This poses a new challenge for the + compiler to now provide means to combine the early BTF and late BTF CO-RE + debug info, similar to DWARF debug info. BTF/CO-RE debug info is not + amenable to such a split generation and a later merging. + + In any case, in absence of linker support for BTF sections at this time, + it is acceptable to simply disallow LTO for BPF CO-RE compilations. */ + + if (flag_lto && TARGET_BPF_CORE) +sorry ("BPF CO-RE does not support LTO"); } #undef TARGET_OPTION_OVERRIDE diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt index 916b53c..4493067 100644 --- a/gcc/config/bpf/bpf.opt +++ b/gcc/config/bpf/bpf.opt @@ -127,3 +127,7 @@ Generate little-endian eBPF. mframe-limit= Target Joined RejectNegative UInteger IntegerRange(0, 32767) Var(bpf_frame_limit) Init(512) Set a hard limit for the size of each stack frame, in bytes. + +mco-re +Target Mask(BPF_CORE) +Generate all necessary information for BPF Compile Once - Run Everywhere. diff --git a/gcc/testsuite/gcc.target/bpf/core-lto-1.c b/gcc/testsuite/gcc.target/bpf/core-lto-1.c new file mode 100644 index 000..927de23 --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/core-lto-1.c @@ -0,0 +1,9 @@ +/* Test -mco-re with -flto. + + -mco-re is used to generate information for BPF CO-RE usecase. To support + the generataion of the .BTF and .BTF.ext sections in GCC, -flto is disabled + with -mco-re. */ + +/* { dg-do compile } */ +/* { dg-message "sorry, unimplemented: BPF CO-RE does not support LTO" "" { target bpf-*-* } 0 } */ +/* { dg-options "-gbtf -mco-re -flto" } */ -- 1.8.3.1
[PATCH,V3 0/3] Allow means for late BTF generation for BPF CO-RE
[Changes from V2] - Instead of target hook, the patch set now adds a new debug format BTF_WITH_CORE_DEBUG. - Renamed the BPF option from -mcore to -mco-re. - Adapted the commit logs a bit. [End of Changes from V2] Hello, This patch series puts the framework in place for late BTF generation (in dwarf2out_finish). This is needed for the landing of BPF CO-RE support in GCC, patches for which were posted earlier - https://gcc.gnu.org/pipermail/gcc-patches/2021-August/576719.html. BPF's Compile Once - Run Everywhere (CO-RE) feature is used to make a compiled BPF program portable across kernel versions, all this without the need to recompile the BPF program. A key part of BPF CO-RE capability is the BTF debug info generated for them. A traditional BPF program (non CO-RE) will have a .BTF section which contains the type information in the BTF debug format. In case of CO-RE, however, an additional section .BTF.ext section is used. The .BTF.ext section contains the CO-RE relocations. A BPF loader will use the .BTF.ext section along with the associated .BTF section to adjust some references in the instructions of BPF program to ensure it is compatible with the required kernel version / headers. A .BTF.ext section contains the CO-RE relocation records. Roughly, each CO-RE relocation record will contain the following info: - offset of BPF instruction to be patched - the BTF ID of the data structure being accessed by the instruction, and - an offset to the "access string" - a BTF string which encodes a series of field accesses to retrieve the field of interest in the instruction. The .BTF.ext section does not have a string table of its own, so these "access strings" are placed in the .BTF section string table. The CO-RE relocation records refer to them by offset into the .BTF string table. Example of access string encoding: struct S { int a; union { int _unused; int b; char c; } u[4]; }; struct S *foo = ...; int x = foo->a; /* encoded as "0:0" */ int y = foo[4]->u[2].b /* encoded as "4:1:2:1" */ char z = foo->u[3].c /* encoded as "0:1:3:2" */ This means that writing out of a .BTF section needs to be delayed until after these "access strings" have been added by the BPF backend, when CO-RE is in effect. High-level design - - The CTF container (CTFC) is populated with the compiler-internal representation for the "type information" at dwarf2out_early_finish time. This information is used for generation of the .BTF section. - For CO-RE relocation records, the information needed to generate .BTF.ext section is added by the BPF backend to the CTF container (CTFC) at expand time. - A new debug format BTF_WITH_CORE_DEBUG is being added. - The BPF backend updates the write_symbols variable with BTF_WITH_CORE_DEBUG debug format signalling the rest of the compiler that BPF/CO-RE is in effect, and hence the need to generate the BTF CO-RE relocation records. - BTF debug information is emitted late in dwarf2out_finish when BTF_WITH_CORE_DEBUG debug format is requested by the user (implicitly via the command line option -mco-re for the BPF backend). - Combining early BTF and late BTF/CO-RE debug information is not feasible due to the way BTF CO-RE format is defined and lack of linker support for the BTF debug format. - Lastly, LTO is disallowed to be used together with CO-RE for the BPF target. Testing Notes - Bootstrapped and reg tested on x86_64 - make all-gcc for --target=bpf-unknown-none; tested ctf.exp, btf.exp and bpf.exp Thanks, Indu Bhagat (3): debug: add BTF_WITH_CORE_DEBUG debug format bpf: Add new -mco-re option for BPF CO-RE dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase gcc/config/bpf/bpf.c | 25 ++ gcc/config/bpf/bpf.opt| 4 +++ gcc/dwarf2ctf.c | 54 +++ gcc/dwarf2ctf.h | 4 ++- gcc/dwarf2out.c | 9 -- gcc/flag-types.h | 6 +++- gcc/flags.h | 4 +++ gcc/opts.c| 8 + gcc/testsuite/gcc.target/bpf/core-lto-1.c | 9 ++ 9 files changed, 106 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gcc.target/bpf/core-lto-1.c -- 1.8.3.1
[PATCH,V3 1/3] debug: add BTF_WITH_CORE_DEBUG debug format
To best handle BTF/CO-RE in GCC, a distinct BTF_WITH_CORE_DEBUG debug format is being added. This helps the compiler detect whether BTF with CO-RE relocations needs to be emitted. gcc/ChangeLog: * flag-types.h (enum debug_info_type): Add new enum DINFO_TYPE_BTF_WITH_CORE. (BTF_WITH_CORE_DEBUG): New bitmask. * flags.h (btf_with_core_debuginfo_p): New declaration. * opts.c (btf_with_core_debuginfo_p): New definition. --- gcc/flag-types.h | 6 +- gcc/flags.h | 4 gcc/opts.c | 8 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/gcc/flag-types.h b/gcc/flag-types.h index 4fb1cb4..cc41b2a 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -31,7 +31,8 @@ enum debug_info_type DINFO_TYPE_VMS = 4,/* VMS debug info. */ DINFO_TYPE_CTF = 5,/* CTF debug info. */ DINFO_TYPE_BTF = 6,/* BTF debug info. */ - DINFO_TYPE_MAX = DINFO_TYPE_BTF /* Marker only. */ + DINFO_TYPE_BTF_WITH_CORE = 7, /* BTF debug info with CO-RE relocations. */ + DINFO_TYPE_MAX = DINFO_TYPE_BTF_WITH_CORE /* Marker only. */ }; #define NO_DEBUG (0U) @@ -47,6 +48,9 @@ enum debug_info_type #define CTF_DEBUG (1U << DINFO_TYPE_CTF) /* Write BTF debug info (using btfout.c). */ #define BTF_DEBUG (1U << DINFO_TYPE_BTF) +/* Write BTF debug info for BPF CO-RE usecase (using btfout.c). */ +#define BTF_WITH_CORE_DEBUG (1U << DINFO_TYPE_BTF_WITH_CORE) + /* Note: Adding new definitions to handle -combination- of debug formats, like VMS_AND_DWARF2_DEBUG is not recommended. This definition remains here for historical reasons. */ diff --git a/gcc/flags.h b/gcc/flags.h index afedef0..af61bcd 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -44,6 +44,10 @@ const char * debug_set_names (uint32_t w_symbols); extern bool btf_debuginfo_p (); +/* Return true iff BTF with CO-RE debug info is enabled. */ + +extern bool btf_with_core_debuginfo_p (); + /* Return true iff CTF debug info is enabled. */ extern bool ctf_debuginfo_p (); diff --git a/gcc/opts.c b/gcc/opts.c index e050155..1d2d22d 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -135,6 +135,14 @@ btf_debuginfo_p () return (write_symbols & BTF_DEBUG); } +/* Return TRUE iff BTF with CO-RE debug info is enabled. */ + +bool +btf_with_core_debuginfo_p () +{ + return (write_symbols & BTF_WITH_CORE_DEBUG); +} + /* Return TRUE iff CTF debug info is enabled. */ bool -- 1.8.3.1
Re: [PATCH, V2 2/3] targhooks: New target hook for CTF/BTF debug info emission
On 8/26/21 3:03 AM, Richard Biener wrote: On Tue, Aug 24, 2021 at 7:07 PM Indu Bhagat wrote: On 8/18/21 12:00 AM, Richard Biener wrote: On Tue, Aug 17, 2021 at 7:26 PM Indu Bhagat wrote: On 8/17/21 1:04 AM, Richard Biener wrote: On Mon, Aug 16, 2021 at 7:39 PM Indu Bhagat wrote: On 8/10/21 4:54 AM, Richard Biener wrote: On Thu, Aug 5, 2021 at 2:52 AM Indu Bhagat via Gcc-patches wrote: This patch adds a new target hook to detect if the CTF container can allow the emission of CTF/BTF debug info at DWARF debug info early finish time. Some backends, e.g., BPF when generating code for CO-RE usecase, may need to emit the CTF/BTF debug info sections around the time when late DWARF debug is finalized (dwarf2out_finish). Without looking at the dwarf2out.c usage in the next patch - I think the CTF part should be always emitted from dwarf2out_early_finish, the "hooks" should somehow arrange for the alternate output specific data to be preserved until dwarf2out_finish time so the late BTF data can be emitted from there. Lumping everything together now just makes it harder to see what info is required to persist and thus make LTO support more intrusive than necessary. In principle, I agree the approach to split generate/emit CTF/BTF like you mention is ideal. But, the BTF CO-RE relocations format is such that the .BTF section cannot be finalized until .BTF.ext contents are all fully known (David Faust summarizes this issue in the other thread "[PATCH, V2 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase".) In summary, the .BTF.ext section refers to strings in the .BTF section. These strings are added at the time the CO-RE relocations are added. Recall that the .BTF section's header has information about the .BTF string table start offset and length. So, this means the "CTF part" (or the .BTF section) cannot simply be emitted in the dwarf2out_early_finish because it's not ready yet. If it is still unclear, please let me know. My judgement here is that the BTF format itself is not amenable to split early/late emission like DWARF. BTF has no linker support yet either. But are the strings used for the CO-RE relocations not all present already? Or does the "CTF part" have only "foo", "bar" and "baz" while the CO-RE part wants to output sth like "foo->bar.baz" (which IMHO would be quite stupid also for size purposes)? Yes, the latter ("foo->bar.baz") is closer to what the format does for CO-RE relocations! That said, fix the format. Alternatively hand the CO-RE part its own string table (what's the fuss with re-using the CTF string table if there's nothing to share ...) BTF and .BTF.ext formats are specified already by implementations in the kernel, libbpf, and LLVM. For that matter, I should add BPF CO-RE to the mix and say that BPF CO-RE capability _and_ .BTF/.BTF.ext debug formats have been defined already by the BPF kernel developers/associated entities. At this time, we as GCC developers simply extending the BPF backend/BTF generation support in GCC, cannot fix the format. That ship has sailed. Hmm, well. How about emitting .BTF.ext.string from GCC and have the linker merge the .BTF.ext.string section with the CTF string section then? You can't really say "the ship has sailed" if I read the CTF webpage - there seems to be many format changes planned. Well. Guess that was it from my side on the topic of ranting about the not well thought out debug format ;) Richard. Hello Richard, As we clarified in this thread, BTF/CO-RE format cannot be changed. What are your thoughts on this patch set now ? Is this OK ? Since the issue is intrinsic to BTF/CO-RE and not the actual target can we do w/o a target hook by just gating on BTF_WITH_CORE as debug format or so? Richard. The issue is intrinsic to BTF debug format *when* CO-RE is in effect, so it is not entirely target independent because the whole "Compile Once - Run Everywhere" scheme is BPF backend specific. The debug information generation routines need to know if CO-RE is in effect (to finalize BTF debug info generation late and not early). Now, because it is the user who selects it via the -mco-re option, we need to have a way to detect this at run-time. Guarding it with a definition like BTF_WITH_CORE (is this what you meant?) will not work. But, yes, we can do without a target hook. We can keep a global var in the BTF context in btfout.c / CTF container (CTFC) which can be updated by the backend when BPF CO-RE is in effect (the -mco-re option). This was also considered as an option but the target hook option was chosen because it appeared to be the GCC's preferred way of conveying information from the backend. Is keeping global var preferable in this specific case ? Indu
Re: [PATCH, V2 2/3] targhooks: New target hook for CTF/BTF debug info emission
On 8/18/21 12:00 AM, Richard Biener wrote: On Tue, Aug 17, 2021 at 7:26 PM Indu Bhagat wrote: On 8/17/21 1:04 AM, Richard Biener wrote: On Mon, Aug 16, 2021 at 7:39 PM Indu Bhagat wrote: On 8/10/21 4:54 AM, Richard Biener wrote: On Thu, Aug 5, 2021 at 2:52 AM Indu Bhagat via Gcc-patches wrote: This patch adds a new target hook to detect if the CTF container can allow the emission of CTF/BTF debug info at DWARF debug info early finish time. Some backends, e.g., BPF when generating code for CO-RE usecase, may need to emit the CTF/BTF debug info sections around the time when late DWARF debug is finalized (dwarf2out_finish). Without looking at the dwarf2out.c usage in the next patch - I think the CTF part should be always emitted from dwarf2out_early_finish, the "hooks" should somehow arrange for the alternate output specific data to be preserved until dwarf2out_finish time so the late BTF data can be emitted from there. Lumping everything together now just makes it harder to see what info is required to persist and thus make LTO support more intrusive than necessary. In principle, I agree the approach to split generate/emit CTF/BTF like you mention is ideal. But, the BTF CO-RE relocations format is such that the .BTF section cannot be finalized until .BTF.ext contents are all fully known (David Faust summarizes this issue in the other thread "[PATCH, V2 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase".) In summary, the .BTF.ext section refers to strings in the .BTF section. These strings are added at the time the CO-RE relocations are added. Recall that the .BTF section's header has information about the .BTF string table start offset and length. So, this means the "CTF part" (or the .BTF section) cannot simply be emitted in the dwarf2out_early_finish because it's not ready yet. If it is still unclear, please let me know. My judgement here is that the BTF format itself is not amenable to split early/late emission like DWARF. BTF has no linker support yet either. But are the strings used for the CO-RE relocations not all present already? Or does the "CTF part" have only "foo", "bar" and "baz" while the CO-RE part wants to output sth like "foo->bar.baz" (which IMHO would be quite stupid also for size purposes)? Yes, the latter ("foo->bar.baz") is closer to what the format does for CO-RE relocations! That said, fix the format. Alternatively hand the CO-RE part its own string table (what's the fuss with re-using the CTF string table if there's nothing to share ...) BTF and .BTF.ext formats are specified already by implementations in the kernel, libbpf, and LLVM. For that matter, I should add BPF CO-RE to the mix and say that BPF CO-RE capability _and_ .BTF/.BTF.ext debug formats have been defined already by the BPF kernel developers/associated entities. At this time, we as GCC developers simply extending the BPF backend/BTF generation support in GCC, cannot fix the format. That ship has sailed. Hmm, well. How about emitting .BTF.ext.string from GCC and have the linker merge the .BTF.ext.string section with the CTF string section then? You can't really say "the ship has sailed" if I read the CTF webpage - there seems to be many format changes planned. Well. Guess that was it from my side on the topic of ranting about the not well thought out debug format ;) Richard. Hello Richard, As we clarified in this thread, BTF/CO-RE format cannot be changed. What are your thoughts on this patch set now ? Is this OK ? Thanks Indu Thanks for reviewing and voicing your concerns. Indu Richard.
DWARF for extern variable
Hello, What is the expected DWARF for extern variable in the following cases? I am seeing that the DWARF generated is different with gcc8.4.1 vs gcc-trunk. Testcase 1 -- extern const char a[]; int foo() { return a != 0; } Testcase 1 Behavior - - gcc-trunk has _no_ DWARF for variable a. - gcc8.4.1 generates following DW_TAG_variable for extern variable a. But does not designate it as a non-defining decl (IIUC, DW_AT_specification is used for such cases?). <..> <1><31>: Abbrev Number: 2 (DW_TAG_array_type) <32> DW_AT_type: <0x48> <36> DW_AT_sibling : <0x3c> <2><3a>: Abbrev Number: 3 (DW_TAG_subrange_type) <2><3b>: Abbrev Number: 0 <1><3c>: Abbrev Number: 4 (DW_TAG_const_type) <3d> DW_AT_type: <0x31> <1><41>: Abbrev Number: 5 (DW_TAG_base_type) <42> DW_AT_byte_size : 1 <43> DW_AT_encoding: 6(signed char) <44> DW_AT_name: (indirect string, offset: 0x1df6): char <1><48>: Abbrev Number: 4 (DW_TAG_const_type) <49> DW_AT_type: <0x41> <1><4d>: Abbrev Number: 6 (DW_TAG_variable) <4e> DW_AT_name: a <50> DW_AT_decl_file : 1 <51> DW_AT_decl_line : 1 <52> DW_AT_decl_column : 19 <53> DW_AT_type: <0x3c> <57> DW_AT_external: 1 <57> DW_AT_declaration : 1 <..> --- Testcase 2 -- extern const char a[]; const char a[] = "testme"; Testcase 2 Behavior - Both gcc-trunk and gcc8.4.1 generate two DW_TAG_variable DIEs (the defining decl holds the reference to the non-defining decl via DW_AT_specification) - But gcc8.4.1 does not generate any DWARF for the type of the defining decl (const char[7]) but gcc-trunk does. ## DWARF for testcase 2 with gcc-trunk is as follows: <...> <1><22>: Abbrev Number: 2 (DW_TAG_array_type) <23> DW_AT_type: <0x39> <27> DW_AT_sibling : <0x2d> <2><2b>: Abbrev Number: 5 (DW_TAG_subrange_type) <2><2c>: Abbrev Number: 0 <1><2d>: Abbrev Number: 1 (DW_TAG_const_type) <2e> DW_AT_type: <0x22> <1><32>: Abbrev Number: 3 (DW_TAG_base_type) <33> DW_AT_byte_size : 1 <34> DW_AT_encoding: 6(signed char) <35> DW_AT_name: (indirect string, offset: 0x2035): char <1><39>: Abbrev Number: 1 (DW_TAG_const_type) <3a> DW_AT_type: <0x32> <1><3e>: Abbrev Number: 6 (DW_TAG_variable) <3f> DW_AT_name: a <41> DW_AT_decl_file : 1 <42> DW_AT_decl_line : 1 <43> DW_AT_decl_column : 19 <44> DW_AT_type: <0x2d> <48> DW_AT_external: 1 <48> DW_AT_declaration : 1 <1><48>: Abbrev Number: 2 (DW_TAG_array_type) <49> DW_AT_type: <0x39> <4d> DW_AT_sibling : <0x58> <2><51>: Abbrev Number: 7 (DW_TAG_subrange_type) <52> DW_AT_type: <0x5d> <56> DW_AT_upper_bound : 6 <2><57>: Abbrev Number: 0 <1><58>: Abbrev Number: 1 (DW_TAG_const_type) <59> DW_AT_type: <0x48> <1><5d>: Abbrev Number: 3 (DW_TAG_base_type) <5e> DW_AT_byte_size : 8 <5f> DW_AT_encoding: 7(unsigned) <60> DW_AT_name: (indirect string, offset: 0x2023): long unsigned int <1><64>: Abbrev Number: 8 (DW_TAG_variable) <65> DW_AT_specification: <0x3e> <69> DW_AT_decl_line : 2 <6a> DW_AT_decl_column : 12 <6b> DW_AT_type: <0x58> <6f> DW_AT_location: 9 byte block: 3 0 0 0 0 0 0 0 0 (DW_OP_addr: 0) <1><79>: Abbrev Number: 0 ## DWARF for testcase 2 with gcc8.4.1 is as follows: <1><21>: Abbrev Number: 2 (DW_TAG_array_type) <22> DW_AT_type: <0x38> <26> DW_AT_sibling : <0x2c> <2><2a>: Abbrev Number: 3 (DW_TAG_subrange_type) <2><2b>: Abbrev Number: 0 <1><2c>: Abbrev Number: 4 (DW_TAG_const_type) <2d> DW_AT_type: <0x21> <1><31>: Abbrev Number: 5 (DW_TAG_base_type) <32> DW_AT_byte_size : 1 <33> DW_AT_encoding: 6(signed char) <34> DW_AT_name: (indirect string, offset: 0x1e04): char <1><38>: Abbrev Number: 4 (DW_TAG_const_type) <39> DW_AT_type: <0x31> <1><3d>: Abbrev Number: 6 (DW_TAG_variable) <3e> DW_AT_name: a <40> DW_AT_decl_file : 1 <41> DW_AT_decl_line : 1 <42> DW_AT_decl_column : 19 <43> DW_AT_type: <0x2c> <47> DW_AT_external: 1 <47> DW_AT_declaration : 1 <1><47>: Abbrev Number: 5 (DW_TAG_base_type) <48> DW_AT_byte_size : 8 <49> DW_AT_encoding: 7(unsigned) <4a> DW_AT_name: (indirect string, offset: 0x1df2): long unsigned int <1><4e>: Abbrev Number: 7 (DW_TAG_variable) <4f> DW_AT_specification: <0x3d> <53> DW_AT_decl_line : 2 <54> DW_AT_decl_column : 12 <55> DW_AT_location: 9 byte block: 3 0 0 0 0 0 0 0 0 (DW_OP_addr: 0) <1><5f>: Abbrev Number: 0 Thanks Indu
Re: [PATCH, V2 2/3] targhooks: New target hook for CTF/BTF debug info emission
On 8/18/21 12:00 AM, Richard Biener wrote: On Tue, Aug 17, 2021 at 7:26 PM Indu Bhagat wrote: On 8/17/21 1:04 AM, Richard Biener wrote: On Mon, Aug 16, 2021 at 7:39 PM Indu Bhagat wrote: On 8/10/21 4:54 AM, Richard Biener wrote: On Thu, Aug 5, 2021 at 2:52 AM Indu Bhagat via Gcc-patches wrote: This patch adds a new target hook to detect if the CTF container can allow the emission of CTF/BTF debug info at DWARF debug info early finish time. Some backends, e.g., BPF when generating code for CO-RE usecase, may need to emit the CTF/BTF debug info sections around the time when late DWARF debug is finalized (dwarf2out_finish). Without looking at the dwarf2out.c usage in the next patch - I think the CTF part should be always emitted from dwarf2out_early_finish, the "hooks" should somehow arrange for the alternate output specific data to be preserved until dwarf2out_finish time so the late BTF data can be emitted from there. Lumping everything together now just makes it harder to see what info is required to persist and thus make LTO support more intrusive than necessary. In principle, I agree the approach to split generate/emit CTF/BTF like you mention is ideal. But, the BTF CO-RE relocations format is such that the .BTF section cannot be finalized until .BTF.ext contents are all fully known (David Faust summarizes this issue in the other thread "[PATCH, V2 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase".) In summary, the .BTF.ext section refers to strings in the .BTF section. These strings are added at the time the CO-RE relocations are added. Recall that the .BTF section's header has information about the .BTF string table start offset and length. So, this means the "CTF part" (or the .BTF section) cannot simply be emitted in the dwarf2out_early_finish because it's not ready yet. If it is still unclear, please let me know. My judgement here is that the BTF format itself is not amenable to split early/late emission like DWARF. BTF has no linker support yet either. But are the strings used for the CO-RE relocations not all present already? Or does the "CTF part" have only "foo", "bar" and "baz" while the CO-RE part wants to output sth like "foo->bar.baz" (which IMHO would be quite stupid also for size purposes)? Yes, the latter ("foo->bar.baz") is closer to what the format does for CO-RE relocations! That said, fix the format. Alternatively hand the CO-RE part its own string table (what's the fuss with re-using the CTF string table if there's nothing to share ...) BTF and .BTF.ext formats are specified already by implementations in the kernel, libbpf, and LLVM. For that matter, I should add BPF CO-RE to the mix and say that BPF CO-RE capability _and_ .BTF/.BTF.ext debug formats have been defined already by the BPF kernel developers/associated entities. At this time, we as GCC developers simply extending the BPF backend/BTF generation support in GCC, cannot fix the format. That ship has sailed. Hmm, well. How about emitting .BTF.ext.string from GCC and have the linker merge the .BTF.ext.string section with the CTF string section then? You can't really say "the ship has sailed" if I read the CTF webpage - there seems to be many format changes planned. BTF originated from CTF long ago. These are two distinct formats and have their own independent evolution trail with specific use-cases. It's true that CTF format has changes planned for V4 and it's open for folks to give feedback or get involved. But BTF will not be a direct benefactor of any of those changes, as BPF/BTF ecosystem is evolving elsewhere (hopefully for the better). Well. Guess that was it from my side on the topic of ranting about the not well thought out debug format ;) Richard. Thanks for reviewing and voicing your concerns. Indu Richard. gcc/ChangeLog: * config/bpf/bpf.c (ctfc_debuginfo_early_finish_p): New definition. (TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P): Undefine and override. * doc/tm.texi: Regenerated. * doc/tm.texi.in: Document the new hook. * target.def: Add a new hook. * targhooks.c (default_ctfc_debuginfo_early_finish_p): Likewise. * targhooks.h (default_ctfc_debuginfo_early_finish_p): Likewise. --- gcc/config/bpf/bpf.c | 14 ++ gcc/doc/tm.texi | 6 ++ gcc/doc/tm.texi.in | 2 ++ gcc/target.def | 10 ++ gcc/targhooks.c | 6 ++ gcc/targhooks.h | 2 ++ 6 files changed, 40 insertions(+) diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c index 028013e..85f6b76 100644 --- a/gcc/config/bpf/bpf.c +++ b/gcc/config/bpf/bpf.c @@ -178,6 +178,20 @@ bpf_option_override (void) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE bpf_option_override +/* Return FALSE iff -mcore has been specif
Re: [PATCH, V2 2/3] targhooks: New target hook for CTF/BTF debug info emission
On 8/17/21 1:04 AM, Richard Biener wrote: On Mon, Aug 16, 2021 at 7:39 PM Indu Bhagat wrote: On 8/10/21 4:54 AM, Richard Biener wrote: On Thu, Aug 5, 2021 at 2:52 AM Indu Bhagat via Gcc-patches wrote: This patch adds a new target hook to detect if the CTF container can allow the emission of CTF/BTF debug info at DWARF debug info early finish time. Some backends, e.g., BPF when generating code for CO-RE usecase, may need to emit the CTF/BTF debug info sections around the time when late DWARF debug is finalized (dwarf2out_finish). Without looking at the dwarf2out.c usage in the next patch - I think the CTF part should be always emitted from dwarf2out_early_finish, the "hooks" should somehow arrange for the alternate output specific data to be preserved until dwarf2out_finish time so the late BTF data can be emitted from there. Lumping everything together now just makes it harder to see what info is required to persist and thus make LTO support more intrusive than necessary. In principle, I agree the approach to split generate/emit CTF/BTF like you mention is ideal. But, the BTF CO-RE relocations format is such that the .BTF section cannot be finalized until .BTF.ext contents are all fully known (David Faust summarizes this issue in the other thread "[PATCH, V2 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase".) In summary, the .BTF.ext section refers to strings in the .BTF section. These strings are added at the time the CO-RE relocations are added. Recall that the .BTF section's header has information about the .BTF string table start offset and length. So, this means the "CTF part" (or the .BTF section) cannot simply be emitted in the dwarf2out_early_finish because it's not ready yet. If it is still unclear, please let me know. My judgement here is that the BTF format itself is not amenable to split early/late emission like DWARF. BTF has no linker support yet either. But are the strings used for the CO-RE relocations not all present already? Or does the "CTF part" have only "foo", "bar" and "baz" while the CO-RE part wants to output sth like "foo->bar.baz" (which IMHO would be quite stupid also for size purposes)? Yes, the latter ("foo->bar.baz") is closer to what the format does for CO-RE relocations! That said, fix the format. Alternatively hand the CO-RE part its own string table (what's the fuss with re-using the CTF string table if there's nothing to share ...) BTF and .BTF.ext formats are specified already by implementations in the kernel, libbpf, and LLVM. For that matter, I should add BPF CO-RE to the mix and say that BPF CO-RE capability _and_ .BTF/.BTF.ext debug formats have been defined already by the BPF kernel developers/associated entities. At this time, we as GCC developers simply extending the BPF backend/BTF generation support in GCC, cannot fix the format. That ship has sailed. Thanks for reviewing and voicing your concerns. Indu Richard. gcc/ChangeLog: * config/bpf/bpf.c (ctfc_debuginfo_early_finish_p): New definition. (TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P): Undefine and override. * doc/tm.texi: Regenerated. * doc/tm.texi.in: Document the new hook. * target.def: Add a new hook. * targhooks.c (default_ctfc_debuginfo_early_finish_p): Likewise. * targhooks.h (default_ctfc_debuginfo_early_finish_p): Likewise. --- gcc/config/bpf/bpf.c | 14 ++ gcc/doc/tm.texi | 6 ++ gcc/doc/tm.texi.in | 2 ++ gcc/target.def | 10 ++ gcc/targhooks.c | 6 ++ gcc/targhooks.h | 2 ++ 6 files changed, 40 insertions(+) diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c index 028013e..85f6b76 100644 --- a/gcc/config/bpf/bpf.c +++ b/gcc/config/bpf/bpf.c @@ -178,6 +178,20 @@ bpf_option_override (void) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE bpf_option_override +/* Return FALSE iff -mcore has been specified. */ + +static bool +ctfc_debuginfo_early_finish_p (void) +{ + if (TARGET_BPF_CORE) +return false; + else +return true; +} + +#undef TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P +#define TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P ctfc_debuginfo_early_finish_p + /* Define target-specific CPP macros. This function in used in the definition of TARGET_CPU_CPP_BUILTINS in bpf.h */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index cb01528..2d5ff05 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10400,6 +10400,12 @@ Define this macro if GCC should produce debugging output in BTF debug format in response to the @option{-gbtf} option. @end defmac +@deftypefn {Target Hook} bool TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P (void) +This target hook returns nonzero if the CTF Container can allow the + emission of the CTF/BTF debug info at the DWARF debuginfo early finish +
Re: [PATCH, V2 2/3] targhooks: New target hook for CTF/BTF debug info emission
On 8/10/21 4:54 AM, Richard Biener wrote: On Thu, Aug 5, 2021 at 2:52 AM Indu Bhagat via Gcc-patches wrote: This patch adds a new target hook to detect if the CTF container can allow the emission of CTF/BTF debug info at DWARF debug info early finish time. Some backends, e.g., BPF when generating code for CO-RE usecase, may need to emit the CTF/BTF debug info sections around the time when late DWARF debug is finalized (dwarf2out_finish). Without looking at the dwarf2out.c usage in the next patch - I think the CTF part should be always emitted from dwarf2out_early_finish, the "hooks" should somehow arrange for the alternate output specific data to be preserved until dwarf2out_finish time so the late BTF data can be emitted from there. Lumping everything together now just makes it harder to see what info is required to persist and thus make LTO support more intrusive than necessary. In principle, I agree the approach to split generate/emit CTF/BTF like you mention is ideal. But, the BTF CO-RE relocations format is such that the .BTF section cannot be finalized until .BTF.ext contents are all fully known (David Faust summarizes this issue in the other thread "[PATCH, V2 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase".) In summary, the .BTF.ext section refers to strings in the .BTF section. These strings are added at the time the CO-RE relocations are added. Recall that the .BTF section's header has information about the .BTF string table start offset and length. So, this means the "CTF part" (or the .BTF section) cannot simply be emitted in the dwarf2out_early_finish because it's not ready yet. If it is still unclear, please let me know. My judgement here is that the BTF format itself is not amenable to split early/late emission like DWARF. BTF has no linker support yet either. gcc/ChangeLog: * config/bpf/bpf.c (ctfc_debuginfo_early_finish_p): New definition. (TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P): Undefine and override. * doc/tm.texi: Regenerated. * doc/tm.texi.in: Document the new hook. * target.def: Add a new hook. * targhooks.c (default_ctfc_debuginfo_early_finish_p): Likewise. * targhooks.h (default_ctfc_debuginfo_early_finish_p): Likewise. --- gcc/config/bpf/bpf.c | 14 ++ gcc/doc/tm.texi | 6 ++ gcc/doc/tm.texi.in | 2 ++ gcc/target.def | 10 ++ gcc/targhooks.c | 6 ++ gcc/targhooks.h | 2 ++ 6 files changed, 40 insertions(+) diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c index 028013e..85f6b76 100644 --- a/gcc/config/bpf/bpf.c +++ b/gcc/config/bpf/bpf.c @@ -178,6 +178,20 @@ bpf_option_override (void) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE bpf_option_override +/* Return FALSE iff -mcore has been specified. */ + +static bool +ctfc_debuginfo_early_finish_p (void) +{ + if (TARGET_BPF_CORE) +return false; + else +return true; +} + +#undef TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P +#define TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P ctfc_debuginfo_early_finish_p + /* Define target-specific CPP macros. This function in used in the definition of TARGET_CPU_CPP_BUILTINS in bpf.h */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index cb01528..2d5ff05 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10400,6 +10400,12 @@ Define this macro if GCC should produce debugging output in BTF debug format in response to the @option{-gbtf} option. @end defmac +@deftypefn {Target Hook} bool TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P (void) +This target hook returns nonzero if the CTF Container can allow the + emission of the CTF/BTF debug info at the DWARF debuginfo early finish + time. +@end deftypefn + @node Floating Point @section Cross Compilation and Floating Point @cindex cross compilation and floating point diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 4a522ae..05b3c2c 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7020,6 +7020,8 @@ Define this macro if GCC should produce debugging output in BTF debug format in response to the @option{-gbtf} option. @end defmac +@hook TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P + @node Floating Point @section Cross Compilation and Floating Point @cindex cross compilation and floating point diff --git a/gcc/target.def b/gcc/target.def index 68a46aa..44e2251 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4016,6 +4016,16 @@ clobbered parts of a register altering the frame register size", machine_mode, (int regno), default_dwarf_frame_reg_mode) +/* Return nonzero if CTF Container can finalize the CTF/BTF emission + at DWARF debuginfo early finish time. */ +DEFHOOK +(ctfc_debuginfo_early_finish_p, + "This target hook returns nonzero if the CTF Container can allow the\n\ + emission of the CTF/BTF debug info at the DWARF debuginfo
[PATCH,V2 1/3] bpf: Add new -mcore option for BPF CO-RE
-mcore in the BPF backend enables code generation for the CO-RE usecase. LTO is disabled for CO-RE compilations. gcc/ChangeLog: * config/bpf/bpf.c (bpf_option_override): For BPF backend, disable LTO support when compiling for CO-RE. * config/bpf/bpf.opt: Add new command line option -mcore. gcc/testsuite/ChangeLog: * gcc.target/bpf/core-lto-1.c: New test. --- gcc/config/bpf/bpf.c | 15 +++ gcc/config/bpf/bpf.opt| 4 gcc/testsuite/gcc.target/bpf/core-lto-1.c | 9 + 3 files changed, 28 insertions(+) create mode 100644 gcc/testsuite/gcc.target/bpf/core-lto-1.c diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c index e635f9e..028013e 100644 --- a/gcc/config/bpf/bpf.c +++ b/gcc/config/bpf/bpf.c @@ -158,6 +158,21 @@ bpf_option_override (void) { /* Set the initializer for the per-function status structure. */ init_machine_status = bpf_init_machine_status; + + /* To support the portability needs of BPF CO-RE approach, BTF debug + information includes the BPF CO-RE relocations. The information + necessary for these relocations is added to the CTF container by the + BPF backend. Enabling LTO poses challenges in the generation of the BPF + CO-RE relocations because if LTO is in effect, they need to be + generated late in the LTO link phase. This in turn means the compiler + needs to provide means to combine the early and late BTF debug info, + similar to DWARF debug info. + + In any case, in absence of linker support for BTF sections at this time, + it is acceptable to simply disallow LTO for BPF CO-RE compilations. */ + + if (flag_lto && TARGET_BPF_CORE) +error ("BPF CO-RE does not support LTO"); } #undef TARGET_OPTION_OVERRIDE diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt index 916b53c..e8926f5 100644 --- a/gcc/config/bpf/bpf.opt +++ b/gcc/config/bpf/bpf.opt @@ -127,3 +127,7 @@ Generate little-endian eBPF. mframe-limit= Target Joined RejectNegative UInteger IntegerRange(0, 32767) Var(bpf_frame_limit) Init(512) Set a hard limit for the size of each stack frame, in bytes. + +mcore +Target Mask(BPF_CORE) +Generate all necessary information for BPF Compile Once - Run Everywhere. diff --git a/gcc/testsuite/gcc.target/bpf/core-lto-1.c b/gcc/testsuite/gcc.target/bpf/core-lto-1.c new file mode 100644 index 000..a90dc5b --- /dev/null +++ b/gcc/testsuite/gcc.target/bpf/core-lto-1.c @@ -0,0 +1,9 @@ +/* Test -mcore with -flto. + + -mcore is used to generate information for BPF CO-RE usecase. To support + the generataion of the .BTF and .BTF.ext sections in GCC, -flto is disabled + with -mcore. */ + +/* { dg-do compile } */ +/* { dg-error "BPF CO-RE does not support LTO" "" { target bpf-*-* } 0 } */ +/* { dg-options "-gbtf -mcore -flto" } */ -- 1.8.3.1
[PATCH, V2 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase
DWARF generation is split between early and late phases when LTO is in effect. This poses challenges for CTF/BTF generation especially if late debug info generation is desirable, as turns out to be the case for BPF CO-RE. In case of BPF CO-RE, the BPF backend adds information about CO-RE relocations to the CTF container. This information is what needs to be emitted as a separate .BTF.ext section when -more is in effect. Further, each CO-RE relocation record holds an offset to a string specifying the access to the structure's field. This means that .BTF string table needs to be modified "late" in the compilation process. In other words, this implies that the BTF sections cannot be finalized in dwarf2out_early_finish when -mcore for the BPF backend is in effect. Now, the emission of CTF/BTF debug info cannot be moved unconditionally to dwarf2out_finish because dwarf2out_finish is not invoked at all for the LTO compile phase for slim LTO objects, thus breaking CTF/BTF generation for other targets when used with LTO. The approach taken here in this patch is that - 1. LTO is disabled for BPF CO-RE The reason to disable LTO for BPF CO-RE is that if LTO is in effect, BPF CO-RE relocations need to be generated in the LTO link phase _after_ the optimizations are done. This means we need to devise way to combine early and late BTF. At this time, in absence of linker support for BTF sections, it makes sense to steer clear of LTO for BPF CO-RE and bypass the issue. 2. Use a target hook to allow BPF backend to cleanly convey the case when late finalization of the CTF container is desirable. So, in other words, dwarf2out_early_finish - Always emit CTF here. - if (BTF && ctfc_debuginfo_early_finish_p), emit BTF now. dwarf2out_finish - if (BTF && !ctfc_debuginfo_early_finish_p && !in_lto_p) emit BTF now. - Use of in_lto_p to make sure LTO link phase does not affect BTF sections for other targets. gcc/ChangeLog: * dwarf2ctf.c (ctf_debug_finalize): Make it static. (ctf_debug_early_finish): New definition. (ctf_debug_finish): Likewise. * dwarf2ctf.h (ctf_debug_finalize): Remove declaration. (ctf_debug_early_finish): New declaration. (ctf_debug_finish): Likewise. * dwarf2out.c (dwarf2out_finish): Invoke ctf_debug_finish. (dwarf2out_early_finish): Invoke ctf_debug_early_finish. --- gcc/dwarf2ctf.c | 55 +++ gcc/dwarf2ctf.h | 4 +++- gcc/dwarf2out.c | 9 +++-- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/gcc/dwarf2ctf.c b/gcc/dwarf2ctf.c index 5e8a725..0fa429c 100644 --- a/gcc/dwarf2ctf.c +++ b/gcc/dwarf2ctf.c @@ -917,6 +917,27 @@ gen_ctf_type (ctf_container_ref ctfc, dw_die_ref die) return type_id; } +/* Prepare for output and write out the CTF debug information. */ + +static void +ctf_debug_finalize (const char *filename, bool btf) +{ + if (btf) +{ + btf_output (filename); + btf_finalize (); +} + + else +{ + /* Emit the collected CTF information. */ + ctf_output (filename); + + /* Reset the CTF state. */ + ctf_finalize (); +} +} + bool ctf_do_die (dw_die_ref die) { @@ -966,25 +987,35 @@ ctf_debug_init_postprocess (bool btf) btf_init_postprocess (); } -/* Prepare for output and write out the CTF debug information. */ +/* Early finish CTF/BTF debug info. */ void -ctf_debug_finalize (const char *filename, bool btf) +ctf_debug_early_finish (const char * filename) { - if (btf) + /* Emit CTF debug info early always. */ + if (ctf_debug_info_level > CTFINFO_LEVEL_NONE + /* Emit BTF debug info early if the target does not require late +emission. */ + || (btf_debuginfo_p () + && targetm.ctfc_debuginfo_early_finish_p ())) { - btf_output (filename); - btf_finalize (); + /* Emit CTF/BTF debug info. */ + ctf_debug_finalize (filename, btf_debuginfo_p ()); } +} - else -{ - /* Emit the collected CTF information. */ - ctf_output (filename); +/* Finish CTF/BTF debug info emission. */ - /* Reset the CTF state. */ - ctf_finalize (); -} +void +ctf_debug_finish (const char * filename) +{ + /* Emit BTF debug info here when the target needs to update the CTF container + (ctfc) in the backend. An example of this, at this time is the BPF CO-RE + usecase. */ + if (btf_debuginfo_p () + && (!in_lto_p && !targetm.ctfc_debuginfo_early_finish_p ())) +/* Emit BTF debug info. */ +ctf_debug_finalize (filename, btf_debuginfo_p ()); } #include "gt-dwarf2ctf.h" diff --git a/gcc/dwarf2ctf.h b/gcc/dwarf2ctf.h index a3cf567..9edbde0 100644 --- a/gcc/dwarf2ctf.h +++ b/gcc/dwarf2ctf.h @@ -24,13 +24,15 @@ along with GCC; see the file COPYING3. If not see #define GCC_DWARF2CTF_H 1 #include "dwarf2out.h" +#include "flags.h" /* Debug Format Interface. Used in dwarf2out.c. */ extern void ctf_debug_init
[PATCH, V2 2/3] targhooks: New target hook for CTF/BTF debug info emission
This patch adds a new target hook to detect if the CTF container can allow the emission of CTF/BTF debug info at DWARF debug info early finish time. Some backends, e.g., BPF when generating code for CO-RE usecase, may need to emit the CTF/BTF debug info sections around the time when late DWARF debug is finalized (dwarf2out_finish). gcc/ChangeLog: * config/bpf/bpf.c (ctfc_debuginfo_early_finish_p): New definition. (TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P): Undefine and override. * doc/tm.texi: Regenerated. * doc/tm.texi.in: Document the new hook. * target.def: Add a new hook. * targhooks.c (default_ctfc_debuginfo_early_finish_p): Likewise. * targhooks.h (default_ctfc_debuginfo_early_finish_p): Likewise. --- gcc/config/bpf/bpf.c | 14 ++ gcc/doc/tm.texi | 6 ++ gcc/doc/tm.texi.in | 2 ++ gcc/target.def | 10 ++ gcc/targhooks.c | 6 ++ gcc/targhooks.h | 2 ++ 6 files changed, 40 insertions(+) diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c index 028013e..85f6b76 100644 --- a/gcc/config/bpf/bpf.c +++ b/gcc/config/bpf/bpf.c @@ -178,6 +178,20 @@ bpf_option_override (void) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE bpf_option_override +/* Return FALSE iff -mcore has been specified. */ + +static bool +ctfc_debuginfo_early_finish_p (void) +{ + if (TARGET_BPF_CORE) +return false; + else +return true; +} + +#undef TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P +#define TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P ctfc_debuginfo_early_finish_p + /* Define target-specific CPP macros. This function in used in the definition of TARGET_CPU_CPP_BUILTINS in bpf.h */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index cb01528..2d5ff05 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10400,6 +10400,12 @@ Define this macro if GCC should produce debugging output in BTF debug format in response to the @option{-gbtf} option. @end defmac +@deftypefn {Target Hook} bool TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P (void) +This target hook returns nonzero if the CTF Container can allow the + emission of the CTF/BTF debug info at the DWARF debuginfo early finish + time. +@end deftypefn + @node Floating Point @section Cross Compilation and Floating Point @cindex cross compilation and floating point diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 4a522ae..05b3c2c 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7020,6 +7020,8 @@ Define this macro if GCC should produce debugging output in BTF debug format in response to the @option{-gbtf} option. @end defmac +@hook TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P + @node Floating Point @section Cross Compilation and Floating Point @cindex cross compilation and floating point diff --git a/gcc/target.def b/gcc/target.def index 68a46aa..44e2251 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4016,6 +4016,16 @@ clobbered parts of a register altering the frame register size", machine_mode, (int regno), default_dwarf_frame_reg_mode) +/* Return nonzero if CTF Container can finalize the CTF/BTF emission + at DWARF debuginfo early finish time. */ +DEFHOOK +(ctfc_debuginfo_early_finish_p, + "This target hook returns nonzero if the CTF Container can allow the\n\ + emission of the CTF/BTF debug info at the DWARF debuginfo early finish\n\ + time.", + bool, (void), + default_ctfc_debuginfo_early_finish_p) + /* If expand_builtin_init_dwarf_reg_sizes needs to fill in table entries not corresponding directly to registers below FIRST_PSEUDO_REGISTER, this hook should generate the necessary diff --git a/gcc/targhooks.c b/gcc/targhooks.c index eb51909..e38566c 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -2112,6 +2112,12 @@ default_dwarf_frame_reg_mode (int regno) return save_mode; } +bool +default_ctfc_debuginfo_early_finish_p (void) +{ + return true; +} + /* To be used by targets where reg_raw_mode doesn't return the right mode for registers used in apply_builtin_return and apply_builtin_arg. */ diff --git a/gcc/targhooks.h b/gcc/targhooks.h index f92e102..55dc443 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -255,6 +255,8 @@ extern unsigned int default_dwarf_poly_indeterminate_value (unsigned int, unsigned int *, int *); extern machine_mode default_dwarf_frame_reg_mode (int); +extern bool default_ctfc_debuginfo_early_finish_p (void); + extern fixed_size_mode default_get_reg_raw_mode (int); extern bool default_keep_leaf_when_profiled (); -- 1.8.3.1
[PATCH,V2 0/3] Allow means for late BTF generation for BPF CO-RE
[Changes from V1] - [1/3] bpf: Add new -mcore option for BPF CO-RE Moved the testcase from gcc.dg/debug/btf/ to gcc.target/bpf/. Adjusted the testcase a bit. - targhooks: New target hook for CTF/BTF debug info emission (Same as V1) - dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase Moved the call to ctf_debug_finish (in dwarf2out_finish) before the point of early exit taken when dwarf_debuginfo_p () is false. [End of Changes from V1] Hello, This patch series puts the framework in place for late BTF generation (in dwarf2out_finish). This is needed for the landing of BPF CO-RE support in GCC, patches for which were posted recently https://gcc.gnu.org/pipermail/gcc-patches/2021-August/576719.html. BPF's Compile Once - Run Everywhere (CO-RE) feature is used to make a compiled BPF program portable across kernel versions, all this without the need to recompile the BPF program. A key part of BPF CO-RE capability is the BTF debug info generated for them. A traditional BPF program (non CO-RE) will have a .BTF section which contains the type information in the BTF debug format. In case of CO-RE, however, an additional section .BTF.ext section is generated. The .BTF.ext section contains the CO-RE relocations. A BPF loader will use the .BTF.ext section along with the associated .BTF.ext section to adjust some references in the instructions of program to ensure it is compatible with the required kernel version / headers. Roughly, each CO-RE relocation record will contain the following info - offset of BPF instruction to be patched - the BTF ID of the data structure being accessed by the instruction, and - an offset to the BTF string which encodes a series of field accesses to retrieve the field of interest in the instruction. High-level design - - The CTF container is populated with the compiler-internal representation for the "type information" at dwarf2out_early_finish time. - In case of CO-RE compilation, the information needed to generate .BTF.ext section is added by the BPF backend to the CTF container (CTFC) at XXX time. This introduces challenges in having LTO support for CO-RE - CO-RE relocations can only be generated late, much like late DWARF. - Combining late and early BTF is not being done as the patch set disables LTO to be used together with CO-RE for the BPF target. - A new target hook is added for the CTFC (CTF Container) to know whether early emission of CTF/BTF is allowed for the target. Testing Notes - Bootstrapped and reg tested on x86_64 - make all-gcc for --target=bpf-unknown-none; tested ctf.exp, btf.exp and bpf.exp Thanks, Indu Bhagat (3): bpf: Add new -mcore option for BPF CO-RE targhooks: New target hook for CTF/BTF debug info emission dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase gcc/config/bpf/bpf.c | 29 gcc/config/bpf/bpf.opt| 4 +++ gcc/doc/tm.texi | 6 gcc/doc/tm.texi.in| 2 ++ gcc/dwarf2ctf.c | 55 --- gcc/dwarf2ctf.h | 4 ++- gcc/dwarf2out.c | 9 +++-- gcc/target.def| 10 ++ gcc/targhooks.c | 6 gcc/targhooks.h | 2 ++ gcc/testsuite/gcc.target/bpf/core-lto-1.c | 9 + 11 files changed, 121 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.target/bpf/core-lto-1.c -- 1.8.3.1
[PATCH 2/3] targhooks: New target hook for CTF/BTF debug info emission
This patch adds a new target hook to detect if the CTF container can allow the emission of CTF/BTF debug info at DWARF debug info early finish time. Some backends, e.g., BPF when generating code for CO-RE usecase, may need to emit the CTF/BTF debug info sections around the time when late DWARF debug is finalized (dwarf2out_finish). gcc/ChangeLog: * config/bpf/bpf.c (ctfc_debuginfo_early_finish_p): New definition. (TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P): Undefine and override. * doc/tm.texi: Regenerated. * doc/tm.texi.in: Document the new hook. * target.def: Add a new hook. * targhooks.c (default_ctfc_debuginfo_early_finish_p): Likewise. * targhooks.h (default_ctfc_debuginfo_early_finish_p): Likewise. --- gcc/config/bpf/bpf.c | 14 ++ gcc/doc/tm.texi | 6 ++ gcc/doc/tm.texi.in | 2 ++ gcc/target.def | 10 ++ gcc/targhooks.c | 6 ++ gcc/targhooks.h | 2 ++ 6 files changed, 40 insertions(+) diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c index 028013e..85f6b76 100644 --- a/gcc/config/bpf/bpf.c +++ b/gcc/config/bpf/bpf.c @@ -178,6 +178,20 @@ bpf_option_override (void) #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE bpf_option_override +/* Return FALSE iff -mcore has been specified. */ + +static bool +ctfc_debuginfo_early_finish_p (void) +{ + if (TARGET_BPF_CORE) +return false; + else +return true; +} + +#undef TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P +#define TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P ctfc_debuginfo_early_finish_p + /* Define target-specific CPP macros. This function in used in the definition of TARGET_CPU_CPP_BUILTINS in bpf.h */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index a464d26..df408ee 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10400,6 +10400,12 @@ Define this macro if GCC should produce debugging output in BTF debug format in response to the @option{-gbtf} option. @end defmac +@deftypefn {Target Hook} bool TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P (void) +This target hook returns nonzero if the CTF Container can allow the + emission of the CTF/BTF debug info at the DWARF debuginfo early finish + time. +@end deftypefn + @node Floating Point @section Cross Compilation and Floating Point @cindex cross compilation and floating point diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 0b60342..6119a30 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -7020,6 +7020,8 @@ Define this macro if GCC should produce debugging output in BTF debug format in response to the @option{-gbtf} option. @end defmac +@hook TARGET_CTFC_DEBUGINFO_EARLY_FINISH_P + @node Floating Point @section Cross Compilation and Floating Point @cindex cross compilation and floating point diff --git a/gcc/target.def b/gcc/target.def index 6b4226c..67bdcba 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4007,6 +4007,16 @@ clobbered parts of a register altering the frame register size", machine_mode, (int regno), default_dwarf_frame_reg_mode) +/* Return nonzero if CTF Container can finalize the CTF/BTF emission + at DWARF debuginfo early finish time. */ +DEFHOOK +(ctfc_debuginfo_early_finish_p, + "This target hook returns nonzero if the CTF Container can allow the\n\ + emission of the CTF/BTF debug info at the DWARF debuginfo early finish\n\ + time.", + bool, (void), + default_ctfc_debuginfo_early_finish_p) + /* If expand_builtin_init_dwarf_reg_sizes needs to fill in table entries not corresponding directly to registers below FIRST_PSEUDO_REGISTER, this hook should generate the necessary diff --git a/gcc/targhooks.c b/gcc/targhooks.c index eb51909..e38566c 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -2112,6 +2112,12 @@ default_dwarf_frame_reg_mode (int regno) return save_mode; } +bool +default_ctfc_debuginfo_early_finish_p (void) +{ + return true; +} + /* To be used by targets where reg_raw_mode doesn't return the right mode for registers used in apply_builtin_return and apply_builtin_arg. */ diff --git a/gcc/targhooks.h b/gcc/targhooks.h index f92e102..55dc443 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -255,6 +255,8 @@ extern unsigned int default_dwarf_poly_indeterminate_value (unsigned int, unsigned int *, int *); extern machine_mode default_dwarf_frame_reg_mode (int); +extern bool default_ctfc_debuginfo_early_finish_p (void); + extern fixed_size_mode default_get_reg_raw_mode (int); extern bool default_keep_leaf_when_profiled (); -- 1.8.3.1
[PATCH 1/3] bpf: Add new -mcore option for BPF CO-RE
-mcore in the BPF backend enables code generation for the CO-RE usecase. LTO is disabled for CO-RE compilations. gcc/ChangeLog: * config/bpf/bpf.c (bpf_option_override): For BPF backend, disable LTO support when compiling for CO-RE. * config/bpf/bpf.opt: Add new command line option -mcore. gcc/testsuite/ChangeLog: * gcc.dg/debug/btf/btf-mcore-1.c: New test. --- gcc/config/bpf/bpf.c | 15 +++ gcc/config/bpf/bpf.opt | 4 gcc/testsuite/gcc.dg/debug/btf/btf-mcore-1.c | 14 ++ 3 files changed, 33 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-mcore-1.c diff --git a/gcc/config/bpf/bpf.c b/gcc/config/bpf/bpf.c index e635f9e..028013e 100644 --- a/gcc/config/bpf/bpf.c +++ b/gcc/config/bpf/bpf.c @@ -158,6 +158,21 @@ bpf_option_override (void) { /* Set the initializer for the per-function status structure. */ init_machine_status = bpf_init_machine_status; + + /* To support the portability needs of BPF CO-RE approach, BTF debug + information includes the BPF CO-RE relocations. The information + necessary for these relocations is added to the CTF container by the + BPF backend. Enabling LTO poses challenges in the generation of the BPF + CO-RE relocations because if LTO is in effect, they need to be + generated late in the LTO link phase. This in turn means the compiler + needs to provide means to combine the early and late BTF debug info, + similar to DWARF debug info. + + In any case, in absence of linker support for BTF sections at this time, + it is acceptable to simply disallow LTO for BPF CO-RE compilations. */ + + if (flag_lto && TARGET_BPF_CORE) +error ("BPF CO-RE does not support LTO"); } #undef TARGET_OPTION_OVERRIDE diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt index 916b53c..e8926f5 100644 --- a/gcc/config/bpf/bpf.opt +++ b/gcc/config/bpf/bpf.opt @@ -127,3 +127,7 @@ Generate little-endian eBPF. mframe-limit= Target Joined RejectNegative UInteger IntegerRange(0, 32767) Var(bpf_frame_limit) Init(512) Set a hard limit for the size of each stack frame, in bytes. + +mcore +Target Mask(BPF_CORE) +Generate all necessary information for BPF Compile Once - Run Everywhere. diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-mcore-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-mcore-1.c new file mode 100644 index 000..58f20d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-mcore-1.c @@ -0,0 +1,14 @@ +/* Testcase for BPF CO-RE. + + -mcore is used to generate information for BPF CO-RE usecase. To support + the generataion of the .BTF and .BTF.ext sections in GCC, -flto is disabled + with -mcore. */ + +/* { dg-do compile { target bpf-*-* } } */ +/* { dg-error "BPF CO-RE does not support LTO" "" { target btf-*-* } 0 } */ + +/* { dg-require-effective-target lto } */ + +/* { dg-options "-gbtf -mcore -flto" } */ + +void func(void) { } -- 1.8.3.1
[PATCH 0/3] Allow means for late BTF generation for BPF CO-RE
Hello, This patch series puts the framework in place for late BTF generation (in dwarf2out_finish). This is needed for the landing of BPF CO-RE support in GCC. BPF's Compile Once - Run Everywhere (CO-RE) feature is used to make a compiled BPF program portable across kernel versions, all this without the need to recompile the BPF program. A key part of BPF CO-RE capability is the BTF debug info generated for the BPF program. A traditional BPF program (non CO-RE) will have a .BTF section which contains the type information in the BTF debug format. In case of CO-RE, however, an additional section .BTF.ext section is generated. The .BTF.ext section contains the CO-RE relocations. A BPF loader will use the .BTF.ext section along with the associated .BTF section to adjust some references in the instructions of the BPF program to ensure it is compatible with the required kernel version / headers. Roughly, each CO-RE relocation record will contain the following info: - offset of BPF instruction to be patched, - the BTF ID of the data structure being accessed by the instruction, and - an offset to the BTF string which encodes a series of field accesses to retrieve the field of interest in the instruction. High-level design - - The CTF container (CTFC) is populated with the compiler-internal representation for the CTF/BTF "type information" at dwarf2out_early_finish time. - In case of CO-RE compilation, the information needed to generate .BTF.ext section will be added by the BPF backend to the CTF container (CTFC) at expand time. This introduces challenges in having LTO support for CO-RE - CO-RE relocations can only be generated late in the compilation process, much like late DWARF. - While .BTF.ext is a separate section, the format requires that the string encodings of field accesses (in the CO-RE relocation record) are added in the .BTF string table. Recall that .BTF strings are owned by the .BTF section. Hence, this means that .BTF section cannot simply be emitted "early" because the CO-RE relocations records will need to add additional .BTF strings to the .BTF section. - This patch set disables LTO to be used together with CO-RE for the BPF target. Combining late and early BTF is not being done in this patch series. BTF debug info emission for CO-RE compilations is done at dwarf2out_finish time. - A new target hook is added for the CTFC (CTF Container) to know whether early emission of CTF/BTF is allowed for the target. The hook returns false when "-mcore" for the BPF target is in effect. Testing notes - - Bootstrapped and reg tested (make check-gcc) on x86_64-pc-linux. - make all-gcc for --target=bpf-unknown-none. Thanks, Indu Bhagat (3): bpf: Add new -mcore option for BPF CO-RE targhooks: New target hook for CTF/BTF debug info emission dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase gcc/config/bpf/bpf.c | 29 +++ gcc/config/bpf/bpf.opt | 4 ++ gcc/doc/tm.texi | 6 +++ gcc/doc/tm.texi.in | 2 + gcc/dwarf2ctf.c | 55 ++-- gcc/dwarf2ctf.h | 4 +- gcc/dwarf2out.c | 9 - gcc/target.def | 10 + gcc/targhooks.c | 6 +++ gcc/targhooks.h | 2 + gcc/testsuite/gcc.dg/debug/btf/btf-mcore-1.c | 14 +++ 11 files changed, 126 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/debug/btf/btf-mcore-1.c -- 1.8.3.1
[PATCH 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase
DWARF generation is split between early and late phases when LTO is in effect. This poses challenges for CTF/BTF generation especially if late debug info generation is desirable, as turns out to be the case for BPF CO-RE. In case of BPF CO-RE, the BPF backend adds information about CO-RE relocations to the CTF container. This information is what needs to be emitted as a separate .BTF.ext section when -more is in effect. Further, each CO-RE relocation record holds an offset to a string specifying the access to the structure's field. This means that .BTF string table needs to be modified "late" in the compilation process. In other words, this implies that the BTF sections cannot be finalized in dwarf2out_early_finish when -mcore for the BPF backend is in effect. Now, the emission of CTF/BTF debug info cannot be moved unconditionally to dwarf2out_finish because dwarf2out_finish is not invoked at all for the LTO compile phase for slim LTO objects, thus breaking CTF/BTF generation for other targets when used with LTO. The approach taken here in this patch is that - 1. LTO is disabled for BPF CO-RE The reason to disable LTO for BPF CO-RE is that if LTO is in effect, BPF CO-RE relocations need to be generated in the LTO link phase _after_ the optimizations are done. This means we need to devise way to combine early and late BTF. At this time, in absence of linker support for BTF sections, it makes sense to steer clear of LTO for BPF CO-RE and bypass the issue. 2. Use a target hook to allow BPF backend to cleanly convey the case when late finalization of the CTF container is desirable. So, in other words, dwarf2out_early_finish - Always emit CTF here. - if (BTF && ctfc_debuginfo_early_finish_p), emit BTF now. dwarf2out_finish - if (BTF && !ctfc_debuginfo_early_finish_p && !in_lto_p) emit BTF now. - Use of in_lto_p to make sure LTO link phase does not affect BTF sections for other targets. gcc/ChangeLog: * dwarf2ctf.c (ctf_debug_finalize): Make it static. (ctf_debug_early_finish): New definition. (ctf_debug_finish): Likewise. * dwarf2ctf.h (ctf_debug_finalize): Remove declaration. (ctf_debug_early_finish): New declaration. (ctf_debug_finish): Likewise. * dwarf2out.c (dwarf2out_finish): Invoke ctf_debug_finish. (dwarf2out_early_finish): Invoke ctf_debug_early_finish. --- gcc/dwarf2ctf.c | 55 +++ gcc/dwarf2ctf.h | 4 +++- gcc/dwarf2out.c | 9 +++-- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/gcc/dwarf2ctf.c b/gcc/dwarf2ctf.c index 5e8a725..0fa429c 100644 --- a/gcc/dwarf2ctf.c +++ b/gcc/dwarf2ctf.c @@ -917,6 +917,27 @@ gen_ctf_type (ctf_container_ref ctfc, dw_die_ref die) return type_id; } +/* Prepare for output and write out the CTF debug information. */ + +static void +ctf_debug_finalize (const char *filename, bool btf) +{ + if (btf) +{ + btf_output (filename); + btf_finalize (); +} + + else +{ + /* Emit the collected CTF information. */ + ctf_output (filename); + + /* Reset the CTF state. */ + ctf_finalize (); +} +} + bool ctf_do_die (dw_die_ref die) { @@ -966,25 +987,35 @@ ctf_debug_init_postprocess (bool btf) btf_init_postprocess (); } -/* Prepare for output and write out the CTF debug information. */ +/* Early finish CTF/BTF debug info. */ void -ctf_debug_finalize (const char *filename, bool btf) +ctf_debug_early_finish (const char * filename) { - if (btf) + /* Emit CTF debug info early always. */ + if (ctf_debug_info_level > CTFINFO_LEVEL_NONE + /* Emit BTF debug info early if the target does not require late +emission. */ + || (btf_debuginfo_p () + && targetm.ctfc_debuginfo_early_finish_p ())) { - btf_output (filename); - btf_finalize (); + /* Emit CTF/BTF debug info. */ + ctf_debug_finalize (filename, btf_debuginfo_p ()); } +} - else -{ - /* Emit the collected CTF information. */ - ctf_output (filename); +/* Finish CTF/BTF debug info emission. */ - /* Reset the CTF state. */ - ctf_finalize (); -} +void +ctf_debug_finish (const char * filename) +{ + /* Emit BTF debug info here when the target needs to update the CTF container + (ctfc) in the backend. An example of this, at this time is the BPF CO-RE + usecase. */ + if (btf_debuginfo_p () + && (!in_lto_p && !targetm.ctfc_debuginfo_early_finish_p ())) +/* Emit BTF debug info. */ +ctf_debug_finalize (filename, btf_debuginfo_p ()); } #include "gt-dwarf2ctf.h" diff --git a/gcc/dwarf2ctf.h b/gcc/dwarf2ctf.h index a3cf567..9edbde0 100644 --- a/gcc/dwarf2ctf.h +++ b/gcc/dwarf2ctf.h @@ -24,13 +24,15 @@ along with GCC; see the file COPYING3. If not see #define GCC_DWARF2CTF_H 1 #include "dwarf2out.h" +#include "flags.h" /* Debug Format Interface. Used in dwarf2out.c. */ extern void ctf_debug_init
Re: Clarification on CTF/BTF workings with LTO
On 7/21/21 11:18 PM, Richard Biener wrote: On Wed, 21 Jul 2021, Indu Bhagat wrote: Hello, Wanted to follow up on the CTF/BTF debug info + LTO workings. To summarize, the current status/workflow on trunk is: - The CTF container is written out in the ctfout.c or btfout.c via the ctf_debug_finalize () API. - At this time, the ctf_debug_finalize () itself is called once in dwarf2out_early_finish (). - Until this time, the requirements of CTF and BTF are simple. - The generated .ctf/.BTF sections needs no demarcation of "early"/"late" debug. All of it can be generated "early". - The generated .ctf/.BTF information does not need to be different for the final assembly and the fat LTO IR. - The BPF CO-RE is not yet implemented on trunk. Writing out the CTF/BTF at dwarf2out_early_finish seems to work - there will always be a .ctf/.BTF section whether it's fat or slim LTO objects (because the emission is still in dwarf2out_early_finish on the trunk). And we have functionality to copy over the .ctf/.BTF debug sections in handle_lto_debug_sections (). However, reading through some of the past emails on the CTF/BTF patch series, it seems that you have been pointing to the CTF/BTF debug info generation being broken when used with LTO. If true, I am most certainly missing some key point here. So, before we move to the next steps of supporting additional requirements of BPF CO-RE etc., I would like to make sure that my current understanding is OK and that the current state of CTF/BTF on trunk is functional -with LTO-. I have tested some bits (with and without fat objects on x86_64) and have not run into issues. Can you please confirm what you see amiss in the current workings of CTF/BTF with LTO on trunk ? So on the functional level it seems to do something, that is, I see .ctf sections in a LTO linked test program as well as in a non-LTO linked program from fat LTO objects. When I dump the .ctf section with readelf I see type info that looks OK but I don't see any function objects (my test has a main and foo function). It might be an artifact of the readelf version I have (2.36.1) since the same happens w/o LTO. So yes, in principle it should work in case there's only info that needs to be emitted early. ISTR that in the beginning you had pieces emitted from dwarf2out_finish and there my concerns were rooted. For DWARF the "late" data (like anything that needs relocations to symbols or addresses) is emitted from dwarf2out_finish and the LTRANS unit where the info is emitted from does not have the DWARF DIE generated early in memory but instead it knows how to reference it by a symbol + offset relocation. So it generates a DIE like DW_TAG_subprogram DW_AT_abstract_origin $early_debug_symbol + offset DW_AT_low_pc .LC0_begin ... to amend the early DIE with additional information, creating the "concrete" instance of the subprogram, re-using the early generated DIE as "abstract" instance. I understand that CTF doesn't work like this (have relocations or DIE offsets or some such) but you need some late annotation at least for BPF? Correct. At this time, CTF does not have any relocations, or any "late" debug info. And with regards to BTF, there are two usecases that BTF is serving and each have different requirements: - [#1] BTF for any backend (including BPF _but_ excluding BPF CO-RE usecase): This just needs the .BTF section. This is currently being generated at dwarf2out_early_finish just like .ctf - [#2] BTF for the _CO-RE_usecase_of BPF backend: This will be invoked explicitly, by say -mcore, for BPF backend and the generated BTF debug info will include additional .BTF.ext section. This .BTF.ext section contains "CO-RE Relocation" records, each containing offset of BPF instruction to be patched, the BTF type ID of the data structure being accessed by the instruction, and an offset to the BTF string which encodes a series of field accesses to retrieve the field of interest in the instruction. A BPF program loader will use this .BTF.ext along with the associated .BTF and make the necessary changes to facilitate the BPF program to run across kernel versions and headers. More details on this when the patch set for BPF's CO-RE support is posted... So, yes, it is the #2 - BTF generated for CO-RE (Compile Once - Run Everywhere) usecase of BPF which needs bits to be emitted from dwarf2out_finish. The approach to best deal with this requirement is still in the works at this time. Thanks Indu
Clarification on CTF/BTF workings with LTO
Hello, Wanted to follow up on the CTF/BTF debug info + LTO workings. To summarize, the current status/workflow on trunk is: - The CTF container is written out in the ctfout.c or btfout.c via the ctf_debug_finalize () API. - At this time, the ctf_debug_finalize () itself is called once in dwarf2out_early_finish (). - Until this time, the requirements of CTF and BTF are simple. - The generated .ctf/.BTF sections needs no demarcation of "early"/"late" debug. All of it can be generated "early". - The generated .ctf/.BTF information does not need to be different for the final assembly and the fat LTO IR. - The BPF CO-RE is not yet implemented on trunk. Writing out the CTF/BTF at dwarf2out_early_finish seems to work - there will always be a .ctf/.BTF section whether it's fat or slim LTO objects (because the emission is still in dwarf2out_early_finish on the trunk). And we have functionality to copy over the .ctf/.BTF debug sections in handle_lto_debug_sections (). However, reading through some of the past emails on the CTF/BTF patch series, it seems that you have been pointing to the CTF/BTF debug info generation being broken when used with LTO. If true, I am most certainly missing some key point here. So, before we move to the next steps of supporting additional requirements of BPF CO-RE etc., I would like to make sure that my current understanding is OK and that the current state of CTF/BTF on trunk is functional -with LTO-. I have tested some bits (with and without fat objects on x86_64) and have not run into issues. Can you please confirm what you see amiss in the current workings of CTF/BTF with LTO on trunk ? Thanks Indu
[PATCH 2/2] debug: Allow means for targets to opt out of CTF/BTF support
CTF/BTF debug formats can be safely enabled for all ELF-based targets by default in GCC. CTF/BTF debug formats now adopt a similar approach as taken for DWARF debug format via the DWARF2_DEBUGGING_INFO. - By default, CTF/BTF formats can be enabled for all ELF-based targets. - By default, CTF/BTF formats can be disabled for all non ELF-based targets. - If the user passed a -gctf but CTF is not enabled for the target, GCC issues an error to the user (as is done currently with other debug formats) - "target system does not support the 'ctf' debug format". Analogous behavior for -gbtf command line option. A previous commit disabled the CTF and BTF testcases on the AIX platform. This is not necessary now that CTF and BTF debug formats are disabled by default on all non-ELF targets. GCC emits an error message when -gctf/-gbtf is used on such platforms and these tests will be skipped. gcc/Changelog: * config/elfos.h (CTF_DEBUGGING_INFO): New definition. (BTF_DEBUGGING_INFO): Likewise. * doc/tm.texi.in: Document the new macros. * doc/tm.texi: Regenerated. * toplev.c: Guard initialization of debug hooks. gcc/testsuite/Changelog: * gcc.dg/debug/btf/btf.exp: Do not run BTF testsuite if target does not support BTF format. Remove redundant check for AIX. * gcc.dg/debug/ctf/ctf.exp: Do not run CTF testsuite if target does not support CTF format. Remove redundant check for AIX. * lib/gcc-dg.exp: Remove redundant check for AIX. --- gcc/config/elfos.h | 8 gcc/doc/tm.texi| 26 ++ gcc/doc/tm.texi.in | 26 ++ gcc/testsuite/gcc.dg/debug/btf/btf.exp | 16 +--- gcc/testsuite/gcc.dg/debug/ctf/ctf.exp | 16 +--- gcc/testsuite/lib/gcc-dg.exp | 1 - gcc/toplev.c | 11 +-- 7 files changed, 87 insertions(+), 17 deletions(-) diff --git a/gcc/config/elfos.h b/gcc/config/elfos.h index 7a736cc..e5cb487 100644 --- a/gcc/config/elfos.h +++ b/gcc/config/elfos.h @@ -68,6 +68,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define DWARF2_DEBUGGING_INFO 1 +/* All ELF targets can support CTF. */ + +#define CTF_DEBUGGING_INFO 1 + +/* All ELF targets can support BTF. */ + +#define BTF_DEBUGGING_INFO 1 + /* The GNU tools operate better with dwarf2, and it is required by some psABI's. Since we don't have any native tools to be compatible with, default to dwarf2. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 3ad3944..c8f4abe 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -9947,6 +9947,8 @@ This describes how to specify debugging information. * File Names and DBX:: Macros controlling output of file names in DBX format. * DWARF:: Macros for DWARF format. * VMS Debug:: Macros for VMS debug format. +* CTF Debug:: Macros for CTF debug format. +* BTF Debug:: Macros for BTF debug format. @end menu @node All Debuggers @@ -10374,6 +10376,30 @@ behavior is controlled by @code{TARGET_OPTION_OPTIMIZATION} and @code{TARGET_OPTION_OVERRIDE}. @end defmac +@need 2000 +@node CTF Debug +@subsection Macros for CTF Debug Format + +@c prevent bad page break with this line +Here are macros for CTF debug format. + +@defmac CTF_DEBUGGING_INFO +Define this macro if GCC should produce debugging output in CTF debug +format in response to the @option{-gctf} option. +@end defmac + +@need 2000 +@node BTF Debug +@subsection Macros for BTF Debug Format + +@c prevent bad page break with this line +Here are macros for BTF debug format. + +@defmac BTF_DEBUGGING_INFO +Define this macro if GCC should produce debugging output in BTF debug +format in response to the @option{-gbtf} option. +@end defmac + @node Floating Point @section Cross Compilation and Floating Point @cindex cross compilation and floating point diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index f881cda..9c4b501 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -6613,6 +6613,8 @@ This describes how to specify debugging information. * File Names and DBX:: Macros controlling output of file names in DBX format. * DWARF:: Macros for DWARF format. * VMS Debug:: Macros for VMS debug format. +* CTF Debug:: Macros for CTF debug format. +* BTF Debug:: Macros for BTF debug format. @end menu @node All Debuggers @@ -6994,6 +6996,30 @@ behavior is controlled by @code{TARGET_OPTION_OPTIMIZATION} and @code{TARGET_OPTION_OVERRIDE}. @end defmac +@need 2000 +@node CTF Debug +@subsection Macros for CTF Debug Format + +@c prevent bad page break with this line +Here are macros for CTF debug format. + +@defmac CTF_DEBUGGING_INFO +Define this macro if GCC should produce debugging output in CTF debug +format in response to the @option{-gctf} option. +@end defmac + +@need
[PATCH 1/2] debug: Add new function ctf_debuginfo_p
gcc/Changelog: * flags.h (ctf_debuginfo_p): New function declaration. * opts.c (ctf_debuginfo_p): New function definition. --- gcc/flags.h | 4 gcc/opts.c | 8 2 files changed, 12 insertions(+) diff --git a/gcc/flags.h b/gcc/flags.h index 85fd228..afedef0 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -44,6 +44,10 @@ const char * debug_set_names (uint32_t w_symbols); extern bool btf_debuginfo_p (); +/* Return true iff CTF debug info is enabled. */ + +extern bool ctf_debuginfo_p (); + /* Return true iff DWARF2 debug info is enabled. */ extern bool dwarf_debuginfo_p (); diff --git a/gcc/opts.c b/gcc/opts.c index 25282f7..93366e6 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -135,6 +135,14 @@ btf_debuginfo_p () return (write_symbols & BTF_DEBUG); } +/* Return TRUE iff CTF debug info is enabled. */ + +bool +ctf_debuginfo_p () +{ + return (write_symbols & CTF_DEBUG); +} + /* Return TRUE iff dwarf2 debug info is enabled. */ bool -- 1.8.3.1
[PATCH 0/2] Allow means for targets to opt out of CTF/BTF
Hello, Thanks for your feedback on the previous RFC version of this proposal. This patch set is a refined and tested version of the same. - Added changes to tm.texi.in and regenerated tm.texi. - Updated the dejagnu files for redundant checks on AIX platform. Bootstrapped and reg tested on x86_64-pc-linux-gnu and powerpc-ibm-aix7.2.4.0. Thanks, Indu Bhagat (2): debug: Add new function ctf_debuginfo_p debug: Allow means for targets to opt out of CTF/BTF support gcc/config/elfos.h | 8 gcc/doc/tm.texi| 26 ++ gcc/doc/tm.texi.in | 26 ++ gcc/flags.h| 4 gcc/opts.c | 8 gcc/testsuite/gcc.dg/debug/btf/btf.exp | 16 +--- gcc/testsuite/gcc.dg/debug/ctf/ctf.exp | 16 +--- gcc/testsuite/lib/gcc-dg.exp | 1 - gcc/toplev.c | 11 +-- 9 files changed, 99 insertions(+), 17 deletions(-) -- 1.8.3.1
[RFC,PATCH] Allow means for targets to out out of CTF/BTF support
Hello, It was brought up when discussing PR debug/101283 (Several tests fail on Darwin with -gctf/gbtf) that it will be good to provide means for targets to opt out of CTF/BTF support. By and large, it seems to me that CTF/BTF debug formats can be safely enabled for all ELF-based targets by default in GCC. So, at a high level: - By default, CTF/BTF formats can be enabled for all ELF-based targets. - By default, CTF/BTF formats can be disabled for all non ELF-based targets. - If the user passed a -gctf but CTF is not enabled for the target, GCC issues an error to the user (as is done currently with other debug formats) - "target system does not support the 'ctf' debug format". This is a makeshift patch which fulfills the above requirements and is based on the approach taken for DWARF via DWARF2_DEBUGGING_INFO (I still have to see if I need some specific handling in common_handle_option in opts.c). On minimal testing, the patch works as desired on x86_64-pc-linux-gnu and a darwin-based target. My question is - Looking around in config.gcc etc., it seems defining in elfos.h gives targets/platforms means to override it by virtue of the recommended order of # includes in $tm_file. What I cannot say for certain is if this is true in practice ? On first look, I believe this could work fine. What do you think ? If you think this approach could work, I will continue on this track and test/refine the patch. Thanks Indu - gcc/ChangeLog: * config/elfos.h (CTF_DEBUGGING_INFO): New definition. (BTF_DEBUGGING_INFO): Likewise. * toplev.c: Guard initialization of debug hooks. gcc/testsuite/ChangeLog: * gcc.dg/debug/btf/btf.exp: Do not run BTF testsuite if target does not support BTF format. * gcc.dg/debug/ctf/ctf.exp: Do not run CTF testsuite if target does not support CTF format. --- gcc/config/elfos.h | 8 gcc/testsuite/gcc.dg/debug/btf/btf.exp | 11 +-- gcc/testsuite/gcc.dg/debug/ctf/ctf.exp | 11 +-- gcc/toplev.c | 11 +-- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/gcc/config/elfos.h b/gcc/config/elfos.h index 7a736cc..e5cb487 100644 --- a/gcc/config/elfos.h +++ b/gcc/config/elfos.h @@ -68,6 +68,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define DWARF2_DEBUGGING_INFO 1 +/* All ELF targets can support CTF. */ + +#define CTF_DEBUGGING_INFO 1 + +/* All ELF targets can support BTF. */ + +#define BTF_DEBUGGING_INFO 1 + /* The GNU tools operate better with dwarf2, and it is required by some psABI's. Since we don't have any native tools to be compatible with, default to dwarf2. */ diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf.exp b/gcc/testsuite/gcc.dg/debug/btf/btf.exp index e173515..a3e680c 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf.exp +++ b/gcc/testsuite/gcc.dg/debug/btf/btf.exp @@ -39,8 +39,15 @@ if ![info exists DEFAULT_CFLAGS] then { dg-init # Main loop. -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\] ]] \ - "" $DEFAULT_CFLAGS +set comp_output [gcc_target_compile \ +"$srcdir/$subdir/../trivial.c" "trivial.S" assembly \ +"additional_flags=-gbtf"] +if { ! [string match "*: target system does not support the * debug format*" \ +$comp_output] } { +remove-build-file "trivial.S" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\] ]] \ + "" $DEFAULT_CFLAGS +} # All done. dg-finish diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp b/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp index 0b650ed..c53cd8b 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf.exp @@ -39,8 +39,15 @@ if ![info exists DEFAULT_CFLAGS] then { dg-init # Main loop. -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\] ]] \ - "" $DEFAULT_CFLAGS +set comp_output [gcc_target_compile \ +"$srcdir/$subdir/../trivial.c" "trivial.S" assembly \ +"additional_flags=-gctf"] +if { ! [string match "*: target system does not support the * debug format*" \ +$comp_output] } { +remove-build-file "trivial.S" +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\] ]] \ + "" $DEFAULT_CFLAGS +} # All done. dg-finish diff --git a/gcc/toplev.c b/gcc/toplev.c index 43f1f7d..8103812 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1463,8 +1463,15 @@ process_options (void) debug_hooks = _debug_hooks; #endif #ifdef DWARF2_DEBUGGING_INFO - else if (dwarf_debuginfo_p () - || dwarf_based_debuginfo_p ()) + else if (dwarf_debuginfo_p ()) +debug_hooks = _debug_hooks; +#endif +#ifdef CTF_DEBUGGING_INFO + else if (write_symbols & CTF_DEBUG) +debug_hooks = _debug_hooks; +#endif +#ifdef BTF_DEBUGGING_INFO + else if (btf_debuginfo_p ()) debug_hooks = _debug_hooks; #endif #ifdef VMS_DEBUGGING_INFO -- 1.8.3.1
[COMMITTED] BTF testsuite: Remove explicit check on btm_type
[Committed as obvious.] The value of btm_type is the BTF type ID of the referred type. The order in which the BTF types are added can change across platforms and also as the code evolves, hence changing the BTF type ID. As there is no direct and portable method of testing that a BTF type refers to another BTF type of a specific kind, remove the explicit check on btm_type. This patch adjusts the testcase without affecting the test coverage as other testcases already have similar constructs. It also fixes a subset of failures as seen on Darwin. 2021-07-06 Indu Bhagat gcc/testsuite/ChangeLog: PR debug/101283 * gcc.dg/debug/btf/btf-bitfields-3.c: Remove the check on btm_type. --- gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c | 9 ++--- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c index 5e68416..0e00f2b 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-3.c @@ -11,7 +11,6 @@ [2] int 'unsigned int' size=4 offset=0 bits=32 [3] struct 'bitt' size=4 member 'f' type=1 bitfield_size=2 bit_offset=0 - member 'data' type=2 bitfield_size=14 bit_offset=2 */ /* { dg-do compile } */ @@ -19,15 +18,12 @@ /* Enum with 4 members. */ /* { dg-final { scan-assembler-times "\[\t \]0x604\[\t \]+\[^\n\]*btt_info" 1 } } */ -/* Struct with bitfield members, and 2 members. */ -/* { dg-final { scan-assembler-times "\[\t \]0x8402\[\t \]+\[^\n\]*btt_info" 1 } } */ +/* Struct with 1 bitfield member. */ +/* { dg-final { scan-assembler-times "\[\t \]0x8401\[\t \]+\[^\n\]*btt_info" 1 } } */ /* Bitfield "f" points to type ID 1. */ /* { dg-final { scan-assembler-times "\[\t \]0x1\[\t \]+\[^\n\]*btm_type" 1 } } */ -/* Bitfield "data" points to type ID 2. */ -/* { dg-final { scan-assembler-times "\[\t \]0x2\[\t \]+\[^\n\]*btm_type" 1 } } */ - enum foo { BAR = 0, @@ -39,5 +35,4 @@ enum foo struct bitt { enum foo f : 2; - unsigned data : 14; } bitty; -- 1.8.3.1
[COMMITTED] CTF testsuite: Remove explicit check on ctv_typeidx
[Committed as obvious.] The value of ctv_typeidx is the CTF type ID of the data type of the associated variable. The order in which the CTF types are added can change across platforms and also as the code evolves, hence changing the CTF type ID. As there is no direct and portable method of testing that the data type of a CTF variable is of a specific kind, remove the check on ctv_typeidx. This also fixes a subset of failures as seen on Darwin. 2021-07-06 Indu Bhagat gcc/testsuite/ChangeLog: PR debug/101283 * gcc.dg/debug/ctf/ctf-attr-mode-1.c: Remove the check for ctv_typeidx. --- gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c index fc3af03..c4801a7 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-attr-mode-1.c @@ -1,7 +1,10 @@ /* Test CTF generation works well with ((mode)) attribute. In this testcase, CTF should report type of bqi to be an enum and - not an int. */ + not an int. Also, CTF for typedef of enum should exist. However, there + are no direct and portable methods of checking that a CTF type / CTF + variable refers to a specific CTF type, so this testcase merely asserts + for existence of individual CTF records. */ /* { dg-do compile ) */ /* { dg-options "-O0 -gctf -dA" } */ @@ -16,7 +19,5 @@ /* { dg-final { scan-assembler-times "\[\t \]0x2203\[\t \]+\[^\n\]*ctt_info" 1 } } */ /* { dg-final { scan-assembler-times "\[\t \]0x2a00\[\t \]+\[^\n\]*ctt_info" 1 } } */ -/* { dg-final { scan-assembler-times "\[\t \]0x3\[\t \]+\[^\n\]*ctv_typeidx" 1} } */ - typedef enum { B1 = 1, B2 = 2, B3 = 3 } B; B __attribute__ ((mode (QI))) bqi; -- 1.8.3.1
[PATCH] dwarf2ctf: the unit of sou field location is bits [PR101283]
If the value of the DW_AT_data_member_location attribute is constant, the associated unit is bytes. This patch amends incorrect behaviour which was being exercised with -gdwarf-2. This caused some of the failures as noted in PR debug/101283 (specifically the BTF tests involving btm_offset). The testcase ctf-struct-array-2.c was erroneously checking for the value of ctm_offset in number of bytes. The patch fixes the calculation of the field location value for a struct member in dwarf2ctf and adjusts the testcase. This patch also fixes some of the failing tests as noted in PR debug/101283. 2021-07-05 Indu Bhagat PR debug/101283 - Several tests fail on Darwin with -gctf/gbtf gcc/ChangeLog: PR debug/101283 * dwarf2ctf.c (ctf_get_AT_data_member_location): Multiply by 8 to get number of bits. gcc/testsuite/ChangeLog: PR debug/101283 * gcc.dg/debug/ctf/ctf-struct-array-2.c: Adjust the value in the testcase. --- gcc/dwarf2ctf.c | 4 ++-- gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gcc/dwarf2ctf.c b/gcc/dwarf2ctf.c index 08e1252..5e8a725 100644 --- a/gcc/dwarf2ctf.c +++ b/gcc/dwarf2ctf.c @@ -100,13 +100,13 @@ ctf_get_AT_data_member_location (dw_die_ref die) gcc_assert (!descr->dw_loc_oprnd2.v.val_unsigned); gcc_assert (descr->dw_loc_oprnd2.val_class == dw_val_class_unsigned_const); - field_location = descr->dw_loc_oprnd1.v.val_unsigned; + field_location = descr->dw_loc_oprnd1.v.val_unsigned * 8; } else { attr = get_AT (die, DW_AT_data_member_location); if (attr && AT_class (attr) == dw_val_class_const) - field_location = AT_int (attr); + field_location = AT_int (attr) * 8; else field_location = (get_AT_unsigned (die, DW_AT_data_member_location) diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c index 9e698fd..37094b5 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-array-2.c @@ -10,6 +10,6 @@ /* { dg-final { scan-assembler-times "0x1200\[\t \]+\[^\n\]*ctt_info" 1 } } */ /* { dg-final { scan-assembler-times "\[\t \]0x4\[\t \]+\[^\n\]*cta_nelems" 1 } } */ /* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*ctm_offset" 1 } } */ -/* { dg-final { scan-assembler-times "\[\t \]0x4\[\t \]+\[^\n\]*ctm_offset" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x20\[\t \]+\[^\n\]*ctm_offset" 1 } } */ static struct ranges {int from, to;} lim_regs[] = {{ 16, 7}, { 16, 6}, { 20, 7},{ 20, 6}}; -- 1.8.3.1
[COMMITTED] CTF, BTF testsuite: Use -gdwarf-4 for restrict type qualifier [PR101283]
[Committed as obvious.] DWARF DIEs do not contain DW_TAG_restrict_type when DWARF version is 2. CTF/BTF generation feeds off DWARF DIEs, and as such, CTF records of kind CTF_K_RESTRICT cease to be generated when DWARF version is 2. This patch fixes the failure of these testcases on Darwin by using an explicit -gdwarf-4 in the dg-options. This keeps the CTF record generation for restrict type qualifier tested. PR debug/101283 - Several tests fail on Darwin with -gctf/gbtf 2021-07-05 Indu Bhagat gcc/testsuite/ChangeLog: PR debug/101283 * gcc.dg/debug/btf/btf-cvr-quals-1.c: Use -gdwarf-4 on Darwin targets. * gcc.dg/debug/ctf/ctf-cvr-quals-1.c: Likewise. --- gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c | 1 + gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c | 1 + 2 files changed, 2 insertions(+) diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c index 79e9f52..33e2f64 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-cvr-quals-1.c @@ -23,6 +23,7 @@ /* { dg-do compile } */ /* { dg-options "-O0 -gbtf -dA" } */ +/* { dg-options "-O0 -gbtf -gdwarf-4 -dA" { target { *-*-darwin* } } } */ /* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*btf_string" 1 } } */ diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c index 9368d47..0137e9d 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-cvr-quals-1.c @@ -31,6 +31,7 @@ /* { dg-do compile ) */ /* { dg-options "-O0 -gctf -dA" } */ +/* { dg-options "-O0 -gctf -gdwarf-4 -dA" { target { *-*-darwin* } } } */ /* { dg-final { scan-assembler-times "ascii \"int.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */ /* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*ctt_name" 7 } } */ -- 1.8.3.1
[COMMITTED] testsuite: Add missing dg-add-options to CTF testcase ctf-skip-types-4.c
[Noticed this failure on powerpc64. Committed as obvious.] testsuite: Add missing dg-add-options to CTF testcase ctf-skip-types-4.c The test already has the appropriate dg-require-effective-target, but requires the dg-add-options to use the flags needed, if any. This patch fixes the failure of this testcase on powerpc64. 2021-06-30 Indu Bhagat gcc/testsuite/ * gcc.dg/debug/ctf/ctf-skip-types-4.c: Add dg-add-options float64 and float64x. --- gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c index f4374e6..7033121 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-skip-types-4.c @@ -14,6 +14,8 @@ /* { dg-require-effective-target float64 } */ /* { dg-require-effective-target float64x } */ +/* { dg-add-options float64 } */ +/* { dg-add-options float64x } */ _Float64 f64; _Float64x f64x; -- 1.8.3.1
[PATCH] Fix PR testsuite/101269
PR testsuite/101269 - new test case gcc.dg/debug/btf/btf-datasec-1.c fails with its introduction in r12-1852 BTF datasec records for .rodata/.data are expected for now for all targets. For powerpc based targets, use -msdata=none when ilp32 is enabled. 2021-06-30 Indu Bhagat gcc/testsuite/ChangeLog: PR testsuite/101269 * gcc.dg/debug/btf/btf-datasec-1.c: Force -msdata=none with ilp32 for powerpc based targets. --- gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c index 88ae4c4..f809d93 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c @@ -11,6 +11,7 @@ /* { dg-do compile ) */ /* { dg-options "-O0 -gbtf -dA" } */ +/* { dg-options "-O0 -gbtf -dA -msdata=none" { target { { powerpc*-*-* } && ilp32 } } } */ /* Check for two DATASEC entries with vlen 3, and one with vlen 1. */ /* { dg-final { scan-assembler-times "0xf03\[\t \]+\[^\n\]*btt_info" 2 } } */ -- 1.8.3.1
Re: [[PATCH V9] 0/7] Support for the CTF and BTF debug formats
On 6/21/21 7:01 AM, Richard Biener via Gcc-patches wrote: Command line options for debug formats == This implementation adds the following command-line options to select the emission of CTF and BTF: -gctf[123] -gbtf These options mimic the -g[123...] options for DWARF. This involved adding new entries for debug_info_type: CTF_DEBUG- Write CTF debug info. BTF_DEBUG- Write BTF debug info. CTF_AND_DWARF2_DEBUG - Write both CTF and DWARF info. That's probably obsolete info now? Yes, that's correct. Since GCC now supports bitmasks in the write_symbols, defining entries for combination of debug formats like CTF_AND_DWARF2_DEBUG is not necessary. Thanks for pointing it out. Indu
[PATCH,committed] MAINTAINERS: Add myself for write after approval
ChangeLog: 2021-05-31 Indu Bhagat * MAINTAINERS (Write After Approval): Add myself. --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index fbaa183..d80ed8f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -324,6 +324,7 @@ Andrew Benson Daniel Berlin Pat Bernardi Jan Beulich +Indu Bhagat David Billinghurst Tomas Bily Laurynas Biveinis -- 1.8.3.1
[PATCH] PR testsuite/100749 - gcc.dg/pch/valid-1.c fails after r12-949
Hi, This patch fixes the failing pch testcases as observed in PR testsuite/100749. Although the PR mentions powerpc64, the issue exists on other arches but appears to be latent. The issue causing the failure was that the underlying char[] df_set_names is a static var. Multiple calls to 'debug_set_names' with different write_symbols like the in c-family/c-pch.c must entail the use of xstrdup or such to retain a reliable copy of the debug format str containing the names. Bootstrapped, regression tested on x86_64, powepc64 (make check-gcc). Thanks, Indu PR testsuite/100749 - gcc.dg/pch/valid-1.c fails after r12-949 Fix failing pch testcases. Use xstrdup to retain a reliable copy of the debug format str containing the names (df_set_names is a static string var). 2021-05-28 Indu Bhagat gcc/c-family/ChangeLog: * c-pch.c (c_common_valid_pch): Use xstrdup for debug format set names. --- gcc/c-family/c-pch.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gcc/c-family/c-pch.c b/gcc/c-family/c-pch.c index 8f0f760..5da6042 100644 --- a/gcc/c-family/c-pch.c +++ b/gcc/c-family/c-pch.c @@ -255,10 +255,13 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd) if (v.pch_write_symbols != write_symbols && write_symbols != NO_DEBUG) { + char *created_str = xstrdup (debug_set_names (v.pch_write_symbols)); + char *used_str = xstrdup (debug_set_names (write_symbols)); cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: created with '%s' debug info, but used with '%s'", name, - debug_set_names (v.pch_write_symbols), - debug_set_names (write_symbols)); + created_str, used_str); + free (created_str); + free (used_str); return 2; } -- 1.8.3.1
Re: [PATCH,V3 2/2] dwarf: new dwarf_debuginfo_p predicate
On 5/20/21 2:40 AM, Richard Biener wrote: On Thu, May 13, 2021 at 12:52 AM Indu Bhagat via Gcc-patches wrote: [Changes from V2] - Tested build (make all-gcc) of cross compiler for target triplets containing c6x/mips/powerpc and darwin/cygwin. [End of changes from V2] This patch introduces a dwarf_debuginfo_p predicate that abstracts and replaces complex checks on write_symbols. OK. Thanks, Richard. Committed. Thanks, Indu gcc/c-family/ChangeLog: * c-lex.c (init_c_lex): Use dwarf_debuginfo_p. gcc/ChangeLog: * config/c6x/c6x.c (c6x_output_file_unwind): Use dwarf_debuginfo_p. * config/darwin.c (darwin_override_options): Likewise. * config/i386/cygming.h (DBX_REGISTER_NUMBER): Likewise. * config/i386/darwin.h (DBX_REGISTER_NUMBER): Likewise. (DWARF2_FRAME_REG_OUT): Likewise. * config/mips/mips.c (mips_output_filename): Likewise. * config/rs6000/rs6000.c (rs6000_xcoff_declare_function_name): Likewise. (rs6000_dbx_register_number): Likewise. * dbxout.c: Include flags.h. * dwarf2cfi.c (cfi_label_required_p): Likewise. (dwarf2out_do_frame): Likewise. * except.c: Include flags.h. * final.c (dwarf2_debug_info_emitted_p): Likewise. (final_scan_insn_1): Likewise. * flags.h (dwarf_debuginfo_p): New function declaration. * opts.c (dwarf_debuginfo_p): New function definition. * targhooks.c (default_debug_unwind_info): Use dwarf_debuginfo_p. * toplev.c (process_options): Likewise. --- gcc/c-family/c-lex.c | 4 ++-- gcc/config/c6x/c6x.c | 4 ++-- gcc/config/darwin.c| 3 ++- gcc/config/i386/cygming.h | 2 +- gcc/config/i386/darwin.h | 4 ++-- gcc/config/mips/mips.c | 3 ++- gcc/config/rs6000/rs6000.c | 4 ++-- gcc/dbxout.c | 1 + gcc/dwarf2cfi.c| 9 - gcc/except.c | 1 + gcc/final.c| 15 ++- gcc/flags.h| 4 gcc/opts.c | 8 gcc/targhooks.c| 2 +- gcc/toplev.c | 6 ++ 15 files changed, 40 insertions(+), 30 deletions(-) diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c index 1c66ecd..c44e7a1 100644 --- a/gcc/c-family/c-lex.c +++ b/gcc/c-family/c-lex.c @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "stor-layout.h" #include "c-pragma.h" #include "debug.h" +#include "flags.h" #include "file-prefix-map.h" /* remap_macro_filename() */ #include "langhooks.h" #include "attribs.h" @@ -87,8 +88,7 @@ init_c_lex (void) /* Set the debug callbacks if we can use them. */ if ((debug_info_level == DINFO_LEVEL_VERBOSE - && (write_symbols == DWARF2_DEBUG - || write_symbols == VMS_AND_DWARF2_DEBUG)) + && dwarf_debuginfo_p ()) || flag_dump_go_spec != NULL) { cb->define = cb_define; diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c index f9ad1e5..e2011f0 100644 --- a/gcc/config/c6x/c6x.c +++ b/gcc/config/c6x/c6x.c @@ -59,6 +59,7 @@ #include "regrename.h" #include "dumpfile.h" #include "builtins.h" +#include "flags.h" /* This file should be included last. */ #include "target-def.h" @@ -439,8 +440,7 @@ c6x_output_file_unwind (FILE * f) { if (flag_unwind_tables || flag_exceptions) { - if (write_symbols == DWARF2_DEBUG - || write_symbols == VMS_AND_DWARF2_DEBUG) + if (dwarf_debuginfo_p ()) asm_fprintf (f, "\t.cfi_sections .debug_frame, .c6xabi.exidx\n"); else asm_fprintf (f, "\t.cfi_sections .c6xabi.exidx\n"); diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index 5d17391..026c1fb 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see #include "lto-section-names.h" #include "intl.h" #include "optabs.h" +#include "flags.h" /* Fix and Continue. @@ -3348,7 +3349,7 @@ darwin_override_options (void) && generating_for_darwin_version >= 9 && (flag_gtoggle ? (debug_info_level == DINFO_LEVEL_NONE) : (debug_info_level >= DINFO_LEVEL_NORMAL)) - && write_symbols == DWARF2_DEBUG) + && dwarf_debuginfo_p ()) flag_var_tracking_uninit = flag_var_tracking; /* Final check on PCI options; for Darwin these are not dependent on the PIE diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h index cfbca34..ac458cd 100644 --- a/gcc/config/i386/cygming.h +++ b/gcc/config/i386/cygming.h @@ -82,7 +82,7 @@ along with GCC; see the file COPYING3. If not see