public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Allow means for late BTF generation for BPF CO-RE
@ 2021-07-30 20:12 Indu Bhagat
  2021-07-30 20:12 ` [PATCH 1/3] bpf: Add new -mcore option " Indu Bhagat
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Indu Bhagat @ 2021-07-30 20:12 UTC (permalink / raw)
  To: 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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] bpf: Add new -mcore option for BPF CO-RE
  2021-07-30 20:12 [PATCH 0/3] Allow means for late BTF generation for BPF CO-RE Indu Bhagat
@ 2021-07-30 20:12 ` Indu Bhagat
  2021-07-30 20:12 ` [PATCH 2/3] targhooks: New target hook for CTF/BTF debug info emission Indu Bhagat
  2021-07-30 20:12 ` [PATCH 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase Indu Bhagat
  2 siblings, 0 replies; 4+ messages in thread
From: Indu Bhagat @ 2021-07-30 20:12 UTC (permalink / raw)
  To: 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 0000000..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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/3] targhooks: New target hook for CTF/BTF debug info emission
  2021-07-30 20:12 [PATCH 0/3] Allow means for late BTF generation for BPF CO-RE Indu Bhagat
  2021-07-30 20:12 ` [PATCH 1/3] bpf: Add new -mcore option " Indu Bhagat
@ 2021-07-30 20:12 ` Indu Bhagat
  2021-07-30 20:12 ` [PATCH 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase Indu Bhagat
  2 siblings, 0 replies; 4+ messages in thread
From: Indu Bhagat @ 2021-07-30 20:12 UTC (permalink / raw)
  To: 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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase
  2021-07-30 20:12 [PATCH 0/3] Allow means for late BTF generation for BPF CO-RE Indu Bhagat
  2021-07-30 20:12 ` [PATCH 1/3] bpf: Add new -mcore option " Indu Bhagat
  2021-07-30 20:12 ` [PATCH 2/3] targhooks: New target hook for CTF/BTF debug info emission Indu Bhagat
@ 2021-07-30 20:12 ` Indu Bhagat
  2 siblings, 0 replies; 4+ messages in thread
From: Indu Bhagat @ 2021-07-30 20:12 UTC (permalink / raw)
  To: 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 (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 884f1e1..4d7b707 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -31976,6 +31976,11 @@ dwarf2out_finish (const char *filename)
       print_die (comp_unit_die (), dump_file);
     }
 
+  /* Generate CTF/BTF debug info.  */
+  if ((ctf_debug_info_level > CTFINFO_LEVEL_NONE
+       || btf_debuginfo_p ()) && lang_GNU_C ())
+    ctf_debug_finish (filename);
+
   /* Initialize sections and labels used for actual assembler output.  */
   unsigned generation = init_sections_and_labels (false);
 
@@ -32788,8 +32793,8 @@ dwarf2out_early_finish (const char *filename)
 	ctf_debug_do_cu (node->die);
       /* Post process the debug data in the CTF container if necessary.  */
       ctf_debug_init_postprocess (btf_debuginfo_p ());
-      /* Emit CTF/BTF debug info.  */
-      ctf_debug_finalize (filename, btf_debuginfo_p ());
+
+      ctf_debug_early_finish (filename);
     }
 
   /* Do not generate DWARF assembler now when not producing LTO bytecode.  */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-07-30 20:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-30 20:12 [PATCH 0/3] Allow means for late BTF generation for BPF CO-RE Indu Bhagat
2021-07-30 20:12 ` [PATCH 1/3] bpf: Add new -mcore option " Indu Bhagat
2021-07-30 20:12 ` [PATCH 2/3] targhooks: New target hook for CTF/BTF debug info emission Indu Bhagat
2021-07-30 20:12 ` [PATCH 3/3] dwarf2out: Emit BTF in dwarf2out_finish for BPF CO-RE usecase Indu Bhagat

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).