[PATCH] D56828: [ELF] Simplify RelRo, TLS, NOBITS section ranks and make RW PT_LOAD start with RelRo

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 2 22:28:15 PST 2019


MaskRay added a comment.

In D56828#1416170 <https://reviews.llvm.org/D56828#1416170>, @joerg wrote:

> Placing `.bss.rel.ro` before `.data` doesn't make sense. It forces the content of `.bss.rel.ro` to embedded into the binary. I also don't really understand the motivation here.  Memory mappins on the kernel side are quite cheap.


.bss.rel.ro is a linker synthesized section whose only purpose is to reserve space for copy relocations of symbols in read-only segments. In most applications, we expect it is very small or does not exist at all.

I agree that in -z relro mode (default), when either .data or .bss exists (almost always true), the contents of .bss.rel.ro are embedded (as if it is .data.rel.ro; this is used by newer ld.bfd/gold). However, since .bss.rel.ro is small, this doesn't matter.

(We use .data.rel.ro as a representative for relro progbits sections like .dynamic .got)

old size: roundup(.data) + roundup(.data.rel.ro)
new size: roundup(.data.rel.ro + .bss.rel.ro) + .data
old-new = (page - .data%page)%page - roundup(.bss.rel.ro - (pagesize - .data.rel.ro%page)%page)

The first term is on average page/2 while the second term is (unbounded in theory), though 0 in most cases, pagesize in rare cases.

So the advantage of this patch:

- Simpler rule: we no longer need to place RelRo in the segment boundary.
- start(PT_TLS) = start(PT_GNU_RELRO) = start(RW PT_LOAD): this simplifies some binary manipulation tools. As I noted, GNU strip<2.31 will not strip RelRo. It should also make llvm-objcopy's life easier. I don't know of a specific corner case but the split RW PT_LOAD may be bug-prone for tools.

Now In.BssRelRo serves as a marker (ld.bfd/gold call it dynrelro). In -z norelro mode, .bss.rel.ro naturally merges with .bss

Before, .got.plt (non-relro by default) is placed before .got (relro by default), which makes it impossible to have _GLOBAL_OFFSET_TABLE_ (start of .got.plt on x86-64) equal to end of .got (R_GOT*_FROM_END) (https://bugs.llvm.org/show_bug.cgi?id=36555): this is not a big deal. To the best of my knowledge it only affects glibc.


Repository:
  rLLD LLVM Linker

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56828/new/

https://reviews.llvm.org/D56828





More information about the llvm-commits mailing list