gcc-12-20250102 is now available

2025-01-02 Thread GCC Administrator via Gcc
Snapshot gcc-12-20250102 is now available on
  https://gcc.gnu.org/pub/gcc/snapshots/12-20250102/
and on various mirrors, see https://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 12 git branch
with the following options: git://gcc.gnu.org/git/gcc.git branch 
releases/gcc-12 revision df5e5d0ad7764b159848c95acaff848f67f5f574

You'll find:

 gcc-12-20250102.tar.xz   Complete GCC

  SHA256=dcb3fa61be36019bb94192d358e7cba7170185f799005548e0e3ef0192d3918c
  SHA1=539b814b07f80c8416212fdb2b52df28a2769aa6

Diffs from 12-20241226 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-12
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.


Re: Errors compiling BPF programs from Linux selftests/bpf with GCC

2025-01-02 Thread Jose E. Marchesi via Gcc


> On Thu, 2025-01-02 at 10:47 +0100, Jose E. Marchesi wrote:
>> Hi Ihor.
>> Thanks for working on this! :)
>> 
>> > [...]
>> > Older versions compile the dummy program without errors, however on
>> > attempt to build the selftests there is a different issue: conflicting
>> > int64 definitions (full log at [6]).
>> > 
>> > In file included from /usr/include/x86_64-linux-gnu/sys/types.h:155,
>> >  from /usr/include/x86_64-linux-gnu/bits/socket.h:29,
>> >  from /usr/include/x86_64-linux-gnu/sys/socket.h:33,
>> >  from /usr/include/linux/if.h:28,
>> >  from /usr/include/linux/icmp.h:23,
>> >  from progs/test_cls_redirect_dynptr.c:10:
>> > /usr/include/x86_64-linux-gnu/bits/stdint-intn.h:27:19: error: 
>> > conflicting types for ‘int64_t’; have ‘__int64_t’ {aka ‘long long int’}
>> >27 | typedef __int64_t int64_t;
>> >   |   ^~~
>> > In file included from progs/test_cls_redirect_dynptr.c:6:
>> > 
>> > /ci/workspace/bpfgcc.20240922/lib/gcc/bpf-unknown-none/15.0.0/include/stdint.h:43:24:
>> > note: previous declaration of ‘int64_t’ with type ‘int64_t’ {aka ‘long
>> > int’}
>> >43 | typedef __INT64_TYPE__ int64_t;
>> >   |^~~
>> 
>> I think this is what is going on:
>> 
>> The BPF selftest is indirectly including glibc headers from the host
>> where it is being compiled.  In this case your x86_64 ubuntu system.
>> 
>> Many glibc headers include bits/wordsize.h, which in the case of x86_64
>> is:
>> 
>>   #if defined __x86_64__ && !defined __ILP32__
>>   # define __WORDSIZE64
>>   #else
>>   # define __WORDSIZE32
>>   #define __WORDSIZE32_SIZE_ULONG0
>>   #define __WORDSIZE32_PTRDIFF_LONG  0
>>   #endif
>> 
>> and then in bits/types.h:
>> 
>>   #if __WORDSIZE == 64
>>   typedef signed long int __int64_t;
>>   typedef unsigned long int __uint64_t;
>>   #else
>>   __extension__ typedef signed long long int __int64_t;
>>   __extension__ typedef unsigned long long int __uint64_t;
>>   #endif
>> 
>> i.e. your BPF program ends using __WORDSIZE 32.  This eventually leads
>> to int64_t being defined as `signed long long int' in stdint-intn.h, as
>> it would correspond to a x86_64 program running in 32-bit mode.
>> 
>> GCC BPF, on the other hand, is a "baremetal" compiler and it provides a
>> small set of headers (including stdint.h) that implement standard C99
>> types like int64_t, adjusted to the BPF architecture.
>> 
>> In this case there is a conflict between the 32-bit x86_64 definition of
>> int64_t and the one of BPF.
>> 
>> PS: the other headers installed by GCC BPF are:
>> float.h iso646.h limits.h stdalign.h stdarg.h stdatomic.h stdbool.h
>> stdckdint.h stddef.h stdfix.h stdint.h stdnoreturn.h syslimits.h
>> tgmath.h unwind.h varargs.h
>
> I wondered how this works with clang, because it does not define
> __x86_64__ for bpf target. After staring and the output of -E:
> - for clang int64_t is defined once and definition originate from
>   /usr/include/bits/stdint-intn.h included from /usr/include/stdint.h;
> - for gcc int64_t is defined two times, definitions originate from:
>   - /bpf-unknown-none/15.0.0/include/stdint.h
>   - /usr/include/bits/stdint-intn.h included from /usr/include/sys/types.h.
>
> So, both refer to stdint-intn.h, but only gcc refers to
> compiler-specific stdint.h. This is so because of the structure of the
> clang's /usr/lib/clang/19/include/stdint.h:
>
> ...
> #if __STDC_HOSTED__ && __has_include_next()
>   ...
>   # include_next 
>   ...
> #else
>   ...
>   typedef __INT64_TYPE__ int64_t;
>   ...
> #endif
> ...
>
> The __STDC_HOSTED__ is defined as 1, thus when clang compiles the test case,
> compiler-specific stdint.h is included, but it's content is ifdef'ed out and
> it refers to system stdint.h instead. On the other hand, gcc-specific stdint.h
> unconditionally typedefs int64_t.

Yes, in the GCC BPF backend we are using

  use_gcc_stdint=provide

which makes GCC to provide the version of stdint.h that assumes
freestanding ("baremetal") mode.  If we changed it to use

  use_gcc_stdint=wrap

then it would install a stdint.h that does somethins similar to what
clang does, at least in hosts providing C99 headers (note the lack of
__has_include_next):

  #ifndef _GCC_WRAP_STDINT_H
  #if __STDC_HOSTED__
  # if defined __cplusplus && __cplusplus >= 201103L
  #  undef __STDC_LIMIT_MACROS
  #  define __STDC_LIMIT_MACROS
  #  undef __STDC_CONSTANT_MACROS
  #  define __STDC_CONSTANT_MACROS
  # endif
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wpedantic" // include_next
  # include_next 
  #pragma GCC diagnostic pop
  #else
  # include "stdint-gcc.h"
  #endif
  #define _GCC_WRAP_STDINT_H
  #endif

We could switch to "wrap" to align with clang, but in that case it would
be up to the user to provide a "

Re: Errors compiling BPF programs from Linux selftests/bpf with GCC

2025-01-02 Thread Eduard Zingerman via Gcc
On Thu, 2025-01-02 at 10:47 +0100, Jose E. Marchesi wrote:
> Hi Ihor.
> Thanks for working on this! :)
> 
> > [...]
> > Older versions compile the dummy program without errors, however on
> > attempt to build the selftests there is a different issue: conflicting
> > int64 definitions (full log at [6]).
> > 
> > In file included from /usr/include/x86_64-linux-gnu/sys/types.h:155,
> >  from /usr/include/x86_64-linux-gnu/bits/socket.h:29,
> >  from /usr/include/x86_64-linux-gnu/sys/socket.h:33,
> >  from /usr/include/linux/if.h:28,
> >  from /usr/include/linux/icmp.h:23,
> >  from progs/test_cls_redirect_dynptr.c:10:
> > /usr/include/x86_64-linux-gnu/bits/stdint-intn.h:27:19: error: 
> > conflicting types for ‘int64_t’; have ‘__int64_t’ {aka ‘long long int’}
> >27 | typedef __int64_t int64_t;
> >   |   ^~~
> > In file included from progs/test_cls_redirect_dynptr.c:6:
> > 
> > /ci/workspace/bpfgcc.20240922/lib/gcc/bpf-unknown-none/15.0.0/include/stdint.h:43:24:
> > note: previous declaration of ‘int64_t’ with type ‘int64_t’ {aka ‘long
> > int’}
> >43 | typedef __INT64_TYPE__ int64_t;
> >   |^~~
> 
> I think this is what is going on:
> 
> The BPF selftest is indirectly including glibc headers from the host
> where it is being compiled.  In this case your x86_64 ubuntu system.
> 
> Many glibc headers include bits/wordsize.h, which in the case of x86_64
> is:
> 
>   #if defined __x86_64__ && !defined __ILP32__
>   # define __WORDSIZE 64
>   #else
>   # define __WORDSIZE 32
>   #define __WORDSIZE32_SIZE_ULONG 0
>   #define __WORDSIZE32_PTRDIFF_LONG   0
>   #endif
> 
> and then in bits/types.h:
> 
>   #if __WORDSIZE == 64
>   typedef signed long int __int64_t;
>   typedef unsigned long int __uint64_t;
>   #else
>   __extension__ typedef signed long long int __int64_t;
>   __extension__ typedef unsigned long long int __uint64_t;
>   #endif
> 
> i.e. your BPF program ends using __WORDSIZE 32.  This eventually leads
> to int64_t being defined as `signed long long int' in stdint-intn.h, as
> it would correspond to a x86_64 program running in 32-bit mode.
> 
> GCC BPF, on the other hand, is a "baremetal" compiler and it provides a
> small set of headers (including stdint.h) that implement standard C99
> types like int64_t, adjusted to the BPF architecture.
> 
> In this case there is a conflict between the 32-bit x86_64 definition of
> int64_t and the one of BPF.
> 
> PS: the other headers installed by GCC BPF are:
> float.h iso646.h limits.h stdalign.h stdarg.h stdatomic.h stdbool.h
> stdckdint.h stddef.h stdfix.h stdint.h stdnoreturn.h syslimits.h
> tgmath.h unwind.h varargs.h

I wondered how this works with clang, because it does not define
__x86_64__ for bpf target. After staring and the output of -E:
- for clang int64_t is defined once and definition originate from
  /usr/include/bits/stdint-intn.h included from /usr/include/stdint.h;
- for gcc int64_t is defined two times, definitions originate from:
  - /bpf-unknown-none/15.0.0/include/stdint.h
  - /usr/include/bits/stdint-intn.h included from /usr/include/sys/types.h.

So, both refer to stdint-intn.h, but only gcc refers to
compiler-specific stdint.h. This is so because of the structure of the
clang's /usr/lib/clang/19/include/stdint.h:

...
#if __STDC_HOSTED__ && __has_include_next()
  ...
  # include_next 
  ...
#else
  ...
  typedef __INT64_TYPE__ int64_t;
  ...
#endif
...

The __STDC_HOSTED__ is defined as 1, thus when clang compiles the test case,
compiler-specific stdint.h is included, but it's content is ifdef'ed out and
it refers to system stdint.h instead. On the other hand, gcc-specific stdint.h
unconditionally typedefs int64_t.

Links:
- test case pre-processed by clang and gcc:
  https://gist.github.com/eddyz87/d381094d67979291bd8338655b15dd5e
- LLVM source code for stdint.h:
  
https://github.com/llvm/llvm-project/blob/c703b4645c79e889fd6a0f3f64f01f957d981aa4/clang/lib/Headers/stdint.h#L24



Re: Errors compiling BPF programs from Linux selftests/bpf with GCC

2025-01-02 Thread Eduard Zingerman via Gcc
On Fri, 2025-01-03 at 01:16 +0100, Jose E. Marchesi wrote:

[...]

> Yes, in the GCC BPF backend we are using
> 
>   use_gcc_stdint=provide
> 
> which makes GCC to provide the version of stdint.h that assumes
> freestanding ("baremetal") mode.  If we changed it to use
> 
>   use_gcc_stdint=wrap
> 
> then it would install a stdint.h that does somethins similar to what
> clang does, at least in hosts providing C99 headers (note the lack of
> __has_include_next):
> 
>   #ifndef _GCC_WRAP_STDINT_H
>   #if __STDC_HOSTED__
>   # if defined __cplusplus && __cplusplus >= 201103L
>   #  undef __STDC_LIMIT_MACROS
>   #  define __STDC_LIMIT_MACROS
>   #  undef __STDC_CONSTANT_MACROS
>   #  define __STDC_CONSTANT_MACROS
>   # endif
>   #pragma GCC diagnostic push
>   #pragma GCC diagnostic ignored "-Wpedantic" // include_next
>   # include_next 
>   #pragma GCC diagnostic pop
>   #else
>   # include "stdint-gcc.h"
>   #endif
>   #define _GCC_WRAP_STDINT_H
>   #endif
> 
> We could switch to "wrap" to align with clang, but in that case it would
> be up to the user to provide a "host" stdint.h that contains sensible
> definitions for BPF.  The kernel selftests, for example, would need to
> do so to avoid including /usr/include/stdint.h that more likely than not
> will provide incorrect definitions for int64_t and friends...

Would it be possible to push a branch that uses '=wrap' thing somewhere?
So that it could be further tested to see if there are more issues with 
selftests.



Re: Errors compiling BPF programs from Linux selftests/bpf with GCC

2025-01-02 Thread Eduard Zingerman via Gcc
On Thu, 2025-01-02 at 19:24 +0100, Jose E. Marchesi wrote:

[...]

> IMO the BPP selftest (and BPF programs in general) must not include host
> glibc headers at all, regardless of what BPF compiler is used.  The
> glibc headers installed in the host are tailored to some particular
> architecture, be it x86_64 or whatever, not necessarily compatible with
> what the compilers assume for the BPF target.
>
> This particular case shows the problem well: all the glibc headers
> included by that BPF selftest assume that `long' is 32 bits, not 64
> bits, because x86_64 is not defined.  This conflicts with both clang's
> and GCC's assumption that in BPF a `long' is 64 bits.  This may or may
> not be a problem, depending on whether the BPF program uses the stuff
> defined in the headers and how it uses it.  Had you be using an arm or
> sparc host instead of x86_64, you may be including macros and stuff that
> assume chars are unsigned.  But chars are signed in bpf.

This makes sense, but might cause some friction.
The following glibc headers are included directly from selftests:
- errno.h
- features.h
- inttypes.h
- limits.h
- netinet/in.h
- netinet/udp.h
- sched.h
- stdint.h
- stdlib.h
- string.h
- sys/socket.h
- sys/types.h
- time.h
- unistd.h

However, removing includes for these headers does not help the test in
question, because some linux UAPI headers include libc headers when exported:

In file included from /usr/include/netinet/udp.h:51,
 from progs/test_cls_redirect_dynptr.c:20:

/home/eddy/work/tmp/gccbpf/lib/gcc/bpf-unknown-none/15.0.0/include/stdint.h:43:24:
 error: conflicting types for ‘int64_t’; have ‘long int’
   43 | typedef __INT64_TYPE__ int64_t;
  |^~~
In file included from /usr/include/sys/types.h:155,
 from /usr/include/bits/socket.h:29,
 from /usr/include/sys/socket.h:33,
 from /usr/include/linux/if.h:28,
 from /usr/include/linux/icmp.h:23,
 from progs/test_cls_redirect_dynptr.c:12:
/usr/include/bits/stdint-intn.h:27:19: note: previous declaration of 
‘int64_t’ with type ‘int64_t’ {aka ‘long long int’}
   27 | typedef __int64_t int64_t;
  |   ^~~

On my system (Fedora 41) the linux/{icmp,if}.h UAPI headers are
provided by kernel-headers package, sys/socket.h is provided by
glibc-devel package.

The UAPI headers have two modes depending whether __KERNEL__ is
defined. When used during kernel build the __KERNEL__ is defined and
there are no outside references. When exported for packages like
kernel-headers (via 'make headers' target) the __KERNEL__ is not
defined and there are some references to libc includes
(in fact, references to '#ifdef __KERNEL__' blocks are cut out during
 headers export).

E.g. here is a fragment of linux/if.h, when viewed from kernel source:

#ifndef _LINUX_IF_H
#define _LINUX_IF_H

#include   /* for compatibility with glibc */
#include /* for "__kernel_caddr_t" et al */
#include/* for "struct sockaddr" et al  */
#include  /* for "__user" et al   */

#ifndef __KERNEL__
#include  /* for struct sockaddr. 
*/
#endif

And here is the same fragment as part of the kernel-headers package
(/usr/include/linux/if.h):

#ifndef _LINUX_IF_H
#define _LINUX_IF_H

#include   /* for compatibility with glibc */
#include /* for "__kernel_caddr_t" et al */
#include/* for "struct sockaddr" et al  */
/* for "__user" et al   */

#include  /* for struct sockaddr. 
*/

As far as I understand, the idea right now is that BPF users can
install the kernel-headers package (or its equivalent) and start
hacking. If we declare that this is no longer a blessed way, people
would need to switch to packages like kernel-devel that provide full
set of kernel headers for use with dkms etc, e.g. for my system the
if.h would be located here:
/usr/src/kernels/6.12.6-200.fc41.x86_64/include/uapi/linux/if.h .

To me this seems logical, however potentially such change might have
implications for existing BPF code-base.



Re: [RFC] Enabling SVE with offloading to nvptx

2025-01-02 Thread Andrew Stubbs

On 27/12/2024 12:29, Prathamesh Kulkarni wrote:




-Original Message-
From: Jakub Jelinek 
Sent: 17 December 2024 19:09
To: Prathamesh Kulkarni 
Cc: Andrew Stubbs ; Richard Biener
; Richard Biener ;
gcc@gcc.gnu.org; Thomas Schwinge 
Subject: Re: [RFC] Enabling SVE with offloading to nvptx

External email: Use caution opening links or attachments


On Mon, Dec 02, 2024 at 11:17:08AM +, Prathamesh Kulkarni wrote:

--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -233,6 +233,12 @@ public:
   flag_finite_loops or similar pragmas state.  */
unsigned finite_p : 1;

+  /* True if SIMD loop needs delayed lowering of artefacts like
+ safelen and length of omp simd arrays that depend on target's
+ max_vf.  This is true for offloading, when max_vf is computed

after

+ streaming out to device.  */
+  unsigned needs_max_vf_lowering: 1;


Consistency, finite_p above uses space before :, the above line
doesn't.


--- a/gcc/omp-expand.cc
+++ b/gcc/omp-expand.cc
@@ -7170,6 +7170,10 @@ expand_omp_simd (struct omp_region *region,

struct omp_for_data *fd)

loop->latch = cont_bb;
add_loop (loop, l1_bb->loop_father);
loop->safelen = safelen_int;
+  loop->needs_max_vf_lowering = is_in_offload_region (region);
+  if (loop->needs_max_vf_lowering)
+ cfun->curr_properties &= ~PROP_gimple_lomp_dev;


Do you really need this for non-SVE arches?
I mean, could you not set loop->needs_max_vf_lowering if maximum
number of poly_int coeffs is 1?  Or if omp_max_vf returns constant or
something similar?

Well, I guess the issue is not really about VLA vectors but when host and 
device have
different max_vf, and selecting optimal max_vf is not really possible during 
omp-low/omp-expand,
since we don't have device's target info available at this point. Andrew's 
recent patch works around this
limitation by searching for "amdgcn" in OFFLOAD_TARGET_NAMES in omp_max_vf, but 
I guess a more general solution
would be to delay lowering max_vf after streaming-out to device irrespective of 
VLA/VLS vectors ?
For AArch64/nvptx offloading with SVE, where host is VLA and device is VLS, the 
issue is more pronounced (failing to compile),
compared to offloading from VLS host to VLS device (selecting sub-optimal 
max_vf).


That patch fixed a couple of cases. The name matching was only used for 
the case where an oversized VF was harmless. The other case where making 
the VF too large would reserve excess memory was deferred to the device 
compiler.


In general, deferring decisions is probably a good idea, but it's not 
always possible, or optimal, and in the above case it certainly wasn't 
the easy option. There's already precedent for doing the name match in 
the SIMT VF code (for NVPTX), so it was easier and sufficient to do the 
same.


Andrew


Re: smtgcc end-of-year update

2025-01-02 Thread Andi Kleen via Gcc
Krister Walfridsson via Gcc  writes:

> But running smtgcc on the test suite is not the best use case for the
> tool -- it only detects bugs where the test triggers an unrelated bug
> compared to what the test is checking, which should be uncommon. I
> therefore plan to start testing by compiling real-world code and doing
> some fuzzing. One problem is that this often finds the open bugs
> mentioned in the previous section, making it time-consuming to check
> if each new issue is a repeat. For example, running yarpgen gives me a
> few failure reports per day of PR106883.

I would increase the priority of PR106883 if it blocks so much testing.
But does disabling the slsr pass not help?

-Andi



Re: Errors compiling BPF programs from Linux selftests/bpf with GCC

2025-01-02 Thread Jose E. Marchesi via Gcc


> On Thursday, January 2nd, 2025 at 1:47 AM, Jose E. Marchesi 
>  wrote:
>
>> Hi Ihor.
>> Thanks for working on this! :)
>> 
>> > [...]
>> > Older versions compile the dummy program without errors, however on
>> > attempt to build the selftests there is a different issue: conflicting
>> > int64 definitions (full log at [6]).
>> > 
>> > In file included from /usr/include/x86_64-linux-gnu/sys/types.h:155,
>> > from /usr/include/x86_64-linux-gnu/bits/socket.h:29,
>> > from /usr/include/x86_64-linux-gnu/sys/socket.h:33,
>> > from /usr/include/linux/if.h:28,
>> > from /usr/include/linux/icmp.h:23,
>> > from progs/test_cls_redirect_dynptr.c:10:
>> > /usr/include/x86_64-linux-gnu/bits/stdint-intn.h:27:19: error:
>> > conflicting types for ‘int64_t’; have ‘__int64_t’ {aka ‘long long
>> > int’}
>> > 27 | typedef __int64_t int64_t;
>> > | ^~~
>> > In file included from progs/test_cls_redirect_dynptr.c:6:
>> > /ci/workspace/bpfgcc.20240922/lib/gcc/bpf-unknown-none/15.0.0/include/stdint.h:43:24:
>> > note: previous declaration of ‘int64_t’ with type ‘int64_t’ {aka ‘long
>> > int’}
>> > 43 | typedef INT64_TYPE int64_t;
>> > | ^~~
>> 
>> 
>> I think this is what is going on:
>> 
>> The BPF selftest is indirectly including glibc headers from the host
>> where it is being compiled. In this case your x86_64 ubuntu system.
>> 
>> Many glibc headers include bits/wordsize.h, which in the case of x86_64
>> is:
>> 
>> #if defined x86_64 && !defined ILP32
>> # define __WORDSIZE 64
>> #else
>> # define __WORDSIZE 32
>> #define __WORDSIZE32_SIZE_ULONG 0
>> #define __WORDSIZE32_PTRDIFF_LONG 0
>> #endif
>> 
>> and then in bits/types.h:
>> 
>> #if __WORDSIZE == 64
>> typedef signed long int __int64_t;
>> typedef unsigned long int __uint64_t;
>> #else
>> extension typedef signed long long int __int64_t;
>> extension typedef unsigned long long int __uint64_t;
>> #endif
>> 
>> i.e. your BPF program ends using __WORDSIZE 32. This eventually leads
>> to int64_t being defined as `signed long long int' in stdint-intn.h, as
>> it would correspond to a x86_64 program running in 32-bit mode.
>> 
>> GCC BPF, on the other hand, is a "baremetal" compiler and it provides a
>> small set of headers (including stdint.h) that implement standard C99
>> types like int64_t, adjusted to the BPF architecture.
>> 
>> In this case there is a conflict between the 32-bit x86_64 definition of
>> int64_t and the one of BPF.
>
> Hi Jose, thanks for breaking this down.
>
> I was able to mitigate int64_t declaration conflict by passing
> -nostdinc to gcc.
>
> Currently system-installed headers are being passed via -idirafter in
> a compilation command:
>
> /ci/workspace/bpfgcc.20241229/bin/bpf-unknown-none-gcc \
> -g -Wall -Werror -D__TARGET_ARCH_x86 -mlittle-endian \
> -I/ci/workspace/tools/testing/selftests/bpf/tools/include
> -I/ci/workspace/tools/testing/selftests/bpf \
> -I/ci/workspace/tools/include/uapi \
> -I/ci/workspace/tools/testing/selftests/usr/include \
> -Wno-compare-distinct-pointer-types \
> -idirafter /usr/lib/gcc/x86_64-linux-gnu/13/include \
> -idirafter /usr/local/include \
> -idirafter /usr/include/x86_64-linux-gnu \
> -idirafter /usr/include \
> -DBPF_NO_PRESERVE_ACCESS_INDEX \
> -Wno-attributes \
> -O2 -std=gnu17 \  # -nostdinc here helps
> -c progs/test_cls_redirect.c \
> -o 
> /ci/workspace/tools/testing/selftests/bpf/bpf_gcc/test_cls_redirect.bpf.o
>
> Passing -nostdinc makes gcc to pick compiler-installed header, if I
> understand correctly.

I think that passing -nostdinc is having the opposite effect: it makes
GCC to not use its own distributed stdint.h, so it finds the host's
stdint.h via idirafter.

With that option GCC BPF behaves like clang BPF, include-wise.

>> 
>> PS: the other headers installed by GCC BPF are:
>> float.h iso646.h limits.h stdalign.h stdarg.h stdatomic.h stdbool.h
>> stdckdint.h stddef.h stdfix.h stdint.h stdnoreturn.h syslimits.h
>> tgmath.h unwind.h varargs.h
>
> From your comments, it seems that BPF programs *must not* include
> system glibc headers when compiled with GCC. Or is this only true for
> the headers you listed above?
>
> I wonder what is the proper way to build BPF programs with gcc then.
> In the source code the includes are what you'd expect:
>
> #include 
> #include 
> #include// conflict is between this
> #include 
>
> #include 
> #include// and this
> #include 
> ...
>
> Any suggestions?

IMO the BPP selftest (and BPF programs in general) must not include host
glibc headers at all, regardless of what BPF compiler is used.  The
glibc headers installed in the host are tailored to some particular
architecture, be it x86_64 or whatever, not necessarily compatible with
what the compilers assume for the BPF target.

This particular case shows the problem well: all the glibc headers
included by that BPF selft

Re: Errors compiling BPF programs from Linux selftests/bpf with GCC

2025-01-02 Thread Ihor Solodrai via Gcc
On Thursday, January 2nd, 2025 at 1:47 AM, Jose E. Marchesi 
 wrote:

> Hi Ihor.
> Thanks for working on this! :)
> 
> > [...]
> > Older versions compile the dummy program without errors, however on
> > attempt to build the selftests there is a different issue: conflicting
> > int64 definitions (full log at [6]).
> > 
> > In file included from /usr/include/x86_64-linux-gnu/sys/types.h:155,
> > from /usr/include/x86_64-linux-gnu/bits/socket.h:29,
> > from /usr/include/x86_64-linux-gnu/sys/socket.h:33,
> > from /usr/include/linux/if.h:28,
> > from /usr/include/linux/icmp.h:23,
> > from progs/test_cls_redirect_dynptr.c:10:
> > /usr/include/x86_64-linux-gnu/bits/stdint-intn.h:27:19: error: conflicting 
> > types for ‘int64_t’; have ‘__int64_t’ {aka ‘long long int’}
> > 27 | typedef __int64_t int64_t;
> > | ^~~
> > In file included from progs/test_cls_redirect_dynptr.c:6:
> > /ci/workspace/bpfgcc.20240922/lib/gcc/bpf-unknown-none/15.0.0/include/stdint.h:43:24:
> > note: previous declaration of ‘int64_t’ with type ‘int64_t’ {aka ‘long
> > int’}
> > 43 | typedef INT64_TYPE int64_t;
> > | ^~~
> 
> 
> I think this is what is going on:
> 
> The BPF selftest is indirectly including glibc headers from the host
> where it is being compiled. In this case your x86_64 ubuntu system.
> 
> Many glibc headers include bits/wordsize.h, which in the case of x86_64
> is:
> 
> #if defined x86_64 && !defined ILP32
> # define __WORDSIZE 64
> #else
> # define __WORDSIZE 32
> #define __WORDSIZE32_SIZE_ULONG 0
> #define __WORDSIZE32_PTRDIFF_LONG 0
> #endif
> 
> and then in bits/types.h:
> 
> #if __WORDSIZE == 64
> typedef signed long int __int64_t;
> typedef unsigned long int __uint64_t;
> #else
> extension typedef signed long long int __int64_t;
> extension typedef unsigned long long int __uint64_t;
> #endif
> 
> i.e. your BPF program ends using __WORDSIZE 32. This eventually leads
> to int64_t being defined as `signed long long int' in stdint-intn.h, as
> it would correspond to a x86_64 program running in 32-bit mode.
> 
> GCC BPF, on the other hand, is a "baremetal" compiler and it provides a
> small set of headers (including stdint.h) that implement standard C99
> types like int64_t, adjusted to the BPF architecture.
> 
> In this case there is a conflict between the 32-bit x86_64 definition of
> int64_t and the one of BPF.

Hi Jose, thanks for breaking this down.

I was able to mitigate int64_t declaration conflict by passing
-nostdinc to gcc.

Currently system-installed headers are being passed via -idirafter in
a compilation command:

/ci/workspace/bpfgcc.20241229/bin/bpf-unknown-none-gcc \
-g -Wall -Werror -D__TARGET_ARCH_x86 -mlittle-endian \
-I/ci/workspace/tools/testing/selftests/bpf/tools/include
-I/ci/workspace/tools/testing/selftests/bpf \
-I/ci/workspace/tools/include/uapi \
-I/ci/workspace/tools/testing/selftests/usr/include \
-Wno-compare-distinct-pointer-types \
-idirafter /usr/lib/gcc/x86_64-linux-gnu/13/include \
-idirafter /usr/local/include \
-idirafter /usr/include/x86_64-linux-gnu \
-idirafter /usr/include \
-DBPF_NO_PRESERVE_ACCESS_INDEX \
-Wno-attributes \
-O2 -std=gnu17 \  # -nostdinc here helps
-c progs/test_cls_redirect.c \
-o 
/ci/workspace/tools/testing/selftests/bpf/bpf_gcc/test_cls_redirect.bpf.o

Passing -nostdinc makes gcc to pick compiler-installed header, if I
understand correctly.

> 
> PS: the other headers installed by GCC BPF are:
> float.h iso646.h limits.h stdalign.h stdarg.h stdatomic.h stdbool.h
> stdckdint.h stddef.h stdfix.h stdint.h stdnoreturn.h syslimits.h
> tgmath.h unwind.h varargs.h

>From your comments, it seems that BPF programs *must not* include
system glibc headers when compiled with GCC. Or is this only true for
the headers you listed above?

I wonder what is the proper way to build BPF programs with gcc then.
In the source code the includes are what you'd expect:

#include 
#include 
#include// conflict is between this
#include 

#include 
#include// and this
#include 
...

Any suggestions?

Thanks.



Re: Errors compiling BPF programs from Linux selftests/bpf with GCC

2025-01-02 Thread Jose E. Marchesi via Gcc


Hi Ihor.
Thanks for working on this! :)

> [...]
> Older versions compile the dummy program without errors, however on
> attempt to build the selftests there is a different issue: conflicting
> int64 definitions (full log at [6]).
>
> In file included from /usr/include/x86_64-linux-gnu/sys/types.h:155,
>  from /usr/include/x86_64-linux-gnu/bits/socket.h:29,
>  from /usr/include/x86_64-linux-gnu/sys/socket.h:33,
>  from /usr/include/linux/if.h:28,
>  from /usr/include/linux/icmp.h:23,
>  from progs/test_cls_redirect_dynptr.c:10:
> /usr/include/x86_64-linux-gnu/bits/stdint-intn.h:27:19: error: 
> conflicting types for ‘int64_t’; have ‘__int64_t’ {aka ‘long long int’}
>27 | typedef __int64_t int64_t;
>   |   ^~~
> In file included from progs/test_cls_redirect_dynptr.c:6:
> 
> /ci/workspace/bpfgcc.20240922/lib/gcc/bpf-unknown-none/15.0.0/include/stdint.h:43:24:
> note: previous declaration of ‘int64_t’ with type ‘int64_t’ {aka ‘long
> int’}
>43 | typedef __INT64_TYPE__ int64_t;
>   |^~~

I think this is what is going on:

The BPF selftest is indirectly including glibc headers from the host
where it is being compiled.  In this case your x86_64 ubuntu system.

Many glibc headers include bits/wordsize.h, which in the case of x86_64
is:

  #if defined __x86_64__ && !defined __ILP32__
  # define __WORDSIZE   64
  #else
  # define __WORDSIZE   32
  #define __WORDSIZE32_SIZE_ULONG   0
  #define __WORDSIZE32_PTRDIFF_LONG 0
  #endif

and then in bits/types.h:

  #if __WORDSIZE == 64
  typedef signed long int __int64_t;
  typedef unsigned long int __uint64_t;
  #else
  __extension__ typedef signed long long int __int64_t;
  __extension__ typedef unsigned long long int __uint64_t;
  #endif

i.e. your BPF program ends using __WORDSIZE 32.  This eventually leads
to int64_t being defined as `signed long long int' in stdint-intn.h, as
it would correspond to a x86_64 program running in 32-bit mode.

GCC BPF, on the other hand, is a "baremetal" compiler and it provides a
small set of headers (including stdint.h) that implement standard C99
types like int64_t, adjusted to the BPF architecture.

In this case there is a conflict between the 32-bit x86_64 definition of
int64_t and the one of BPF.

PS: the other headers installed by GCC BPF are:
float.h iso646.h limits.h stdalign.h stdarg.h stdatomic.h stdbool.h
stdckdint.h stddef.h stdfix.h stdint.h stdnoreturn.h syslimits.h
tgmath.h unwind.h varargs.h