summaryrefslogtreecommitdiff
path: root/sysdeps/powerpc/powerpc32
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/powerpc/powerpc32')
-rw-r--r--sysdeps/powerpc/powerpc32/bits/link.h62
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.c5
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.h175
-rw-r--r--sysdeps/powerpc/powerpc32/dl-trampoline.S174
4 files changed, 248 insertions, 168 deletions
diff --git a/sysdeps/powerpc/powerpc32/bits/link.h b/sysdeps/powerpc/powerpc32/bits/link.h
new file mode 100644
index 0000000000..7f44087120
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/bits/link.h
@@ -0,0 +1,62 @@
+/* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+
+/* Registers for entry into PLT on PPC32. */
+typedef struct La_ppc32_regs
+{
+ uint32_t lr_reg[8];
+ double lr_fp[8];
+ uint32_t lr_vreg[12][4];
+ uint32_t lr_r1;
+ uint32_t lr_lr;
+} La_ppc32_regs;
+
+/* Return values for calls from PLT on PPC32. */
+typedef struct La_ppc32_retval
+{
+ uint32_t lrv_r3;
+ uint32_t lrv_r4;
+ double lrv_fp[8];
+ uint32_t lrv_v2[4];
+} La_ppc32_retval;
+
+
+__BEGIN_DECLS
+
+extern Elf32_Addr la_ppc32_gnu_pltenter (Elf32_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ La_ppc32_regs *__regs,
+ unsigned int *__flags,
+ const char *__symname,
+ long int *__framesizep);
+extern unsigned int la_ppc32_gnu_pltexit (Elf32_Sym *__sym,
+ unsigned int __ndx,
+ uintptr_t *__refcook,
+ uintptr_t *__defcook,
+ const La_ppc32_regs *__inregs,
+ La_ppc32_retval *__outregs,
+ const char *symname);
+
+__END_DECLS
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c
index 06960716b9..4120a02382 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.c
+++ b/sysdeps/powerpc/powerpc32/dl-machine.c
@@ -1,5 +1,5 @@
/* Machine-dependent ELF dynamic relocation functions. PowerPC version.
- Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1995-2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -242,7 +242,8 @@ __elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
: _dl_runtime_resolve);
Elf32_Word offset;
- if (profile && _dl_name_match_p (GLRO(dl_profile), map))
+ if (profile && GLRO(dl_profile) != NULL
+ && _dl_name_match_p (GLRO(dl_profile), map))
/* This is the object we are looking for. Say that we really
want profiling and the timers are started. */
GL(dl_profile_map) = map;
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index a8c1e3e490..de3b9e923a 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -1,5 +1,5 @@
/* Machine-dependent ELF dynamic relocation inline functions. PowerPC version.
- Copyright (C) 1995-2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1995-2002, 2003, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -100,160 +100,6 @@ elf_machine_load_address (void)
/* The PLT uses Elf32_Rela relocs. */
#define elf_machine_relplt elf_machine_rela
-/* This code is used in dl-runtime.c to call the `fixup' function
- and then redirect to the address it returns. It is called
- from code built in the PLT by elf_machine_runtime_setup. */
-#if !defined PROF
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\n\
- .section \".text\" \n\
- .align 2 \n\
- .globl _dl_runtime_resolve \n\
- .type _dl_runtime_resolve,@function \n\
-_dl_runtime_resolve: \n\
- # We need to save the registers used to pass parameters, and register 0,\n\
- # which is used by _mcount; the registers are saved in a stack frame.\n\
- stwu 1,-64(1) \n\
- stw 0,12(1) \n\
- stw 3,16(1) \n\
- stw 4,20(1) \n\
- # The code that calls this has put parameters for `fixup' in r12 and r11.\n\
- mr 3,12 \n\
- stw 5,24(1) \n\
- mr 4,11 \n\
- stw 6,28(1) \n\
- mflr 0 \n\
- # We also need to save some of the condition register fields.\n\
- stw 7,32(1) \n\
- stw 0,48(1) \n\
- stw 8,36(1) \n\
- mfcr 0 \n\
- stw 9,40(1) \n\
- stw 10,44(1) \n\
- stw 0,8(1) \n\
- bl fixup@local \n\
- # 'fixup' returns the address we want to branch to.\n\
- mtctr 3 \n\
- # Put the registers back...\n\
- lwz 0,48(1) \n\
- lwz 10,44(1) \n\
- lwz 9,40(1) \n\
- mtlr 0 \n\
- lwz 8,36(1) \n\
- lwz 0,8(1) \n\
- lwz 7,32(1) \n\
- lwz 6,28(1) \n\
- mtcrf 0xFF,0 \n\
- lwz 5,24(1) \n\
- lwz 4,20(1) \n\
- lwz 3,16(1) \n\
- lwz 0,12(1) \n\
- # ...unwind the stack frame, and jump to the PLT entry we updated.\n\
- addi 1,1,64 \n\
- bctr \n\
- .size _dl_runtime_resolve,.-_dl_runtime_resolve \n\
- \n\
- .align 2 \n\
- .globl _dl_prof_resolve \n\
- .type _dl_prof_resolve,@function \n\
-_dl_prof_resolve: \n\
- # We need to save the registers used to pass parameters, and register 0,\n\
- # which is used by _mcount; the registers are saved in a stack frame.\n\
- stwu 1,-64(1) \n\
- stw 0,12(1) \n\
- stw 3,16(1) \n\
- stw 4,20(1) \n\
- # The code that calls this has put parameters for `fixup' in r12 and r11.\n\
- mr 3,12 \n\
- stw 5,24(1) \n\
- mr 4,11 \n\
- stw 6,28(1) \n\
- mflr 5 \n\
- # We also need to save some of the condition register fields.\n\
- stw 7,32(1) \n\
- stw 5,48(1) \n\
- stw 8,36(1) \n\
- mfcr 0 \n\
- stw 9,40(1) \n\
- stw 10,44(1) \n\
- stw 0,8(1) \n\
- bl profile_fixup@local \n\
- # 'fixup' returns the address we want to branch to.\n\
- mtctr 3 \n\
- # Put the registers back...\n\
- lwz 0,48(1) \n\
- lwz 10,44(1) \n\
- lwz 9,40(1) \n\
- mtlr 0 \n\
- lwz 8,36(1) \n\
- lwz 0,8(1) \n\
- lwz 7,32(1) \n\
- lwz 6,28(1) \n\
- mtcrf 0xFF,0 \n\
- lwz 5,24(1) \n\
- lwz 4,20(1) \n\
- lwz 3,16(1) \n\
- lwz 0,12(1) \n\
- # ...unwind the stack frame, and jump to the PLT entry we updated.\n\
- addi 1,1,64 \n\
- bctr \n\
- .size _dl_prof_resolve,.-_dl_prof_resolve \n\
- # Undo '.section text'.\n\
- .previous \n\
-");
-#else
-# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\n\
- .section \".text\" \n\
- .align 2 \n\
- .globl _dl_runtime_resolve \n\
- .globl _dl_prof_resolve \n\
- .type _dl_runtime_resolve,@function \n\
- .type _dl_prof_resolve,@function \n\
-_dl_runtime_resolve: \n\
-_dl_prof_resolve: \n\
- # We need to save the registers used to pass parameters, and register 0,\n\
- # which is used by _mcount; the registers are saved in a stack frame.\n\
- stwu 1,-64(1) \n\
- stw 0,12(1) \n\
- stw 3,16(1) \n\
- stw 4,20(1) \n\
- # The code that calls this has put parameters for `fixup' in r12 and r11.\n\
- mr 3,12 \n\
- stw 5,24(1) \n\
- mr 4,11 \n\
- stw 6,28(1) \n\
- mflr 0 \n\
- # We also need to save some of the condition register fields.\n\
- stw 7,32(1) \n\
- stw 0,48(1) \n\
- stw 8,36(1) \n\
- mfcr 0 \n\
- stw 9,40(1) \n\
- stw 10,44(1) \n\
- stw 0,8(1) \n\
- bl fixup@local \n\
- # 'fixup' returns the address we want to branch to.\n\
- mtctr 3 \n\
- # Put the registers back...\n\
- lwz 0,48(1) \n\
- lwz 10,44(1) \n\
- lwz 9,40(1) \n\
- mtlr 0 \n\
- lwz 8,36(1) \n\
- lwz 0,8(1) \n\
- lwz 7,32(1) \n\
- lwz 6,28(1) \n\
- mtcrf 0xFF,0 \n\
- lwz 5,24(1) \n\
- lwz 4,20(1) \n\
- lwz 3,16(1) \n\
- lwz 0,12(1) \n\
- # ...unwind the stack frame, and jump to the PLT entry we updated.\n\
- addi 1,1,64 \n\
- bctr \n\
- .size _dl_runtime_resolve,.-_dl_runtime_resolve \n\
-");
-#endif
-
/* Mask identifying addresses reserved for the user program,
where the dynamic linker should not map anything. */
#define ELF_MACHINE_USER_ADDRESS_MASK 0xf0000000UL
@@ -328,9 +174,14 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
return value + reloc->r_addend;
}
+
+/* Names of the architecture-specific auditing callback functions. */
+#define ARCH_LA_PLTENTER ppc32_gnu_pltenter
+#define ARCH_LA_PLTEXIT ppc32_gnu_pltexit
+
#endif /* dl_machine_h */
-#ifdef RESOLVE
+#ifdef RESOLVE_MAP
/* Do the actual processing of a reloc, once its target address
has been determined. */
@@ -381,16 +232,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
value = map->l_addr;
else
{
-# if defined USE_TLS && !defined RTLD_BOOTSTRAP
sym_map = RESOLVE_MAP (&sym, version, r_type);
- value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
-# else
- value = RESOLVE (&sym, version, r_type);
-# ifndef RTLD_BOOTSTRAP
- if (sym != NULL)
-# endif
- value += sym->st_value;
-# endif
+ value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
}
value += reloc->r_addend;
#else
@@ -474,4 +317,4 @@ elf_machine_lazy_rel (struct link_map *map,
DT_RELA table. */
#define ELF_MACHINE_PLTREL_OVERLAP 1
-#endif /* RESOLVE */
+#endif /* RESOLVE_MAP */
diff --git a/sysdeps/powerpc/powerpc32/dl-trampoline.S b/sysdeps/powerpc/powerpc32/dl-trampoline.S
new file mode 100644
index 0000000000..ea5ce7b45a
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/dl-trampoline.S
@@ -0,0 +1,174 @@
+/* PLT trampolines. PPC32 version.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+
+ .section ".text"
+ .align 2
+ .globl _dl_runtime_resolve
+ .type _dl_runtime_resolve,@function
+_dl_runtime_resolve:
+ # We need to save the registers used to pass parameters, and register 0,
+ # which is used by _mcount; the registers are saved in a stack frame.
+ stwu r1,-64(r1)
+ stw r0,12(r1)
+ stw r3,16(r1)
+ stw r4,20(r1)
+ # The code that calls this has put parameters for `fixup' in r12 and r11.
+ mr r3,r12
+ stw r5,24(r1)
+ mr r4,r11
+ stw r6,28(r1)
+ mflr r0
+ # We also need to save some of the condition register fields
+ stw r7,32(r1)
+ stw r0,48(r1)
+ stw r8,36(r1)
+ mfcr r0
+ stw r9,40(r1)
+ stw r10,44(r1)
+ stw r0,8(r1)
+ bl _dl_fixup@local
+ # 'fixup' returns the address we want to branch to.
+ mtctr r3
+ # Put the registers back...
+ lwz r0,48(r1)
+ lwz r10,44(r1)
+ lwz r9,40(r1)
+ mtlr r0
+ lwz r8,36(r1)
+ lwz r0,8(r1)
+ lwz r7,32(r1)
+ lwz r6,28(r1)
+ mtcrf 0xFF,r0
+ lwz r5,24(r1)
+ lwz r4,20(r1)
+ lwz r3,16(r1)
+ lwz r0,12(r1)
+ # ...unwind the stack frame, and jump to the PLT entry we updated.
+ addi r1,r1,64
+ bctr
+ .size _dl_runtime_resolve,.-_dl_runtime_resolve
+
+ .align 2
+ .globl _dl_prof_resolve
+ .type _dl_prof_resolve,@function
+_dl_prof_resolve:
+ # We need to save the registers used to pass parameters, and register 0,
+ # which is used by _mcount; the registers are saved in a stack frame.
+ stwu r1,-320(r1)
+ /* Stack layout:
+
+ +312 stackframe
+ +308 lr
+ +304 r1
+ +288 v12
+ +272 v11
+ +256 v10
+ +240 v9
+ +224 v8
+ +208 v7
+ +192 v6
+ +176 v5
+ +160 v4
+ +144 v3
+ +128 v2
+ +112 v1
+ +104 fp8
+ +96 fp7
+ +88 fp6
+ +80 fp5
+ +72 fp4
+ +64 fp3
+ +56 fp2
+ +48 fp1
+ +44 r10
+ +40 r9
+ +36 r8
+ +32 r7
+ +28 r6
+ +24 r5
+ +20 r4
+ +16 r3
+ +12 r0
+ +8 cr
+ r1 link
+ */
+ stw r0,12(r1)
+ stw r3,16(r1)
+ stw r4,20(r1)
+ # The code that calls this has put parameters for `fixup' in r12 and r11.
+ mr r3,r12
+ stw r5,24(r1)
+ mr r4,r11
+ stw r6,28(r1)
+ mflr r5
+ # We also need to save some of the condition register fields.
+ stw r7,32(r1)
+ stw r5,308(r1)
+ stw r8,36(r1)
+ mfcr r0
+ stw r9,40(r1)
+ stw r10,44(r1)
+ stw r0,8(r1)
+ # Save the floating point registers
+ stfd fp1,48(r1)
+ stfd fp2,56(r1)
+ stfd fp3,64(r1)
+ stfd fp4,72(r1)
+ stfd fp5,80(r1)
+ stfd fp6,88(r1)
+ stfd fp7,96(r1)
+ stfd fp8,104(r1)
+ # XXX TODO: store vmx registers
+ # Load the extra parameters.
+ addi r6,r1,16
+ addi r7,r1,312
+ li r0,-1
+ stw r0,0(r7)
+ bl _dl_profile_fixup@local
+ # 'fixup' returns the address we want to branch to.
+ mtctr r3
+ # Put the registers back...
+ lwz r0,308(r1)
+ lwz r10,44(r1)
+ lwz r9,40(r1)
+ mtlr r0
+ lwz r8,36(r1)
+ lwz r0,8(r1)
+ lwz r7,32(r1)
+ lwz r6,28(r1)
+ mtcrf 0xFF,r0
+ lwz r5,24(r1)
+ lwz r4,20(r1)
+ lwz r3,16(r1)
+ lwz r0,12(r1)
+ # Load the floating point registers.
+ lfd fp1,48(r1)
+ lfd fp2,56(r1)
+ lfd fp3,64(r1)
+ lfd fp4,72(r1)
+ lfd fp5,80(r1)
+ lfd fp6,88(r1)
+ lfd fp7,96(r1)
+ lfd fp8,104(r1)
+ # ...unwind the stack frame, and jump to the PLT entry we updated.
+ addi r1,r1,320
+ bctr
+ .size _dl_prof_resolve,.-_dl_prof_resolve