• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisionca958dc21e854734630870f38975ff05eb930f6d (tree)
Time2021-06-04 23:22:31
AuthorYann Sionneau <yann@sion...>
CommiterWaldemar Brodkorb

Log Message

powerpc: fix PIE/PIC builds with newer gcc/binutils which use secureplt by default

This patch fixes segfault of all user space processes (including init, which caused a panic) on recent buildroot powerpc32 builds.

The issue has been reported by Romain Naour in this thread: https://mailman.uclibc-ng.org/pipermail/devel/2021-May/002068.html

Recent buildroot toolchain enables secure PLT in powerpc gcc.
The latter will then supply -msecure-plt to gas invocations by default.
Recent buildroot also enables PIE by defaults.

For the secure PLT to work in PIC, the r30 register needs to point to the GOT.
Old "bss plt" was just a one-instruction-wide PLT slot, pointed-to by a R_PPC_JMP_SLOT relocation, which was written on-the-fly to contain a branch instruction to the correct address. It therefore had to stay writable.
New secure PLT only contains read-only code which loads the branch address from the writable GOT.

Note: secure PLT without PIC does not need r30 to be set. Because offset between plt stub code and got is known at link-time. In this case the PLT entry looks like:
1009b3e0 <uClibc_main@plt>:
1009b3e0: 3d 60 10 0e lis r11,4110
1009b3e4: 81 6b 03 74 lwz r11,884(r11)
1009b3e8: 7d 69 03 a6 mtctr r11
1009b3ec: 4e 80 04 20 bctr

Whereas secure PLT with PIC - offset between plt and got is unknown at link-time - looks like this:
000af800 <00000000.plt_pic32.uClibc_main>:

af800: 81 7e 03 80 lwz r11,896(r30)
af804: 7d 69 03 a6 mtctr r11
af808: 4e 80 04 20 bctr
af80c: 60 00 00 00 nop

Signed-off-by: Yann Sionneau <yann@sionneau.net>

Change Summary

Incremental Difference

--- a/Rules.mak
+++ b/Rules.mak
@@ -483,9 +483,10 @@ ifeq ($(TARGET_ARCH),powerpc)
483483 PICFLAG:=-fpic
484484 PIEFLAG_NAME:=-fpie
485485 PPC_HAS_REL16:=$(shell printf "\t.text\n\taddis 11,30,_GLOBAL_OFFSET_TABLE_-.@ha\n" | $(CC) -c -x assembler -o /dev/null - 2> /dev/null && echo -n y || echo -n n)
486+ PPC_HAS_SECUREPLT:=$(shell $(CC) --verbose 2>&1 | grep -- --enable-secureplt > /dev/null && echo -n y || echo -n n)
487+ CPU_CFLAGS-$(PPC_HAS_SECUREPLT) += -DPPC_HAS_SECUREPLT
486488 CPU_CFLAGS-$(PPC_HAS_REL16)+= -DHAVE_ASM_PPC_REL16
487489 CPU_CFLAGS-$(CONFIG_E500) += "-D__NO_MATH_INLINES"
488-
489490 endif
490491
491492 ifeq ($(TARGET_ARCH),bfin)
--- a/ldso/ldso/powerpc/dl-startup.h
+++ b/ldso/ldso/powerpc/dl-startup.h
@@ -26,6 +26,10 @@ __asm__(
2626 " bl _GLOBAL_OFFSET_TABLE_-4@local\n" /* Put our GOT pointer in r31, */
2727 " mflr 31\n"
2828 #endif
29+/* I'm quite sure this piece of code is always compiled as PIC but let's be sure */
30+#if defined(PPC_HAS_SECUREPLT) && defined(__PIC__)
31+ " mr 30,31\n"
32+#endif
2933 " addi 1,1,16\n" /* Restore SP */
3034 " lwz 7,_dl_skip_args@got(31)\n" /* load EA of _dl_skip_args */
3135 " lwz 7,0(7)\n" /* Load word from _dl_skip_args */
--- a/libc/sysdeps/linux/powerpc/crt1.S
+++ b/libc/sysdeps/linux/powerpc/crt1.S
@@ -57,6 +57,10 @@ _start:
5757 bl _GLOBAL_OFFSET_TABLE_-4@local
5858 mflr r31
5959 # endif
60+ /* in PIC/PIE, plt stubs need r30 to point to the GOT if using secure-plt */
61+# ifdef PPC_HAS_SECUREPLT
62+ mr 30,31
63+# endif
6064 #endif
6165 /* Set up the small data pointer in r13. */
6266 #ifdef __PIC__