1

Linux separates the linker-time search path and run-time search path.

For the run-time search path, I found the rule for ld.so in its man page (8 ld.so):

  1. DT_RPATH
  2. environment LD_LIBRARY_PATH
  3. DT_RUNPATH
  4. ld.so.cache
  5. /lib, /usr/lib

But for linker-time search path, no luck for ld :(

Man page for ld (1 ld) says, besides -L option:

The default set of paths searched (without being specified with -L) depends on which emulation mode ld is using, and in some cases also on how it was configured.

The paths can also be specified in a link script with the "SEARCH_DIR" command. Directories specified this way are searched at the point in which the linker script appears in the command line.

Does the "default set of paths" depending on emulation mode mean "SEARCH_DIR"?

osgx
  • 90,338
  • 53
  • 357
  • 513
misssprite
  • 616
  • 9
  • 17
  • misssprite, what is the "ld"? Is it "ld.so", or is it "ld-linux.so" or "libdl.so"? ["ld-linux.so"](http://man7.org/linux/man-pages/man8/ld.so.8.html) (ELF dynamic linker / loader) is registered as interpreter in the dynamic ELF file, section... [INTERP](http://stackoverflow.com/a/5130690/196561), check `readelf -l ./dynamic_application`. PS Which man page you used, is it http://man7.org/linux/man-pages/man8/ld.so.8.html or http://man7.org/linux/man-pages/man1/ld.1.html or some other? – osgx Mar 16 '17 at 01:34
  • I mean the `linker` in GCC, not the loader. I'll edit it.@osgx – misssprite Mar 16 '17 at 01:42
  • misssprite, your understanding of man page 1 ld http://man7.org/linux/man-pages/man1/ld.1.html is incorrect, DT_RPATH and other are used for searching dynamic libraries (they are named `libSOMETHING.so` like `libc.so`), required by the application with NEEDED entries of the dynamic section (check output of `readelf -d ./dynamic_program`). There is no dynamic library named `ld.so`. – osgx Mar 16 '17 at 01:58
  • I know `ld.so` is the LOADER, not a .so library.. Maybe you can help me edit the question to fix anywhere confusing.@osgx – misssprite Mar 16 '17 at 02:08
  • dynamic libraries are searched (in run-time) by dynamic loader ld-linux.so as you described in the question. And ld-linux.so path (at end of compile+link process) is hardcoded in the binutils linker `ld` (incorrectly) and in gcc (correctly, check `gcc -dumpspecs|grep dynamic-linker`), and passed from gcc to ld (check my answer). – osgx Mar 16 '17 at 02:11

3 Answers3

0

Speaking about the ld itself, the library path search order is the following:

  1. Directories specified via -L command line flags
  2. Directories in the LIBRARY_PATH environment variable
  3. SEARCH_DIR variables in the linker script.

You can look what directories are specified in the default linker script by running ld --verbose | grep SEARCH_DIR. Note that = in the SEARCH_DIR values will be replaced by the value of --sysroot option if you specify it.

Usually ld is not invoked directly, but via compiler driver which passes several -L options to the linker. In the case of gcc or clang you can print the additional library search directories added by a compiler by invoking it with -print-search-dirs option. Also note that if you specify some machine-specific compiler flags (like e.g -m32 as misssprite mentioned) than the linker may use different linker script according to the chosen ELF emulation. In the case of gcc you can use -dumpspecs option to look how different compiler flags affect the linker invocation. But IMHO the simplest way to look for the linker command line is to compile and link a simple program with -v specified.

Community
  • 1
  • 1
segfault
  • 71
  • 4
  • LIBRARY_PATH doesn't work for me. I edited the question to clarified the question. Can you update responding to the two issues? By the way, I didn't mention `-m32`. It seems that another buddy removed his answer. – misssprite Mar 16 '17 at 01:31
  • @misssprite, what was your exact command which you tried to modify with LIBRARY_PATH? I see no reads of LIBRARY_PATH in ld sources in binutils: https://github.com/bneumeier/binutils/search?q=LIBRARY_PATH&type=Code and `ldfile_add_library_path` https://github.com/bneumeier/binutils/search?q=ldfile_add_library_path+ is filled with SEARCH_DIR options of linker script (https://github.com/bneumeier/binutils/blob/db980de65ca9f296aae8db4d13ee884f0c18ac8a/ld/ldgram.y#L328) and ld `-L options` https://github.com/bneumeier/binutils/blob/db980de65ca9f296aae8db4d13ee884f0c18ac8a/ld/ldfile.c#L569 – osgx Mar 16 '17 at 02:30
  • @osgx, the command should be OK, `export LIBRARY_PATH=.:$LIBRARY_PATH`. So the src code also indicates that LIBRARY_PATH does not take effect. – misssprite Mar 16 '17 at 03:02
  • @osgx, so all the things related are SEARCH_DIR and -L? – misssprite Mar 16 '17 at 03:03
  • @misssprite, this is not full command, this is only changing of LIBRARY_PATH. How you started `ld` and which `ld` options were used? – osgx Mar 16 '17 at 15:22
  • 1
    @osgx, I run `ld hello.o -ltest -L.` and `ld hello.o -ltest`, with LIRARY_PATH set. The former found the `libtest.so` in pwd, and the latter didn't. – misssprite Mar 17 '17 at 01:53
  • @misssprite, and what is your OS, is it ubuntu? Is your ld from gnu binutils? – osgx Mar 18 '17 at 17:42
  • 1
    @osgx, yes, it's ubuntu gnu ld. As you stated previously, `LIBRARY_PATH` does not appear in the ld source, it should not take effect. It makes sense. – misssprite Mar 19 '17 at 14:34
0

misssprite, to look for the linker search path for specific ELF emulation just run ld -m<emulation> --verbose | grep SEARCH_DIR

Community
  • 1
  • 1
segfault
  • 71
  • 4
0

misssprite, there is no search for ld.so or ld-linux.so in the binutils's ld linker.

When dynamic program is build with gcc, it uses option -dynamic-linker of ld (collect2) program: http://man7.org/linux/man-pages/man1/ld.1.html

-Ifile, --dynamic-linker=file

  Set the name of the dynamic linker.  This is only meaningful when
       generating dynamically linked ELF executables.  The default
       dynamic linker is normally correct; don't use this unless you
       know what you are doing.")

Usually used as runtime loader for ELF, the "ld-linux.so" is registered as interpreter in the dynamic ELF file, program header INTERP (.interp), check output readelf -l ./dynamic_application. This field is for full path, as I understand.

When there is no gcc (directly called 'ld' program) or no this option was given, ld uses hardcoded string of full path to ld.so; and this default is incorrect for most OS, including Linux:

https://github.com/bneumeier/binutils/blob/db980de65ca9f296aae8db4d13ee884f0c18ac8a/bfd/elf64-x86-64.c#L510

/* The name of the dynamic interpreter.  This is put in the .interp
   section.  */

#define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
#define ELF32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1"

https://github.com/bneumeier/binutils/blob/db980de65ca9f296aae8db4d13ee884f0c18ac8a/gold/x86_64.cc#L816

template<>
const Target::Target_info Target_x86_64<64>::x86_64_info =
 ...
  "/lib/ld64.so.1",     // program interpreter
const Target::Target_info Target_x86_64<32>::x86_64_info =
 ...
  "/libx32/ldx32.so.1", // program interpreter

Correct dynamic linker/loader path is hardcoded in machine spec files of gcc, grep output of gcc -dumpspecs command for ld-linux for -dynamic-linker option value.

osgx
  • 90,338
  • 53
  • 357
  • 513
  • Specs and ld.so paths are hardcoded in gcc sources here: https://github.com/gcc-mirror/gcc/search?q=-dynamic-linker&type=Code & https://github.com/gcc-mirror/gcc/search?q=GLIBC_DYNAMIC_LINKER in gcc/config/*/*.h files: https://github.com/gcc-mirror/gcc/blob/1cb6c2eb3b8361d850be8e8270c597270a1a7967/gcc/config/i386/linux.h gcc/config/i386/linux.h `#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"` & https://github.com/gcc-mirror/gcc/blob/700a97608cadfe8adcd1a98e6388a5cbee9d76f6/gcc/config/i386/linux64.h gcc/config/i386/linux64.h `#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2"` – osgx Mar 16 '17 at 02:20
  • 1
    Thanks for the detailed explanation of how `ld` locates `ld-linux.so` when linking. But my real question is "what does 'the default set of paths' mean in man page for `ld` for searching .so?" – misssprite Mar 16 '17 at 02:23