Ah sorry, I should have been more clear. So
ET_DYN is just the kind of binary in the ELF header struct (the
e_type field), or if you run
readelf -e or
objdump -f it’ll have similar output.
readelf -e /bin/ls will show the type as
EXEC, whereas if you run it on a rustc binary compiled with the standard toolchain on linux (i.e. just
readelf -e main should report
A PIE is just a shared object (DLL, dynamic library, or
ET_DYN) with an entry point, so it can be loaded anywhere in memory (and thus can take advantage of ASLR) and executed. For example, this is a requirement on the android platform now iirc.
So grepping through
liblibc-<hash>.rlib and my
libc.a from compiling musl the rustlib has the problematic
R_X86_64_32S relocation, but the
libc.a does not.
After spending a bunch of time on this I just realized that I originally had this problem a while back, and I added this line into the musl
./configure in my
make_static.sh script which was adopted from the chapter on advanced linking, and which essentially mirrors your build setup:
CFLAGS=-fPIC ./configure --disable-shared --prefix=$PREFIX
I’ve just tested, and if I build musl without the
CFLAGS=-fPIC environment variable given to configure (i.e.,
./configure --disabled-shared and not
CFLAGS=-fPIC ./configure --disable-shared) then it will have those problematic relocations.
So, your initial intuition was correct!
Additionally if you look at the musl
Makefile, you’ll see that if passes
-fPIC to the shared object (which we disable):
$(LOBJS) $(LDSO_OBJS): CFLAGS_ALL += -fPIC
but not to the static libc version :]
CFLAG=-fPIC is an ugly hack, but it seems to work for me.
I believe you can also add this line in the musl
Makefile (but it’s more invasive):
$(AOBJ): CFLAGS_ALL += -fPIC
How is the
liblibc-<hash>.rlib generated? I’d like to create the artifact with the
-fPIC'd libc.a to verify it works correctly, etc.