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