Re: A partial workaround for lang/gcc14 building on/for armv7, given STANDARD_BOOTSTRAP hitting some FreeBSD __aeabi_* symbol issues

From: Mark Millard <marklmi_at_yahoo.com>
Date: Sat, 26 Apr 2025 18:53:30 UTC
On Apr 26, 2025, at 07:45, Michal Meloun <mmel@freebsd.org> wrote:
> 
> On 26.04.2025 9:23, Mark Millard wrote:
>> FreeBSD has not and does not support all the __aeabi_ prefixed
>> symbols to make everything work for all the lang/gcc* .
>> It has gotten to the point that for lang/gcc14 (so modern) that
>> the likes of:
>> __aeabi_unwind_cpp_pr0
>> __aeabi_unwind_cpp_pr1
>> __aeabi_unwind_cpp_pr2
>> lead to the likes of:
>> /usr/local/bin/ld: a.out: hidden symbol `__aeabi_unwind_cpp_pr0' in /wrkdirs/usr/ports/lang/gcc14/work/.build/./prev-gcc/libgcc_eh.a(unwind-arm.o) is referenced by DSO
> I am afraid that this is an incorrect and misleading analysis:

Okay. These specific symbols are apparently not analogous
to others that have been run into in the past. I assumed
too much common context.

> 1) FreeBSD provides (and has provided for a long time) __aeabi_unwind_cpp_pr* symbols in /usr/lib/libgcc_eh.lib in very similar manner as gcc.

FYI: lang/gcc13 builds with STANDARD_BOOTSTRAP okay. lang/gcc14 and lang gcc15 do not.

The below explores the installed package materials, not the
bootstrap materials that failed. (I've not gotten to that
yet.)

When I look for definitions in the installed /usr/local/lib/gcc13/
I find:

# find /usr/local/lib/gcc13/ -type f -exec readelf -a {} \; -print 2>&1 | grep -e __aeabi_unwind_cpp_pr -e ^/ -e ^File: | grep -v "readelf: Not an ELF file" | grep -v " UND " | grep -v " R_ARM_NONE" | more
/usr/local/lib/gcc13/gcc/armv7-portbld-freebsd15.0/13.3.0/plugin/libcc1plugin.so.0.0.0
/usr/local/lib/gcc13/gcc/armv7-portbld-freebsd15.0/13.3.0/plugin/libcp1plugin.so.0.0.0
File: /usr/local/lib/gcc13/gcc/armv7-portbld-freebsd15.0/13.3.0/libgcc_eh.a(unwind-arm.o)
000000f8 0000291a R_ARM_GOT_BREL      00000c34 __aeabi_unwind_cpp_pr2
000000fc 00002a1a R_ARM_GOT_BREL      00000c2c __aeabi_unwind_cpp_pr1
    40: 0000000000000c24     8 FUNC    GLOBAL HIDDEN     1 __aeabi_unwind_cpp_pr0
    41: 0000000000000c34     8 FUNC    WEAK   HIDDEN     1 __aeabi_unwind_cpp_pr2
    42: 0000000000000c2c     8 FUNC    WEAK   HIDDEN     1 __aeabi_unwind_cpp_pr1
File: /usr/local/lib/gcc13/gcc/armv7-portbld-freebsd15.0/13.3.0/libgcc_eh.a(libunwind.o)
File: /usr/local/lib/gcc13/gcc/armv7-portbld-freebsd15.0/13.3.0/libgcc_eh.a(pr-support.o)
File: /usr/local/lib/gcc13/gcc/armv7-portbld-freebsd15.0/13.3.0/libgcc_eh.a(unwind-c.o)
File: /usr/local/lib/gcc13/gcc/armv7-portbld-freebsd15.0/13.3.0/libgcc_eh.a(emutls.o)
/usr/local/lib/gcc13/gcc/armv7-portbld-freebsd15.0/13.3.0/libgcc_eh.a
. . .
0001e6cc 00005715 R_ARM_GLOB_DAT      0001bc84 __aeabi_unwind_cpp_pr2
0001e6d0 00005115 R_ARM_GLOB_DAT      0001bc74 __aeabi_unwind_cpp_pr0
0001e6e8 00005515 R_ARM_GLOB_DAT      0001bc7c __aeabi_unwind_cpp_pr1
    81: 000000000001bc74     8 FUNC    GLOBAL DEFAULT   12 __aeabi_unwind_cpp_pr0@@GCC_3.5 (12)
    85: 000000000001bc7c     8 FUNC    WEAK   DEFAULT   12 __aeabi_unwind_cpp_pr1@@GCC_3.5 (12)
    87: 000000000001bc84     8 FUNC    WEAK   DEFAULT   12 __aeabi_unwind_cpp_pr2@@GCC_3.5 (12)
  3974: 000000000001bc84     8 FUNC    WEAK   DEFAULT   12 __aeabi_unwind_cpp_pr2
  3984: 000000000001bc74     8 FUNC    GLOBAL DEFAULT   12 __aeabi_unwind_cpp_pr0
  4557: 000000000001bc7c     8 FUNC    WEAK   DEFAULT   12 __aeabi_unwind_cpp_pr1
/usr/local/lib/gcc13/libgcc_s.so.1

(Note that each file path was listed after the content instead
of before.)


My work around build of lang/gcc14 ends up with:

# find /usr/local/lib/gcc14/ -type f -exec readelf -a {} \; -print 2>&1 | grep -e __aeabi_unwind_cpp_pr -e ^/ -e ^File: | grep -v "readelf: Not an ELF file" | grep -v " UND " | grep -v " R_ARM_NONE" | more
. . .
File: /usr/local/lib/gcc14/gcc/armv7-portbld-freebsd15.0/14.2.0/libgcc_eh.a(unwind-arm.o)
000000f8 00002f1a R_ARM_GOT_BREL      00000c30 __aeabi_unwind_cpp_pr2
000000fc 0000301a R_ARM_GOT_BREL      00000c28 __aeabi_unwind_cpp_pr1
    46: 0000000000000c20     8 FUNC    GLOBAL HIDDEN     1 __aeabi_unwind_cpp_pr0
    47: 0000000000000c30     8 FUNC    WEAK   HIDDEN     1 __aeabi_unwind_cpp_pr2
    48: 0000000000000c28     8 FUNC    WEAK   HIDDEN     1 __aeabi_unwind_cpp_pr1
File: /usr/local/lib/gcc14/gcc/armv7-portbld-freebsd15.0/14.2.0/libgcc_eh.a(libunwind.o)
File: /usr/local/lib/gcc14/gcc/armv7-portbld-freebsd15.0/14.2.0/libgcc_eh.a(pr-support.o)
File: /usr/local/lib/gcc14/gcc/armv7-portbld-freebsd15.0/14.2.0/libgcc_eh.a(unwind-c.o)
File: /usr/local/lib/gcc14/gcc/armv7-portbld-freebsd15.0/14.2.0/libgcc_eh.a(emutls.o)
/usr/local/lib/gcc14/gcc/armv7-portbld-freebsd15.0/14.2.0/libgcc_eh.a
. . .
0001eb90 00005715 R_ARM_GLOB_DAT      0001c12c __aeabi_unwind_cpp_pr2
0001eb94 00005115 R_ARM_GLOB_DAT      0001c11c __aeabi_unwind_cpp_pr0
0001ebac 00005515 R_ARM_GLOB_DAT      0001c124 __aeabi_unwind_cpp_pr1
    81: 000000000001c11c     8 FUNC    GLOBAL DEFAULT   12 __aeabi_unwind_cpp_pr0@@GCC_3.5 (14)
    85: 000000000001c124     8 FUNC    WEAK   DEFAULT   12 __aeabi_unwind_cpp_pr1@@GCC_3.5 (14)
    87: 000000000001c12c     8 FUNC    WEAK   DEFAULT   12 __aeabi_unwind_cpp_pr2@@GCC_3.5 (14)
  4007: 000000000001c12c     8 FUNC    WEAK   DEFAULT   12 __aeabi_unwind_cpp_pr2
  4017: 000000000001c11c     8 FUNC    GLOBAL DEFAULT   12 __aeabi_unwind_cpp_pr0
  4593: 000000000001c124     8 FUNC    WEAK   DEFAULT   12 __aeabi_unwind_cpp_pr1
/usr/local/lib/gcc14/libgcc_s.so.1

(Note that each file path was listed after the content instead
of before.)


What I see in FreeBSD's /usr/lib/libgcc* are:

# readelf -a /usr/lib/libgcc* -print 2>&1 | grep -e __aeabi_unwind_cpp_pr -e ^File: | grep -v "readelf: Not an ELF # readelf -a /usr/lib/libgcc* 2>&1 | grep -e __aeabi_unwind_cpp_pr -e ^File: | grep -v "readelf: Not an ELF file" | grep -v " UND " | grep -v " R_ARM_NONE" | more
. . .
File: /usr/lib/libgcc_eh.a
File: /usr/lib/libgcc_eh.a(int_util.o)
File: /usr/lib/libgcc_eh.a(gcc_personality_v0.o)
File: /usr/lib/libgcc_eh.a(Unwind-EHABI.o)
    44: 00000000000009f4    12 FUNC    GLOBAL DEFAULT    2 __aeabi_unwind_cpp_pr0
    56: 0000000000000bc4    12 FUNC    GLOBAL DEFAULT    2 __aeabi_unwind_cpp_pr1
    61: 0000000000000bd0    12 FUNC    GLOBAL DEFAULT    2 __aeabi_unwind_cpp_pr2
File: /usr/lib/libgcc_eh.a(Unwind-sjlj.o)
File: /usr/lib/libgcc_eh.a(UnwindLevel1-gcc-ext.o)
File: /usr/lib/libgcc_eh.a(UnwindLevel1.o)
File: /usr/lib/libgcc_eh.a(UnwindRegistersRestore.o)
File: /usr/lib/libgcc_eh.a(UnwindRegistersSave.o)
File: /usr/lib/libgcc_eh.a(libunwind.o)
000001e4 0000af60 R_ARM_GOT_PREL      00000000 __aeabi_unwind_cpp_pr1
000001e8 0000b560 R_ARM_GOT_PREL      00000000 __aeabi_unwind_cpp_pr0
000001fc 0000de60 R_ARM_GOT_PREL      00000000 __aeabi_unwind_cpp_pr2
File: /usr/lib/libgcc_s.so
00028f98 00001515 R_ARM_GLOB_DAT      0001674c __aeabi_unwind_cpp_pr2
00028f88 00005515 R_ARM_GLOB_DAT      00016570 __aeabi_unwind_cpp_pr0
00028f90 00005c15 R_ARM_GLOB_DAT      00016740 __aeabi_unwind_cpp_pr1
    21: 000000000001674c    12 FUNC    GLOBAL DEFAULT   14 __aeabi_unwind_cpp_pr2@@GCC_3.5 (8)
    85: 0000000000016570    12 FUNC    GLOBAL DEFAULT   14 __aeabi_unwind_cpp_pr0@@GCC_3.5 (8)
    92: 0000000000016740    12 FUNC    GLOBAL DEFAULT   14 __aeabi_unwind_cpp_pr1@@GCC_3.5 (8)
   256: 0000000000016570    12 FUNC    GLOBAL DEFAULT   14 __aeabi_unwind_cpp_pr0
   273: 0000000000016740    12 FUNC    GLOBAL DEFAULT   14 __aeabi_unwind_cpp_pr1
   326: 000000000001674c    12 FUNC    GLOBAL DEFAULT   14 __aeabi_unwind_cpp_pr2

[Note that each file path was listed before the content instead
of after. There is a "File: " prefix but no '(*.o)' suffix on
the just-file-name lines.]


I do not know if the below is of any significance or not.

Note the libgcc_eh.a (R_ARM_NONE examples filtered out)
gcc14 vs. FreeBSD has:

000000f8 00002f1a R_ARM_GOT_BREL      00000c30 __aeabi_unwind_cpp_pr2
000000fc 0000301a R_ARM_GOT_BREL      00000c28 __aeabi_unwind_cpp_pr1
vs.
000001e4 0000af60 R_ARM_GOT_PREL      00000000 __aeabi_unwind_cpp_pr1
000001e8 0000b560 R_ARM_GOT_PREL      00000000 __aeabi_unwind_cpp_pr0
000001fc 0000de60 R_ARM_GOT_PREL      00000000 __aeabi_unwind_cpp_pr2

That suggests gcc14 has R_ARM_NONE for all __aeabi_unwind_cpp_pr0
references in libgcc_eh.a .

Also, the libgcc_eh.a gcc14 vs. FreeBSD has:

    46: 0000000000000c20     8 FUNC    GLOBAL HIDDEN     1 __aeabi_unwind_cpp_pr0
    47: 0000000000000c30     8 FUNC    WEAK   HIDDEN     1 __aeabi_unwind_cpp_pr2
    48: 0000000000000c28     8 FUNC    WEAK   HIDDEN     1 __aeabi_unwind_cpp_pr1
vs.
    44: 00000000000009f4    12 FUNC    GLOBAL DEFAULT    2 __aeabi_unwind_cpp_pr0
    56: 0000000000000bc4    12 FUNC    GLOBAL DEFAULT    2 __aeabi_unwind_cpp_pr1
    61: 0000000000000bd0    12 FUNC    GLOBAL DEFAULT    2 __aeabi_unwind_cpp_pr2

And libgcc_eh.a has the Unwind-EHABI.o / libunwind.o split in FreeBSD vs.
the just unwind-arm.o in gcc14.

There is the libgcc_s.so.1 (gcc14) vs. libgcc_s.so (FreeBSD) having:

    81: 000000000001c11c     8 FUNC    GLOBAL DEFAULT   12 __aeabi_unwind_cpp_pr0@@GCC_3.5 (14)
    85: 000000000001c124     8 FUNC    WEAK   DEFAULT   12 __aeabi_unwind_cpp_pr1@@GCC_3.5 (14)
    87: 000000000001c12c     8 FUNC    WEAK   DEFAULT   12 __aeabi_unwind_cpp_pr2@@GCC_3.5 (14)
  4007: 000000000001c12c     8 FUNC    WEAK   DEFAULT   12 __aeabi_unwind_cpp_pr2
  4017: 000000000001c11c     8 FUNC    GLOBAL DEFAULT   12 __aeabi_unwind_cpp_pr0
  4593: 000000000001c124     8 FUNC    WEAK   DEFAULT   12 __aeabi_unwind_cpp_pr1
vs.
    21: 000000000001674c    12 FUNC    GLOBAL DEFAULT   14 __aeabi_unwind_cpp_pr2@@GCC_3.5 (8)
    85: 0000000000016570    12 FUNC    GLOBAL DEFAULT   14 __aeabi_unwind_cpp_pr0@@GCC_3.5 (8)
    92: 0000000000016740    12 FUNC    GLOBAL DEFAULT   14 __aeabi_unwind_cpp_pr1@@GCC_3.5 (8)
   256: 0000000000016570    12 FUNC    GLOBAL DEFAULT   14 __aeabi_unwind_cpp_pr0
   273: 0000000000016740    12 FUNC    GLOBAL DEFAULT   14 __aeabi_unwind_cpp_pr1
   326: 000000000001674c    12 FUNC    GLOBAL DEFAULT   14 __aeabi_unwind_cpp_pr2


Again: I do not know the significance vs. lack of such.

But lang/gcc13 and lang/gcc14 seem to agree for those sorts
of things. So it seems I should ignore such gcc* vs. FreeBSD
distinctions when I later look at the bootstrap failure
materials.

> 2) The problem is exactly the opposite, gcc14 does not provide these symbols.

For the above, I did not look at the bootstrap stage materials
yet. So I'm not making any claim about this at this point here.

> In the configuration phase, configure builds executable with the bootstrap libgcc(in this case the static libgcc.a), but with the host(FBSD) libc. The FBSD libc uses unwinder, but the bootstrap libgcc.a does not provide it.
> 
> see:
> "/usr/ports/lang/gcc14/work/.build/./prev-gcc/xgcc -B/usr/ports/lang/gcc14/work/.build/./prev-gcc/ -B/usr/local/armv7-portbld-freebsd15.0/bin/ -B/usr/local/armv7-portbld-freebsd15.0/bin/ -B/usr/local/armv7-portbld-freebsd15.0/lib/ -isystem /usr/local/armv7-portbld-freebsd15.0/include -isystem /usr/local/armv7-portbld-freebsd15.0/sys-include   -fno-checking -g -O2 -fno-checking -gtoggle -DLIBICONV_PLUG -static-libstdc++ -static-libgcc conftest.c
> 
> In any case, I don't see any way to fix this on the FBSD (kernel, userland) side. There is only one little strange item: that each single object references __aeabi_unwind_cpp_p* symbols...
> 
> Michal
> 
>> when attempting a build of lang/gcc14 for:
>> OPTIONS_DEFAULT_armv7= STANDARD_BOOTSTRAP
>> # find /wrkdirs/ -name config.log -exec grep -q __aeabi_unwind_cpp_pr0 {} \; -print | more
>> /wrkdirs/usr/ports/lang/gcc14/work/.build/libdecnumber/config.log
>> /wrkdirs/usr/ports/lang/gcc14/work/.build/libbacktrace/config.log
>> /wrkdirs/usr/ports/lang/gcc14/work/.build/libiberty/config.log
>> /wrkdirs/usr/ports/lang/gcc14/work/.build/lto-plugin/config.log
>> Note: The poudriere log file ends up instead reporting the likes of:
>> checking for library containing strerror... configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES.
>> So: Giving no clue about the specifics.
>> Going in the direction of instead having:
>> #OPTIONS_DEFAULT_armv7= STANDARD_BOOTSTRAP
>> so that gcc is not used at all, the "jit" in:
>> LANGUAGES:=     c,c++,objc,fortran,jit
>> prevents having the system clang/clang++ do all
>> the build: after the early stages, gcc/g++
>> depends on library coding conventions specific
>> to gcc/g++ and clang/clang++ based builds do
>> not follow those conventions in libc++ or such.
>> (Poisoned names are detected and stop the build.)
>> As I do not need jit, I do the following in
>> order to have lang/gcc14 build on/for armv7
>> (and, presumably could for armv6 as well) :
>> # git -C /usr/ports/ diff lang/gcc14/ | cat
>> diff --git a/lang/gcc14/Makefile b/lang/gcc14/Makefile
>> index 74c59905c48d..7f082e68ecfe 100644
>> --- a/lang/gcc14/Makefile
>> +++ b/lang/gcc14/Makefile
>> @@ -39,8 +39,8 @@ CXXFLAGS:= ${CXXFLAGS:N-mretpoline}
>>    OPTIONS_DEFINE= GRAPHITE
>>  OPTIONS_DEFAULT_aarch64=STANDARD_BOOTSTRAP
>> -OPTIONS_DEFAULT_armv6= STANDARD_BOOTSTRAP
>> -OPTIONS_DEFAULT_armv7= STANDARD_BOOTSTRAP
>> +#OPTIONS_DEFAULT_armv6= STANDARD_BOOTSTRAP
>> +#OPTIONS_DEFAULT_armv7= STANDARD_BOOTSTRAP
>>  OPTIONS_DEFAULT_amd64= STANDARD_BOOTSTRAP
>>  OPTIONS_DEFAULT_i386= STANDARD_BOOTSTRAP
>>  OPTIONS_DEFAULT_powerpc= STANDARD_BOOTSTRAP
>> @@ -80,7 +80,11 @@ CONFIGURE_TARGET= x86_64-portbld-${OPSYS:tl}${OSREL}
>>  CONFIGURE_ARGS+= --with-abi=elfv2
>>  .endif
>>  +.if ${ARCH} == armv7 || ${ARCH} == armv6
>> +LANGUAGES:= c,c++,objc,fortran
>> +.else
>>  LANGUAGES:= c,c++,objc,fortran,jit
>> +.endif
>>  TARGLIB= ${PREFIX}/lib/gcc${SUFFIX}
>>  TARGLIB32= ${PREFIX}/lib32 # The version information is added later
>>  LIBEXEC= ${PREFIX}/libexec/gcc${SUFFIX}
>> (I do not show my disabling of install-strip use,
>> which is done for other reasons.)
>> At least for now that allows me to have lang/gcc14
>> other than for the jit language that I do not use.
>> But gcc14 or g++14 is not involved in producing
>> that gcc14 and g++14 .
> 


===
Mark Millard
marklmi at yahoo.com