Skip to content

Instantly share code, notes, and snippets.

@nickdesaulniers
Last active August 21, 2024 18:45
Show Gist options
  • Save nickdesaulniers/9d7407937427a22c816c4dfe258c02cc to your computer and use it in GitHub Desktop.
Save nickdesaulniers/9d7407937427a22c816c4dfe258c02cc to your computer and use it in GitHub Desktop.
linking hello world against musl built as LTO
# Building musl
$ ./configure CC=clang LD=lld
$ make -j72
# Building with musl (non-lto, no patch)
$ clang hello.c -nostdlib -fuse-ld=lld -L lib -lc -static lib/crt1.o
# Building against musl LTO
$ clang hello.c -nostdlib -fuse-ld=lld -static lib/crt1.o -Wl,--whole-archive lib/libc.a -Wl,--no-whole-archive -Wl,--gc-sections
# maybe of interest to add: -O2 -fno-asynchronous-unwind-tables, then run strip
# objcopy --remove-section .comment --remove-section .gnu.hash --remove-section .note.gnu.build-id a.out
$ gcc -nostdlib -fuse-ld=lld hello.c path/to/musl/lib/libc.a path/to/musl/lib/crt1.o \
-nostdinc -I path/to/musl/include -I path/to/musl/obj/include
$ clang -nostdlib -nostdinc -fuse-ld=lld hello.c path/to/musl/lib/libc.a \
path/to/musl/lib/crt1.o -Wl,--gc-sections -I path/to/musl/include \
-I path/to/musl/obj/include -fno-asynchronous-unwind-tables -static
diff --git a/configure b/configure
index a5231a0ebb73..e27b186203e1 100755
--- a/configure
+++ b/configure
@@ -491,6 +491,8 @@ tryflag CFLAGS_AUTO -fno-asynchronous-unwind-tables
#
tryflag CFLAGS_AUTO -ffunction-sections
tryflag CFLAGS_AUTO -fdata-sections
+tryflag CFLAGS_AUTO -flto
+tryldflag CFLAGS_AUTO -fuse-ld=lld
#
# On x86, make sure we don't have incompatible instruction set
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 8b67ef5927b8..3aa9caa43fdc 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -1639,7 +1639,8 @@ static void install_new_tls(void)
* linker itself, but some of the relocations performed may need to be
* replaced later due to copy relocations in the main program. */
-hidden void __dls2(unsigned char *base, size_t *sp)
+__attribute__((visibility("default")))
+void __dls2(unsigned char *base, size_t *sp)
{
size_t *auxv;
for (auxv=sp+1+*sp+1; *auxv; auxv++);
@MaskRay
Copy link

MaskRay commented May 20, 2021

Yes, visibility works. Another workaround is -Wl,-u,__dls2. https://www.openwall.com/lists/musl/2021/01/29/4

@nickdesaulniers
Copy link
Author

Thanks for that link; it looks like there's another suggestion to just disable LTO for that file, too: https://www.openwall.com/lists/musl/2021/01/30/3.

@nickdesaulniers
Copy link
Author

nickdesaulniers commented Mar 28, 2022

Looks like the "nobuiltins" IR attribute is blocking inlining of libc into callers.

./configure CC=clang CFLAGS=-flto LDFLAGS="-fuse-ld=lld -Wl,-u,__dls2"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment