Re: gcc14 static linking ends with segfault
Date: Mon, 27 Jan 2025 19:24:34 UTC
On Mon, Jan 27, 2025 at 10:42:25AM -0800, Steve Kargl wrote: > On Mon, Jan 27, 2025 at 04:34:22PM +0100, Dimitry Andric wrote: > > /usr/lib/crt1.o \ > > /usr/lib/crti.o \ > > /usr/lib/crtbeginT.o \ > (...) > > /usr/local/lib/gcc13/gcc/x86_64-portbld-freebsd15.0/13.3.0/crtend.o \ > > /usr/lib/crtn.o > > > > > > > > Summarizing, I think that it is weird that gcc doesn't use its own > > crtbegin object, at least for static linking. There may be some > > historical reason for it, but it should then also not use its own crtend > > object! > > Not sure about a historical reason, but gcc14 seems to not > supply crt1.o, crt1.o, crtbeginT.o, ot crtn.o. Thus, the > linker is picking up those files from /usr/lib. > > % find /usr/local/lib/gcc14/ -name crt\*.o > /usr/local/lib/gcc14/gcc/x86_64-portbld-freebsd15.0/14.2.0/crtbegin.o > /usr/local/lib/gcc14/gcc/x86_64-portbld-freebsd15.0/14.2.0/crtend.o > /usr/local/lib/gcc14/gcc/x86_64-portbld-freebsd15.0/14.2.0/crtbeginS.o > /usr/local/lib/gcc14/gcc/x86_64-portbld-freebsd15.0/14.2.0/crtendS.o > > If I move gcc14/.../crtend.o out of the way, then the segfault goes away > as the linker shows > > -V -Bstatic -o z > /usr/lib/crt1.o > /usr/lib/crti.o > /usr/lib/crtbeginT.o > ... > /usr/lib/crtend.o > /usr/lib/crtn.o The following patch worked for me without changing anything in gcc. From 976aa780b8ad212127d84a47a5a05f1bd6aef60c Mon Sep 17 00:00:00 2001 From: Konstantin Belousov <kib@FreeBSD.org> Date: Mon, 27 Jan 2025 21:21:20 +0200 Subject: [PATCH] crtbegin: accurately check for the end of .dtors not relying only on the end section marker, but also checking for the section size when iterating. Reported by: kargl Analyzed by: dim Sponsored by: The FreeBSD Foundation MFC after: 1 week --- lib/csu/common/crtbegin.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/csu/common/crtbegin.c b/lib/csu/common/crtbegin.c index d6978859af4a..06fe990052f7 100644 --- a/lib/csu/common/crtbegin.c +++ b/lib/csu/common/crtbegin.c @@ -66,19 +66,27 @@ static crt_func __DTOR_LIST__[] __section(".dtors") __used = { (crt_func)-1 }; +extern const char startof_dtors[] __asm(".startof..dtors") + __weak_symbol __hidden; +extern const char sizeof_dtors[] __asm(".sizeof..dtors") + __weak_symbol __hidden; + static void __do_global_dtors_aux(void) { crt_func fn; + uintptr_t dtors_end; int n; #ifdef SHARED run_cxa_finalize(); #endif + dtors_end = (uintptr_t)&startof_dtors + (uintptr_t)&sizeof_dtors; for (n = 1;; n++) { fn = __DTOR_LIST__[n]; - if (fn == (crt_func)0 || fn == (crt_func)-1) + if (fn == (crt_func)0 || fn == (crt_func)-1 || (dtors_end > 0 && + (uintptr_t)&__DTOR_LIST__[n] >= dtors_end)) break; fn(); } -- 2.48.1