From b92f2d04237b7e7165f2c476d8f61e86dbb2779c Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sun, 16 Jan 2005 02:07:30 +0000 Subject: [PATCH] * sysdeps/m68k/dl-machine.h: Remove trampoline code. Define ARCH_LA_PLTENTER and ARCH_LA_PLTEXIT. (elf_machine_runtime_setup): If profile != 0 does not anymore mean GLRO(dl_profile) != NULL. * sysdeps/m68k/dl-trampoline.S: New file. * sysdeps/m68k/bits/link.h: New file. * sysdeps/generic/ldsodefs.h (struct audit_ifaces): Add m68k variants. * elf/tst-auditmod1.c: Add m68k support. 2005-01-16 Andreas Schwab * sysdeps/m68k/dl-machine.h: Remove trampoline code. Define ARCH_LA_PLTENTER and ARCH_LA_PLTEXIT. (elf_machine_runtime_setup): If profile != 0 does not anymore mean GLRO(dl_profile) != NULL. * sysdeps/m68k/dl-trampoline.S: New file. * sysdeps/m68k/bits/link.h: New file. * sysdeps/generic/ldsodefs.h (struct audit_ifaces): Add m68k variants. * elf/tst-auditmod1.c: Add m68k support. --- ChangeLog | 12 ++++ elf/tst-auditmod1.c | 23 ++++++++ sysdeps/generic/ldsodefs.h | 9 +++ sysdeps/m68k/bits/link.h | 58 +++++++++++++++++++ sysdeps/m68k/dl-machine.h | 49 +++++----------- sysdeps/m68k/dl-trampoline.S | 129 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 246 insertions(+), 34 deletions(-) create mode 100644 sysdeps/m68k/bits/link.h create mode 100644 sysdeps/m68k/dl-trampoline.S diff --git a/ChangeLog b/ChangeLog index 798a728..c31cc61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2005-01-16 Andreas Schwab + + * sysdeps/m68k/dl-machine.h: Remove trampoline code. Define + ARCH_LA_PLTENTER and ARCH_LA_PLTEXIT. + (elf_machine_runtime_setup): If profile != 0 does not anymore mean + GLRO(dl_profile) != NULL. + * sysdeps/m68k/dl-trampoline.S: New file. + * sysdeps/m68k/bits/link.h: New file. + * sysdeps/generic/ldsodefs.h (struct audit_ifaces): Add m68k + variants. + * elf/tst-auditmod1.c: Add m68k support. + 2005-01-14 Ulrich Drepper * posix/regcomp.c [!_LIBC] (init_dfa): Fix determining of relevant diff --git a/elf/tst-auditmod1.c b/elf/tst-auditmod1.c index ae76776..2354447 100644 --- a/elf/tst-auditmod1.c +++ b/elf/tst-auditmod1.c @@ -217,6 +217,29 @@ la_sh_gnu_pltexit (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook, return 0; } +#elif defined __mc68000__ +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) +{ + printf ("m68k_pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n", + symname, (long int) sym->st_value, ndx, *flags); + + return sym->st_value; +} + +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) +{ + printf ("m68k_pltexit: symname=%s, st_value=%#lx, ndx=%u, retval=%tu\n", + symname, (long int) sym->st_value, ndx, outregs->lrv_d0); + + return 0; +} #else # error "architecture specific code needed" #endif diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index e402441..6daa5d4 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 0000000..9d0a945 --- /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 directly; use 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 146c586..89d7106 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 0000000..8791280 --- /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 + + .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 -- 2.7.4