about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Weigand <Ulrich.Weigand@de.ibm.com>2013-12-04 06:55:03 -0600
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>2013-12-04 07:41:39 -0600
commit8b8a692cfd7d80f1ee7c8b9ab356a259367dd187 (patch)
tree7740d5d71feed939fb59df34e1f3535fb14e990f
parent122b66defdb9e4ded3ccc5c2b290f0520c6fa3cd (diff)
downloadglibc-8b8a692cfd7d80f1ee7c8b9ab356a259367dd187.tar.gz
glibc-8b8a692cfd7d80f1ee7c8b9ab356a259367dd187.tar.xz
glibc-8b8a692cfd7d80f1ee7c8b9ab356a259367dd187.zip
PowerPC64 ELFv2 ABI 4/6: Stack frame layout changes
This updates glibc for the changes in the ELFv2 relating to the
stack frame layout.  These are described in more detail here:
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01149.html
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01146.html

Specifically, the "compiler and linker doublewords" were removed,
which has the effect that the save slot for the TOC register is
now at offset 24 rather than 40 to the stack pointer.

In addition, a function may now no longer necessarily assume that
its caller has set up a 64-byte register save area its use.

To address the first change, the patch goes through all assembler
files and replaces immediate offsets in instructions accessing the
ABI-defined stack slots by symbolic offsets.  Those already were
defined in ucontext_i.sym and used in some of the context routines,
but that doesn't really seem like the right place for those defines.

The patch instead defines those symbolic offsets in sysdeps.h,
in two variants for the old and new ABI, and uses them systematically
in all assembler files, not just the context routines.

The second change only affected a few assembler files that used
the save area to temporarily store some registers.  In those
cases where this happens within a leaf function, this patch
changes the code to store those registers to the "red zone"
below the stack pointer.  Otherwise, the functions already allocate
a stack frame, and the patch changes them to add extra space in
these frames as temporary space for the ELFv2 ABI.
-rw-r--r--ChangeLog50
-rw-r--r--nptl/ChangeLog13
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h60
-rw-r--r--sysdeps/powerpc/powerpc64/__longjmp-common.S4
-rw-r--r--sysdeps/powerpc/powerpc64/crti.S8
-rw-r--r--sysdeps/powerpc/powerpc64/crtn.S8
-rw-r--r--sysdeps/powerpc/powerpc64/dl-trampoline.S48
-rw-r--r--sysdeps/powerpc/powerpc64/ppc-mcount.S14
-rw-r--r--sysdeps/powerpc/powerpc64/setjmp-common.S16
-rw-r--r--sysdeps/powerpc/powerpc64/sysdep.h76
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S16
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S4
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S32
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S29
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym21
15 files changed, 249 insertions, 150 deletions
diff --git a/ChangeLog b/ChangeLog
index 668fe03d2b..0be780a3c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,54 @@
 2013-12-04  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
+
+	* sysdeps/powerpc/powerpc64/sysdep.h (FRAME_MIN_SIZE): Define.
+	(FRAME_MIN_SIZE_PARM): Likewise.
+	(FRAME_BACKCHAIN): Likewise.
+	(FRAME_CR_SAVE): Likewise.
+	(FRAME_LR_SAVE): Likewise.
+	(FRAME_TOC_SAVE): Likewise.
+	(FRAME_PARM_SAVE): Likewise.
+	(FRAME_PARM1_SAVE, FRAME_PARM2_SAVE, FRAME_PARM3_SAVE,
+	FRAME_PARM4_SAVE, FRAME_PARM5_SAVE, FRAME_PARM6_SAVE,
+	FRAME_PARM7_SAVE, FRAME_PARM8_SAVE, FRAME_PARM9_SAVE): Likewise.
+	(call_mcount_parm_offset): New macro.
+	(SAVE_ARG, REST_ARG, CFI_SAVE_ARG): Use it.
+	(PROF): Use symbolic stack frame offsets.
+	(TAIL_CALL_SYSCALL_ERROR): Likewise.
+	* sysdeps/powerpc/powerpc64/dl-trampoline.S (FRAME_SIZE, INT_PARMS):
+	Redefine in terms of FRAME_MIN_SIZE.
+	(_dl_runtime_resolve): Use symbolic stack frame offsets.
+	(_dl_profile_resolve): Likewise.  Update comment.
+	* sysdeps/powerpc/powerpc64/setjmp-common.S (__GI__setjmp): Use
+	symbols stack frame offsets.
+	(__sigsetjmp): Likewise.
+	* sysdeps/powerpc/powerpc64/__longjmp-common.S (__longjmp): Likewise.
+	* sysdeps/powerpc/powerpc64/ppc-mcount.S (_mcount): Likewise.
+	* sysdeps/powerpc/powerpc64/crti.S (_init, _fini): Likewise.
+	* sysdeps/powerpc/powerpc64/crtn.S (_init, _fini): Likewise.
+
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym
+	(FRAME_BACKCHAIN): Remove.
+	(FRAME_CR_SAVE): Likewise.
+	(FRAME_LR_SAVE): Likewise.
+	(FRAME_COMPILER_DW): Likewise.
+	(FRAME_LINKER_DW): Likewise.
+	(FRAME_TOC_SAVE): Likewise.
+	(FRAME_PARM_SAVE): Likewise.
+	(FRAME_PARM1_SAVE, FRAME_PARM2_SAVE, FRAME_PARM3_SAVE,
+	FRAME_PARM4_SAVE, FRAME_PARM5_SAVE, FRAME_PARM6_SAVE,
+	FRAME_PARM7_SAVE, FRAME_PARM8_SAVE, FRAME_PARM9_SAVE): Likewise.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S
+	(CHECK_SP): Use symbolic stack frame offsets.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S (__brk): Use "red
+	zone" instead of caller's parameter save area for temp storage.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S (__clone):
+	Likewise.  Also, use symbolic stack frame offsets.
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S (FRAMESIZE,
+	stackblock): Redefine for _CALL_ELF == 2 to save parameters into
+	our own stack frame instead of the caller's.
+	(__socket): Use symbolic stack frame offsets.
+
+2013-12-04  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
 	    Alan Modra  <amodra@gmail.com>
 
 	* elf/elf.h (DT_PPC64_OPT, PPC64_OPT_TLS, PPC64_OPT_MULTI_TOC):
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 9f4063016f..64dc17f254 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,16 @@
+2013-12-04  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
+
+	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+	(CANCEL_FRAMESIZE, CANCEL_PARM_SAVE): New macros to save parameters
+	into our own stack frame instead of the caller's.
+	(PSEUDO): Use them.  Use symbolic stack frame offsets.
+	(DOCARGS_1, UNDOCARGS_1): Use CANCEL_PARM_SAVE.
+	(DOCARGS_2, UNDOCARGS_2): Likewise.
+	(DOCARGS_3, UNDOCARGS_3): Likewise.
+	(DOCARGS_4, UNDOCARGS_4): Likewise.
+	(DOCARGS_5, UNDOCARGS_5): Likewise.
+	(DOCARGS_6, UNDOCARGS_6): Likewise.
+
 2013-11-26  Ondřej Bílka  <neleai@seznam.cz>
 	* sysdeps/i386/tls.h: Use __glibc_reserved instead __unused.
 	* sysdeps/x86_64/tls.h: Likewise.
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
index 51e021df59..d711dc6cf1 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
@@ -31,6 +31,14 @@
 #  define DASHDASHPFX(str) __##str
 # endif
 
+#if _CALL_ELF == 2
+#define CANCEL_FRAMESIZE (FRAME_MIN_SIZE+16+48)
+#define CANCEL_PARM_SAVE (FRAME_MIN_SIZE+16)
+#else
+#define CANCEL_FRAMESIZE (FRAME_MIN_SIZE+16)
+#define CANCEL_PARM_SAVE (CANCEL_FRAMESIZE+FRAME_PARM_SAVE)
+#endif
+
 # undef PSEUDO
 # define PSEUDO(name, syscall_name, args)				\
   .section ".text";							\
@@ -44,52 +52,52 @@
     PSEUDO_RET;								\
   .size DASHDASHPFX(syscall_name##_nocancel),.-DASHDASHPFX(syscall_name##_nocancel);	\
   .Lpseudo_cancel:							\
-    stdu 1,-128(1);							\
-    cfi_adjust_cfa_offset (128);					\
+    stdu 1,-CANCEL_FRAMESIZE(1);					\
+    cfi_adjust_cfa_offset (CANCEL_FRAMESIZE);				\
     mflr 9;								\
-    std  9,128+16(1);							\
-    cfi_offset (lr, 16);						\
+    std  9,CANCEL_FRAMESIZE+FRAME_LR_SAVE(1);				\
+    cfi_offset (lr, FRAME_LR_SAVE);					\
     DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
     CENABLE;								\
-    std  3,112(1);	/* store CENABLE return value (MASK).  */	\
+    std  3,FRAME_MIN_SIZE(1); /* store CENABLE return value (MASK).  */	\
     UNDOCARGS_##args;	/* restore syscall args.  */			\
     DO_CALL (SYS_ify (syscall_name));					\
     mfcr 0;		/* save CR/R3 around CDISABLE.  */		\
-    std  3,120(1);							\
-    std  0,128+8(1);							\
-    cfi_offset (cr, 8);							\
-    ld   3,112(1);	/* pass MASK to CDISABLE.  */			\
+    std  3,FRAME_MIN_SIZE+8(1);						\
+    std  0,CANCEL_FRAMESIZE+FRAME_CR_SAVE(1);				\
+    cfi_offset (cr, FRAME_CR_SAVE);					\
+    ld   3,FRAME_MIN_SIZE(1); /* pass MASK to CDISABLE.  */		\
     CDISABLE;								\
-    ld   9,128+16(1);							\
-    ld   0,128+8(1);	/* restore CR/R3. */				\
-    ld   3,120(1);							\
+    ld   9,CANCEL_FRAMESIZE+FRAME_LR_SAVE(1);				\
+    ld   0,CANCEL_FRAMESIZE+FRAME_CR_SAVE(1); /* restore CR/R3. */	\
+    ld   3,FRAME_MIN_SIZE+8(1);						\
     mtlr 9;								\
     mtcr 0;								\
-    addi 1,1,128;							\
-    cfi_adjust_cfa_offset (-128);					\
+    addi 1,1,CANCEL_FRAMESIZE;						\
+    cfi_adjust_cfa_offset (-CANCEL_FRAMESIZE);				\
     cfi_restore (lr);							\
     cfi_restore (cr)
 
 # define DOCARGS_0
 # define UNDOCARGS_0
 
-# define DOCARGS_1	std 3,128+48(1); DOCARGS_0
-# define UNDOCARGS_1	ld 3,128+48(1); UNDOCARGS_0
+# define DOCARGS_1	std 3,CANCEL_PARM_SAVE(1); DOCARGS_0
+# define UNDOCARGS_1	ld 3,CANCEL_PARM_SAVE(1); UNDOCARGS_0
 
-# define DOCARGS_2	std 4,128+56(1); DOCARGS_1
-# define UNDOCARGS_2	ld 4,128+56(1); UNDOCARGS_1
+# define DOCARGS_2	std 4,CANCEL_PARM_SAVE+8(1); DOCARGS_1
+# define UNDOCARGS_2	ld 4,CANCEL_PARM_SAVE+8(1); UNDOCARGS_1
 
-# define DOCARGS_3	std 5,128+64(1); DOCARGS_2
-# define UNDOCARGS_3	ld 5,128+64(1); UNDOCARGS_2
+# define DOCARGS_3	std 5,CANCEL_PARM_SAVE+16(1); DOCARGS_2
+# define UNDOCARGS_3	ld 5,CANCEL_PARM_SAVE+16(1); UNDOCARGS_2
 
-# define DOCARGS_4	std 6,128+72(1); DOCARGS_3
-# define UNDOCARGS_4	ld 6,128+72(1); UNDOCARGS_3
+# define DOCARGS_4	std 6,CANCEL_PARM_SAVE+24(1); DOCARGS_3
+# define UNDOCARGS_4	ld 6,CANCEL_PARM_SAVE+24(1); UNDOCARGS_3
 
-# define DOCARGS_5	std 7,128+80(1); DOCARGS_4
-# define UNDOCARGS_5	ld 7,128+80(1); UNDOCARGS_4
+# define DOCARGS_5	std 7,CANCEL_PARM_SAVE+32(1); DOCARGS_4
+# define UNDOCARGS_5	ld 7,CANCEL_PARM_SAVE+32(1); UNDOCARGS_4
 
-# define DOCARGS_6	std 8,128+88(1); DOCARGS_5
-# define UNDOCARGS_6	ld 8,128+88(1); UNDOCARGS_5
+# define DOCARGS_6	std 8,CANCEL_PARM_SAVE+40(1); DOCARGS_5
+# define UNDOCARGS_6	ld 8,CANCEL_PARM_SAVE+40(1); UNDOCARGS_5
 
 # ifdef IS_IN_libpthread
 #  ifdef SHARED
diff --git a/sysdeps/powerpc/powerpc64/__longjmp-common.S b/sysdeps/powerpc/powerpc64/__longjmp-common.S
index 4f1e3c88d3..ce5a018e37 100644
--- a/sysdeps/powerpc/powerpc64/__longjmp-common.S
+++ b/sysdeps/powerpc/powerpc64/__longjmp-common.S
@@ -130,7 +130,7 @@ L(no_vmx):
 	ld r14,((JB_GPRS+0)*8)(r3)
 	lfd fp14,((JB_FPRS+0)*8)(r3)
 #if defined SHARED && !defined IS_IN_rtld
-	std r2,40(r1)	/* Restore the callers TOC save area.  */
+	std r2,FRAME_TOC_SAVE(r1)	/* Restore the callers TOC save area.  */
 #endif
 	ld r15,((JB_GPRS+1)*8)(r3)
 	lfd fp15,((JB_FPRS+1)*8)(r3)
@@ -148,7 +148,7 @@ L(no_vmx):
 	PTR_DEMANGLE2 (r0, r25)
 #endif
 	mtlr r0
-/* 	std r2,40(r1)	Restore the TOC save area.  */
+/* 	std r2,FRAME_TOC_SAVE(r1)	Restore the TOC save area.  */
 	ld r21,((JB_GPRS+7)*8)(r3)
 	lfd fp21,((JB_FPRS+7)*8)(r3)
 	ld r22,((JB_GPRS+8)*8)(r3)
diff --git a/sysdeps/powerpc/powerpc64/crti.S b/sysdeps/powerpc/powerpc64/crti.S
index 7eff7fd97c..6e1ece8d66 100644
--- a/sysdeps/powerpc/powerpc64/crti.S
+++ b/sysdeps/powerpc/powerpc64/crti.S
@@ -66,8 +66,8 @@
 BODY_LABEL (_init):
 	LOCALENTRY(_init)
 	mflr 0
-	std 0, 16(r1)
-	stdu r1, -112(r1)
+	std 0, FRAME_LR_SAVE(r1)
+	stdu r1, -FRAME_MIN_SIZE_PARM(r1)
 #if PREINIT_FUNCTION_WEAK
 	addis r9, r2, .LC0@toc@ha
 	ld r0, .LC0@toc@l(r9)
@@ -84,5 +84,5 @@ BODY_LABEL (_init):
 BODY_LABEL (_fini):
 	LOCALENTRY(_fini)
 	mflr 0
-	std 0, 16(r1)
-	stdu r1, -112(r1)
+	std 0, FRAME_LR_SAVE(r1)
+	stdu r1, -FRAME_MIN_SIZE_PARM(r1)
diff --git a/sysdeps/powerpc/powerpc64/crtn.S b/sysdeps/powerpc/powerpc64/crtn.S
index 364e53aae7..cdd3b0f340 100644
--- a/sysdeps/powerpc/powerpc64/crtn.S
+++ b/sysdeps/powerpc/powerpc64/crtn.S
@@ -39,13 +39,13 @@
 #include <sysdep.h>
 
 	.section .init,"ax",@progbits
-	addi r1, r1, 112
-	ld r0, 16(r1)
+	addi r1, r1, FRAME_MIN_SIZE_PARM
+	ld r0, FRAME_LR_SAVE(r1)
 	mtlr r0
 	blr
 
 	.section .fini,"ax",@progbits
-	addi r1, r1, 112
-	ld r0, 16(r1)
+	addi r1, r1, FRAME_MIN_SIZE_PARM
+	ld r0, FRAME_LR_SAVE(r1)
 	mtlr r0
 	blr
diff --git a/sysdeps/powerpc/powerpc64/dl-trampoline.S b/sysdeps/powerpc/powerpc64/dl-trampoline.S
index e31311cf18..18c8a3aa01 100644
--- a/sysdeps/powerpc/powerpc64/dl-trampoline.S
+++ b/sysdeps/powerpc/powerpc64/dl-trampoline.S
@@ -26,13 +26,13 @@
    parm1 (r3) and the index (r0) need to be converted to an offset
    (index * 24) in parm2 (r4).  */
 
-#define FRAME_SIZE 176
+#define FRAME_SIZE (FRAME_MIN_SIZE+64)
 /* We need to save the registers used to pass parameters, ie. r3 thru
    r10;  Use local var space rather than the parameter save area,
    because gcc as of 2010/05 doesn't allocate a proper stack frame for
    a function that makes no calls except for __tls_get_addr and we
    might be here resolving the __tls_get_addr call.  */
-#define INT_PARMS 112
+#define INT_PARMS FRAME_MIN_SIZE
 EALIGN(_dl_runtime_resolve, 4, 0)
 	stdu	r1,-FRAME_SIZE(r1)
 	cfi_adjust_cfa_offset (FRAME_SIZE)
@@ -48,25 +48,25 @@ EALIGN(_dl_runtime_resolve, 4, 0)
 	mflr	r0
 	std	r8,INT_PARMS+40(r1)
 /* Store the LR in the LR Save area.  */
-	std	r0,FRAME_SIZE+16(r1)
-	cfi_offset (lr, 16)
+	std	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
+	cfi_offset (lr, FRAME_LR_SAVE)
 	mfcr	r0
 	std	r9,INT_PARMS+48(r1)
 	std	r10,INT_PARMS+56(r1)
 /* I'm almost certain we don't have to save cr...  be safe.  */
-	std	r0,FRAME_SIZE+8(r1)
+	std	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
 	bl	JUMPTARGET(_dl_fixup)
 #ifndef SHARED
 	nop
 #endif
 /* Put the registers back.  */
-	ld	r0,FRAME_SIZE+16(r1)
+	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
 	ld	r10,INT_PARMS+56(r1)
 	ld	r9,INT_PARMS+48(r1)
 	ld	r8,INT_PARMS+40(r1)
 	ld	r7,INT_PARMS+32(r1)
 	mtlr	r0
-	ld	r0,FRAME_SIZE+8(r1)
+	ld	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
 	ld	r6,INT_PARMS+24(r1)
 	ld	r5,INT_PARMS+16(r1)
 	ld	r4,INT_PARMS+8(r1)
@@ -76,7 +76,7 @@ EALIGN(_dl_runtime_resolve, 4, 0)
 	ld	r3,INT_PARMS+0(r1)
 #if _CALL_ELF == 2
 /* Restore the caller's TOC in case we jump to a local entry point.  */
-	ld	r2,FRAME_SIZE+40(r1)
+	ld	r2,FRAME_SIZE+FRAME_TOC_SAVE(r1)
 #endif
 /* Unwind the stack frame, and jump.  */
 	addi	r1,r1,FRAME_SIZE
@@ -86,6 +86,7 @@ END(_dl_runtime_resolve)
 #undef INT_PARMS
 
 	/* Stack layout:
+	   (Note: some of these are not required for the ELFv2 ABI.)
 	  +592   previous backchain
 	  +584   spill_r31
 	  +576   spill_r30
@@ -147,10 +148,11 @@ END(_dl_runtime_resolve)
 	  +64    parm3
 	  +56    parm2
 	  +48    parm1
-	 * Parameter save area, Allocated by the call, at least 8 double words
-	  +40    TOC save area
-	  +32    Reserved for linker
-	  +24    Reserved for compiler
+	 * Parameter save area
+	 * (v1 ABI: Allocated by the call, at least 8 double words)
+	  +40    v1 ABI: TOC save area
+	  +32    v1 ABI: Reserved for linker
+	  +24    v1 ABI: Reserved for compiler / v2 ABI: TOC save area
 	  +16    LR save area
 	  +8     CR save area
 	r1+0     stack back chain
@@ -206,15 +208,15 @@ EALIGN(_dl_profile_resolve, 4, 0)
 /* Store the LR in the LR Save area of the previous frame.  */
 /* XXX Do we have to do this?  */
 	la	r8,FRAME_SIZE(r1)
-	std	r5,FRAME_SIZE+16(r1)
-	cfi_offset (lr, 16)
+	std	r5,FRAME_SIZE+FRAME_LR_SAVE(r1)
+	cfi_offset (lr, FRAME_LR_SAVE)
 	std	r5,CALLING_LR(r1)
 	mfcr	r0
 	std	r9,INT_PARMS+48(r1)
 	std	r10,INT_PARMS+56(r1)
 	std	r8,CALLING_SP(r1)
 /* I'm almost certain we don't have to save cr...  be safe.  */
-	std	r0,FRAME_SIZE+8(r1)
+	std	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
 	ld	r12,.LC__dl_hwcap@toc(r2)
 #ifdef SHARED
 	/* Load _rtld_local_ro._dl_hwcap.  */
@@ -311,13 +313,13 @@ L(saveFP):
 	lvx	v12,r11,r10
 	lvx	v13,r11,r9
 L(restoreFXR):
-	ld	r0,FRAME_SIZE+16(r1)
+	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
 	ld	r10,INT_PARMS+56(r1)
 	ld	r9,INT_PARMS+48(r1)
 	ld	r8,INT_PARMS+40(r1)
 	ld	r7,INT_PARMS+32(r1)
 	mtlr	r0
-	ld	r0,FRAME_SIZE+8(r1)
+	ld	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
 	ld	r6,INT_PARMS+24(r1)
 	ld	r5,INT_PARMS+16(r1)
 	ld	r4,INT_PARMS+8(r1)
@@ -327,7 +329,7 @@ L(restoreFXR):
 	ld	r3,INT_PARMS+0(r1)
 #if _CALL_ELF == 2
 /* Restore the caller's TOC in case we jump to a local entry point.  */
-	ld	r2,FRAME_SIZE+40(r1)
+	ld	r2,FRAME_SIZE+FRAME_TOC_SAVE(r1)
 #endif
 /* Load the floating point registers.  */
 	lfd	fp1,FPR_PARMS+0(r1)
@@ -375,19 +377,19 @@ L(do_pltexit):
 	lvx	v12,r11,r10
 	lvx	v13,r11,r9
 L(restoreFXR2):
-	ld	r0,FRAME_SIZE+16(r1)
+	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
 	ld	r10,INT_PARMS+56(r1)
 	ld	r9,INT_PARMS+48(r1)
 	ld	r8,INT_PARMS+40(r1)
 	ld	r7,INT_PARMS+32(r1)
 	mtlr	r0
-	ld	r0,FRAME_SIZE+8(r1)
+	ld	r0,FRAME_SIZE+FRAME_CR_SAVE(r1)
 	ld	r6,INT_PARMS+24(r1)
 	ld	r5,INT_PARMS+16(r1)
 	ld	r4,INT_PARMS+8(r1)
 	mtcrf	0xFF,r0
 /* Prepare for calling the function returned by fixup.  */
-	std	r2,40(r1)
+	std	r2,FRAME_TOC_SAVE(r1)
 	PPC64_LOAD_FUNCPTR r3
 	ld	r3,INT_PARMS+0(r1)
 /* Load the floating point registers.  */
@@ -406,7 +408,7 @@ L(restoreFXR2):
 	lfd	fp13,FPR_PARMS+96(r1)
 /* Call the target function.  */
 	bctrl
-	ld	r2,40(r1)
+	ld	r2,FRAME_TOC_SAVE(r1)
 	lwz	r12,VR_VRSAVE(r1)
 /* But return here and store the return values.  */
 	std	r3,INT_RTN(r1)
@@ -441,7 +443,7 @@ L(callpltexit):
 	beq	L(pltexitreturn)
 	lvx	v2,0,r10
 L(pltexitreturn):
-	ld	r0,FRAME_SIZE+16(r1)
+	ld	r0,FRAME_SIZE+FRAME_LR_SAVE(r1)
 	ld	r31,584(r1)
 	ld	r30,576(r1)
 	mtlr	r0
diff --git a/sysdeps/powerpc/powerpc64/ppc-mcount.S b/sysdeps/powerpc/powerpc64/ppc-mcount.S
index 3d21a70669..9824a55f5f 100644
--- a/sysdeps/powerpc/powerpc64/ppc-mcount.S
+++ b/sysdeps/powerpc/powerpc64/ppc-mcount.S
@@ -24,16 +24,16 @@
 ENTRY(_mcount)
 	mflr		 r4
 	ld		 r11, 0(r1)
-	stdu		 r1,-112(r1)
-	cfi_adjust_cfa_offset (112)
-	std		 r4, 128(r1)
-	cfi_offset (lr, 16)
-	ld		 r3, 16(r11)
+	stdu		 r1,-FRAME_MIN_SIZE(r1)
+	cfi_adjust_cfa_offset (FRAME_MIN_SIZE)
+	std		 r4, FRAME_MIN_SIZE+FRAME_LR_SAVE(r1)
+	cfi_offset (lr, FRAME_LR_SAVE)
+	ld		 r3, FRAME_LR_SAVE(r11)
 	bl		 JUMPTARGET(__mcount_internal)
 	nop
-	ld		 r0, 128(r1)
+	ld		 r0, FRAME_MIN_SIZE+FRAME_LR_SAVE(r1)
 	mtlr		 r0
-	addi		 r1,r1,112
+	addi		 r1,r1,FRAME_MIN_SIZE
 	blr
 END(_mcount)
 
diff --git a/sysdeps/powerpc/powerpc64/setjmp-common.S b/sysdeps/powerpc/powerpc64/setjmp-common.S
index db4b3497c7..9e4fb02779 100644
--- a/sysdeps/powerpc/powerpc64/setjmp-common.S
+++ b/sysdeps/powerpc/powerpc64/setjmp-common.S
@@ -54,7 +54,7 @@ END (setjmp)
    bugz #269.  __GI__setjmp is used in csu/libc-start.c when
    HAVE_CLEANUP_JMP_BUF is defined.  */
 ENTRY (__GI__setjmp)
-	std r2,40(r1)		/* Save the callers TOC in the save area.  */
+	std r2,FRAME_TOC_SAVE(r1)		/* Save the callers TOC in the save area.  */
 	CALL_MCOUNT 1
 	li r4,0			/* Set second argument to 0.  */
 	b JUMPTARGET (GLUE(__sigsetjmp,_ent))
@@ -80,7 +80,7 @@ JUMPTARGET(GLUE(__sigsetjmp,_ent)):
 #endif
 	mflr r0
 #if defined SHARED && !defined IS_IN_rtld
-	ld   r5,40(r1)	/* Retrieve the callers TOC.  */
+	ld   r5,FRAME_TOC_SAVE(r1)	/* Retrieve the callers TOC.  */
 	std  r5,(JB_GPR2*8)(3)
 #else
 	std  r2,(JB_GPR2*8)(3)
@@ -216,14 +216,14 @@ L(no_vmx):
 	b	JUMPTARGET (__sigjmp_save)
 #else
 	mflr	r0
-	std	r0,16(r1)
-	stdu	r1,-112(r1)
-	cfi_adjust_cfa_offset(112)
-	cfi_offset(lr,16)
+	std	r0,FRAME_LR_SAVE(r1)
+	stdu	r1,-FRAME_MIN_SIZE(r1)
+	cfi_adjust_cfa_offset(FRAME_MIN_SIZE)
+	cfi_offset(lr,FRAME_LR_SAVE)
 	bl	JUMPTARGET (__sigjmp_save)
 	nop
-	ld	r0,112+16(r1)
-	addi	r1,r1,112
+	ld	r0,FRAME_MIN_SIZE+FRAME_LR_SAVE(r1)
+	addi	r1,r1,FRAME_MIN_SIZE
 	mtlr	r0
 	blr
 #endif
diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
index 779fd90265..112e4187c5 100644
--- a/sysdeps/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/powerpc/powerpc64/sysdep.h
@@ -20,25 +20,67 @@
 
 #ifdef __ASSEMBLER__
 
+/* Stack frame offsets.  */
+#if _CALL_ELF != 2
+#define FRAME_MIN_SIZE		112
+#define FRAME_MIN_SIZE_PARM	112
+#define FRAME_BACKCHAIN		0
+#define FRAME_CR_SAVE		8
+#define FRAME_LR_SAVE		16
+#define FRAME_TOC_SAVE		40
+#define FRAME_PARM_SAVE		48
+#define FRAME_PARM1_SAVE	48
+#define FRAME_PARM2_SAVE	56
+#define FRAME_PARM3_SAVE	64
+#define FRAME_PARM4_SAVE	72
+#define FRAME_PARM5_SAVE	80
+#define FRAME_PARM6_SAVE	88
+#define FRAME_PARM7_SAVE	96
+#define FRAME_PARM8_SAVE	104
+#define FRAME_PARM9_SAVE	112
+#else
+#define FRAME_MIN_SIZE		32
+#define FRAME_MIN_SIZE_PARM	96
+#define FRAME_BACKCHAIN		0
+#define FRAME_CR_SAVE		8
+#define FRAME_LR_SAVE		16
+#define FRAME_TOC_SAVE		24
+#define FRAME_PARM_SAVE		32
+#define FRAME_PARM1_SAVE	32
+#define FRAME_PARM2_SAVE	40
+#define FRAME_PARM3_SAVE	48
+#define FRAME_PARM4_SAVE	56
+#define FRAME_PARM5_SAVE	64
+#define FRAME_PARM6_SAVE	72
+#define FRAME_PARM7_SAVE	80
+#define FRAME_PARM8_SAVE	88
+#define FRAME_PARM9_SAVE	96
+#endif
+
 /* Support macros for CALL_MCOUNT.  */
+#if _CALL_ELF == 2
+#define call_mcount_parm_offset (-64)
+#else
+#define call_mcount_parm_offset FRAME_PARM_SAVE
+#endif
 	.macro SAVE_ARG NARG
 	.if \NARG
 	SAVE_ARG \NARG-1
-	std	2+\NARG,40+8*(\NARG)(1)
+	std	2+\NARG,call_mcount_parm_offset-8+8*(\NARG)(1)
 	.endif
 	.endm
 
 	.macro REST_ARG NARG
 	.if \NARG
 	REST_ARG \NARG-1
-	ld	2+\NARG,112+40+8*(\NARG)(1)
+	ld	2+\NARG,FRAME_MIN_SIZE_PARM+call_mcount_parm_offset-8+8*(\NARG)(1)
 	.endif
 	.endm
 
 	.macro CFI_SAVE_ARG NARG
 	.if \NARG
 	CFI_SAVE_ARG \NARG-1
-	cfi_offset(2+\NARG,40+8*(\NARG))
+	cfi_offset(2+\NARG,call_mcount_parm_offset-8+8*(\NARG))
 	.endif
 	.endm
 
@@ -55,20 +97,20 @@
 #ifdef	PROF
 	mflr	r0
 	SAVE_ARG \NARG
-	std	r0,16(r1)
-	stdu	r1,-112(r1)
-	cfi_adjust_cfa_offset(112)
-	cfi_offset(lr,16)
+	std	r0,FRAME_LR_SAVE(r1)
+	stdu	r1,-FRAME_MIN_SIZE_PARM(r1)
+	cfi_adjust_cfa_offset(FRAME_MIN_SIZE_PARM)
+	cfi_offset(lr,FRAME_LR_SAVE)
 	CFI_SAVE_ARG \NARG
 	bl	JUMPTARGET (_mcount)
 #ifndef SHARED
 	nop
 #endif
-	ld	r0,128(r1)
+	ld	r0,FRAME_MIN_SIZE_PARM+FRAME_LR_SAVE(r1)
 	REST_ARG \NARG
 	mtlr	r0
-	addi	r1,r1,112
-	cfi_adjust_cfa_offset(-112)
+	addi	r1,r1,FRAME_MIN_SIZE_PARM
+	cfi_adjust_cfa_offset(-FRAME_MIN_SIZE_PARM)
 	cfi_restore(lr)
 	CFI_REST_ARG \NARG
 #endif
@@ -267,15 +309,15 @@ LT_LABELSUFFIX(name,_name_end): ; \
     .else; \
 .Local_syscall_error: \
     mflr 0; \
-    std 0,16(1); \
-    stdu 1,-112(1); \
-    cfi_adjust_cfa_offset(112); \
-    cfi_offset(lr,16); \
+    std 0,FRAME_LR_SAVE(1); \
+    stdu 1,-FRAME_MIN_SIZE(1); \
+    cfi_adjust_cfa_offset(FRAME_MIN_SIZE); \
+    cfi_offset(lr,FRAME_LR_SAVE); \
     bl JUMPTARGET(__syscall_error); \
     nop; \
-    ld 0,112+16(1); \
-    addi 1,1,112; \
-    cfi_adjust_cfa_offset(-112); \
+    ld 0,FRAME_MIN_SIZE+FRAME_LR_SAVE(1); \
+    addi 1,1,FRAME_MIN_SIZE; \
+    cfi_adjust_cfa_offset(-FRAME_MIN_SIZE); \
     mtlr 0; \
     cfi_restore(lr); \
     blr; \
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S
index 270e21e001..ae576d62c3 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/____longjmp_chk.S
@@ -33,24 +33,24 @@
 	cmpld	reg, r1;				\
 	bge+	.Lok;					\
 	mflr	r0;					\
-	std	r0,16(r1);				\
+	std	r0,FRAME_LR_SAVE(r1);			\
 	mr	r31,r3;					\
 	mr	r30,r4;					\
-	stdu	r1,-144(r1);				\
+	stdu	r1,-FRAME_MIN_SIZE-32(r1);		\
 	cfi_remember_state;				\
-	cfi_adjust_cfa_offset (144);			\
-	cfi_offset (lr, 16);				\
+	cfi_adjust_cfa_offset (FRAME_MIN_SIZE+32);	\
+	cfi_offset (lr, FRAME_LR_SAVE);			\
 	li	r3,0;					\
-	addi	r4,r1,112;				\
+	addi	r4,r1,FRAME_MIN_SIZE;			\
 	li	r0,__NR_sigaltstack;			\
 	sc;						\
 	/* Without working sigaltstack we cannot perform the test.  */ \
 	bso	.Lok2;					\
-	lwz	r0,112+8(r1);				\
+	lwz	r0,FRAME_MIN_SIZE+8(r1);		\
 	andi.	r4,r0,1;				\
 	beq	.Lfail;					\
-	ld	r0,112+16(r1);				\
-	ld	r4,112(r1);				\
+	ld	r0,FRAME_MIN_SIZE+16(r1);		\
+	ld	r4,FRAME_MIN_SIZE(r1);			\
 	add	r4,r4,r0;				\
 	sub	r3,r3,reg;				\
 	cmpld	r3,r0;					\
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
index 348aeb5ba0..33cdf25225 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
@@ -28,9 +28,9 @@
 ENTRY (__brk)
 	CALL_MCOUNT 1
 
-	std	r3,48(r1)
+	std	r3,-8(r1)
 	DO_CALL(SYS_ify(brk))
-	ld	r6,48(r1)
+	ld	r6,-8(r1)
 	ld	r5,.LC__curbrk@toc(r2)
 	std     r3,0(r5)
 	cmpld   r6,r3
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
index 4151d15c37..37d9d24fb9 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
@@ -40,22 +40,22 @@ ENTRY (__clone)
 	cror	cr0*4+eq,cr1*4+eq,cr0*4+eq
 	beq-	cr0,L(badargs)
 
-	/* Save some regs in parm save area.  */
+	/* Save some regs in the "red zone".  */
 #ifdef RESET_PID
-	std	r29,48(r1)
+	std	r29,-24(r1)
 #endif
-	std	r30,56(r1)
-	std	r31,64(r1)
+	std	r30,-16(r1)
+	std	r31,-8(r1)
 #ifdef RESET_PID
-	cfi_offset(r29,48)
+	cfi_offset(r29,-24)
 #endif
-	cfi_offset(r30,56)
-	cfi_offset(r31,64)
+	cfi_offset(r30,-16)
+	cfi_offset(r31,-8)
 
 	/* Set up stack frame for child.  */
 	clrrdi	r4,r4,4
 	li	r0,0
-	stdu	r0,-112(r4) /* min stack frame is 112 bytes per ABI */
+	stdu	r0,-FRAME_MIN_SIZE_PARM(r4)
 
 	/* Save fn, args, stack across syscall.  */
 	mr	r30,r3			/* Function in r30.  */
@@ -97,12 +97,12 @@ L(nomoregetpid):
 L(oldpid):
 #endif
 
-	std	r2,40(r1)
+	std	r2,FRAME_TOC_SAVE(r1)
 	/* Call procedure.  */
 	PPC64_LOAD_FUNCPTR r30
 	mr	r3,r31
 	bctrl
-	ld	r2,40(r1)
+	ld	r2,FRAME_TOC_SAVE(r1)
 	/* Call _exit with result from procedure.  */
 #ifdef SHARED
 	b	JUMPTARGET(__GI__exit)
@@ -121,15 +121,15 @@ L(badargs):
 L(parent):
 	/* Parent.  Restore registers & return.  */
 #ifdef RESET_PID
-	cfi_offset(r29,48)
+	cfi_offset(r29,-24)
 #endif
-	cfi_offset(r30,56)
-	cfi_offset(r31,64)
+	cfi_offset(r30,-16)
+	cfi_offset(r31,-8)
 #ifdef RESET_PID
-	ld	r29,48(r1)
+	ld	r29,-24(r1)
 #endif
-	ld	r30,56(r1)
-	ld	r31,64(r1)
+	ld	r30,-16(r1)
+	ld	r31,-8(r1)
 #ifdef RESET_PID
 	cfi_restore(r29)
 #endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S b/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
index 018e55c997..aba2d80902 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/socket.S
@@ -46,8 +46,13 @@
 # endif
 #endif
 
-#define FRAMESIZE 128
-#define stackblock FRAMESIZE+48 /* offset to parm save area.  */
+#if _CALL_ELF == 2
+#define FRAMESIZE (FRAME_MIN_SIZE+16+64)
+#define stackblock (FRAME_MIN_SIZE+16)
+#else
+#define FRAMESIZE (FRAME_MIN_SIZE+16)
+#define stackblock (FRAMESIZE+FRAME_PARM_SAVE) /* offset to parm save area.  */
+#endif
 
 	.text
 ENTRY(__socket)
@@ -98,22 +103,22 @@ ENTRY(__socket)
 .Lsocket_cancel:
 	cfi_adjust_cfa_offset(FRAMESIZE)
 	mflr	r9
-	std	r9,FRAMESIZE+16(r1)
-	cfi_offset (lr, 16)
+	std	r9,FRAMESIZE+FRAME_LR_SAVE(r1)
+	cfi_offset (lr, FRAME_LR_SAVE)
 	CENABLE
-	std	r3,120(r1)
+	std	r3,FRAME_MIN_SIZE+8(r1)
 	li	r3,P(SOCKOP_,socket)
 	addi	r4,r1,stackblock
 	DO_CALL(SYS_ify(socketcall))
 	mfcr	r0
-	std	r3,112(r1)
-	std	r0,FRAMESIZE+8(r1)
-	cfi_offset (cr, 8)
-	ld  	r3,120(r1)
+	std	r3,FRAME_MIN_SIZE(r1)
+	std	r0,FRAMESIZE+FRAME_CR_SAVE(r1)
+	cfi_offset (cr, FRAME_CR_SAVE)
+	ld  	r3,FRAME_MIN_SIZE+8(r1)
 	CDISABLE
-	ld	r4,FRAMESIZE+16(r1)
-	ld	r0,FRAMESIZE+8(r1)
-	ld	r3,112(r1)
+	ld	r4,FRAMESIZE+FRAME_LR_SAVE(r1)
+	ld	r0,FRAMESIZE+FRAME_CR_SAVE(r1)
+	ld	r3,FRAME_MIN_SIZE(r1)
 	mtlr	r4
 	mtcr	r0
 	addi	r1,r1,FRAMESIZE
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym b/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym
index a35418d9d4..8364e4614f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.sym
@@ -8,27 +8,6 @@ SIG_BLOCK
 SIG_SETMASK
 
 
--- Offsets of the fields in the powerpc64 ABI stack frame.
--- XXX Do these correspond to some struct?
-
-FRAME_BACKCHAIN		0
-FRAME_CR_SAVE		8
-FRAME_LR_SAVE		16
-FRAME_COMPILER_DW	24
-FRAME_LINKER_DW		32
-FRAME_TOC_SAVE		40
-FRAME_PARM_SAVE		48
-FRAME_PARM1_SAVE	48
-FRAME_PARM2_SAVE	56
-FRAME_PARM3_SAVE	64
-FRAME_PARM4_SAVE	72
-FRAME_PARM5_SAVE	80
-FRAME_PARM6_SAVE	88
-FRAME_PARM7_SAVE	96
-FRAME_PARM8_SAVE	104
-FRAME_PARM9_SAVE	112
-
-
 -- Offsets of the fields in the ucontext_t structure.
 #define ucontext(member)	offsetof (ucontext_t, member)
 #define mcontext(member)	ucontext (uc_mcontext.member)