Description
Environment
- Linux with x86_64 kernel and i386 glibc userspace
- Zig snapshot from
zig-linux-x86_64-0.8.0-dev.1104+5e81b048a.tar.xz
tarball
$ zig version
0.8.0-dev.1104+5e81b048a
Minimal reproducible example
// dummy.zig
export fn dummy() c_int {
return 0;
}
$ zig build-lib dummy.zig -dynamic -target i386-native
zig build-lib output (with `ld.lld` error)
ld.lld: error: relocation R_386_PC32 cannot be used against symbol __zig_probe_stack; recompile with -fPIC
>>> defined in /tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/libcompiler_rt.a(/tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/compiler_rt.o)
>>> referenced by fs.zig:684 (/tmp/zig/zig-linux-x86_64-0.8.0-dev.1104+5e81b048a/lib/std/fs.zig:684)
>>> zig-cache/o/dbc73e4dde353bae2e8456cf743e6f42/dummy.o:(std.fs.Dir.openFile)
ld.lld: error: relocation R_386_PC32 cannot be used against symbol __zig_probe_stack; recompile with -fPIC
>>> defined in /tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/libcompiler_rt.a(/tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/compiler_rt.o)
>>> referenced by os.zig:4504 (/tmp/zig/zig-linux-x86_64-0.8.0-dev.1104+5e81b048a/lib/std/os.zig:4504)
>>> zig-cache/o/dbc73e4dde353bae2e8456cf743e6f42/dummy.o:(std.os.toPosixPath)
ld.lld: error: relocation R_386_PC32 cannot be used against symbol __zig_probe_stack; recompile with -fPIC
>>> defined in /tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/libcompiler_rt.a(/tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/compiler_rt.o)
>>> referenced by debug.zig:1040 (/tmp/zig/zig-linux-x86_64-0.8.0-dev.1104+5e81b048a/lib/std/debug.zig:1040)
>>> zig-cache/o/dbc73e4dde353bae2e8456cf743e6f42/dummy.o:(std.debug.printLineFromFileAnyOs)
error: LLDReportedFailure
Note
It happens only in -O Debug
. It doesn't happen in all other -O
modes.
Workaround
- Just add
-z notext
tobuild-lib
command line arguments, like:
zig build-lib dummy.zig -dynamic -target i386-native -z notext
-
This option could be set in
build.zig
. As suggested in ld.lld: error: relocation R_386_PC32 cannot be used against symbol __zig_probe_stack #7935 (comment):you can set
lib.link_z_notext = true;
in yourbuild.zig
See pull request #10056 (and merged commit 2cdffc9).
Zig 0.8.1 didn't include this commit, following downloadable releases should allow this workaround. I've tested it with 0.9.0-dev.1561+5ebdc8c46
(released on 2021-11-03).
Workaround (for Zig versions released before 29-Oct-2021)
Execute `zig ld.lld` manually with added `-z notext`
- Find
ld.lld
invocation arguments.
$ zig build-lib dummy.zig -dynamic -target i386-native --verbose-link
ld.lld -error-limit=0 --gc-sections -m elf_i386 -shared -o libdummy.so -soname libdummy.so zig-cache/o/dbc73e4dde353bae2e8456cf743e6f42/dummy.o /tmp/zig/cache/zig/o/44e6d86d0e734b882fd45d9658d515d8/libc.a /tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/libcompiler_rt.a
ld.lld: error: relocation R_386_PC32 cannot be used against symbol __zig_probe_stack; recompile with -fPIC
>>> defined in /tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/libcompiler_rt.a(/tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/compiler_rt.o)
>>> referenced by fs.zig:684 (/tmp/zig/zig-linux-x86_64-0.8.0-dev.1104+5e81b048a/lib/std/fs.zig:684)
>>> zig-cache/o/dbc73e4dde353bae2e8456cf743e6f42/dummy.o:(std.fs.Dir.openFile)
ld.lld: error: relocation R_386_PC32 cannot be used against symbol __zig_probe_stack; recompile with -fPIC
>>> defined in /tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/libcompiler_rt.a(/tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/compiler_rt.o)
>>> referenced by os.zig:4504 (/tmp/zig/zig-linux-x86_64-0.8.0-dev.1104+5e81b048a/lib/std/os.zig:4504)
>>> zig-cache/o/dbc73e4dde353bae2e8456cf743e6f42/dummy.o:(std.os.toPosixPath)
ld.lld: error: relocation R_386_PC32 cannot be used against symbol __zig_probe_stack; recompile with -fPIC
>>> defined in /tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/libcompiler_rt.a(/tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/compiler_rt.o)
>>> referenced by debug.zig:1040 (/tmp/zig/zig-linux-x86_64-0.8.0-dev.1104+5e81b048a/lib/std/debug.zig:1040)
>>> zig-cache/o/dbc73e4dde353bae2e8456cf743e6f42/dummy.o:(std.debug.printLineFromFileAnyOs)
error: LLDReportedFailure
- Execute
zig ld.lld
manually with added-z notext
.
$ zig ld.lld -error-limit=0 --gc-sections -m elf_i386 -shared -o libdummy.so -soname libdummy.so zig-cache/o/dbc73e4dde353bae2e8456cf743e6f42/dummy.o /tmp/zig/cache/zig/o/44e6d86d0e734b882fd45d9658d515d8/libc.a /tmp/zig/cache/zig/o/24934007c007b2d5b7135d2223ee0adf/libcompiler_rt.a -z notext
libdummy.so
will be produced.
Conclusions
That begs a question: is it or is it not possible to pass freeform extra arguments to internal zig ld.lld
invocation simply by using additional zig build-lib
options and/or by using appropriate function in build.zig
? (I didn't find a way to do it.)
Also I don't know and can't argue whether passing -z notext
is a safe or right solution. Just reporting that it works.
Relevant links
-z notext
- reviews.llvm.org / [ELF] - Implemented -znotext
- can't create dynamic relocation R_386_32 with LLD ClangBuiltLinux/linux#579
- Unable to install openssl on FreeBSD 12.1 32 bit openssl/openssl#11305 (comment) and FreeBSD Bugzilla – Attachment #197583: OpenSSL 1.1 LLD fix for bug #231459