Bug 125182 - [16/17 Regression] libgcc/config/aarch64/cpuinfo.c now presumes linux ABI's AT_HWCAP, other ABI's need not match
Summary: [16/17 Regression] libgcc/config/aarch64/cpuinfo.c now presumes linux ABI's A...
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 16.0
: P3 normal
Target Milestone: 16.3
Assignee: Not yet assigned to anyone
URL:
Keywords: build
Depends on:
Blocks:
 
Reported: 2026-05-04 19:04 UTC by Mark Millard
Modified: 2026-08-07 08:02 UTC (History)
6 users (show)

See Also:
Host:
Target: aarch64-freebsd
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Millard 2026-05-04 19:04:01 UTC
This is tied to:

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=294062

for aarch65 lang/gcc16-devel builds not working after the
libgcc/config/aarch64/cpuinfo.c changes.

FreeBSD had 16 in use in its list of values before it added
AT_HWCAP (for example) and has historically used the cpuinfo.c
#ifndef . . . #endif structure to deal with providing such
differences by predefining the value. Now the example value
is hardwired to exactly match Linux and overrides the
FreeBSD OS value.

asm/hwcap.h was a linux header. So a change being something
that avoids looking for that file and instead uses some path
that would be expected to not already exist unless deliberately
being newly created would work for them avoiding the linux
header.

May be such a change could involve a name something like:

hwcap_os_specific_abi_value_overrides.h

that would be unlikely to otherwise be created.

For FreeBSD use, as an example, that file could exist and in
turn #include the normal FreeBSD source of values. But normal
gcc16+ could avoid the linux header use as well.

Overall: this suggests making an allowance for having OS
specific ABI values that need not always match the Linux ABI
values, even if it not via the specific type of handing
referenced above.
Comment 1 Mark Millard 2026-05-05 17:12:30 UTC
(In reply to Mark Millard from comment #0)

Besides AT_HWCAP, AT_HWCAP3 and AT_HWCAP4 have different
FreeBSD ABI values than gcc16/linux. AT_HWCAP2 happens to
be a match.
Comment 2 Alex Coplan 2026-05-08 14:54:17 UTC
I suppose this is r16-2683-ga6bb6934a491015c4d3f08763455d86ccfb3bcbe ?
Comment 3 Mark Millard 2026-05-08 15:21:27 UTC
(In reply to Alex Coplan from comment #2)
> I suppose this is r16-2683-ga6bb6934a491015c4d3f08763455d86ccfb3bcbe ?

Yes, that change hard coded linux ABI values for
AT_HWCAP, AT_SWCAP2, AT_HWCAP3, and AT_HWCAP4 .

For the FreeBSD OS: AT_HWCAP, AT_HWCAP3, and AT_HWCAP4
differ in its ABI.

If there are any other of the names that might be of
OS ABI definitions, they would also be at potential
issue for some operating systems.
Comment 4 Alice Carlotti 2026-05-08 16:37:39 UTC
Is it just the four getauxval arguments that differ? That is, are the bit assignments withing each HWCAP the same?

We should probably condition the AT_HWCAP* definitions upon the target OS. Checking a header file first might work in practice, but it feels less robust in case the header file is missing some of the definitions.
Comment 5 Alice Carlotti 2026-05-08 16:55:12 UTC
Based on https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=294062#c5, it looks like there's also an issue with <sys/auxv.h> indirectly including defines for HWCAP_ that are numerically equivalent but spelled differently. So I think we'll need to do one of:
- make the definitions conditional,
- not include <sys/auxb.h>, or
- use different names for the HWCAP_* macros to avoid the clash.

The last option looks like the cleanest one to me.
Comment 6 Mark Millard 2026-05-08 17:13:40 UTC
(In reply to Alice Carlotti from comment #4)
> Is it just the four getauxval arguments that differ? That is, are the bit
> assignments withing each HWCAP the same?
> 
> We should probably condition the AT_HWCAP* definitions upon the target OS.
> Checking a header file first might work in practice, but it feels less
> robust in case the header file is missing some of the definitions.

The 4 are what I'm familiar with and they are ABI history/choice
values rather than descriptions of aarch64 internal bit assignments
or the like.

I would not necessarily recognize another name that was also an
example of ABI history/choice value but there may well not be other
such in this context.

What range of target ABI's would be covered in the conditioning?
I've submitted for the FreeBSD OS context --but overall it is just
an example of the more overall issue. Also, future ABI additions
here with new names will repeat for each such distinct ABI.

I'm not one of the folks that actually maintains the FreeBSD
ports' lang/gcc1[67] or later. But I sometimes (rarely) have
helped identify details of why/how lang/gcc* builds broke when
extra eyes were needed. Thus my input to alternative techniques
for handling the varying ABI value definitions is likely to be
rather limited, even from a FreeBSD OS ports specific viewpoint.

FreeBSD does have additional devel/freebsd-gcc* ports set up for
testing building FreeBSD itself with gcc in its CI context. Those
have not started using gcc16+ yet (gcc15 is the most recent)
--and so have not yet hit the issue but at some point gcc16 will
start to be used.
Comment 7 Mark Millard 2026-05-08 17:45:27 UTC
(In reply to Alice Carlotti from comment #5)
> Based on https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=294062#c5, it
> looks like there's also an issue with <sys/auxv.h> indirectly including
> defines for HWCAP_ that are numerically equivalent but spelled differently.
> So I think we'll need to do one of:
> - make the definitions conditional,
> - not include <sys/auxb.h>, or
> - use different names for the HWCAP_* macros to avoid the clash.
> 
> The last option looks like the cleanest one to me.

For names that are not names for allowing ABI history/choice based
value variations, using names that are obviously GCC specific, and
so unlikely to get #define conflicts with other contexts, would
seem like a good idea to me.

Relative to FreeBSD code, for example, these are names with textual
definitions that would have no reason to need to track FreeBSD
naming or the values FreeBSD code has in its #defines for its names
--or to track how those values are expressed in the FreeBSD code.
Comment 8 Mark Millard 2026-05-08 17:56:28 UTC
A note on the FreeBSD explorations on the issue that
are visible in the FreeBSD port's 294062 bugzilla-entry. :

Not knowing what gcc16+ would  do for the overall issue,
reverting to what is basically the historical technique
for lang/gcc15 and before is what has been explored
relative to checking build-ability. That included
reverting the relevant aarch64 cpuinfo.c code structure
to the old style.

With that I was able to build --and so know that no
other issues prevented building.

But it does not necessarily make for the way gcc would
want to handle the issues associated with aarch64's
cpuinfo.c for gcc16 or later long term. It is just a
workaround for now as far as I'm concerned. (But I do
not maintain any lang/gcc* ports or devel/freebsd-gcc*
ports.)
Comment 9 Wilco 2026-05-11 13:57:51 UTC
It should be easy to add the 

#if __has_include(<asm/hwcap.h>)

back in if that is what worked in the past (or use __gnu_linux__).

Should there be a #elif that includes a different header for FreeBSD? Does it support the ABI for ifuncs?

How is the similar issue resolved for libgcc/config/aarch64/lse-init.c?
Comment 10 Mark Millard 2026-05-11 17:11:24 UTC
(In reply to Wilco from comment #9)
> It should be easy to add the 
> 
> #if __has_include(<asm/hwcap.h>)
> 
> back in if that is what worked in the past (or use __gnu_linux__).
> 
> . . .

As for going in that direction . . .

It was also the use of #ifndef . . .  #endif that was in place
to allow overrides of the gcc16+ defaults in the original code
structure. Now the linux API values are AT_HWCAP* are hard coded
without allowing for such.

> Should there be a #elif that includes a different header for FreeBSD?

That is getting into specifics that the actual maintainer folks
should be answering for anything done that is FreeBSD OS specific
directly in the gcc code.

> Does it support the ABI for ifuncs?

The FreeBSD OS does use ifuncs. But I'm not familiar with the
details.

> How is the similar issue resolved for libgcc/config/aarch64/lse-init.c?

I'm not familiar with that. I only had looked into the known
build breakage as an independent set of eyes. I'm not a
maintainer of any lang/gcc* or freebsd-gcc* ports or anything
associated with the system clang/clang++ or devel/llvm* ports
either.

So I'll have to look around and to get a clue.
Comment 11 Mark Millard 2026-05-11 17:50:47 UTC
(In reply to Mark Millard from comment #10)

> > How is the similar issue resolved for libgcc/config/aarch64/lse-init.c?

Looks to me like the lang/gcc* and devel/freebsd-gcc* ports
never had identified this area as something needing FreeBSD
specifics. The:

#ifdef __gnu_linux__
. . .
#endif /* __gnu_linux__  */

structure avoided having init_have_lse_atomics or its
independent AT_HWCAP 16 definition involved so it was
not made obvious by a build failure historically, nor
by making __getauxval(16) calls that would be odd to
FreeBSD 's code for the context but possibly hard to
notice.


(Note: devel/freebsd-gcc* has not progressed beyond
gcc15 yet.)
Comment 12 John Baldwin 2026-05-12 18:24:00 UTC
(In reply to Wilco from comment #9)
> It should be easy to add the 
> 
> #if __has_include(<asm/hwcap.h>)
> 
> back in if that is what worked in the past (or use __gnu_linux__).
> 
> Should there be a #elif that includes a different header for FreeBSD? Does
> it support the ABI for ifuncs?
> 
> How is the similar issue resolved for libgcc/config/aarch64/lse-init.c?

Mark pointed me here.  I am not the primary maintainer of aarch64 support in FreeBSD, but I am familiar with some of the details.  From what I can tell, lse-init.c doesn't handle FreeBSD either.  FreeBSD does have ifunc support for aarch64, and its ABI is compatible with what cpuinfo.c expects.  On FreeBSD/aarch64, ifunc resolvers are passed the value of AT_HWCAP in the first argument (ored with _IFUNC_ARG_HWCAP), and a pointer to an __ifunc_arg_t object with the same layout as that used in cpuinfo.c as the second argument.

The various HWCAP_* constants are defined on FreeBSD in <machine/elf.h> which is included by other headers such as <sys/auxv.h> and <sys/elf.h>.

For lse-init.c, FreeBSD's <sys/auxv.h> defines a function elf_aux_info which is similar in spirit to __getauxval() though the calling convention is slightly different, I think the equivalent would be:

#include <sys/auxv.h>
#include <sys/elf.h>

static void __attribute__((constructor (90)))
init_have_lse_atomics (void)
{
  unsigned long hwcap;
  if (elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)) == 0)
    __arch64_have_lse_atomics = (hwcap & HWCAP_ATOMICS) != 0;
}

For cpuinfo.c, I think the main thing you'd have to deal with to support FreeBSD is that you can't assume a fixed value for AT_* (or at least not the same value used on Linux), and the calls to __getauxval would use elf_aux_info instead.

If it would be helpful I could come up with an initial patch for FreeBSD support, but I might need a pointer to a test if you have one for both the lse-init.c bits and cpuinfo.c bits.  I'll also happily defer to you on how you would prefer to handle the AT_HWCAP* values being different on different systems.
Comment 13 Jakub Jelinek 2026-08-07 08:02:41 UTC
GCC 16.2 is being released, retargeting bugs to GCC 16.3.