diff options
author | Ulrich Weigand <Ulrich.Weigand@de.ibm.com> | 2013-12-04 06:55:03 -0600 |
---|---|---|
committer | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2013-12-04 07:41:39 -0600 |
commit | 8b8a692cfd7d80f1ee7c8b9ab356a259367dd187 (patch) | |
tree | 7740d5d71feed939fb59df34e1f3535fb14e990f /sysdeps/powerpc | |
parent | 122b66defdb9e4ded3ccc5c2b290f0520c6fa3cd (diff) | |
download | glibc-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.
Diffstat (limited to 'sysdeps/powerpc')
-rw-r--r-- | sysdeps/powerpc/powerpc64/__longjmp-common.S | 4 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/crti.S | 8 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/crtn.S | 8 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/dl-trampoline.S | 48 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/ppc-mcount.S | 14 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/setjmp-common.S | 16 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/sysdep.h | 76 |
7 files changed, 109 insertions, 65 deletions
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; \ |