Re: [PATCH v4 4/6] btf: add -gprune-btf option

2024-06-24 Thread Indu Bhagat

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

2024-06-05 Thread Indu Bhagat

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

2024-06-05 Thread Indu Bhagat

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

2024-06-05 Thread Indu Bhagat

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

2024-06-05 Thread Indu Bhagat

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

2024-06-05 Thread Indu Bhagat

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

2024-06-05 Thread Indu Bhagat

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

2024-05-03 Thread Indu Bhagat

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

2024-05-03 Thread Indu Bhagat

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

2024-05-03 Thread Indu Bhagat

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

2024-05-03 Thread Indu Bhagat

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

2024-05-03 Thread Indu Bhagat

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

2024-04-11 Thread Indu Bhagat

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

2024-04-11 Thread Indu Bhagat

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

2024-04-11 Thread Indu Bhagat

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

2024-04-10 Thread Indu Bhagat
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

2024-04-10 Thread Indu Bhagat
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

2024-04-10 Thread Indu Bhagat
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]

2024-04-09 Thread Indu Bhagat

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]

2024-04-08 Thread Indu Bhagat

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

2024-03-05 Thread Indu Bhagat
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

2024-03-04 Thread Indu Bhagat
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

2024-03-01 Thread Indu Bhagat

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]

2023-12-19 Thread Indu Bhagat

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

2023-12-05 Thread Indu Bhagat

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

2023-12-05 Thread Indu Bhagat
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

2023-12-05 Thread Indu Bhagat
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

2023-12-05 Thread Indu Bhagat
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]

2023-12-05 Thread Indu Bhagat

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

2023-11-30 Thread Indu Bhagat
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

2023-11-30 Thread Indu Bhagat
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

2023-05-31 Thread Indu Bhagat via Gcc-patches

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

2023-05-31 Thread Indu Bhagat via Gcc-patches

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

2023-05-30 Thread Indu Bhagat via Gcc-patches

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

2023-05-30 Thread Indu Bhagat via Gcc-patches

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

2023-04-06 Thread Indu Bhagat via Gcc-patches
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]

2022-12-13 Thread Indu Bhagat via Gcc-patches

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]

2022-12-12 Thread Indu Bhagat via Gcc-patches

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]

2022-12-12 Thread Indu Bhagat via Gcc-patches

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]

2022-12-12 Thread Indu Bhagat via Gcc-patches

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]

2022-12-08 Thread Indu Bhagat via Gcc-patches

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]

2022-12-08 Thread Indu Bhagat via Gcc-patches

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]

2022-12-08 Thread Indu Bhagat via Gcc-patches

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

2022-10-31 Thread Indu Bhagat via Gcc-patches

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

2022-10-21 Thread Indu Bhagat via Gcc-patches

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

2022-10-18 Thread Indu Bhagat via Gcc-patches

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

2022-10-11 Thread Indu Bhagat via Gcc-patches

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

2022-09-29 Thread Indu Bhagat via Gcc-patches

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]

2022-09-04 Thread Indu Bhagat via Gcc-patches

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

2022-07-26 Thread Indu Bhagat via Gcc-patches

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

2022-07-12 Thread Indu Bhagat via Gcc-patches

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

2022-07-11 Thread Indu Bhagat via Gcc-patches

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

2022-04-07 Thread Indu Bhagat via Gcc-patches

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]

2022-03-30 Thread Indu Bhagat via Gcc-patches
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]

2022-03-30 Thread Indu Bhagat via Gcc-patches
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-30 Thread Indu Bhagat via Gcc-patches
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

2022-03-30 Thread Indu Bhagat via Gcc-patches
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

2022-03-28 Thread Indu Bhagat via Gcc-patches
[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.

2022-01-03 Thread Indu Bhagat via Gcc-patches

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

2021-10-13 Thread Indu Bhagat via Gcc-patches
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 ()

2021-10-05 Thread Indu Bhagat via Gcc-patches
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

2021-09-29 Thread Indu Bhagat via Gcc-patches

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

2021-09-28 Thread Indu Bhagat via Gcc-patches
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

2021-09-28 Thread Indu Bhagat via Gcc-patches
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

2021-09-02 Thread Indu Bhagat via Gcc-patches

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

2021-09-01 Thread Indu Bhagat via Gcc-patches

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

2021-08-31 Thread Indu Bhagat via Gcc-patches
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

2021-08-31 Thread Indu Bhagat via Gcc-patches
-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

2021-08-31 Thread Indu Bhagat via Gcc-patches
[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

2021-08-31 Thread Indu Bhagat via Gcc-patches
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

2021-08-26 Thread Indu Bhagat via Gcc-patches

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

2021-08-24 Thread Indu Bhagat via Gcc-patches

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

2021-08-23 Thread Indu Bhagat via Gcc-patches

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

2021-08-18 Thread Indu Bhagat via Gcc-patches

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

2021-08-17 Thread Indu Bhagat via Gcc-patches

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

2021-08-16 Thread Indu Bhagat via Gcc-patches

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

2021-08-04 Thread Indu Bhagat via Gcc-patches
-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

2021-08-04 Thread Indu Bhagat via Gcc-patches
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

2021-08-04 Thread Indu Bhagat via Gcc-patches
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

2021-08-04 Thread Indu Bhagat via Gcc-patches
[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

2021-07-30 Thread Indu Bhagat via Gcc-patches
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

2021-07-30 Thread Indu Bhagat via Gcc-patches
-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

2021-07-30 Thread Indu Bhagat via Gcc-patches
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

2021-07-30 Thread Indu Bhagat via Gcc-patches
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

2021-07-22 Thread Indu Bhagat via Gcc-patches

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

2021-07-21 Thread Indu Bhagat via Gcc-patches

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

2021-07-17 Thread Indu Bhagat via Gcc-patches
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

2021-07-17 Thread Indu Bhagat via Gcc-patches
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

2021-07-17 Thread Indu Bhagat via Gcc-patches
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

2021-07-08 Thread Indu Bhagat via Gcc-patches
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

2021-07-06 Thread Indu Bhagat via Gcc-patches
[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

2021-07-06 Thread Indu Bhagat via Gcc-patches
[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]

2021-07-05 Thread Indu Bhagat via Gcc-patches
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]

2021-07-05 Thread Indu Bhagat via Gcc-patches
[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

2021-06-30 Thread Indu Bhagat via Gcc-patches
[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

2021-06-30 Thread Indu Bhagat via Gcc-patches
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

2021-06-22 Thread Indu Bhagat via Gcc-patches

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

2021-05-31 Thread Indu Bhagat via Gcc-patches
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

2021-05-29 Thread Indu Bhagat via Gcc-patches
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

2021-05-20 Thread Indu Bhagat via Gcc-patches

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

  1   2   >