Bug 29249

Summary: csu/libc-tls.c:202: undefined reference to `_startup_fatal_not_constant'
Product: glibc Reporter: James Hilliard <james.hilliard1>
Component: libcAssignee: Florian Weimer <fweimer>
Status: RESOLVED FIXED    
Severity: normal CC: drepper.fsp, fweimer, hjl.tools, koutheir, Martin.Jansa, nsz, rwmacleod, yann
Priority: P2 Flags: fweimer: security-
Version: 2.35   
Target Milestone: 2.37   
Host: Target:
Build: Last reconfirmed: 2022-06-15 00:00:00
Attachments: A patch to force -O2
Update TLS_INIT_TP

Description James Hilliard 2022-06-15 06:06:10 UTC
I'm hitting this build failure in the glibc 2.35 branch:
csu/libc-tls.c:202: undefined reference to `_startup_fatal_not_constant'

Reverting the following commit appears to prevent the build failure:
https://sourceware.org/git/?p=glibc.git;a=commit;h=2d05ba7f8ef979947e910a37ae8115a816eb4d08

I'm not sure what the correct fix for this is.
Comment 1 Florian Weimer 2022-06-15 07:11:56 UTC
Probably build with more optimization? We build all targets regularly using different GCC versions, and have not seen this issue.

We may not have a working strlen this early during statically linked process startup, which is why we rely on the compiler to compute the string length for us.
Comment 2 James Hilliard 2022-06-15 07:18:09 UTC
Seems I'm hitting it with -Og optimizations which appears to work fine without that one commit.
Comment 3 Florian Weimer 2022-06-15 07:22:32 UTC
I see. Which architecture do you build for, and which GCC version do you use?

We can probably avoid the strlen dependency in some other way.
Comment 4 James Hilliard 2022-06-15 07:47:45 UTC
Should be gcc 12.1 building for x86_64.
Comment 5 Florian Weimer 2022-06-15 07:56:19 UTC
(In reply to James Hilliard from comment #4)
> Should be gcc 12.1 building for x86_64.

Do you just set CFLAGS="-Wall -Og -g"? Thanks.

I'll try to come up with something (along with regular testing), but probably not this week.
Comment 6 James Hilliard 2022-06-15 08:07:18 UTC
I think it's just -Og and -g3, although build system might be setting a few other things. I think build works fine with other optimization settings like -O2.
Comment 7 Martin Jansa 2022-07-27 11:23:18 UTC
It's reproducible with -O1 and not reproducible with -O2 (or -O1 + -fexpensive-optimizations):

objdump -x build-x86_64-oe-linux/csu/libc-tls.o | grep _startup_fatal_not_constant

doesn't show the symbol at all with -fexpensive-optimizations, while with just -O1:

objdump -x build-x86_64-oe-linux/csu/libc-tls.o.O1 | grep _startup_fatal_not_constant
0000000000000000         *UND*  0000000000000000 _startup_fatal_not_constant
00000000000002bb R_X86_64_PLT32    _startup_fatal_not_constant-0x0000000000000004
Comment 8 Martin Jansa 2022-08-07 13:53:06 UTC
I've tested if this is still reproducible with latest 2.36 (revision ac47d8f6cf9744139adb12f540fb9cc610cac579) and it is still reproducible, plus there is another build issue with -Og/-O1 I've reported in bug 29454
Comment 9 Martin Jansa 2022-08-09 10:44:43 UTC
H.J can you please take a look at this one as well?

-O2 and higher works
-O1 and -Og fails

-O1 + -fexpensive-optimizations works
-Og + -fexpensive-optimizations fails

I'm aware of
https://sourceware.org/glibc/wiki/FAQ#Why_do_I_get:.60.23error_.22glibc_cannot_be_compiled_without_optimization.22.27.2C_when_trying_to_compile_GNU_libc_with_GNU_CC.3F
and use of -O0 is prevented with #error, but do we need to prevent using -O1/-Og as well?

This seems currently the only issue (now when bug 29454 was fixed, there is separate issue bug 19444 when building with -Os, patch available since 2018 in https://patchwork.ozlabs.org/project/glibc/patch/20181217213618.29538-1-Martin.Jansa@gmail.com/).

As work around this commit was already reverted in OpenEmbedded and Buildroot:
https://git.openembedded.org/openembedded-core/commit/?id=642348f9b4656a090b5a272c18a6723c60100e08
https://github.com/buildroot/buildroot/commit/8d6e07e525617ee0c4ccc4f07345b1b1a70526f7
Comment 10 H.J. Lu 2022-08-09 19:03:01 UTC
Created attachment 14269 [details]
A patch to force -O2
Comment 11 Martin Jansa 2022-08-13 12:34:16 UTC
Thanks H.J. Lu, I've verified that this patch works in my environment.
Comment 12 H.J. Lu 2022-08-15 20:39:01 UTC
(In reply to Martin Jansa from comment #11)
> Thanks H.J. Lu, I've verified that this patch works in my environment.

The patch is wrong since __OPTIMIZE__ is also set to 1 for -O3 and -Ofast.
Comment 13 H.J. Lu 2022-08-15 20:54:25 UTC
Created attachment 14283 [details]
Update TLS_INIT_TP
Comment 14 H.J. Lu 2022-08-16 17:13:26 UTC
(In reply to H.J. Lu from comment #13)
> Created attachment 14283 [details]
> Update TLS_INIT_TP

This doesn't work for elf/rtld.c.
Comment 15 Szabolcs Nagy 2022-11-03 11:25:26 UTC
we hit this on arm with gcc-trunk and -O2 after a recent change.

i think TLS_INIT_TP should just indicate failure and then the caller can print a generic message. i don't think arch specific message is very important for this.
Comment 16 Florian Weimer 2022-11-03 11:44:50 UTC
(In reply to Szabolcs Nagy from comment #15)
> we hit this on arm with gcc-trunk and -O2 after a recent change.
> 
> i think TLS_INIT_TP should just indicate failure and then the caller can
> print a generic message. i don't think arch specific message is very
> important for this.

Yeah, that's reasonable, I'll to come up with a patch.

Failure is also less likely here because of the mmap fallback we introduced.
Comment 17 Florian Weimer 2022-11-03 15:02:58 UTC
Patch posted: https://sourceware.org/pipermail/libc-alpha/2022-November/143178.html
Comment 18 Florian Weimer 2022-11-03 16:29:10 UTC
Fixed for 2.37 via:

commit 1f34a2328890aa192141f96449d25b77f666bf47
Author: Florian Weimer <fweimer@redhat.com>
Date:   Thu Nov 3 17:28:03 2022 +0100

    elf: Introduce <dl-call_tls_init_tp.h> and call_tls_init_tp (bug 29249)
    
    This makes it more likely that the compiler can compute the strlen
    argument in _startup_fatal at compile time, which is required to
    avoid a dependency on strlen this early during process startup.
    
    Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>