diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 9 | ||||
-rw-r--r-- | sysdeps/m68k/bits/link.h | 58 | ||||
-rw-r--r-- | sysdeps/m68k/dl-machine.h | 49 | ||||
-rw-r--r-- | sysdeps/m68k/dl-trampoline.S | 129 |
4 files changed, 211 insertions, 34 deletions
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index e4024419e3..6daa5d4ee5 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -185,6 +185,8 @@ struct La_ppc64_regs; struct La_ppc64_retval; struct La_sh_regs; struct La_sh_retval; +struct La_m68k_regs; +struct La_m68k_retval; struct audit_ifaces @@ -222,6 +224,10 @@ struct audit_ifaces uintptr_t *, const struct La_sh_regs *, unsigned int *, const char *name, long int *framesizep); + Elf32_Addr (*m68k_gnu_pltenter) (Elf32_Sym *, unsigned int, uintptr_t *, + uintptr_t *, struct La_m68k_regs *, + unsigned int *, const char *name, + long int *framesizep); }; union { @@ -244,6 +250,9 @@ struct audit_ifaces unsigned int (*sh_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *, uintptr_t *, const struct La_sh_regs *, struct La_sh_retval *, const char *); + unsigned int (*m68k_gnu_pltexit) (Elf32_Sym *, unsigned int, uintptr_t *, + uintptr_t *, const struct La_m68k_regs *, + struct La_m68k_retval *, const char *); }; unsigned int (*objclose) (uintptr_t *); diff --git a/sysdeps/m68k/bits/link.h b/sysdeps/m68k/bits/link.h new file mode 100644 index 0000000000..9d0a94592f --- /dev/null +++ b/sysdeps/m68k/bits/link.h @@ -0,0 +1,58 @@ +/* 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. */ + +#ifndef _LINK_H +# error "Never include <bits/link.h> directly; use <link.h> instead." +#endif + + +/* Registers for entry into PLT on M68K. */ +typedef struct La_m68k_regs +{ + uint32_t lr_a0; + uint32_t lr_a1; + uint32_t lr_sp; +} La_m68k_regs; + +/* Return values for calls from PLT on M68K. */ +typedef struct La_m68k_retval +{ + uint32_t lrv_d0; + uint32_t lrv_d1; + uint32_t lrv_a0; + long double lrv_fp0; +} La_m68k_retval; + + +__BEGIN_DECLS + +extern Elf32_Addr la_m68k_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + La_m68k_regs *__regs, + unsigned int *__flags, + const char *__symname, + long int *__framesizep); +extern unsigned int la_m68k_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx, + uintptr_t *__refcook, + uintptr_t *__defcook, + const La_m68k_regs *__inregs, + La_m68k_retval *__outregs, + const char *symname); + +__END_DECLS diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h index 146c5866a9..89d7106365 100644 --- a/sysdeps/m68k/dl-machine.h +++ b/sysdeps/m68k/dl-machine.h @@ -1,5 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. m68k version. - Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1996-2001, 2002, 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 @@ -85,7 +85,8 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) { got[2] = (Elf32_Addr) &_dl_runtime_profile; - if (_dl_name_match_p (GLRO(dl_profile), l)) + if (GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), l)) { /* This is the object we are looking for. Say that we really want profiling and the timers are started. */ @@ -101,36 +102,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) return lazy; } -/* This code is used in dl-runtime.c to call the `fixup' function - and then redirect to the address it returns. */ -#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \ -"| Trampoline for " #fixup_name "\n\ - .globl " #tramp_name "\n\ - .type " #tramp_name ", @function\n\ -" #tramp_name ":\n\ - | Save %a0 (struct return address) and %a1.\n\ - move.l %a0, -(%sp)\n\ - move.l %a1, -(%sp)\n\ - | Call the real address resolver.\n\ - jbsr " #fixup_name "\n\ - | Restore register %a0 and %a1.\n\ - move.l (%sp)+, %a1\n\ - move.l (%sp)+, %a0\n\ - | Pop parameters\n\ - addq.l #8, %sp\n\ - | Call real function.\n\ - jmp (%d0)\n\ - .size " #tramp_name ", . - " #tramp_name "\n" -#ifndef PROF -#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ -asm (TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup) \ - TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup)); -#else -#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ -asm (TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup) \ - ".globl _dl_runtime_profile\n" \ - ".set _dl_runtime_profile, _dl_runtime_resolve"); -#endif #define ELF_MACHINE_RUNTIME_FIXUP_ARGS long int save_a0, long int save_a1 @@ -216,9 +187,13 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, return value; } +/* Names of the architecture-specific auditing callback functions. */ +#define ARCH_LA_PLTENTER m68k_gnu_pltenter +#define ARCH_LA_PLTEXIT m68k_gnu_pltexit + #endif /* !dl_machine_h */ -#ifdef RESOLVE +#ifdef RESOLVE_MAP /* Perform the relocation specified by RELOC and SYM (which is fully resolved). MAP is the object containing the reloc. */ @@ -236,9 +211,15 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, else { const Elf32_Sym *const refsym = sym; +#ifndef RTLD_BOOTSTRAP + struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); + Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; +#else Elf32_Addr value = RESOLVE (&sym, version, r_type); + if (sym) value += sym->st_value; +#endif /* !RTLD_BOOTSTRAP */ switch (r_type) { @@ -313,4 +294,4 @@ elf_machine_lazy_rel (struct link_map *map, _dl_reloc_bad_type (map, ELF32_R_TYPE (reloc->r_info), 1); } -#endif /* RESOLVE */ +#endif /* RESOLVE_MAP */ diff --git a/sysdeps/m68k/dl-trampoline.S b/sysdeps/m68k/dl-trampoline.S new file mode 100644 index 0000000000..8791280371 --- /dev/null +++ b/sysdeps/m68k/dl-trampoline.S @@ -0,0 +1,129 @@ +/* PLT trampolines. m68k 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> + + .text + .globl _dl_runtime_resolve + .type _dl_runtime_resolve, @function +_dl_runtime_resolve: + | Save %a0 (struct return address) and %a1. + move.l %a0, -(%sp) + move.l %a1, -(%sp) + | Call the real address resolver. + jbsr _dl_fixup + | Restore register %a0 and %a1. + move.l (%sp)+, %a1 + move.l (%sp)+, %a0 + | Pop parameters + addq.l #8, %sp + | Call real function. + jmp (%d0) + .size _dl_runtime_resolve, . - _dl_runtime_resolve + + .text + .globl _dl_runtime_profile + .type _dl_runtime_profile, @function +_dl_runtime_profile: + pea 8(%sp) + move.l %a1, -(%sp) + move.l %a0, -(%sp) + pea -1.w + | Push parameters for _dl_profile_fixup + pea (%sp) + pea 8(%sp) + move.l 32(%sp), -(%sp) + move.l 32(%sp), -(%sp) + move.l 32(%sp), -(%sp) + subq.l #8, %sp + | Call the real address resolver. + jbsr _dl_profile_fixup + | Pop parameters + lea 28(%sp), %sp + move.l (%sp), %d1 + jpl 1f + addq.l #4, %sp + | Restore register %a0 and %a1. + move.l (%sp)+, %a0 + move.l (%sp)+, %a1 + lea 12(%sp), %sp + | Call real function. + jmp (%d0) + + /* + +24 return address + +20 PLT1 + +16 PLT2 + +12 %sp + +8 %a1 + +4 %a0 + %sp free + */ +1: move.l %a2, (%sp) + move.l %sp, %a2 + move.l %sp, %a0 + lea 28(%sp), %a1 + | Round framesize up to even + addq.l #1, %d1 + lsr #1, %d1 + sub.l %d1, %a0 + sub.l %d1, %a0 + move.l %a0, %sp + jra 2f +1: move.w (%a1)+, (%a0)+ +2: dbra %d1,1b + /* + %a2+24 return address + %a2+20 PLT1 + %a2+16 PLT2 + %a2+12 %sp + %a2+8 %a1 + %a2+4 %a0 + %a2 %a2 + %sp copied stack frame + */ + + move.l 4(%a2), %a0 + move.l 8(%a2), %a1 + jsr (%d0) + move.l %a2, %sp + move.l (%sp)+, %a2 + /* + +20 return address + +16 PLT1 + +12 PLT2 + +8 %sp + +4 %a1 + %sp %a0 + */ + fmove.x %fp0, -(%sp) + move.l %d1, -(%sp) + move.l %d0, -(%sp) + pea (%sp) + pea 20(%sp) + move.l 40(%sp), -(%sp) + move.l 40(%sp), -(%sp) + jbsr _dl_call_pltexit + lea 16(%sp), %sp + move.l (%sp)+, %d0 + move.l (%sp)+, %d1 + fmove.x (%sp)+, %fp0 + lea 20(%sp), %sp + rts + .size _dl_runtime_profile, . - _dl_runtime_profile |