summary refs log tree commit diff
path: root/sysdeps/powerpc/bits
diff options
context:
space:
mode:
authorUlrich Weigand <Ulrich.Weigand@de.ibm.com>2013-12-04 06:59:37 -0600
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>2013-12-04 07:41:39 -0600
commit61cd8fe4017c251617dd300818917e61a12ab48e (patch)
treedfac7e867271b7a5889db22693883cd54b41e9ac /sysdeps/powerpc/bits
parent8b8a692cfd7d80f1ee7c8b9ab356a259367dd187 (diff)
downloadglibc-61cd8fe4017c251617dd300818917e61a12ab48e.tar.gz
glibc-61cd8fe4017c251617dd300818917e61a12ab48e.tar.xz
glibc-61cd8fe4017c251617dd300818917e61a12ab48e.zip
PowerPC64 ELFv2 ABI 5/6: LD_AUDIT interface changes
The ELFv2 ABI changes the calling convention by passing and returning
structures in registers in more cases than the old ABI:
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01145.html
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01147.html

For the most part, this does not affect glibc, since glibc assembler
files do not use structure parameters / return values.  However, one
place is affected: the LD_AUDIT interface provides a structure to
the audit routine that contains all registers holding function
argument and return values for the intercepted PLT call.

Since the new ABI now sometimes uses registers to return values
that were never used for this purpose in the old ABI, this structure
has to be extended.  To force audit routines to be modified for the
new ABI if necessary, the patch defines v2 variants of the la_ppc64
types and routines.

In addition, the patch contains two unrelated changes to the
PLT trampoline routines: it fixes a bug where FPR return values
were stored in the wrong place, and it removes the unnecessary
save/restore of CR.
Diffstat (limited to 'sysdeps/powerpc/bits')
-rw-r--r--sysdeps/powerpc/bits/link.h46
1 files changed, 45 insertions, 1 deletions
diff --git a/sysdeps/powerpc/bits/link.h b/sysdeps/powerpc/bits/link.h
index f06092f105..2f1da8be4f 100644
--- a/sysdeps/powerpc/bits/link.h
+++ b/sysdeps/powerpc/bits/link.h
@@ -63,7 +63,7 @@ extern unsigned int la_ppc32_gnu_pltexit (Elf32_Sym *__sym,
 
 __END_DECLS
 
-#else
+#elif _CALL_ELF != 2
 
 /* Registers for entry into PLT on PPC64.  */
 typedef struct La_ppc64_regs
@@ -107,4 +107,48 @@ extern unsigned int la_ppc64_gnu_pltexit (Elf64_Sym *__sym,
 
 __END_DECLS
 
+#else
+
+/* Registers for entry into PLT on PPC64 in the ELFv2 ABI.  */
+typedef struct La_ppc64v2_regs
+{
+  uint64_t lr_reg[8];
+  double lr_fp[13];
+  uint32_t __padding;
+  uint32_t lr_vrsave;
+  uint32_t lr_vreg[12][4] __attribute__ ((aligned (16)));
+  uint64_t lr_r1;
+  uint64_t lr_lr;
+} La_ppc64v2_regs;
+
+/* Return values for calls from PLT on PPC64 in the ELFv2 ABI.  */
+typedef struct La_ppc64v2_retval
+{
+  uint64_t lrv_r3;
+  uint64_t lrv_r4;
+  double lrv_fp[10];
+  uint32_t lrv_vreg[8][4] __attribute__ ((aligned (16)));
+} La_ppc64v2_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf64_Addr la_ppc64v2_gnu_pltenter (Elf64_Sym *__sym,
+					   unsigned int __ndx,
+					   uintptr_t *__refcook,
+					   uintptr_t *__defcook,
+					   La_ppc64v2_regs *__regs,
+					   unsigned int *__flags,
+					   const char *__symname,
+					   long int *__framesizep);
+extern unsigned int la_ppc64v2_gnu_pltexit (Elf64_Sym *__sym,
+					    unsigned int __ndx,
+					    uintptr_t *__refcook,
+					    uintptr_t *__defcook,
+					    const La_ppc64v2_regs *__inregs,
+					    La_ppc64v2_retval *__outregs,
+					    const char *__symname);
+
+__END_DECLS
+
 #endif