Date: Mon, 27 Jan 2025 21:24:34 +0200 From: Konstantin Belousov <kostikbel@gmail.com> To: Steve Kargl <sgk@troutmask.apl.washington.edu> Cc: Dimitry Andric <dim@freebsd.org>, freebsd-hackers@freebsd.org Subject: Re: gcc14 static linking ends with segfault Message-ID: <Z5fdcvWgUpibIBXq@kib.kiev.ua> In-Reply-To: <Z5fTkXmqr1MZKk8d@troutmask.apl.washington.edu> References: <Z5aYNdVQdGdVImBG@troutmask.apl.washington.edu> <Z5cRe8tivqpgme1I@kib.kiev.ua> <Z5cnYyWxcT5pk1Wf@troutmask.apl.washington.edu> <C09215C1-ABF0-4248-A69A-F0137BBC7E2B@FreeBSD.org> <Z5fTkXmqr1MZKk8d@troutmask.apl.washington.edu>
next in thread | previous in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Z5fdcvWgUpibIBXq>