[LLVMdev] Some thought on handling ELF shared libraries in lld

Rafael Espíndola
2015-07-21T12:46:58Z

Most ELF shared libraries can be sliced in two ways. One is following
the information in the program headers (e_phoff). The other is
following the information in the section headers (e_shoff).

Regular relocatable objects only have the section header.

At runtime, the dynamic linker only uses the program headers. In fact,
the section headers is optional.

When given a shared library, how should the static linker handle it?

Note that, unlike the dynamic linker, the static one has to find all
the defined symbol is a shared library. It is not enough to just look
up the currently undefined symbols. To see that, consider

$ cat test.c
void f(void) { }
$ cat test2.c
void f(void);
void g(void) {
  f();
}

$ clang -c test.c test2.c -fPIC
$ clang -shared test.o -o test.so
$ rm -f test.a
$ ar rc test.a test.o
$ clang test.so test2.o test.a -o t.so -Wl,-t -shared
$ clang         test2.o test.a -o t.so -Wl,-t -shared

The second link will include the archive member, the first one will not.

It is tempting to use the program headers in the static linker. Doing
so would let us support linking with shared libraries with no section
headers, but there are a few issues:

* The intention of the spec seems to be for everything static to use
the section headers and everything dynamic to use the program headers.
* Finding the number of symbols with the program header in a
traditional ELF file is a hack. One has to read the nchain field of
the hash table.
* It doesn't seem even possible to find that information in files
using the newer gnu hash format
(https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections).

Given that, it looks like we should use the sections. For what it is
worth, it looks like that is what every other ELF linker does.

Cheers,
Rafael