I want to compile a program for a target ARM system, the system's program uses /lib/ld-linux.so.3
for the dynamic linker path, but my toolchain uses /lib/ld-linux-armhf.so.3
. Even if I compile my program using command:
arm-linux-gnueabihf-gcc -std=c17 -Wall -pipe -O3 -flto -s prog.c -Wl,-dynamic-linker,/lib/ld-linux.so.3 -Wl,--build-id=none -lcrypto -lcurl -ljson-c -ldl -o prog
It still links the default linker:
[root@archlinux d]# readelf -dW prog
Dynamic section at offset 0x1ef0 contains 30 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libcrypto.so.1.1]
0x00000001 (NEEDED) Shared library: [libcurl.so.4]
0x00000001 (NEEDED) Shared library: [libjson-c.so.2]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x00000001 (NEEDED) Shared library: [ld-linux-armhf.so.3]
0x0000000c (INIT) 0x9d8
0x0000000d (FINI) 0x1740
0x00000019 (INIT_ARRAY) 0x2ee8
0x0000001b (INIT_ARRAYSZ) 4 (bytes)
0x0000001a (FINI_ARRAY) 0x2eec
0x0000001c (FINI_ARRAYSZ) 4 (bytes)
0x6ffffef5 (GNU_HASH) 0x188
0x00000005 (STRTAB) 0x500
0x00000006 (SYMTAB) 0x1d0
0x0000000a (STRSZ) 666 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x3000
0x00000002 (PLTRELSZ) 288 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x8b8
0x00000011 (REL) 0x860
0x00000012 (RELSZ) 88 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffb (FLAGS_1) Flags: PIE
0x6ffffffe (VERNEED) 0x800
0x6fffffff (VERNEEDNUM) 3
0x6ffffff0 (VERSYM) 0x79a
0x6ffffffa (RELCOUNT) 6
0x00000000 (NULL) 0x0
Is there any configure options to change the default dynamic linker to ld-linux.so.3
when building the glibc/gcc? Or any compile options to specify the dynamic loader for the program? (P.S. on the target system, the programs use libld.so.2 instead of ld-linux*.so.3)
Okay, it turns out I was using the wrong toolchain. The target system was actually built using arm-linux-gnueabi
toolchain instead of the hard float version arm-linux-gnueabihf
. The dynamic linker's soname of arm-linux-gnueabi
is indeed ld-linux.so.3
. Removing the --with-float=hard
configure option when building the GCC will build a soft float toolchain.
If you encounter a non standard soname for the dynamic linker, there is also a workaround. You can use command patchelf --set-soname
to change the soname of the dynamic linker, which will in turn makes the dynamic linker use the new soname when linking.