[Bug target/107479] New: bpf: add __builtin_btf_type_id

2022-10-31 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107479

Bug ID: 107479
   Summary: bpf: add __builtin_btf_type_id
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david.faust at oracle dot com
  Target Milestone: ---

LLVM supports a BPF builtin:
  __builtin_btf_type_id (param, flag)

which returns the BTF type id of 'param' to the program,
and records a BPF CO-RE relocation according to 'flag'.

We should support the same functionality in GCC. 

These are the relevant changes in LLVM and clang:
  https://reviews.llvm.org/D74572
  https://reviews.llvm.org/D74668

[Bug target/107480] New: bpf: add __builtin_preserve_type_info

2022-10-31 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107480

Bug ID: 107480
   Summary: bpf: add __builtin_preserve_type_info
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david.faust at oracle dot com
  Target Milestone: ---

LLVM supports a BPF builtin:
  __builtin_preserve_type_info (param, flag)

which is used to generate additional relocations for the
Compile Once - Run Everywhere (CO-RE) mechanism.

This builtin produces a relocation recording the information
about the type of 'param', such as it's size or whether or
not it exists on the host kernel, according to 'flag'. This
information is returned to the program and patched by the
eBPF loader during loading.

We should support this functionality in GCC.

These are the relevant changes in LLVM:
  https://reviews.llvm.org/D83878
  https://reviews.llvm.org/D83242

[Bug target/107481] New: bpf: add __builtin_preserve_enum_value

2022-10-31 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107481

Bug ID: 107481
   Summary: bpf: add __builtin_preserve_enum_value
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david.faust at oracle dot com
  Target Milestone: ---

LLVM supports a builtin:
  __builtin_preserve_enum_value (param, flag)

which is used to generate additional relocations for the
Compile Once - Run Everywhere (CO-RE) mechanism.

This builtin produces a CO-RE relocation recording information
about the enumerator value in 'param' according to 'flag', and
returns that information to the program. For example, the
integer value of the enumerator, or a boolean value representing
whether or not that enumerator exists on the host kernel. These
values are patched by the eBPF loader according to the CO-RE
relocation.

We should support the same functionality in GCC.

These are the relevant changes in LLVM:
  https://reviews.llvm.org/D83878
  https://reviews.llvm.org/D83242

[Bug target/107846] error: result of '8000 << 8' requires 22 bits to represent, but 'short int' only has 16 bits

2022-11-23 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107846

--- Comment #1 from David Faust  ---
I think this is a bug in the test itself (or with these macros from libbpf).

libbpf/src/bpf_endian.h
#define ___bpf_mvb(x, b, n, m) ((__u##b)(x) << (b-(n+1)*8) >> (b-8) << (m*8))

#define ___bpf_swab16(x) ((__u16)(  \
  ___bpf_mvb(x, 16, 0, 1) | \
  ___bpf_mvb(x, 16, 1, 0)))

# define __bpf_constant_htons(x)___bpf_swab16(x)

In tools/testing/selftests/bpf/progs/test_tc_tunnel.c:

static const int cfg_port = 8000;
static const int cfg_udp_src = 2;
...

then at e.g. line 276

if (tcph.dest != __bpf_constant_htons(cfg_port))
return TC_ACT_OK;

Expanding this __bpf_constant_htons macro:

__bpf_constant_htons (cfg_port)
__bpf_constant_htons (8000)
((__u16)(8000) << (16-(0+1)*8) >> (16-8) << (1*8)
((__u16)(8000) << (16-(1)*8) >> (8) << 8)
((__u16)(8000) << (8) >> 8 << 8
((__u16)(8000) << 8)

...which raises the shift-overflow warning.

[Bug target/106773] libbpf: failed to find BTF info for global/extern symbol 'bpf_link_fops'

2022-11-28 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106773

--- Comment #3 from David Faust  ---
There are two remaining issues:

1. We are missing support for 'linkage=extern' encoding for variables,
   so 'bpf_link_fops' and others are incorrectly marked with 'linkage=global'
   instead.

2. 'bpf_link_fops' variable is encoded as 'void' type not 'const void'.
   This is a result of the BTF being generated from internal DWARF
   representation. The distinction seems to be intentionally removed in
   dwarf2out.cc:add_type_attribute(), with the later side-effect that
   looking up the type DIE for the variable when generating BTF actually
   fails and falls back to the default 'void'.

I have an implementation for (1) in progress. For (2) I need to understand
why the 'void'/'const void' distinction is removed in DWARF and how to work 
around it.

[Bug target/106773] libbpf: failed to find BTF info for global/extern symbol 'bpf_link_fops'

2022-11-30 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106773

--- Comment #4 from David Faust  ---
Created attachment 53993
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53993&action=edit
proposed patch

Should fix the remaining issues with 'extern' linkage and the missing 'const'
modifier (and includes the earlier partial fixes in this bug)

[Bug target/106773] libbpf: failed to find BTF info for global/extern symbol 'bpf_link_fops'

2022-12-01 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106773

--- Comment #8 from David Faust  ---
(In reply to James Hilliard from comment #5)
> (In reply to David Faust from comment #4)
> > Created attachment 53993 [details]
> > proposed patch
> > 
> > Should fix the remaining issues with 'extern' linkage and the missing
> > 'const' modifier (and includes the earlier partial fixes in this bug)
> 
> Fixes the reported test failure but some others(unclear if related to this
> bug) are still failing such as tailcall_bpf2bpf3.c:

Thanks for testing and confirming.

> $ /home/buildroot/bpf-next/tools/testing/selftests/bpf/tools/sbin/bpftool
> --debug gen object
> /home/buildroot/bpf-next/tools/testing/selftests/bpf/bpf_gcc/
> tailcall_bpf2bpf3.bpf.linked1.o
> /home/buildroot/bpf-next/tools/testing/selftests/bpf/bpf_gcc/
> tailcall_bpf2bpf3.bpf.o
> libbpf: linker: adding object file
> '/home/buildroot/bpf-next/tools/testing/selftests/bpf/bpf_gcc/
> tailcall_bpf2bpf3.bpf.o'...
> libbpf: failed to find BTF info for global/extern symbol 'llvm.bpf.load.word'
> Error: failed to link

> https://github.com/torvalds/linux/blob/v6.1-rc7/tools/testing/selftests/bpf/bpf_legacy.h
unsigned long long load_word(void *skb,
 unsigned long long off) asm("llvm.bpf.load.word");

Looks like LLVM-specific inline asm to use their llvm.bpf.load.word intrinsic.

GCC has equivalent __builtin_load_{byte,half,word} target builtins.

> There's also this error during skeleton generation for kfunc_call_test.c:
> ...
> libbpf: failed to find BTF for extern 'bpf_kfunc_call_test2': -22

Hm, looks like we are OK for extern variables but are mis-generating something
(or missing something) for extern funcs still. Will look into this.

[Bug target/106773] libbpf: failed to find BTF info for global/extern symbol 'bpf_link_fops'

2022-12-01 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106773

David Faust  changed:

   What|Removed |Added

  Attachment #53993|0   |1
is obsolete||

--- Comment #9 from David Faust  ---
Created attachment 54002
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54002&action=edit
updated patch

Update the 'extern' variable marking, and also mark 'extern' funcs.

[Bug target/106773] libbpf: failed to find BTF info for global/extern symbol 'bpf_link_fops'

2022-12-05 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106773

--- Comment #13 from David Faust  ---
Created attachment 54017
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54017&action=edit
DATASEC entries for extern funcs

Applies on top of 54002: updated patch
Adds emission of DATASEC entries for extern funcs. Rough, needs cleanup.

[Bug target/106773] libbpf: failed to find BTF info for global/extern symbol 'bpf_link_fops'

2022-12-05 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106773

David Faust  changed:

   What|Removed |Added

  Attachment #54017|0   |1
is obsolete||

--- Comment #15 from David Faust  ---
Created attachment 54021
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54021&action=edit
[v2] DATASEC entries for extern funcs

v2 fixes an off-by-one bug introduced in the patch which was causing
libbpf: Invalid BTF total size

[Bug target/107843] error: incompatible type for argument in ___bpf_ctx_cast2

2022-12-06 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107843

--- Comment #1 from David Faust  ---
Looks like this is an issue with passing void* where an enum type is
expected in a function call. This is not specific to the BPF backend.

Not entirely clear to me whether this is expected or a bug, but it
does differ from llvm behavior.

Reproducer below, tried with a few gccs, same behavior:
today (6 Dec 2022)'s master 81476bc4f4a20bcf3af7ac2548c2322d48499402
gcc-12 (Debian 12.2.0-9) 12.2.0
gcc-10 (Debian 10.4.0-5) 10.4.0
gcc-8 (Debian 8.4.0-7) 8.4.0

$ cat enumcast.c
enum E {
  E_FOO = 0,
  E_BAR = 1,
};

int foo_enum (enum E e);

int bar_enum (enum E e) {
  return foo_enum ((void *) e);
}

int foo_int (int x);

int bar_int (int x) {
  return foo_int ((void *) x);
}


$ gcc -c enumcast.c -o enumcast.o
enumcast.c: In function ‘bar_enum’:
enumcast.c:10:20: error: incompatible type for argument 1 of ‘foo_enum’
   10 |   return foo_enum ((void *) e);
  |^~
  ||
  |void *
enumcast.c:7:22: note: expected ‘enum E’ but argument is of type ‘void *’
7 | int foo_enum (enum E e);
  |   ~~~^
enumcast.c: In function ‘bar_int’:
enumcast.c:16:19: warning: cast to pointer from integer of different size
[-Wint-to-pointer-cast]
   16 |   return foo_int ((void *) x);
  |   ^
enumcast.c:16:19: warning: passing argument 1 of ‘foo_int’ makes integer from
pointer without a cast [-Wint-conversion]
   16 |   return foo_int ((void *) x);
  |   ^~
  |   |
  |   void *
enumcast.c:13:18: note: expected ‘int’ but argument is of type ‘void *’
   13 | int foo_int (int x);
  |  ^


$ clang -c enumcast.c -o enumcast.o
enumcast.c:10:20: warning: incompatible pointer to integer conversion passing
'void *' to parameter of type 'enum E' [-Wint-conversion]
  return foo_enum ((void *) e);
   ^~
enumcast.c:7:22: note: passing argument to parameter 'e' here
int foo_enum (enum E e);
 ^
enumcast.c:16:19: warning: cast to 'void *' from smaller integer type 'int'
[-Wint-to-void-pointer-cast]
  return foo_int ((void *) x);
  ^~
enumcast.c:16:19: warning: incompatible pointer to integer conversion passing
'void *' to parameter of type 'int' [-Wint-conversion]
  return foo_int ((void *) x);
  ^~
enumcast.c:13:18: note: passing argument to parameter 'x' here
int foo_int (int x);
 ^
3 warnings generated.

[Bug target/106745] segfault in bpf_core_get_sou_member_index

2022-08-26 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106745

David Faust  changed:

   What|Removed |Added

 CC||david.faust at oracle dot com

--- Comment #1 from David Faust  ---
Thanks, I've reproduced the failure and found the issue.
The code which generates the CO-RE relocations isn't correctly handling
anonymous inner struct/union decls. So for example:
struct core_reloc_flavors___weird {
 struct {
  int b;
 };

 union {
  int a;
  int c;
 };
};

Asking to generate a CO-RE relo for access to a, b or c here will trigger the
SEGV. Working on a fix.

[Bug target/109253] libbpf: failed to find BTF info for global/extern symbol '__divdi3'

2023-03-23 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109253

--- Comment #1 from David Faust  ---
See:
https://gcc.gnu.org/pipermail/gcc-patches/2022-December/608152.html

Also related as Andrew pointed out in the above thread:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48783

[Bug debug/110073] [14 regression] btfout.cc format errors break bootstrap

2023-06-01 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110073

--- Comment #1 from David Faust  ---
Created attachment 55234
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55234&action=edit
alternate proposed patch

Thank you for catching this, and for the fix!

With the proposed patch on linux x86_64 I see the following:

../../../gcc/gcc/btfout.cc: In function ‘void
btf_asm_func_type(ctf_container_ref, ctf_dtdef_ref, size_t)’:
../../../gcc/gcc/btfout.cc:952:31: warning: format ‘%u’ expects argument of
type ‘unsigned int’, but argument 4 has type ‘size_t’ {aka ‘long unsigned int’}
[-Wformat=]
  952 |"TYPE %u BTF_KIND_FUNC '%s'",
  |  ~^
  |   |
  |   unsigned int
  |  %lu
  953 |num_types_added + num_vars_added + 1 + i,
  |
  | |
  | size_t {aka
long unsigned int}

I believe %zu instead of %u should work.

Alternatively, a small refactor to the offending code makes it behave in line
with the other functions (to properly use a ctf_id_t, and then PRIu64 as in
your patch). But I haven't verified this on solaris/x86 yet.

[Bug debug/110073] [14 regression] btfout.cc format errors break bootstrap

2023-06-02 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110073

--- Comment #4 from David Faust  ---
(In reply to Iain Sandoe from comment #3)
> (In reply to Iain Sandoe from comment #2)
> > there seems to be a second fail on x86_64 darwin on line 970.
> 
> I tried the alternate patch on a number of x86_64, i686 and power Darwin
> systems and bootstrap is restored.

Thanks for confirming. I'll go ahead and send it to the list.

[Bug debug/110073] [14 regression] btfout.cc format errors break bootstrap

2023-06-02 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110073

--- Comment #6 from David Faust  ---
(In reply to Iain Sandoe from comment #5)
> (In reply to David Faust from comment #4)
> > (In reply to Iain Sandoe from comment #3)
> > > (In reply to Iain Sandoe from comment #2)
> > > > there seems to be a second fail on x86_64 darwin on line 970.
> > > 
> > > I tried the alternate patch on a number of x86_64, i686 and power Darwin
> > > systems and bootstrap is restored.
> > 
> > Thanks for confirming. I'll go ahead and send it to the list.
> 
> I think with bootstrap fixes, you are allowed a bit more independence - i.e.
> can go ahead and apply - but now needs resolution with Alex's patch,

OK, thanks. And yes I just ran into the conflict. Rebasing now.

[Bug debug/110073] [14 regression] btfout.cc format errors break bootstrap

2023-06-02 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110073

--- Comment #9 from David Faust  ---
(In reply to Alex Coplan from comment #8)
> Thanks for the follow-up fix and apologies for the mid-air collision, I
> didn't see the %zu problem on the target I was testing.

No problem, thanks for the fixes :) I'm slow on the patch formatting etc.
Hopefully these are all taken care of now between the two patches.

[Bug target/114431] bpf: GCC generates unverifiable code for systemd restrict_fs_bpf

2024-04-09 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114431

David Faust  changed:

   What|Removed |Added

 CC||david.faust at oracle dot com

--- Comment #7 from David Faust  ---
Patch above had some fallout for non-BPF targets.  I pushed the below to fix
that. The behavior for BPF is unchanged.

https://gcc.gnu.org/g:8075477f81ae8d0abf64b80dfbd179151f91b417

commit r14-9876-g8075477f81ae8d0abf64b80dfbd179151f91b417
Author: David Faust 
Date:   Mon Apr 8 11:10:41 2024 -0700

btf: emit symbol refs in DATASEC entries only for BPF [PR114608]

[Bug target/107844] error: argument is not a field access for __builtin_preserve_field_info

2023-01-18 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107844

--- Comment #1 from David Faust  ---
Looks like this is a result of the combination of how the bpf_core_field_exists
macro is defined and some sort of optimization(?) happening in the C frontend.

Consider:

  struct S {
unsigned short x;
char c[12];
  };

  int foo () {
int has_c = bpf_core_field_exists (struct S, c);
return has_c;
  }

The bpf_core_field_exists macro expands to:

  int has_c =
__builtin_preserve_field_infotypeof(struct S) *)0)->c),
BPF_RELO_FIELD_EXISTS);

For some reason, for array members specifically, this construction results in
the tree for the parameter when resolving the builtin being simply:

  (gdb) pt param
constant 2>

i.e. a pointer to 0x2, the offset of 'c' in a 'struct S' mapped at 0x0. For
non-array members, 'param' is some kind of  as I'd expect.

This gives us two problems:
 a) We cannot distinguish an array member from a non-member constant-value
pointer.
 b) We cannot correctly compute information for the CO-RE relocation.
For example, in this case BPF_RELO_FIELD_BYTE_SIZE will be calculated as 8
(size of pointer), not 12 (size of the array).

I'm not sure how to resolve this and support the existing helper macros in the
kernel/libbpf. Might need some change in the C frontend, or to somehow pass
more
information to the target_resolve_overloaded_builtin hook...

[Bug target/107844] error: argument is not a field access for __builtin_preserve_field_info

2023-01-18 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107844

--- Comment #3 from David Faust  ---
Thanks for the info Andrew. I'll look at __builtin_offsetof.

As for the implementation in clang, I can point to some bits relevant to
the builtin itself:
llvm-project/clang/lib/CodeGen/CGBuiltin.cpp
  CodeGenFunction::EmitBPFBuiltinExpr ()

llvm-project/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp
  BPFAbstractMemberAccess::GetFieldInfo ()

But I am less familiar with the surrounding machinery such as their
parsing and type systems..

[Bug target/107844] error: argument is not a field access for __builtin_preserve_field_info

2023-01-18 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107844

--- Comment #5 from David Faust  ---
(In reply to Andrew Pinski from comment #4)
> (In reply to David Faust from comment #3)
> > Thanks for the info Andrew. I'll look at __builtin_offsetof.
> > 
> > As for the implementation in clang, I can point to some bits relevant to
> > the builtin itself:
> > llvm-project/clang/lib/CodeGen/CGBuiltin.cpp
> >   CodeGenFunction::EmitBPFBuiltinExpr ()
> > 
> > llvm-project/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp
> >   BPFAbstractMemberAccess::GetFieldInfo ()
> > 
> > But I am less familiar with the surrounding machinery such as their
> > parsing and type systems..
> 
> So I looked (First off I am shocked they don't have target functions to
> handle the builtins and every target builtin is handled in that file seems
> wrong), and you are handed the AST before folding. This is different from
> GCC where it is you are handed it after folding.

Aha! I had never realized this difference until now. Thanks for pointing
that out!

> 
> So I think we need some special handling in the c (and C++) parser to handle
> this. I suspect we want to do the full handling of the builtin
> (bpf_core_field_exists) in the parser rather than the macro expanded view of
> it too. Similar to how offsetof is handled ...
> Of course this will need some modifications to the bpf headers too. And that
> solves some other issues too.

Yes, I see. I'll have to study the parser a little since I have not touched
it before, but the approach makes sense.

I wonder if it would be feasible and/or worthwhile to add some sort of
TARGET_PARSE_BUILTIN hook to enable this sort of handling for any other
targets which may want it..? Maybe that can wait.

In any case, thank you very much for the suggestions.

[Bug target/108790] New: bpf: gcc emits malformed ldxdw instruction at -O2

2023-02-14 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108790

Bug ID: 108790
   Summary: bpf: gcc emits malformed ldxdw instruction at -O2
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david.faust at oracle dot com
CC: cupertino.miranda at oracle dot com
  Target Milestone: ---
Target: bpf

With -O2 GCC emits a malformed ldxdw instruction in some cases:

$ cat ldxdw.c
unsigned long long test () {
  return *((unsigned long long *) 0x4000);
}

$ bpf-unknown-none-gcc -c -O2 ldxdw.c -o ldxdw.o
/tmp/ccsuVj7l.s: Assembler messages:
/tmp/ccsuVj7l.s:7: Error: unrecognized form of instruction `ldxdw %r0,16384'

ldxdw (and all other {ldx,stx}{b,h,w,dw} insns should have a form like

ldxdw %rX, [%rY + OFFSET]

Looks like we need a better constraint on the memory operand in *mov.

Testing a patch for this now.

[Bug target/109068] New: bpf: "error: too many function arguments for eBPF" for always_inline function

2023-03-08 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109068

Bug ID: 109068
   Summary: bpf: "error: too many function arguments for eBPF" for
always_inline function
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david.faust at oracle dot com
CC: cupertino.miranda at oracle dot com, jemarch at gcc dot 
gnu.org
  Target Milestone: ---
Target: bpf

BPF calling convention does not support function calls with more than
5 arguments. But if the function is inlined this restriction should be
relaxed.

Many convenience macros for BPF in the kernel make use of always_inline
functions, and the expansion of the macro uses can result in an
always_inline function with >5 args. There are several examples of this
in the BPF selftests, so GCC fails to compile those tests.
e.g. on bpf-next:
linux/tools/testing/selftests/bpf/progs/bpf_syscall_macro.c
 and corresponding BPF_KSYSCALL macro def in
linux/tools/testing/selftests/bpf/tools/include/bpf/bpf_tracing.h
 duplicated from
linux/tools/lib/bpf/bpf_tracing.h

clang compiles these tests without issue.

We should fix the BPF backend check for function arguments to allow
calls to inline functions with >5 args.


$ cat args.c
inline __attribute__((always_inline))
int foo (int a, int b, int c, int d, int e, int f)
{
  return a + b + c + d + e + f;
}

int bar (int x)
{
  return foo (x, x*2, x*3, x*4, x*5, x*6);
}

$ bpf-unknown-none-gcc -c args.c -o args.o
args.c: In function ‘foo’:
args.c:2:5: error: too many function arguments for eBPF
2 | int foo (int a, int b, int c, int d, int e, int f)
  | ^~~

[Bug debug/110439] New: Missing DW_TAG_typedef for variable with attribute of typedef'd type

2023-06-27 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110439

Bug ID: 110439
   Summary: Missing DW_TAG_typedef for variable with attribute of
typedef'd type
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: debug
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david.faust at oracle dot com
  Target Milestone: ---

$ cat typedef-skip-1.c
typedef int foo;
foo __attribute__((may_alias)) attr_foo;
foo plain_foo;

DW_AT_type in the variable DIE for 'attr_foo' refers to the base int type,
while for 'plain_foo' it refers to the typedef DIE I would expect: 

$ gcc -g -c typedef-skip-1.c
$ readelf -wi typedef-skip-1.o

 <0>: Abbrev Number: 2 (DW_TAG_compile_unit)
   DW_AT_producer: (indirect string, offset: 0): GNU C17 12.2.0
-mtune=generic -march=x86-64 -g -fasynchronous-unwind-tables
<11>   DW_AT_language: 29   (C11)
<12>   DW_AT_name: (indirect line string, offset: 0):
typedef-skip-1.c
<16>   DW_AT_comp_dir: (indirect line string, offset: 0x11):
/home/dfaust/playpen
<1a>   DW_AT_stmt_list   : 0
 <1><1e>: Abbrev Number: 3 (DW_TAG_typedef)
<1f>   DW_AT_name: foo
<23>   DW_AT_decl_file   : 1
<24>   DW_AT_decl_line   : 1
<25>   DW_AT_decl_column : 13
<26>   DW_AT_type: <0x2a>
 <1><2a>: Abbrev Number: 4 (DW_TAG_base_type)
<2b>   DW_AT_byte_size   : 4
<2c>   DW_AT_encoding: 5(signed)
<2d>   DW_AT_name: int
 <1><31>: Abbrev Number: 1 (DW_TAG_variable)
<32>   DW_AT_name: (indirect string, offset: 0x4c): attr_foo
<36>   DW_AT_decl_file   : 1
<36>   DW_AT_decl_line   : 2
<37>   DW_AT_decl_column : 32
<38>   DW_AT_type: <0x2a>
<3c>   DW_AT_external: 1
<3c>   DW_AT_location: 9 byte block: 3 0 0 0 0 0 0 0 0  (DW_OP_addr: 0)
 <1><46>: Abbrev Number: 1 (DW_TAG_variable)
<47>   DW_AT_name: (indirect string, offset: 0x55): plain_foo
<4b>   DW_AT_decl_file   : 1
<4b>   DW_AT_decl_line   : 3
<4c>   DW_AT_decl_column : 5
<4d>   DW_AT_type: <0x1e>
<51>   DW_AT_external: 1
<51>   DW_AT_location: 9 byte block: 3 4 0 0 0 0 0 0 0  (DW_OP_addr: 4)
 <1><5b>: Abbrev Number: 0

DWARF output by clang has the DW_TAG_typedef DIE in DW_AT_type for both
variables:

$ clang -c -g typedef-skip-1.c -o typedef-skip-1.o.clang
$ readelf -wi typedef-skip-1.o.clang

 <1><1e>: Abbrev Number: 2 (DW_TAG_variable)
<1f>   DW_AT_name: (indexed string: 0x3): attr_foo
<20>   DW_AT_type: <0x29>
<24>   DW_AT_external: 1
<24>   DW_AT_decl_file   : 0
<25>   DW_AT_decl_line   : 2
<26>   DW_AT_location:  (DW_OP_addrx <0>)
 <1><29>: Abbrev Number: 3 (DW_TAG_typedef)
<2a>   DW_AT_type: <0x31>
<2e>   DW_AT_name: (indexed string: 0x5): foo
<2f>   DW_AT_decl_file   : 0
<30>   DW_AT_decl_line   : 1
 <1><31>: Abbrev Number: 4 (DW_TAG_base_type)
<32>   DW_AT_name: (indexed string: 0x4): int
<33>   DW_AT_encoding: 5(signed)
<34>   DW_AT_byte_size   : 4
 <1><35>: Abbrev Number: 2 (DW_TAG_variable)
<36>   DW_AT_name: (indexed string: 0x6): plain_foo
<37>   DW_AT_type: <0x29>
<3b>   DW_AT_external: 1
<3b>   DW_AT_decl_file   : 0
<3c>   DW_AT_decl_line   : 3
<3d>   DW_AT_location:  (DW_OP_addrx <0x1>)
 <1><40>: Abbrev Number: 0


Note this isn't strictly related to 'may_alias', I just found it to be a
reliable
reproducer.  I tripped on this while working on a patch to support a BPF
feature,
the btf_type_tag attribute.


I think this happens because this lookup in modified_type_die:

  /* If we do, then we can just use its DIE, if it exists.  */
  if (qualified_type)
{
  mod_type_die = lookup_type_die (qualified_type);

finds the typedef DIE for the un-__attribute__-ed use 'foo', but
returns NULL for the __attribute__-ed use of 'foo':

Breakpoint 6, modified_type_die (type=,
cv_quals=0, reverse=false, 
context_die=) at
../../../gcc/gcc/dwarf2out.cc:13631
(gdb) pt type
  constant 32>
unit-size  constant 4>
align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x776215e8
attributes > precision:32 min
 max >
...
13699 if (qualified_type)
(gdb) 
13701 mod_type_die = lookup_type_die (qualified_type);
(gdb) 
13706 if (mod_type_die
(gdb) p mod_type_die
$1 = 

Then recurses with

  return modified_type_die (DECL_ORIGINAL_TYPE (name), cv_quals,
  reverse, context_die);

Where DECL_ORIGINAL_TYPE (name) is a plain integer type:

  constant 32>
unit-size  constant 4>
align:32 warn_if_not_align:0 symtab:-142864960 alias-set -1 canonical-type
0x776215e8 precision:32 min  max

pointer_to_this >


I am not 100% sure whether the GCC output is "strictly incorrect" DWA

[Bug debug/110439] Missing DW_TAG_typedef for variable with attribute of typedef'd type

2023-06-27 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110439

David Faust  changed:

   What|Removed |Added

 CC||jemarch at gcc dot gnu.org

--- Comment #2 from David Faust  ---
(In reply to Andrew Pinski from comment #1)
> The may_alias does not apply directly to variables nor their types 

I use may_alias here as a placeholder, since it persists in the TREE
representation through this point.  I found this while implementing a new
attribute (btf_type_tag, a BPF feature) which does apply directly to types with
a similar representation in the TREE, which triggered the same behavior.

[Bug target/109558] bpf: support BTF and DWARF tag annotations for BPF

2023-07-19 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109558

--- Comment #1 from David Faust  ---
v1 patch series for btf_decl_tag:

https://gcc.gnu.org/pipermail/gcc-patches/2023-July/624156.html

This also adds infrastructure which will be used for btf_type_tag.

[Bug target/109558] bpf: support BTF and DWARF tag annotations for BPF

2023-07-19 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109558

--- Comment #2 from David Faust  ---
Patches for btf_type_tag WIP, but DWARF for type_tags in certain cases is
incorrect seemingly due to PR debug/110439.  I am still investigating.

  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110439

[Bug debug/112849] btf: wrong BTF_KIND_DATSEC entries for extern variables without known section

2023-12-04 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112849

--- Comment #1 from David Faust  ---
Simple reproducer. Note how clang does not emit an entry
in BTF_KIND_DATASEC for 'extern int a'.

$ cat a.c
extern int a;
int b;

int foo (void)
{
  return a + b;
}

$ ~/toolchains/bpf/bin/bpf-unknown-none-gcc -gbtf -c a.c -o a.o
$ /usr/sbin/bpftool btf dump file a.o
[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
[2] FUNC_PROTO '(anon)' ret_type_id=1 vlen=0
[3] VAR 'a' type_id=1, linkage=extern
[4] VAR 'b' type_id=1, linkage=global
[5] FUNC 'foo' type_id=2 linkage=global
[6] DATASEC '.bss' size=0 vlen=2
type_id=3 offset=0 size=4 (VAR 'a')
type_id=4 offset=0 size=4 (VAR 'b')

$ ~/toolchains/llvm/bin/clang -target bpf -c -g a.c -o a.o
$ /usr/sbin/bpftool btf dump file a.o
[1] FUNC_PROTO '(anon)' ret_type_id=2 vlen=0
[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
[3] FUNC 'foo' type_id=1 linkage=global
[4] VAR 'a' type_id=2, linkage=extern
[5] VAR 'b' type_id=2, linkage=global
[6] DATASEC '.bss' size=0 vlen=1
type_id=5 offset=0 size=4 (VAR 'b')

[Bug debug/112849] New: btf: wrong BTF_KIND_DATSEC entries for extern variables without known section

2023-12-04 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112849

Bug ID: 112849
   Summary: btf: wrong BTF_KIND_DATSEC entries for extern
variables without known section
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Keywords: btf-debug, wrong-debug
  Severity: normal
  Priority: P3
 Component: debug
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david.faust at oracle dot com
CC: cupertino.miranda at oracle dot com, ibhagat at gcc dot 
gnu.org,
jemarch at gcc dot gnu.org
  Target Milestone: ---

When building bpf-next selftests with gcc trunk, we get the following
error from libbpf:

libbpf: linker: adding object file 'linked_vars1.bpf.o'...
libbpf: linker: adding object file 'linked_vars2.bpf.o'...
libbpf: global 'input_data1': section mismatch 4 vs 5
Error: failed to link 'linked_vars2.bpf.o': Invalid argument (22)

Here libbpf is doing some form of linking of the two objects.
'input_data1' is declared and initialized in linked_vars1, and
placed in .data. In linked_vars2 it is declared extern, however
an entry for it is added in the .bss BTF_KIND_DATASEC record in
linked_vars2.bpf.o.

clang does not emit entries in BTF_KIND_DATASEC for extern variable
decls without an explicit section e.g. via __attribute__((section(...))).

gcc
[7237] DATASEC '.bss' size=0 vlen=8
type_id=7059 offset=0 size=4 (VAR 'input_data1')  <-
type_id=7167 offset=0 size=4 (VAR 'input_bss1')   <-
type_id=7100 offset=0 size=4 (VAR 'output_sink2')
type_id=7111 offset=0 size=4 (VAR 'output_rodata2')
type_id=7065 offset=0 size=4 (VAR 'output_data2')
type_id=7090 offset=0 size=4 (VAR 'output_bss2')
type_id=7079 offset=0 size=4 (VAR 'input_bss_weak')
type_id=7192 offset=0 size=4 (VAR 'input_bss2')

clang
[34] DATASEC '.bss' size=0 vlen=6
type_id=18 offset=0 size=4 (VAR 'input_bss2')
type_id=19 offset=0 size=4 (VAR 'input_bss_weak')
type_id=20 offset=0 size=4 (VAR 'output_bss2')
type_id=21 offset=0 size=4 (VAR 'output_data2')
type_id=22 offset=0 size=4 (VAR 'output_rodata2')
type_id=23 offset=0 size=4 (VAR 'output_sink2')


The problem is that when creating the BTF_KIND_DATASEC entires,
gcc is incorrectly falling back to a default section name (like .bss)
for variables, even if they are 'extern' decls. 

gcc should be changed to not emit entries in any BTF_KIND_DATASEC
for extern variable decls without a known section.

[Bug debug/111735] incorrect BTF representation of forward-declared enums

2023-12-05 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111735

David Faust  changed:

   What|Removed |Added

 CC||david.faust at oracle dot com

--- Comment #1 from David Faust  ---
Sorry for the delay, somehow I missed this until now.

Confirmed... though this really ought to be further discussed and
formalized with the kernel BPF folks. As of now, btf.rst does not
specify any representation at all for forward-declared enums. And,
it lists in 'encoding requirements' for BTF_KIND_ENUM that 'size'
must be one of 1/2/4/8, so in a sense this de-facto representation
is not really valid.

IMO it would be better to adjust the BTF_KIND_FWD definition to
support forward-declared enums. CTF for example encodes the kind
of the forward in the 'type' field of its KIND_FWD, which in BTF
is simply unused. Anyway, that can be raised for discussion on
the bpf list.

In the meanwhile, it should not be problematic to adapt GCC to
follow clang and pahole in emitting KIND_ENUM with vlen=0.

[Bug debug/113566] New: btf: incorrect BTF_KIND_DATASEC entries for variables which are optimized out

2024-01-23 Thread david.faust at oracle dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113566

Bug ID: 113566
   Summary: btf: incorrect BTF_KIND_DATASEC entries for variables
which are optimized out
   Product: gcc
   Version: 14.0
Status: UNCONFIRMED
  Keywords: btf-debug
  Severity: normal
  Priority: P3
 Component: debug
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david.faust at oracle dot com
CC: david.faust at oracle dot com, jemarch at gcc dot gnu.org
  Target Milestone: ---
Target: all

Consider a simple program:

$ cat static.c
static int a = 5;

int foo (int x) {
return a + x;
}

When compiled with -O2, variable 'a' is optimized away, and its use is
replaced with a literal 5 in the resulting object code.

For all targets except BPF, BTF is emitted at early_finish always.
For the BPF target, if -mco-re is in effect, then BTF is emitted at finish
rather than early_finish.

The combination of -O2 with emitting BTF at early_finish causes incorrect
BTF_KIND_DATASEC entries to be emitted for all targets except BPF CO-RE:

$ ~/toolchains/bpf/bin/bpf-unknown-none-gcc -c -gbtf -O2 -mco-re static.c -o
static.o
$ /usr/sbin/bpftool btf dump file static.o
[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
[2] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1
'x' type_id=1
[3] VAR 'a' type_id=1, linkage=static
[4] FUNC 'foo' type_id=2 linkage=global

$ ~/toolchains/bpf/bin/bpf-unknown-none-gcc -c -gbtf -O2 -mno-co-re static.c -o
static.o
$ /usr/sbin/bpftool btf dump file static.o
[1] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
[2] FUNC_PROTO '(anon)' ret_type_id=1 vlen=1
'x' type_id=1
[3] VAR 'a' type_id=1, linkage=static
[4] FUNC 'foo' type_id=2 linkage=global
[5] DATASEC '.data' size=0 vlen=1
type_id=3 offset=0 size=4 (VAR 'a')
(same for e.g. x86_64 with -gbtf)

In either case, 'a' is optimized away, and is not allocated in .data: 

$ ~/toolchains/bpf/bin/bpf-unknown-none-objdump -dh static.o

static.o: file format elf64-bpfle

Sections:
Idx Name  Size  VMA   LMA   File off  Algn
  0 .text 0018      0040  2**3
  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data       0058  2**0
  CONTENTS, ALLOC, LOAD, DATA
  2 .bss        0058  2**0
  ALLOC
...

So, the BTF_KIND_DATASEC entry claiming 'a' is allocated in .data is incorrect.
Clang correctly does not generate such a DATASEC entry.

The only case where the entry is correctly not generated by gcc is for the BPF
target with -mco-re, since in that case the DATASEC entries will be generated
at finish rather than early finish, by which time 'a' is known to be optimized
away.