> 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. > Index: elf.sc > =================================================================== > RCS file: /OpenBSD/src/gnu/usr.bin/binutils-2.17/ld/scripttempl/elf.sc,v > retrieving revision 1.8 > diff -u -p -r1.8 elf.sc > --- elf.sc 9 Aug 2014 04:49:47 -0000 1.8 > +++ elf.sc 18 Aug 2015 05:02:41 -0000 > @@ -195,10 +195,12 @@ if test "$NO_PAD" = "y" ; then > PAD_RO0="${RELOCATING+${RODATA_ALIGN} + ${RODATA_ALIGN_ADD_VAL};}" > PAD_PLT0="${RELOCATING+. = ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - > 1));} .pltpad0 ${RELOCATING-0} : { ${RELOCATING+__plt_start = .;} }" > PAD_PLT1=".pltpad1 ${RELOCATING-0} : { ${RELOCATING+__plt_end = .;}} > ${RELOCATING+. = ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1));}" > - PAD_GOT0="${RELOCATING+. = ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - > 1));} .gotpad0 ${RELOCATING-0} : { ${RELOCATING+__got_start = .;} }" > - PAD_GOT1=".gotpad1 ${RELOCATING-0} : { ${RELOCATING+__got_end = .;}} > ${RELOCATING+. = ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1));}" > + PAD_GOT0="${RELOCATING+. = ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - > 1));}" > + PAD_GOT1="${RELOCATING+. = ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - > 1));}" > test "$NO_PAD_CDTOR" = "y" || PAD_CDTOR= > fi > +GOTSTART="PROVIDE (__got_start = .);" > +GOTEND="PROVIDE (__got_end = .);" > > CTOR=".ctors ${CONSTRUCTING-0} : > { > @@ -420,9 +422,11 @@ cat <<EOF > ${OTHER_RELRO_SECTIONS} > ${TEXT_DYNAMIC-${DYNAMIC}} > ${DATA_GOT+${PAD_GOT+${PAD_GOT0}}} > + ${DATA_GOT+${GOTSTART}} > ${DATA_GOT+${DATA_NONEXEC_PLT+${PLT}}} > ${DATA_GOT+${RELRO_NOW+${GOT}}} > ${DATA_GOT+${RELRO_NOW+${GOTPLT}}} > + ${DATA_GOT+${RELRO_NOW+${GOTEND}}} > ${DATA_GOT+${RELRO_NOW+${PAD_GOT+${PAD_GOT1}}}} > ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT+${GOT}}}} > /* If PAD_CDTOR, and separate .got and .got.plt sections, CTOR and DTOR > @@ -430,11 +434,13 @@ cat <<EOF > > ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT+${PAD_CDTOR+${RELOCATING+${CTOR}}}}}} > > ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT+${PAD_CDTOR+${RELOCATING+${DTOR}}}}}} > ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT+${PAD_GOT+${PAD_GOT1}}}}} > + ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT+${GOTEND}}}} > ${RELOCATING+${DATA_SEGMENT_RELRO_END}} > ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT-${GOT}}}} > > ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT-${PAD_CDTOR+${RELOCATING+${CTOR}}}}}} > > ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT-${PAD_CDTOR+${RELOCATING+${DTOR}}}}}} > ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT-${PAD_GOT+${PAD_GOT1}}}}} > + ${DATA_GOT+${RELRO_NOW-${SEPARATE_GOTPLT-${GOTEND}}}} > ${DATA_GOT+${RELRO_NOW-${GOTPLT}}} > > ${DATA_NONEXEC_PLT-${DATA_PLT+${PLT_BEFORE_GOT-${PAD_PLT+${PAD_PLT0}}}}} > @@ -458,6 +464,7 @@ cat <<EOF > ${DATA_NONEXEC_PLT-${DATA_PLT+${PLT_BEFORE_GOT+${PLT}}}} > ${DATA_NONEXEC_PLT-${DATA_PLT+${PLT_BEFORE_GOT+${PAD_PLT+${PAD_PLT1}}}}} > ${SDATA_GOT+${PAD_GOT+${PAD_GOT0}}} > + ${SDATA_GOT+${GOTSTART}} > ${SDATA_GOT+${DATA_NONEXEC_PLT+${PLT}}} > ${SDATA_GOT+${RELOCATING+${OTHER_GOT_SYMBOLS}}} > ${SDATA_GOT+${GOT}} > @@ -468,6 +475,7 @@ cat <<EOF > ${DATA_GOT-${PAD_CDTOR+${RELOCATING+${DTOR}}}} > > ${SDATA_GOT+${OTHER_GOT_SECTIONS}} > + ${SDATA_GOT+${GOTEND}} > ${SDATA_GOT+${PAD_GOT+${PAD_GOT1}}} > > ${SDATA} >