Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[zig cc] unable to dynamically link musl executables #11909

Open
motiejus opened this issue Jun 22, 2022 · 10 comments · Fixed by #12894
Open

[zig cc] unable to dynamically link musl executables #11909

motiejus opened this issue Jun 22, 2022 · 10 comments · Fixed by #12894
Labels
bug Observed behavior contradicts documented or intended behavior miscompilation The compiler reports success but produces semantically incorrect code. os-linux zig cc Zig as a drop-in C compiler feature
Milestone

Comments

@motiejus
Copy link
Contributor

motiejus commented Jun 22, 2022

Zig Version

0.10.0-dev.2473+e498fb155

Like the title says: zig cc frontend cannot compile a dynaimcally-linked musl binary. Created a separate issue as requested by @ifreund in #5364 (comment)

Full repro

main.c

#include <stdio.h>
#include <features.h>

int main() {
    #ifdef __GLIBC__
    printf("glibc_%d.%d\n", __GLIBC__, __GLIBC_MINOR__);
    #else
    printf("non-glibc\n");
    #endif
    return 0;
}

Compiling:

$ zig cc -v -target x86_64-linux-musl main.c -fPIE -lc -dynamic -o main
<...>
LLD Link... ld.lld -error-limit=0 -O0 -z stack-size=16777216 --gc-sections --eh-frame-hdr -znow -m elf_x86_64 -static -pie -o /home/motiejus/.cache/zig/o/503c6bf2ee43b2d33014a8d71f6bc1d2/main /home/motiejus/.cache/zig/o/60b545a849e93516862f973801e6307b/rcrt1.o /home/motiejus/.cache/zig/o/1f9266dba05df20689bccc6b184442ec/crti.o /home/motiejus/.cache/zig/o/6471a2fd822202eae06273e85f08f5c6/main.o /home/motiejus/.cache/zig/o/baf786ce8c76ce866d19a60d75637d88/libcompiler_rt.a --as-needed /home/motiejus/.cache/zig/o/a111f160cb9815a5d7c8128bcf0c7af8/libc.a /home/motiejus/.cache/zig/o/c8866bc9544d3faae13fa04a4728ac91/crtn.o --allow-shlib-undefined

Inspect the resulting main. It is static:

$ objdump --dynamic-syms main
main:     file format elf64-x86-64

DYNAMIC SYMBOL TABLE:
no symbols


$ file main
main: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), static-pie linked, with debug_info, not stripped

Looking at the linker line above, you can see that -static is passed to the linker, and at least --dynamic-linker option is missing.

@motiejus motiejus added the bug Observed behavior contradicts documented or intended behavior label Jun 22, 2022
@ifreund ifreund added the zig cc Zig as a drop-in C compiler feature label Jun 22, 2022
@motiejus motiejus changed the title [zig cc] cannot compile dynamically-linked musl binaries [zig cc] unable to dynamically link musl binaries Jun 22, 2022
@andrewrk andrewrk added miscompilation The compiler reports success but produces semantically incorrect code. contributor friendly This issue is limited in scope and/or knowledge of Zig internals. labels Jun 28, 2022
@andrewrk andrewrk added this to the 0.10.0 milestone Jun 28, 2022
@ghost
Copy link

ghost commented Jul 14, 2022

As a first-time contributor to zig, I want to try to do this. Where is the code for zig cc?

Edit: think I found it ;)

@ghost
Copy link

ghost commented Jul 14, 2022

Hm, after building Zig from source, version 0.10.0-dev.2997+1653a9b25, I can no longer reproduce the issue.

My OS is Artix Linux and I have LLVM 14.0.6.

@ghost
Copy link

ghost commented Jul 14, 2022

I notice the version you used expected LLVM 13, which I can't seem to easily get my system to use. Could it have been fixed by this update?

@andrewrk
Copy link
Member

The resolution to this issue was reverted in 4f9345d.

@andrewrk andrewrk reopened this Oct 18, 2022
@andrewrk andrewrk removed the contributor friendly This issue is limited in scope and/or knowledge of Zig internals. label Oct 18, 2022
@andrewrk andrewrk modified the milestones: 0.10.0, 0.10.1 Oct 18, 2022
@andrewrk
Copy link
Member

note that the proper flag is not -dynamic but -shared.

@andrewrk andrewrk modified the milestones: 0.10.1, 0.11.0 Jan 10, 2023
@iacore
Copy link
Contributor

iacore commented May 7, 2023

It ignores -Wl,--dynamic-linker=x as well

@vazub
Copy link

vazub commented Dec 3, 2023

0.12.0-dev.1718+3acb0e30a

I've been trying to build a dynamic executable for Python interpreter, with zig cc / musl, and can confirm that it is not working - the resulting binary is always statically linked, no matter extra -dynamic flags or whatnot.

Unless I am doing something wrong, I would say this issue is a showstopper for zig cc usage with any big and complex projects requiring a dynamic executable, where setting up own build.zig flow from scratch is prohibitively tedious.

@vazub
Copy link

vazub commented Dec 3, 2023

After some poking around and testing, I've found a temporary mitigation option. It appears, that if you directly pass LDFLAGS="-dynamic-linker <path-to-interpreter>" along with compiler invocation, zig will pick it up and command the linker to build a dynamic executable.

However, there is a caveat to keep in mind: a linker path/name you pass there is not honored, and it defaults to /lib/ld-musl-x86_64.so.1 in the final linker invocation no matter what, so if you have one in some other place - you would have to use patchelf --set-interpreter <whatever-pathname-you-have> on the resulting executable to fix it.

@alexrp
Copy link
Member

alexrp commented Apr 28, 2024

Just noting for any future readers that this seems to only affect executables, not shared libraries:

bat main.c
       File: main.c
   1   #include <stdio.h>
   2   
   3   int main()
   4   {
   5       printf("hello world\n");
   6   }zig cc main.c -target x86_64-linux-musl -o mainreadelf -d main

There is no dynamic section in this file.ldd main
	not a dynamic executablefile main
main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped
bat test.c
       File: test.c
   1   #include <stdio.h>
   2   
   3   void hello_world()
   4   {
   5       printf("hello world\n");
   6   }zig cc test.c -target aarch64-linux-musl -shared -fPIC -o libtest.soreadelf -d libtest.so

Dynamic section at offset 0x3f0 contains 16 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.so]
 0x000000000000001e (FLAGS)              BIND_NOW
 0x000000006ffffffb (FLAGS_1)            Flags: NOW
 0x0000000000000017 (JMPREL)             0x2f8
 0x0000000000000002 (PLTRELSZ)           24 (bytes)
 0x0000000000000003 (PLTGOT)             0x204f0
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000006 (SYMTAB)             0x200
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000005 (STRTAB)             0x2d0
 0x000000000000000a (STRSZ)              40 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x278
 0x0000000000000004 (HASH)               0x2a0
 0x000000000000000c (INIT)               0x10398
 0x000000000000000d (FINI)               0x103a8
 0x0000000000000000 (NULL)               0x0musl-ldd libtest.so
	musl-ldd (0x7c907ad8d000)
	libc.so => musl-ldd (0x7c907ad8d000)
Error relocating libtest.so: unsupported relocation type 1026file libtest.so
libtest.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, with debug_info, not stripped

@fidgetingbits
Copy link

After some poking around and testing, I've found a temporary mitigation option. It appears, that if you directly pass LDFLAGS="-dynamic-linker <path-to-interpreter>" along with compiler invocation, zig will pick it up and command the linker to build a dynamic executable.

However, there is a caveat to keep in mind: a linker path/name you pass there is not honored, and it defaults to /lib/ld-musl-x86_64.so.1 in the final linker invocation no matter what, so if you have one in some other place - you would have to use patchelf --set-interpreter <whatever-pathname-you-have> on the resulting executable to fix it.

Do you have a more exact example of how you managed to do this? I've been trying various incantations for awhile, but no luck yet. I always end up with a static binary. I am working on a project that uses zig to build some C stuff and I need to dynamically link against musl, so would be useful.

@andrewrk andrewrk modified the milestones: 0.14.0, 0.16.0 Aug 8, 2024
@alexrp alexrp changed the title [zig cc] unable to dynamically link musl binaries [zig cc] unable to dynamically link musl executables Oct 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior miscompilation The compiler reports success but produces semantically incorrect code. os-linux zig cc Zig as a drop-in C compiler feature
Projects
None yet
7 participants