https://bugs.kde.org/show_bug.cgi?id=526075
Bug ID: 526075
Summary: Tool link fails against a libgcc built without
optimisation: undefined reference to _Unwind_Resume /
__gcc_personality_v0
Classification: Developer tools
Product: valgrind
Version First 3.26.0
Reported In:
Platform: unspecified
OS: Linux
Status: REPORTED
Severity: normal
Priority: NOR
Component: general
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
Created attachment 196443
--> https://bugs.kde.org/attachment.cgi?id=196443&action=edit
This is a patch that fixes the above mentioned issue
SUMMARY
Linking the tools fails when the toolchain's libgcc.a has been built without
optimisation:
ld: libgcc.a(_divdi3.o): in function `__divdi3':
libgcc2.c:1226: undefined reference to `_Unwind_Resume'
ld:
libgcc.a(_divdi3.o):(.data.rel.local.DW.ref.__gcc_personality_v0[DW.ref.__gcc_personality_v0]+0x0):
undefined reference to `__gcc_personality_v0'
ld: libgcc.a(_moddi3.o): in function `__moddi3':
libgcc2.c:1249: undefined reference to `_Unwind_Resume'
ld: libgcc.a(_umoddi3.o): in function `__udivmoddi4':
libgcc2.c:1204: undefined reference to `_Unwind_Resume'
collect2: error: ld returned 1 exit status
make[4]: *** [Makefile:1180: memcheck-x86-linux] Error 1
Seen on x86/Linux (32 bit) with gcc 15.3.0 and binutils 2.45, in Buildroot's
autobuilders. It is not Buildroot specific: any toolchain whose libgcc was
compiled at -O0 triggers it.
STEPS TO REPRODUCE
1. Build a cross toolchain whose libgcc is compiled without optimisation. With
Buildroot this is what BR2_OPTIMIZE_0=y does, because the target CFLAGS end up
after libgcc's own -O2 on the libgcc2.c command line:
gcc/Makefile.in:507
GCC_CFLAGS = $(CFLAGS_FOR_TARGET) $(INTERNAL_CFLAGS) ... [->
libgcc.mvars]
libgcc/Makefile.in:249
LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) ...
so the last -O on the command line is the -O0 from CFLAGS_FOR_TARGET.
2. Confirm libgcc's divmod objects carry the unwinder references:
$ i686-linux-gnu-ar x $(i686-linux-gnu-gcc -print-file-name=libgcc.a)
_divdi3.o
$ i686-linux-gnu-nm -u _divdi3.o
U __gcc_personality_v0
U _Unwind_Resume
3. Configure and build valgrind for that target:
./configure --host=i686-buildroot-linux-gnu CFLAGS="-O0 -g0
-fno-stack-protector"
make
OBSERVED RESULT — the link of every tool fails as shown above.
EXPECTED RESULT — the tools link.
ANALYSIS
libgcc's 64 bit division helpers are deliberately compiled with exceptions
enabled (libgcc/Makefile.in:548):
LIB2_DIVMOD_EXCEPTION_FLAGS := -fexceptions -fnon-call-exceptions
At -O0 GCC keeps the exception landing pads in those objects, so _divdi3.o,
_moddi3.o and _umoddi3.o reference _Unwind_Resume() and __gcc_personality_v0(),
which live in libgcc_eh.a. At -O1 and above the landing pads are optimised away
and the references disappear. Recompiling the very same object with only the
trailing -O changed shows this clearly (same command line libgcc uses, gcc
15.3.0, i686):
effective -O0 : U __gcc_personality_v0 U _Unwind_Resume
... -O1 : (none)
... -O2 : (none)
Tools are linked with
-static -nodefaultlibs -nostartfiles -u _start ... -lgcc $(LIBGCC_SUP)
so libgcc_eh.a is not on the link line, and the references cannot be resolved.
The division helpers themselves are genuinely needed: on x86 the tools pull in
__divdi3, __moddi3, __udivdi3 and __umoddi3 from -lgcc at every optimisation
level, so this cannot be avoided by building valgrind differently.
Adding -lgcc_eh is not a workable fix, since it drags in unwind-dw2.o and
unwind-dw2-fde-dip.o, which need abort(), strlen() and dl_iterate_phdr() — none
of which are available under -nodefaultlibs.
PROPOSED FIX
The attached patch adds dummy definitions of _Unwind_Resume() and
__gcc_personality_v0() to coregrind/m_libgcc_sup.c, which is exactly the place
for "supplemental functions for libgcc". They can never be reached, since the
core is plain C and never raises an exception.
Because they end up in libgcc-sup-<platform>.a, which is linked after -lgcc,
archive members are only pulled in on demand: a toolchain that does provide the
real symbols in libgcc.a keeps using those and the dummies are never
extracted.
Verified on x86/Linux: with an object reproducing an -O0 built _divdi3.o added
to the tool link, the link fails with exactly the two errors above without
libgcc-sup-x86-linux.a and succeeds with it. A full build of 3.26.0 for i686
with the patch applied is clean.
Happy to rework it if you would rather gate the definitions on a configure
check, or have them call VG_(core_panic)() instead of __builtin_trap() — I used
the builtin to keep m_libgcc_sup.o free of references back into libcoregrind.a,
since it is linked last.
--
You are receiving this mail because:
You are watching all bug changes.