linuxgccglibctoolchain

How to specify the default dynamic linker name when building gcc/glibc?


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)


Solution

  • 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.