-z notext should allow relocations in a read-only (i.e., the .text) segment, but lld changes behaviour when -z notext is specified and linking a trivial application on FreeBSD fails: % cc -Wl,-z,notext hello.c /usr/bin/ld: error: relocation R_X86_64_PC32 cannot be used against shared object; recompile with -fPIC >>> defined in /lib/libc.so.7 >>> referenced by crt1.c:63 (/usr/home/emaste/src/freebsd/lib/csu/amd64/crt1.c:63) >>> /usr/lib/crt1.o:(_start) cc: error: linker command failed with exit code 1 (use -v to see invocation) I do not have a reduced test case, but can attach a reproducer for the hello world link if desired. However, I observe that RelExpr() bypasses the special case for Sym.isFunc() if !Config->ZText. There's a comment in RelExpr() that describes this same issue occurring with glibc.
Created attachment 19588 [details] FreeBSD 'hello world' -Wl,-z,notext build failure reproducer
Also I think the sense of this comment is backwards: // Or, if we are allowed to create dynamic relocations against // read-only sections (i.e. unless "-z notext" is given), // we can create a dynamic relocation as we want, too. if (!Config->ZText) return Expr; That should be "i.e., if "-z notext" is given"
(In reply to emaste from comment #2) > Also I think the sense of this comment is backwards: > > // Or, if we are allowed to create dynamic relocations against > // read-only sections (i.e. unless "-z notext" is given), > // we can create a dynamic relocation as we want, too. > if (!Config->ZText) > return Expr; > > That should be "i.e., if "-z notext" is given" Looking at this. But you also helped to find bug in google translate :) It translates "unless" to russian "if", and not to "if ... not": https://translate.google.ru/#en/ru/unless notice, when pressing switch message button, backward translation from russian is "if" then.
Reduced test case is following. main.s: .text _start: callq atexit dso.s: .text .global atexit atexit: nop llvm-mc -filetype=obj -triple=x86_64-pc-linux main.s -o main.o llvm-mc -filetype=obj -triple=x86_64-pc-linux dso.s -o dso.o ld.lld -shared dso.o -o dso.so ld.lld test.o -o out dso.so -z notext > error: relocation R_X86_64_PC32 cannot be used against shared object; recompile with -fPIC
Fix: https://reviews.llvm.org/D41541
First fix for 'hello world' was committed as r321400.
Second fix is https://reviews.llvm.org/D41551, I checked that 'hello world' provided links fine with it.
Last piece: r321473.