> 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?
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}