> > Date: Tue, 18 Aug 2015 05:03:19 +0000 > > From: Miod Vallat <m...@online.fr> > > > > > I spent some time today figuting out why the binutils update broke ld > > > -Z on powerpc. Turns out to be a fairly thorny issue. > > > > > > The new binutils discard empty setions. As a result the .gotpad0 and > > > .gotpad1 sections have disappeared. And a s a consequence the > > > __got_start and __got_end symbols are now "absolute" symbols as the > > > section they referenced to is no longer there. For example, an older > > > libc has: > > > > > > 845: 000eeb68 0 NOTYPE GLOBAL DEFAULT 17 __got_start > > > > > > whereas -current has: > > > > > > 810: 000eeb58 0 NOTYPE GLOBAL DEFAULT ABS __got_start > > > > > > On powerpc, crt0.o has weak references to __got_start and __got_end. > > > When building a binary with ld -Z, these are resolved to the absolute > > > symbols from libc. At runtime we then use these values, relocated as > > > if they were addresses within the binary itself, to change protections > > > and flush the instruction cache. This is very likely to result in a > > > segmentation fault. > > > > > > There is probably a linker bug here, as it doesn't make any sense for > > > the linker to pick the address of these symbols from libc and stick it > > > into the binary. But I'm not sure about this. And it isn't all that > > > obvious what the fix would be. Is the bug that the symbols end up as > > > absolute? Or is the problem that it sibsequently resolves these to > > > the values from libc.so? > > > > Wouldn't something like that address the problem better? > > Unfortunately not. Using PROVIDE() makes the __got_start/end symbols > disappear from shared libraries. If I use: > > GOTSTART="__got_start = .;" > > I end up with the same "absolute" symbols as before. You really have > to tie the symbols to a specific section that isn't discarded to make > them end up as "normal" symbols. And that is difficult since we try > to make __got_start/end cover multiple sections, some of which may or > may not be present. > > I still think my diff to remove code is the way to go. As I > explained, it isn't really clear which set of symbols the references > in crt0.o will actually resolve to. And the secure-plt work will > require changes to the code anyway to make sure we don't end up with > an executable GOT after all.
This sucks. I'd love to see a libelf-based linker appear eventually, but to be a drop-in replacement for GNU ld, it needs linker script support, and then the nightmare start. That said, I only have two things to say: 1. going the opposite way of strict memory permissions, even in a diminishing use case (true static binaries) does not fit with the ``no compromises'' OpenBSD way of doing things. 2. I believe that some light smarts could be added to bfd to make .ctors and .dtors read-only when linking a true static binary, which would alleviate crt0 (.got being already RO in that case). So I will come with a binutils diff shortly, so that you will be able to put your crt0 diff in.