Various programs depending on libunwind fail to build/run on armv6/armv7 due to the symbol __aeabi_uidiv not found. For example, various Ruby ports fail like this: -- Ruby level backtrace information ---------------------------------------- extconf.rb:700:in `<main>' extconf.rb:294:in `ensure_package_configuration' extconf.rb:287:in `have_package_configuration' extconf.rb:258:in `try_package_configuration' /usr/local/lib/ruby/3.1/mkmf.rb:988:in `checking_for' /usr/local/lib/ruby/3.1/mkmf.rb:350:in `postpone' /usr/local/lib/ruby/3.1/mkmf.rb:324:in `open' /usr/local/lib/ruby/3.1/mkmf.rb:354:in `block in postpone' /usr/local/lib/ruby/3.1/mkmf.rb:324:in `open' /usr/local/lib/ruby/3.1/mkmf.rb:354:in `block (2 levels) in postpone' /usr/local/lib/ruby/3.1/mkmf.rb:989:in `block in checking_for' extconf.rb:259:in `block in try_package_configuration' /usr/local/lib/ruby/gems/3.1/gems/pkg-config-1.5.1/lib/pkg-config.rb:659:in `have_package' /usr/local/lib/ruby/gems/3.1/gems/pkg-config-1.5.1/lib/pkg-config.rb:607:in `cflags_only_other' /usr/local/lib/ruby/gems/3.1/gems/pkg-config-1.5.1/lib/pkg-config.rb:302:in `cflags_only_other' /usr/local/lib/ruby/gems/3.1/gems/pkg-config-1.5.1/lib/pkg-config.rb:399:in `collect_cflags' /usr/local/lib/ruby/gems/3.1/gems/pkg-config-1.5.1/lib/pkg-config.rb:434:in `normalize_cflags' /usr/local/lib/ruby/gems/3.1/gems/pkg-config-1.5.1/lib/pkg-config.rb:434:in `loop' /usr/local/lib/ruby/gems/3.1/gems/pkg-config-1.5.1/lib/pkg-config.rb:435:in `block in normalize_cflags' /usr/local/lib/ruby/gems/3.1/gems/pkg-config-1.5.1/lib/pkg-config.rb:435:in `next' -- C level backtrace information ------------------------------------------- ld-elf.so.1: /usr/local/lib/libunwind.so.8: Undefined symbol "__aeabi_uidiv" It is unclear for me what the specific problem is, where this symbol is needed and why there is a linking problem.
*** Bug 257271 has been marked as a duplicate of this bug. ***
*** Bug 259617 has been marked as a duplicate of this bug. ***
Also affects the symbols __aeabi_uldivmod, __aeabi_uidivmod and likely others. Ideally, all the __aeabi symbols should be exported as they are required by the ARM EABI and clang likes to generate references to them when it feels like it.
Just a dump of my investigation: There are two categories of __aeabi_ symbols: those that are libgcc/libcompiler_rt-like, i.e. things like integer division, and those that are libc-like, i.e. things like memcpy. Currently, lib/libc/arm/aeabi/Symbol.map defines a bunch of floating-point symbols, __aeabi_atexit, some memory-related symbols and some integer division symbols. The __aeabi_atexit and memory-related ones should be in libc as they are today. The floating-point and integer ones should not be; they belong in libgcc (which really is libcompiler_rt). Moreover, certain symbols, such as __aeabi_uidivmod, do not appear in either Symbol.map, and so are not exported from either library, rendering them inaccessible, despite being specified in "Run-time ABI for the Arm® Architecture". This needs a full audit of every symbol in the specification to determine its rightful location and to ensure it is exported. GNU/Linux systems can make a useful reference here.
The https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=259617 that was made a duplicate of this one always had armv6 as a context but this one references armv7 too. Not sure of the equivalence. In fact, on armv7 (main main): # more x.c // cc -mthumb -o x x.c #include <stdio.h> #include <stdlib.h> int main() { double f; f = strtod("1.0", NULL); printf("%u\n", (unsigned int)f); } # cc -mthumb -o x x.c # uname -p armv7 so that example was either armv6 specific or for some reason 13.* and main are different. I'll remind of the proposal to possibly drop armv6 as of 14.0-release. A reference is: https://lists.freebsd.org/archives/freebsd-arm/2022-December/002091.html
(In reply to Mark Millard from comment #5) ARMv6 doesn't have FP support in thumb mode and may thus call into the __aeabi stubs when compiling for thumb. At the end of the day, it's the same issue: the __aeabi functions required by the ABI are missing, leading to problems when the linker desires to use them. The best way to fix this problem is to just add all the missing symbols.
Created attachment 246527 [details] linker script changes to export arithmetic __eabi_ symbols from libgcc_s.so
(In reply to John F. Carr from comment #7) Thank you for supplying this patch. I'll have a look. The symbol __aeabi_uldivmod is needed by a bunch of ports but is missing from your port. Is this intentional?
I did not intentionally omit __aeabi_uldivmod. I probably mistook it for a second instance of __aeabi_uidivmod. I should have used sort -u instead of manually removing duplicates. This ought to generate the right list: nm --defined-only /usr/obj/usr/src/arm.armv7/tmp/usr/lib/libgcc.a|awk '/__aeabi_[^m]/ { print $3 }' | sort -u
I've tested the changeset and found that it fixes some of the broken ports. One port, devel/omniORB, then breaks for an unrelated reason. Another one, games/toppler, fails because it expects a different symbol version: ( cd _build && gimp -i -b "(let* ((image (car(gimp-xcf-load 1 \"../datafile/font.xcf\" \"ttt\")))(layers (cadr(gimp-image-get-layers image))))(file-png-save-defaults 1 image (aref layers 0) \"font_mask_rgb.png\" \"ttt\")(gimp-quit 1))" ) GEGL-Message: 19:18:17.974: Module '/usr/local/lib/gegl-0.4/gegl-common-cxx.so' load error: /usr/local/lib/gegl-0.4/gegl-common-cxx.so: Undefined symbol "__aeabi_d2lz@GCC_3.5" This may be a bug in GEGL. Overall, I'd say add the missing entry for __aeabi_uldivmod and perhaps ship it?
I can not build gegl myself (rust is in the dependency list). I verified that the prebuilt package has the dependencies: $ objdump -T gegl-common-cxx.so|grep GC 00000000 DF *UND* 00000000 (GCC_3.5) __aeabi_unwind_cpp_pr0 00000000 DF *UND* 00000000 (GCC_3.5) __aeabi_d2lz 00000000 DF *UND* 00000000 (GCC_3.5) __aeabi_idiv 00000000 DF *UND* 00000000 (GCC_3.5) __aeabi_idivmod 00000000 DF *UND* 00000000 (GCC_3.5) __aeabi_unwind_cpp_pr1 00000000 DF *UND* 00000000 (GCC_3.5) __aeabi_l2d Possibly this is a Linuxism we want to be binary compatible with. Without evidence of that, I say don't make changes just to please gegl. Ship it with __aeabi_uldivmod added.
(In reply to John F. Carr from comment #11) I think this is because gegl is compiled with gcc on armv7. It seems like GCC_3.5 is the symbol version of this __aeabi symbol as used by gcc?
(In reply to Robert Clausecker from comment #12) [Note: I do nto recommend waiting for complete coverage of GCC_* related symbols that FreeBSD is missing.. More on this later.] None of this is a complete coverage of the symbols that GCC deepends on for aarch64. To use the exterme form as an example: GCC_4.5.0 is completely missing in FreeBSD (main): # strings /lib/libgcc_s.so.1 | grep GCC_ | more GCC_3.0 GCC_3.3 GCC_3.3.1 GCC_3.4 GCC_3.4.2 GCC_3.4.4 GCC_3.5 GCC_4.0.0 GCC_4.2.0 GCC_4.3.0 GCC_4.6.0 (That list was generated today. I'm going to use older reference material for other examples.) Quoting from an older bugzilla entry that overlapped with this issue: QUOTE # more fp-binding-failure-aarch64.cpp #include <cmath> volatile long double v=NAN; int main() { return std::isnan(v) ? 1 : 0; } # g++11 fp-binding-failure-aarch64.cpp # ./a.out ld-elf.so.1: /lib/libgcc_s.so.1: version GCC_4.5.0 required by /usr/home/root/c_tests/a.out not found The a.out has its own reference to __unordtf2@GCC_4.5.0 : # nm -a a.out | grep '@GCC_[4-9]\.' | more U __unordtf2@GCC_4.5.0 END QUOTE But even though GCC_3.0 is, by contrast, present, it is incomplete: QUOTE # more trivial.cpp // aarch64 g++12 example that shows the symbols missing for the // /usr/local/lib/gcc12/libstdc++.so.6 build involved : // // # g++12 -o trivial -L/usr/lib trivial.cpp // // This finds /usr/lib/libgcc_s.so , which in turn is a link // to /lib/libgcc_s.so.1 . int main() { } For example, in my context: # g++12 -o trivial -L/usr/lib trivial.cpp /usr/local/bin/ld: /usr/local/lib/gcc12/gcc/aarch64-portbld-freebsd13.1/12.2.0/../../../libstdc++.so: undefined reference to `__floatunditf@GCC_4.2.0' /usr/local/bin/ld: /usr/local/lib/gcc12/gcc/aarch64-portbld-freebsd13.1/12.2.0/../../../libstdc++.so: undefined reference to `__subtf3@GCC_3.0' /usr/local/bin/ld: /usr/local/lib/gcc12/gcc/aarch64-portbld-freebsd13.1/12.2.0/../../../libstdc++.so: undefined reference to `__unordtf2@GCC_4.5.0' /usr/local/bin/ld: /usr/local/lib/gcc12/gcc/aarch64-portbld-freebsd13.1/12.2.0/../../../libstdc++.so: undefined reference to `__getf2@GCC_3.0' /usr/local/bin/ld: /usr/local/lib/gcc12/gcc/aarch64-portbld-freebsd13.1/12.2.0/../../../libstdc++.so: undefined reference to `__addtf3@GCC_3.0' /usr/local/bin/ld: /usr/local/lib/gcc12/gcc/aarch64-portbld-freebsd13.1/12.2.0/../../../libstdc++.so: undefined reference to `__letf2@GCC_3.0' /usr/local/bin/ld: /usr/local/lib/gcc12/gcc/aarch64-portbld-freebsd13.1/12.2.0/../../../libstdc++.so: undefined reference to `__fixunstfdi@GCC_3.0' /usr/local/bin/ld: /usr/local/lib/gcc12/gcc/aarch64-portbld-freebsd13.1/12.2.0/../../../libstdc++.so: undefined reference to `__multf3@GCC_3.0' /usr/local/bin/ld: /usr/local/lib/gcc12/gcc/aarch64-portbld-freebsd13.1/12.2.0/../../../libstdc++.so: undefined reference to `__eqtf2@GCC_3.0' /usr/local/bin/ld: /usr/local/lib/gcc12/gcc/aarch64-portbld-freebsd13.1/12.2.0/../../../libstdc++.so: undefined reference to `__lttf2@GCC_3.0' collect2: error: ld returned 1 exit status If it turns out that GCC/G++ happens to not generate a reference to something that is missing, such build errors do not happen when /lib/libgcc_s.so.1 is being used. But if GCC/G++ generates a reference to such, a use of a /usr/local/lib/gcc*/libgcc_s.so.1 is needed. Some ports were likely marked broken instead of being fixed. END QUOTE I recommend whatever fixes are made available be committed and then dealing with the next block when someone knowledgable and willing increases the coverage somewhat. Waiting for completeness is likely a blocking issue to progress here. Lots of examples are long known and long unchanged.
(In reply to Mark Millard from comment #13) Another old note from yet another old bugzilla: QUOTE An interesting point is amd64 vs. aarch64 for /usr/local/lib/gcc11/libgcc_s.so.1 : +GCC_4.6.0 __unordtf2 vs. +GCC_4.5.0 __unordtf2 So the GCC_* vintage is architecture specific. END QUOTE
(In reply to Mark Millard from comment #13) Thank you for these explanations. Could I interest you in moving ahead with the commit then? I assigned this one to cognet@ several weeks ago as he wanted to have a look, but it seems like he is busy with other things.
(In reply to Robert Clausecker from comment #15) I'm not a FreeBSD committer, not system, not ports. So I can not "mov[e] ahead with the commit".
Just an FYI for reference, comparing FreeBSD's /lib/libgcc_s.so.1 vs. /usr/local/lib/gcc13/libgcc_s.so.1 for GCC_* related symbol differences: # objdump -T /usr/local/lib/gcc13/libgcc_s.so.1 | sort -k6 | grep GCC_ | cut -f6-7 -w > ~/gcc13_lbgcc_s_GCC_symbols.txt # objdump -T /lib/libgcc_s.so.1 | sort -k6 | grep GCC_ | cut -f6-7 -w > ~/fbsd_main_lbgcc_s_GCC_symbols.txt # diff -u ~/fbsd_main_lbgcc_s_GCC_symbols.txt ~/gcc13_lbgcc_s_GCC_symbols.txt --- /usr/home/root/fbsd_main_lbgcc_s_GCC_symbols.txt 2023-11-28 22:18:53.230930000 -0800 +++ /usr/home/root/gcc13_lbgcc_s_GCC_symbols.txt 2023-11-28 22:18:19.358931000 -0800 @@ -1,3 +1,4 @@ +GCC_3.0 GCC_3.0 GCC_3.0 _Unwind_DeleteException GCC_3.0 _Unwind_Find_FDE GCC_3.0 _Unwind_ForcedUnwind @@ -15,50 +16,34 @@ GCC_3.0 __absvsi2 GCC_3.0 __addvdi3 GCC_3.0 __addvsi3 -GCC_3.0 __ashldi3 GCC_3.0 __ashlti3 -GCC_3.0 __ashrdi3 GCC_3.0 __ashrti3 GCC_3.0 __clear_cache -GCC_3.0 __cmpdi2 GCC_3.0 __cmpti2 GCC_3.0 __deregister_frame GCC_3.0 __deregister_frame_info GCC_3.0 __deregister_frame_info_bases -GCC_3.0 __divdi3 GCC_3.0 __divti3 +GCC_3.0 __extendsfdf2 GCC_3.0 __ffsdi2 GCC_3.0 __ffsti2 -GCC_3.0 __fixdfdi GCC_3.0 __fixdfti -GCC_3.0 __fixsfdi GCC_3.0 __fixsfti GCC_3.0 __fixunsdfdi -GCC_3.0 __fixunsdfsi GCC_3.0 __fixunsdfti GCC_3.0 __fixunssfdi -GCC_3.0 __fixunssfsi GCC_3.0 __fixunssfti GCC_3.0 __fixunsxfdi -GCC_3.0 __fixunsxfsi GCC_3.0 __fixunsxfti -GCC_3.0 __fixxfdi GCC_3.0 __fixxfti -GCC_3.0 __floatdidf -GCC_3.0 __floatdisf -GCC_3.0 __floatdixf GCC_3.0 __floattidf GCC_3.0 __floattisf GCC_3.0 __floattixf -GCC_3.0 __lshrdi3 GCC_3.0 __lshrti3 -GCC_3.0 __moddi3 GCC_3.0 __modti3 -GCC_3.0 __muldi3 GCC_3.0 __multi3 GCC_3.0 __mulvdi3 GCC_3.0 __mulvsi3 -GCC_3.0 __negdi2 GCC_3.0 __negti2 GCC_3.0 __negvdi2 GCC_3.0 __negvsi2 @@ -70,37 +55,36 @@ GCC_3.0 __register_frame_table GCC_3.0 __subvdi3 GCC_3.0 __subvsi3 -GCC_3.0 __ucmpdi2 +GCC_3.0 __truncdfsf2 GCC_3.0 __ucmpti2 -GCC_3.0 __udivdi3 -GCC_3.0 __udivmoddi4 GCC_3.0 __udivmodti4 GCC_3.0 __udivti3 -GCC_3.0 __umoddi3 GCC_3.0 __umodti3 +GCC_3.3 GCC_3.3 GCC_3.3 _Unwind_Backtrace GCC_3.3 _Unwind_FindEnclosingFunction GCC_3.3 _Unwind_GetCFA GCC_3.3 _Unwind_Resume_or_Rethrow +GCC_3.3.1 GCC_3.3.1 GCC_3.3.1 __gcc_personality_v0 +GCC_3.4 GCC_3.4 GCC_3.4 __clzdi2 -GCC_3.4 __clzsi2 GCC_3.4 __clzti2 GCC_3.4 __ctzdi2 -GCC_3.4 __ctzsi2 GCC_3.4 __ctzti2 GCC_3.4 __paritydi2 -GCC_3.4 __paritysi2 GCC_3.4 __parityti2 GCC_3.4 __popcountdi2 -GCC_3.4 __popcountsi2 GCC_3.4 __popcountti2 +GCC_3.4.2 GCC_3.4.2 GCC_3.4.2 __enable_execute_stack +GCC_3.4.4 GCC_3.4.4 GCC_3.4.4 __absvti2 GCC_3.4.4 __addvti3 GCC_3.4.4 __mulvti3 GCC_3.4.4 __negvti2 GCC_3.4.4 __subvti3 +GCC_4.0.0 GCC_4.0.0 GCC_4.0.0 __divdc3 GCC_4.0.0 __divsc3 GCC_4.0.0 __divxc3 @@ -110,12 +94,55 @@ GCC_4.0.0 __powidf2 GCC_4.0.0 __powisf2 GCC_4.0.0 __powixf2 +GCC_4.2.0 GCC_4.2.0 GCC_4.2.0 _Unwind_GetIPInfo -GCC_4.2.0 __floatundidf -GCC_4.2.0 __floatundisf -GCC_4.2.0 __floatundixf GCC_4.2.0 __floatuntidf GCC_4.2.0 __floatuntisf GCC_4.2.0 __floatuntixf +GCC_4.3.0 GCC_4.3.0 GCC_4.3.0 __bswapdi2 GCC_4.3.0 __bswapsi2 +GCC_4.3.0 __emutls_get_address +GCC_4.3.0 __emutls_register_common +GCC_4.6.0 GCC_4.6.0 +GCC_4.6.0 __addtf3 +GCC_4.6.0 __divtc3 +GCC_4.6.0 __divtf3 +GCC_4.6.0 __eqtf2 +GCC_4.6.0 __extenddftf2 +GCC_4.6.0 __extendsftf2 +GCC_4.6.0 __extendxftf2 +GCC_4.6.0 __fixtfdi +GCC_4.6.0 __fixtfsi +GCC_4.6.0 __fixtfti +GCC_4.6.0 __fixunstfdi +GCC_4.6.0 __fixunstfsi +GCC_4.6.0 __fixunstfti +GCC_4.6.0 __floatditf +GCC_4.6.0 __floatsitf +GCC_4.6.0 __floattitf +GCC_4.6.0 __floatunditf +GCC_4.6.0 __floatunsitf +GCC_4.6.0 __floatuntitf +GCC_4.6.0 __getf2 +GCC_4.6.0 __gttf2 +GCC_4.6.0 __letf2 +GCC_4.6.0 __lttf2 +GCC_4.6.0 __multc3 +GCC_4.6.0 __multf3 +GCC_4.6.0 __negtf2 +GCC_4.6.0 __netf2 +GCC_4.6.0 __powitf2 +GCC_4.6.0 __subtf3 +GCC_4.6.0 __trunctfdf2 +GCC_4.6.0 __trunctfsf2 +GCC_4.6.0 __trunctfxf2 +GCC_4.6.0 __unordtf2 +GCC_4.7.0 GCC_4.7.0 +GCC_4.7.0 __clrsbdi2 +GCC_4.7.0 __clrsbti2 +GCC_4.8.0 GCC_4.8.0 +GCC_4.8.0 __cpu_indicator_init +GCC_4.8.0 __cpu_model +GCC_7.0.0 GCC_7.0.0 +GCC_7.0.0 __divmodti4
We should follow file libgcc/config/arm/libgcc-bpapi.ver in the gcc sources and put all the __aeabi symbols in version GCC_3.5 and not in the new name EABI_1 I proposed. I assume they are all compatible.
Created attachment 247658 [details] linker script changes to export __aeabi symbols from libgcc.so