[PATCH] D42748: [ELF] Don't create a .dynamic section when linking with -Bstatic

Konstantin Belousov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed May 29 12:26:19 PDT 2019

kib added a comment.

In D42748#1515212 <https://reviews.llvm.org/D42748#1515212>, @MaskRay wrote:

> > Regarding this patch: I don't think _DYNAMIC would be useful for -static-pie since we would need to relocate it first so _DYNAMIC could still be undefined and used to check for dynamic linker presence.
> You need `_DYNAMIC` for -static-pie. You need `_DYNAMIC` to find `DT_REL*` tags, then perform relocations.
> > I had a quick look at glibc's static-pie code and it seems like glibc loads the first GOT entry for most architectures to get the address of the dynamic section.
> It is one thing I don't like (I don't know any other program that needs this) about glibc (this is wrriten in x86 psABI, but probably not in other psABIs): the first entry of .got.plt or .got holds the link-time address of `_DYNAMIC`. At runtime a pcrel load of `_GLOBAL_OFFSET_TABLE_` gets the link-time address, subtracts it from the runtime address of `_DYNAMIC`, then you get the load base. glibc could parse the program header to get `p_vaddr` of `PT_DYNAMIC` instead.

[Perhaps, pcrel load gets runtime address, not important.]

The content of the first GOT entry (&_DYNAMIC) is specified in x86_64 psABI doc.  More, the language there is explicit that this algorithm should be used to find the relocs.  In fact it is quite relieving comparing with previous suggestion to find aux, then parse it to find program headers, then to find PT_INTERP and PT_DYNAMIC.  It is two or three instructions in crt1 vs. several hundreds, which must be linked into each binary.

>> Also, as I noted above, PT_INTERP absence does not really mean that the binary is static.
> @kib I'm happy to know about FreeBSD crt internals but I'm afraid we've digressed from the topic, or I fail to understand how you justify the this patch.

If linker decisions make crt operation hard or impossible, it is important.

> I tried not using the term dynamically/statically linked program (the file utility may say a `-static-pie` is "dynamic" while glibc ldd says it is "static"). I'm sorry if I failed to do that.
> I'm not happy with some decisions made in the GNU toolchain: `-static` does not compose with `-pie` (it overrides `-pie`) so they added `-static-pie`, ld.bfd has default PT_INTERP path for various platforms so it needs `--no-dynamic-linker`, `-static` seems to override `-export-dynamic`, etc.
> @ed's explanation of `-export-dynamic` makes sense to me. I don't understand why this patch wants to override part of the semantics of `-export-dynamic` with `-static`, making the overall logic harder to reason about.
> A -static-pie needs `_DYNAMIC`. When FreeBSD gets to -static-pie, if the expectation is that it resembles more a -static than a dynamic (finalizers called in the exe, not in ld.so/libc.so), the simplistic check `&_DYNAMIC != NULL` will not work.
>  Or when you decide to support dlopen() from a static program, it also needs `_DYNAMIC`. If the current (`&_DYNAMIC!=` is true) status makes applications crash, you need to figure out a more reliable approach.

I am fine with whatever approach which does not require me to link significant portion of rtld into each binary just to detect the presence of rtld and libc in the process.
`&_DYNAMIC == NULL` is good enough from the PoV.  If new world order requires changes due to linker evolution, I am fine with that, but the method should be equally streamlined and boil down to very simple runtime check, feasible to do in the pre-relocated state.

  rLLD LLVM Linker



More information about the llvm-commits mailing list