Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Jan 2025 21:23:36 +0100
From:      Dimitry Andric <dim@FreeBSD.org>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        Steve Kargl <sgk@troutmask.apl.washington.edu>, freebsd-hackers@freebsd.org
Subject:   Re: gcc14 static linking ends with segfault
Message-ID:  <DF181741-C357-47EA-AEF2-0743C598503F@FreeBSD.org>
In-Reply-To: <Z5fdcvWgUpibIBXq@kib.kiev.ua>
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> <Z5fdcvWgUpibIBXq@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On 27 Jan 2025, at 20:24, Konstantin Belousov <kostikbel@gmail.com> =
wrote:
>=20
> On Mon, Jan 27, 2025 at 10:42:25AM -0800, Steve Kargl wrote:
...
>> If I move gcc14/.../crtend.o out of the way, then the segfault goes =
away
>> as the linker shows
>>=20
>> -V -Bstatic -o z
>> /usr/lib/crt1.o
>> /usr/lib/crti.o
>> /usr/lib/crtbeginT.o
>> ...
>> /usr/lib/crtend.o
>> /usr/lib/crtn.o
>=20
> The following patch worked for me without changing anything in gcc.
>=20
> =46rom 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
>=20
> not relying only on the end section marker, but also checking for the
> section size when iterating.
>=20
> 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(-)
>=20
> 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 =3D {
> (crt_func)-1
> };
>=20
> +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;
>=20
> #ifdef SHARED
> run_cxa_finalize();
> #endif
>=20
> + dtors_end =3D (uintptr_t)&startof_dtors + (uintptr_t)&sizeof_dtors;
> for (n =3D 1;; n++) {
> fn =3D __DTOR_LIST__[n];
> - if (fn =3D=3D (crt_func)0 || fn =3D=3D (crt_func)-1)
> + if (fn =3D=3D (crt_func)0 || fn =3D=3D (crt_func)-1 || (dtors_end > =
0 &&
> +     (uintptr_t)&__DTOR_LIST__[n] >=3D dtors_end))
> break;
> fn();
> }

Yes, this looks good to me, thanks! Note that even with this safety belt
applied to crtbegin, it's still a good idea to fix the gcc side... :)

Btw, it would also be nice to add a similar safety belt for ctors?

-Dimitry




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?DF181741-C357-47EA-AEF2-0743C598503F>