[PATCH v2] bpf: add line_info support to BTF.ext section

Cupertino Miranda cupertino.miranda@oracle.com
Mon Mar 2 11:58:55 GMT 2026


Hi David, Jose,

Indeed it is much better like this.

Patch as been pushed with requested change.

Thanks,
Cupertino

On 27-02-2026 5:46 PM, Jose E. Marchesi wrote:
> 
>> Hi Cupertino,
>>
>> On 2/27/26 08:08, Cupertino Miranda wrote:
>>> Hi everyone, David
>>>
>>> This is v2 for line_info support.
>>> Looking forward to your review.
>>
>> Very nice.
>> I tried it with a couple of tests locally and it works well, now
>> we get accurate source line info from verifier errors :)
>>
>> I have one small comment below, but otherwise LGTM.
>> OK with that addressed.
>>
>> Thanks!
>>
>>>
>>> Cheers,
>>> Cupertino
>>>
>>> Changes from v1:
>>>   - Corrected typos.
>>>   - Fixed line_col encoding and created macros.
>>>   - Added a test case for line_info.
>>>   - Improved line and column info repetition detection.
>>>     Previous patch was generating multiple entries for the same line and
>>>     column data for consecutive labels.
>>>
>>>
>>> This patch adds line_info debug information support to .BTF.ext
>>> sections.
>>>
>>> Line info information is used by the BPF verifier to improve error
>>> reporting and give more precise source code referenced errors.
>>>
>>> gcc/ChangeLog:
>>> 	PR target/113453
>>> 	* config/bpf/bpf-protos.h (bpf_output_call): Change prototype.
>>> 	* config/bpf/bpf.cc (bpf_output_call): Change to adapt operands
>>> 	and return
>>> 	the instruction template instead of immediately emit asm and
>>> 	not allow proper final expected execution flow.
>>> 	(bpf_output_line_info): Add function to introduce line info
>>> 	entries in respective structures
>>> 	(bpf_asm_out_unwind_emit): Add function as hook to
>>> 	TARGET_ASM_UNWIND_EMIT. This hook is called before any
>>> 	instruction is emitted.
>>> 	* config/bpf/bpf.md: Change calls to bpf_output_call.
>>> 	* config/bpf/btfext-out.cc (struct btf_ext_lineinfo): Add fields
>>> 	to struct.
>>> 	(bpf_create_lineinfo, btf_add_line_info_for): Add support
>>> 	function to insert line_info data in respective structures.
>>> 	(output_btfext_line_info): Function to emit line_info data in
>>> 	.BTF.ext section.
>>> 	(btf_ext_output): Call output_btfext_line_info.
>>> 	* config/bpf/btfext-out.h: Add prototype for
>>> 	btf_add_line_info_for.
>>>
>>> gcc/testsuite/ChangeLog:
>>> 	PR target/113453
>>> 	* gcc.target/bpf/btfext-funcinfo.c: Adapt test.
>>> 	* gcc.target/bpf/btfext-lineinfo.c: New test.
>>> ---
>>>   gcc/config/bpf/bpf-protos.h                   |   2 +-
>>>   gcc/config/bpf/bpf.cc                         | 105 +++++++++++++---
>>>   gcc/config/bpf/bpf.md                         |   4 +-
>>>   gcc/config/bpf/btfext-out.cc                  | 114 +++++++++++++++++-
>>>   gcc/config/bpf/btfext-out.h                   |   4 +
>>>   .../gcc.target/bpf/btfext-funcinfo.c          |   3 +-
>>>   .../gcc.target/bpf/btfext-lineinfo.c          |  51 ++++++++
>>>   7 files changed, 262 insertions(+), 21 deletions(-)
>>>   create mode 100644 gcc/testsuite/gcc.target/bpf/btfext-lineinfo.c
>>>
>>> diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h
>>> index 4a4799e9bf22..1113cc3e6d17 100644
>>> --- a/gcc/config/bpf/bpf-protos.h
>>> +++ b/gcc/config/bpf/bpf-protos.h
>>> @@ -23,7 +23,7 @@ along with GCC; see the file COPYING3.  If not see
>>>   /* Routines implemented in bpf.cc.  */
>>>   
>>>   extern HOST_WIDE_INT bpf_initial_elimination_offset (int, int);
>>> -extern const char *bpf_output_call (rtx);
>>> +extern const char *bpf_output_call (const char *templ, rtx *, int target_index);
>>>   extern void bpf_target_macros (cpp_reader *);
>>>   extern void bpf_print_operand (FILE *, rtx, int);
>>>   extern void bpf_print_operand_address (FILE *, rtx);
>>> diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
>>> index d91013ad140b..4773d789d8e3 100644
>>> --- a/gcc/config/bpf/bpf.cc
>>> +++ b/gcc/config/bpf/bpf.cc
>>> @@ -745,14 +745,12 @@ bpf_output_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
>>>      bpf.md.  */
>>>   
>>>   const char *
>>> -bpf_output_call (rtx target)
>>> +bpf_output_call (const char *templ, rtx *operands, int target_index)
>>>   {
>>> -  rtx xops[1];
>>> -
>>> +  rtx target = operands[target_index];
>>>     switch (GET_CODE (target))
>>>       {
>>>       case CONST_INT:
>>> -      output_asm_insn ("call\t%0", &target);
>>>         break;
>>>       case SYMBOL_REF:
>>>         {
>>> @@ -765,26 +763,21 @@ bpf_output_call (rtx target)
>>>   	  {
>>>   	    tree attr_args = TREE_VALUE (attr);
>>>   
>>> -	    xops[0] = GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (attr_args)));
>>> -	    output_asm_insn ("call\t%0", xops);
>>> +	    operands[target_index] =
>>> +	      GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (attr_args)));
>>>   	  }
>>> -	else
>>> -	  output_asm_insn ("call\t%0", &target);
>>> -
>>>   	break;
>>>         }
>>>       default:
>>> -      if (TARGET_XBPF)
>>> -	output_asm_insn ("call\t%0", &target);
>>> -      else
>>> +      if (!TARGET_XBPF)
>>>   	{
>>>   	  error ("indirect call in function, which are not supported by eBPF");
>>> -	  output_asm_insn ("call 0", NULL);
>>> +	  operands[target_index] = GEN_INT (0);
>>>   	}
>>>         break;
>>>       }
>>>   
>>> -  return "";
>>> +  return templ;
>>>   }
>>>   
>>>   const char *
>>> @@ -1145,6 +1138,90 @@ bpf_debug_unwind_info ()
>>>   #undef TARGET_DEBUG_UNWIND_INFO
>>>   #define TARGET_DEBUG_UNWIND_INFO bpf_debug_unwind_info
>>>   
>>> +/* Create a BTF.ext line_info entry.  */
>>> +
>>> +static void
>>> +bpf_output_line_info (FILE *asm_out_file, rtx_insn *insn)
>>> +{
>>> +  static unsigned int line_info_label = 1;
>>> +  static tree cfun_decl = NULL_TREE;
>>> +  static bool func_start_added = false;
>>> +  const char *label = NULL;
>>> +  unsigned int loc = 0;
>>> +  expanded_location exploc = {NULL, 0, 0, NULL, false};
>>> +  static expanded_location prev_exploc = {NULL, 0, 0, NULL, false};
>>> +
>>> +  if(!btf_debuginfo_p () || flag_building_libgcc)
>>> +    return;
>>> +
>>> +  gcc_assert (insn != NULL_RTX);
>>> +
>>> +  if (current_function_decl != cfun_decl
>>> +      && GET_CODE (insn) == NOTE)
>>> +    {
>>> +      label = current_function_func_begin_label;
>>> +      loc = DECL_SOURCE_LOCATION (current_function_decl);
>>> +      exploc = expand_location (loc);
>>> +      func_start_added = true;
>>> +      prev_exploc = exploc;
>>> +    }
>>> +  else
>>> +    {
>>> +      if (GET_CODE (insn) == NOTE)
>>> +	return;
>>> +
>>> +      /* Already added a label for this location.  This might not be fully
>>> +	 accurate but it is better then adding 2 entries on the same location,
>>> +	 which is incompatible with the verifier expectations.  */
>>> +      if (func_start_added == true)
>>> +	{
>>> +	  func_start_added = false;
>>> +	  return;
>>> +	}
>>> +
>>> +
>>> +      if (!INSN_HAS_LOCATION (insn))
>>> +	return;
>>> +
>>> +      exploc = insn_location (insn);
>>> +
>>> +      if (exploc.file == NULL || exploc.line == 0
>>> +	  || (exploc.line == prev_exploc.line
>>> +	      && exploc.column == prev_exploc.column))
>>> +	return;
>>> +
>>> +      prev_exploc = exploc;
>>> +
>>> +      char tmp_label[25];
>>> +      sprintf (tmp_label, "LI%u", line_info_label);
>>> +      ASM_OUTPUT_LABEL (asm_out_file, tmp_label);
>>> +      line_info_label += 1;
>>> +      label = const_cast<char *> (ggc_strdup (tmp_label));
>>> +    }
>>> +
>>> +  cfun_decl = current_function_decl;
>>> +
>>> +  if (exploc.file != NULL && exploc.line != 0)
>>> +    btf_add_line_info_for (label, exploc.file, exploc.line, exploc.column);
>>> +}
>>> +
>>> +
>>> +/* This hook is defined as a way for BPF target to create a label before each
>>> +   emitted instruction and emit line_info information.  This data is later
>>> +   output in .BTF.ext section.
>>> +   This approach expects TARGET_EMIT_BEFORE_INSN to be returning TRUE as
>>> +   this function needs to be called before the instruction is emitted.  Current
>>> +   default behaviour returns TRUE and the hook is left undefined.  */
>>> +
>>> +static void
>>> +bpf_asm_out_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
>>> +{
>>> +  bpf_output_line_info (asm_out_file, insn);
>>> +}
>>> +
>>> +#undef TARGET_ASM_UNWIND_EMIT
>>> +#define TARGET_ASM_UNWIND_EMIT bpf_asm_out_unwind_emit
>>> +
>>>   /* Output assembly directives to assemble data of various sized and
>>>      alignments.  */
>>>   
>>> diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
>>> index 0eec006d3cfe..bc739f2746c0 100644
>>> --- a/gcc/config/bpf/bpf.md
>>> +++ b/gcc/config/bpf/bpf.md
>>> @@ -545,7 +545,7 @@
>>>     ;; operands[2] is next_arg_register
>>>     ;; operands[3] is struct_value_size_rtx.
>>>     ""
>>> -  { return bpf_output_call (operands[0]); }
>>> +  { return bpf_output_call ("call\t%0", operands, 0); }
>>>     [(set_attr "type" "jmp")])
>>>   
>>>   (define_expand "call_value"
>>> @@ -568,7 +568,7 @@
>>>     ;; operands[3] is next_arg_register
>>>     ;; operands[4] is struct_value_size_rtx.
>>>     ""
>>> -  { return bpf_output_call (operands[1]); }
>>> +  { return bpf_output_call ("call\t%1", operands, 1); }
>>>     [(set_attr "type" "jmp")])
>>>   
>>>   (define_insn "sibcall"
>>> diff --git a/gcc/config/bpf/btfext-out.cc b/gcc/config/bpf/btfext-out.cc
>>> index 04bc60d69b0e..9a7e34aeb634 100644
>>> --- a/gcc/config/bpf/btfext-out.cc
>>> +++ b/gcc/config/bpf/btfext-out.cc
>>> @@ -32,6 +32,7 @@
>>>   #include "rtl.h"
>>>   #include "tree-pretty-print.h"
>>>   #include "cgraph.h"
>>> +#include "toplev.h"  /* get_src_pwd */
>>>   
>>>   #include "btfext-out.h"
>>>   
>>> @@ -124,14 +125,19 @@ struct GTY ((chain_next ("%h.next"))) btf_ext_funcinfo
>>>   /* A lineinfo record, in the .BTF.ext lineinfo section.  */
>>>   struct GTY ((chain_next ("%h.next"))) btf_ext_lineinfo
>>>   {
>>> -  uint32_t insn_off;      /* Offset of the instruction.  */
>>> +  const char *insn_label; /* Instruction label.  */
>>> +  const char *file_name;  /* Source-code file name.  */
>>>     uint32_t file_name_off; /* Offset of file name in BTF string table.  */
>>>     uint32_t line_off;      /* Offset of source line in BTF string table.  */
>>> -  uint32_t line_col;      /* Line number (bits 31-11) and column (11-0).  */
>>> +  uint32_t line_col;      /* Line number (bits 31-10) and column (9-0).  */
>>>   
>>>     struct btf_ext_lineinfo *next; /* Linked list to collect line_info elems.  */
>>>   };
>>>   
>>> +#define BTF_LINE_INFO_LINE(line_col)	      ((line_col) >> 10)
>>> +#define BTF_LINE_INFO_COLUMN(line_col)        ((line_col) & 0x3ff)
>>> +#define BTF_LINE_INFO_LINE_COL(line, column)  (line << 10 | (column & 0x3ff))
>>> +
>>>   /* Internal representation of a BPF CO-RE relocation record.  */
>>>   struct GTY ((chain_next ("%h.next"))) btf_ext_core_reloc {
>>>     ctf_dtdef_ref bpfcr_type;		/* BTF type involved in relocation.  */
>>> @@ -235,6 +241,26 @@ bpf_create_or_find_funcinfo (const char *fnname, const char *sec_name,
>>>     return *head;
>>>   }
>>>   
>>> +/* Function to create a lineinfo node in info.  */
>>> +
>>> +static struct btf_ext_lineinfo *
>>> +bpf_create_lineinfo (const char *sec_name, btf_ext_info_sec **in_sec = NULL)
>>> +{
>>> +  struct btf_ext_info_sec *sec_elem =
>>> +    btfext_info_sec_find_or_add (sec_name, true);
>>> +
>>> +  if (in_sec != NULL)
>>> +    *in_sec = sec_elem;
>>> +
>>> +  struct btf_ext_lineinfo **head =
>>> +    SEARCH_NODE_AND_RETURN(struct btf_ext_lineinfo,
>>> +			   sec_elem->line_info.head,
>>> +			   false);
>>> +  *head = ggc_cleared_alloc<struct btf_ext_lineinfo> ();
>>> +
>>> +  return *head;
>>> +}
>>> +
>>>   /* Function to create a core_reloc node in info.  */
>>>   
>>>   static struct btf_ext_core_reloc *
>>> @@ -438,6 +464,47 @@ btf_validate_funcinfo (btf_ext_info_sec *sec)
>>>       }
>>>   }
>>>   
>>> +#define STR_BUFF_SIZE 256
>>> +
>>> +struct btf_ext_lineinfo *
>>> +btf_add_line_info_for (const char *label, const char *filename,
>>> +		       unsigned int line, unsigned int column)
>>> +{
>>> +  const char *sec_name = decl_section_name (current_function_decl);
>>> +
>>> +  if (sec_name == NULL)
>>> +    sec_name = ".text";
>>> +
>>> +  struct btf_ext_info_sec *sec = NULL;
>>> +  struct btf_ext_lineinfo *info =
>>> +    bpf_create_lineinfo (sec_name, &sec);
>>> +
>>> +  info->insn_label = label;
>>> +
>>> +  if (!IS_DIR_SEPARATOR (filename[0]))
>>> +    {
>>> +      char full_filename[STR_BUFF_SIZE];
>>> +
>>> +      /* Filename is a relative path.  */
>>> +      const char * cu_pwd = get_src_pwd ();
>>> +      gcc_assert (strlen (cu_pwd) + strlen (filename) + 2 < STR_BUFF_SIZE);
>>> +
>>> +      sprintf (full_filename, "%s%c%s", cu_pwd, DIR_SEPARATOR, filename);
>>
>> On second look I don't like using gcc_assert here; this will result in an
>> ICE simply if the input filename is very long...
>>
>> While I doubt that will occur much in practice, we should still deal with
>> it gracefully.  IMO just truncating via e.g. snprintf would be fine and
>> much better than causing an ICE.
> 
> There is no need to truncate.
> Just use xasprintf.
> 
>>
>>> +      info->file_name = ggc_strdup (full_filename);
>>> +    }
>>> +  else
>>> +    /* Filename is an absolute path.  */
>>> +    info->file_name = ggc_strdup (filename);
>>> +
>>> +  info->file_name_off = btf_ext_add_string (info->file_name);
>>> +  info->line_off = 0;
>>> +  info->line_col = BTF_LINE_INFO_LINE_COL (line, column);
>>> +
>>> +  sec->line_info.num_info += 1;
>>> +  return info;
>>> +}
>>> +#undef STR_BUFF_SIZE
>>> +
>>>   /* Compute the section size in section for func_info, line_info and core_info
>>>      regions of .BTF.ext.  */
>>>   
>>> @@ -545,6 +612,48 @@ output_btfext_func_info (struct btf_ext_info_sec *sec)
>>>       }
>>>   }
>>>   
>>> +/* Outputs line_info region on .BTF.ext.  */
>>> +
>>> +static void
>>> +output_btfext_line_info (struct btf_ext_info_sec *sec)
>>> +{
>>> +  unsigned int str_aux_off = ctfc_get_strtab_len (ctf_get_tu_ctfc (),
>>> +						  CTF_STRTAB);
>>> +  bool executed = false;
>>> +  while (sec != NULL)
>>> +    {
>>> +      uint32_t count = 0;
>>> +      if (sec->line_info.num_info > 0)
>>> +	{
>>> +	  if (executed == false && (executed = true))
>>> +	    dw2_asm_output_data (4, 16, "LineInfo entry size");
>>> +	  dw2_asm_output_data (4, sec->sec_name_off + str_aux_off,
>>> +			       "LineInfo section string for %s",
>>> +			       sec->sec_name);
>>> +	  dw2_asm_output_data (4, sec->line_info.num_info, "Number of entries");
>>> +
>>> +	  struct btf_ext_lineinfo *elem = sec->line_info.head;
>>> +	  while (elem != NULL)
>>> +	    {
>>> +	      count += 1;
>>> +	      dw2_asm_output_offset (4, elem->insn_label, NULL, "insn_label");
>>> +
>>> +	      unsigned int file_name_off = btf_ext_add_string (elem->file_name);
>>> +	      dw2_asm_output_data (4, file_name_off + str_aux_off,
>>> +				   "file_name_off");
>>> +	      dw2_asm_output_data (4, elem->line_off, "line_off");
>>> +	      dw2_asm_output_data (4, elem->line_col, "(line, col) (%u, %u)",
>>> +				   BTF_LINE_INFO_LINE (elem->line_col),
>>> +				   BTF_LINE_INFO_COLUMN (elem->line_col));
>>> +	      elem = elem->next;
>>> +	    }
>>> +	}
>>> +
>>> +      gcc_assert (count == sec->line_info.num_info);
>>> +      sec = sec->next;
>>> +    }
>>> +}
>>> +
>>>   /* Output all CO-RE relocation sections.  */
>>>   
>>>   static void
>>> @@ -622,6 +731,7 @@ btf_ext_output (void)
>>>   
>>>     output_btfext_header ();
>>>     output_btfext_func_info (btf_ext);
>>> +  output_btfext_line_info (btf_ext);
>>>     if (TARGET_BPF_CORE)
>>>       output_btfext_core_sections ();
>>>   
>>> diff --git a/gcc/config/bpf/btfext-out.h b/gcc/config/bpf/btfext-out.h
>>> index a4c87ffd1f02..fe9b3768643e 100644
>>> --- a/gcc/config/bpf/btfext-out.h
>>> +++ b/gcc/config/bpf/btfext-out.h
>>> @@ -99,6 +99,10 @@ extern int bpf_core_get_sou_member_index (ctf_container_ref, const tree);
>>>   
>>>   struct btf_ext_funcinfo *btf_add_func_info_for (tree decl,
>>>   						const char *label);
>>> +struct btf_ext_lineinfo *
>>> +btf_add_line_info_for (const char *label, const char *filename,
>>> +		       unsigned int line, unsigned int column);
>>> +
>>>   unsigned int btf_ext_add_string (const char *str);
>>>   
>>>   #ifdef	__cplusplus
>>> diff --git a/gcc/testsuite/gcc.target/bpf/btfext-funcinfo.c b/gcc/testsuite/gcc.target/bpf/btfext-funcinfo.c
>>> index fbbefeae68f0..f7f5b44b1ff4 100644
>>> --- a/gcc/testsuite/gcc.target/bpf/btfext-funcinfo.c
>>> +++ b/gcc/testsuite/gcc.target/bpf/btfext-funcinfo.c
>>> @@ -39,6 +39,5 @@ int bar_func (struct T *t)
>>>   /* { dg-final { scan-assembler-times "ascii \"bar_sec.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
>>>   /* { dg-final { scan-assembler-times "FuncInfo entry size" 1 } } */
>>>   
>>> -/* { dg-final { scan-assembler-times ".4byte\t0x1\t# Number of entries" 3 } } */
>>> -/* { dg-final { scan-assembler-times ".4byte\t0x2\t# Number of entries" 1 } } */
>>> +/* { dg-final { scan-assembler-times "FuncInfo section\[^\n\]*\n\[^0\]*0x1\t# Number of entries" 2 } } */
>>>   /* { dg-final { scan-assembler-times "Required padding" 1 } } */
>>> diff --git a/gcc/testsuite/gcc.target/bpf/btfext-lineinfo.c b/gcc/testsuite/gcc.target/bpf/btfext-lineinfo.c
>>> new file mode 100644
>>> index 000000000000..dc1c297d663e
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/bpf/btfext-lineinfo.c
>>> @@ -0,0 +1,51 @@
>>> +/* { dg-do compile } */
>>> +/* { dg-options "-O2 -dA -gbtf -masm=normal" } */
>>> +
>>> +struct T {
>>> +  int a;
>>> +  int b;
>>> +  struct U {
>>> +    int c;
>>> +    struct V {
>>> +      int d;
>>> +      int e[4];
>>> +      int f;
>>> +    } v;
>>> +  } u;
>>> +} __attribute__((preserve_access_index));
>>> +
>>> +__attribute__((section("foo_sec"), used))
>>> +int foo_func (struct T *t)
>>> +{
>>> +  t->u.c = 5;
>>> +  return t->u.v.e[3];
>>> +}
>>> +
>>> +__attribute__((section("bar_sec"), used))
>>> +int bar_func (struct T *t)
>>> +{
>>> +  int *x = &(t->u.v.f);
>>> +  int old = *x;
>>> +  *x = 4;
>>> +  return old;
>>> +}
>>> +
>>> +/* { dg-final { scan-assembler-times "LineInfo section string for foo_sec" 1 } } */
>>> +/* { dg-final { scan-assembler-times "LineInfo section string for bar_sec" 1 } } */
>>> +/* { dg-final { scan-assembler-times "label for function foo_func" 1 } } */
>>> +/* { dg-final { scan-assembler-times "label for function bar_func" 1 } } */
>>> +
>>> +
>>> +/* { dg-final { scan-assembler-times "btfext-lineinfo\.c.0\"\[\t \]+\[^\n\]*btf_aux_string" 1 } } */
>>> +/* { dg-final { scan-assembler-times "4byte\[\t \]+\.LFB.\[\t \]+# insn_label" 2 } } */
>>> +/* { dg-final { scan-assembler-times "4byte\[\t \]+LI.\[\t \]+# insn_label" 6 } } */
>>> +
>>> +/* { dg-final { scan-assembler-times "# \\(line, col\\)" 8 } } */
>>> +/* { dg-final { scan-assembler-times "# \\(line, col\\) \\(18, 5\\)" 1 } } */
>>> +/* { dg-final { scan-assembler-times "# \\(line, col\\) \\(20, 10\\)" 1 } } */
>>> +/* { dg-final { scan-assembler-times "# \\(line, col\\) \\(21, 18\\)" 1 } } */
>>> +/* { dg-final { scan-assembler-times "# \\(line, col\\) \\(22, 1\\)" 1 } } */
>>> +/* { dg-final { scan-assembler-times "# \\(line, col\\) \\(25, 5\\)" 1 } } */
>>> +/* { dg-final { scan-assembler-times "# \\(line, col\\) \\(28, 7\\)" 1 } } */
>>> +/* { dg-final { scan-assembler-times "# \\(line, col\\) \\(29, 6\\)" 1 } } */
>>> +/* { dg-final { scan-assembler-times "# \\(line, col\\) \\(31, 1\\)" 1 } } */



More information about the bpf mailing list