From bb38d32c233ff7b2323ac273c09556c0d5884391 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 29 Jan 2005 00:07:16 +0000 Subject: Update. * sysdeps/s390/bits/link.h: New file. * sysdeps/s390/s390-32/dl-trampoline.S: New file. * sysdeps/s390/s390-64/dl-trampoline.S: New file. * sysdeps/s390/s390-32/dl-machine.h: Move PLT trampolines to dl-trampoline.S. Use RESOLVE_MAP instead of RESOLVE to protect relocation code. (elf_machine_runtime_setup): Test for dl_profile non-null. (elf_machine_rela): Remove code using RESOLVE. (ARCH_LA_PLTENTER, ARCH_LA_PLTEXIT): New. * sysdeps/s390/s390-64/dl-machine.h: Likewise. * sysdeps/generic/ldsodefs.h (La_s390_32_regs, La_s390_32_retval, La_s390_64_regs, La_s390_64_retval): New. * elf/tst-auditmod1.c: Add s390 entries. --- sysdeps/s390/s390-32/dl-machine.h | 151 ++++------------------------------- sysdeps/s390/s390-32/dl-trampoline.S | 133 ++++++++++++++++++++++++++++++ sysdeps/s390/s390-64/dl-machine.h | 137 ++++--------------------------- sysdeps/s390/s390-64/dl-trampoline.S | 126 +++++++++++++++++++++++++++++ 4 files changed, 290 insertions(+), 257 deletions(-) create mode 100644 sysdeps/s390/s390-32/dl-trampoline.S create mode 100644 sysdeps/s390/s390-64/dl-trampoline.S (limited to 'sysdeps/s390') diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h index 52922a813b..8bbf858fbf 100644 --- a/sysdeps/s390/s390-32/dl-machine.h +++ b/sysdeps/s390/s390-32/dl-machine.h @@ -1,5 +1,6 @@ /* Machine-dependent ELF dynamic relocation inline functions. S390 Version. - Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 + Free Software Foundation, Inc. Contributed by Carl Pederson & Martin Schwidefsky. This file is part of the GNU C Library. @@ -21,7 +22,6 @@ #ifndef dl_machine_h #define dl_machine_h - #define ELF_MACHINE_NAME "s390" #include @@ -112,7 +112,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. */ GL(dl_profile_map) = l; @@ -126,124 +127,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. */ - -/* s390: - Arguments are in register. - r2 - r7 holds the original parameters for the function call, fixup - and trampoline code use r0-r5 and r14-15. For the correct function - call r2-r5 and r14-15 must be restored. - Arguments from the PLT are stored at 24(r15) and 28(r15) - and must be moved to r2 and r3 for the fixup call (see elf32-s390.c - in the binutils for the PLT code). - Fixup function address in r2. -*/ -#ifndef PROF -#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ - asm ( "\ - .text\n\ - .globl _dl_runtime_resolve\n\ - .type _dl_runtime_resolve, @function\n\ - .align 16\n\ - " CFI_STARTPROC "\n\ -_dl_runtime_resolve:\n\ - # save registers\n\ - stm 2,5,32(15)\n\ - st 14,48(15)\n\ - lr 0,15\n\ - ahi 15,-96\n\ - " CFI_ADJUST_CFA_OFFSET(96)"\n\ - st 0,0(15)\n\ - # load args saved by PLT\n\ - lm 2,3,120(15)\n\ - basr 1,0\n\ -0: ahi 1,1f-0b\n\ - l 14,0(1)\n\ - bas 14,0(14,1) # call fixup\n\ - lr 1,2 # function addr returned in r2\n\ - # restore registers\n\ - ahi 15,96\n\ - " CFI_ADJUST_CFA_OFFSET(-96)" \n\ - l 14,48(15)\n\ - lm 2,5,32(15)\n\ - br 1\n\ -1: .long fixup-1b\n\ - " CFI_ENDPROC "\n\ - .size _dl_runtime_resolve, .-_dl_runtime_resolve\n\ -\n\ - .globl _dl_runtime_profile\n\ - .type _dl_runtime_profile, @function\n\ - .align 16\n\ - " CFI_STARTPROC "\n\ -_dl_runtime_profile:\n\ - # save registers\n\ - stm 2,5,32(15)\n\ - st 14,48(15)\n\ - lr 0,15\n\ - ahi 15,-96\n\ - " CFI_ADJUST_CFA_OFFSET(96)"\n\ - st 0,0(15)\n\ - # load args saved by PLT\n\ - lm 2,3,120(15)\n\ - # load return address as third parameter\n\ - lr 4,14\n\ - basr 1,0\n\ -0: ahi 1,1f-0b\n\ - l 14,0(1)\n\ - bas 14,0(14,1) # call fixup\n\ - lr 1,2 # function addr returned in r2\n\ - # restore registers\n\ - ahi 15,96\n\ - " CFI_ADJUST_CFA_OFFSET(-96)" \n\ - l 14,48(15)\n\ - lm 2,5,32(15)\n\ - br 1\n\ -1: .long profile_fixup-1b\n\ - " CFI_ENDPROC "\n\ - .size _dl_runtime_profile, .-_dl_runtime_profile\n\ -"); -#else -#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ - asm ( "\ - .text\n\ - .globl _dl_runtime_resolve\n\ - .globl _dl_runtime_profile\n\ - .type _dl_runtime_resolve, @function\n\ - .type _dl_runtime_profile, @function\n\ - .align 16\n\ - " CFI_STARTPROC "\n\ -_dl_runtime_resolve:\n\ -_dl_runtime_profile:\n\ - # save registers\n\ - stm 2,5,32(15)\n\ - st 14,48(15)\n\ - lr 0,15\n\ - ahi 15,-96\n\ - " CFI_ADJUST_CFA_OFFSET(96)"\n\ - st 0,0(15)\n\ - # load args saved by PLT\n\ - lm 2,3,120(15)\n\ - # load return address as third parameter\n\ - lr 4,14\n\ - basr 1,0\n\ -0: ahi 1,1f-0b\n\ - l 14,0(1)\n\ - bas 14,0(14,1) # call fixup\n\ - lr 1,2 # function addr returned in r2\n\ - # restore registers\n\ - ahi 15,96\n\ - " CFI_ADJUST_CFA_OFFSET(-96)" \n\ - l 14,48(15)\n\ - lm 2,5,32(15)\n\ - br 1\n\ -1: .long fixup-1b\n\ - " CFI_ENDPROC "\n\ - .size _dl_runtime_resolve, .-_dl_runtime_resolve\n\ - .size _dl_runtime_profile, .-_dl_runtime_profile\n\ -"); -#endif - /* Mask identifying addresses reserved for the user program, where the dynamic linker should not map anything. */ #define ELF_MACHINE_USER_ADDRESS_MASK 0xf8000000UL @@ -375,15 +258,20 @@ 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 s390_32_gnu_pltenter +#define ARCH_LA_PLTEXIT s390_32_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. */ -static inline void +auto inline void +__attribute__ ((always_inline)) elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, const Elf32_Sym *sym, const struct r_found_version *version, void *const reloc_addr_arg) @@ -417,17 +305,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, #ifndef RESOLVE_CONFLICT_FIND_MAP const Elf32_Sym *const refsym = sym; #endif -#if defined USE_TLS && !defined 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); - -# ifndef RTLD_BOOTSTRAP - if (sym) -# endif - value += sym->st_value; -#endif /* use TLS and !RTLD_BOOTSTRAP */ switch (r_type) { @@ -539,7 +418,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, } } -static inline void +auto inline void +__attribute__ ((always_inline)) elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, void *const reloc_addr_arg) { @@ -547,7 +427,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, *reloc_addr = l_addr + reloc->r_addend; } -static inline void +auto inline void +__attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, Elf32_Addr l_addr, const Elf32_Rela *reloc) { @@ -567,4 +448,4 @@ elf_machine_lazy_rel (struct link_map *map, _dl_reloc_bad_type (map, r_type, 1); } -#endif /* RESOLVE */ +#endif /* RESOLVE_MAP */ diff --git a/sysdeps/s390/s390-32/dl-trampoline.S b/sysdeps/s390/s390-32/dl-trampoline.S new file mode 100644 index 0000000000..4ee2295b89 --- /dev/null +++ b/sysdeps/s390/s390-32/dl-trampoline.S @@ -0,0 +1,133 @@ +/* PLT trampolines. s390 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. */ + +/* This code is used in dl-runtime.c to call the `fixup' function + and then redirect to the address it returns. */ + +/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile + * with the following linkage: + * r2 - r6 : parameter registers + * f0, f2 : floating point parameter registers + * 24(r15), 28(r15) : PLT arguments PLT1, PLT2 + * 96(r15) : additional stack parameters + * The normal clobber rules for function calls apply: + * r0 - r5 : call clobbered + * r6 - r13 : call saved + * r14 : return address (call clobbered) + * r15 : stack pointer (call saved) + * f4, f6 : call saved + * f0 - f3, f5, f7 - f15 : call clobbered + */ + +#include + + .text + .globl _dl_runtime_resolve + .type _dl_runtime_resolve, @function + cfi_startproc + .align 16 +_dl_runtime_resolve: + stm %r2,%r5,32(%r15) # save registers + st %r14,8(%r15) + lr %r0,%r15 # create stack frame + ahi %r15,-96 + cfi_adjust_cfa_offset (96) + st 0,0(%r15) + lm %r2,%r3,120(%r15) # load args saved by PLT + basr %r1,0 +0: l %r14,1f-0b(%r1) + bas %r14,0(%r14,%r1) # call resolver + lr %r1,%r2 # function addr returned in r2 + ahi %r15,96 # remove stack frame + cfi_adjust_cfa_offset (-96) + l %r14,8(15) # restore registers + lm %r2,%r5,32(%r15) + br %r1 +1: .long _dl_fixup - 0b + cfi_endproc + .size _dl_runtime_resolve, .-_dl_runtime_resolve + + + .globl _dl_runtime_profile + .type _dl_runtime_profile, @function + cfi_startproc + .align 16 +_dl_runtime_profile: + stm %r2,%r6,32(%r15) # save registers + std %f0,56(%r15) + std %f2,64(%r15) + st %r6,8(%r15) + st %r12,12(%r15) + st %r14,16(%r15) + lr %r12,%r15 # create stack frame + cfi_def_cfa_register (12) + ahi %r15,-96 + st %r12,0(%r15) + lm %r2,%r3,24(%r12) # load arguments saved by PLT + lr %r4,%r14 # return address as third parameter + basr %r1,0 +0: l %r14,6f-0b(%r1) + la %r5,32(%r12) # pointer to struct La_s390_32_regs + la %r6,20(%r12) # long int * framesize + bas %r14,0(%r14,%r1) # call resolver + lr %r1,%r2 # function addr returned in r2 + icm %r0,15,20(%r12) # load & test framesize + jnm 2f + lm %r2,%r6,32(%r12) + ld %f0,56(%r12) + ld %f2,64(%r12) + basr %r14,%r1 # call resolved function +1: lr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + l %r14,16(%r15) # restore registers + l %r12,12(%r15) + l %r6,8(%r15) + br %r14 + cfi_def_cfa_register (12) +2: jz 4f # framesize == 0 ? + ahi %r0,7 # align framesize to 8 + lhi %r2,-8 + nr %r0,%r2 + slr %r15,%r0 # make room for framesize bytes + st %r12,0(%r15) + la %r2,96(%r15) + la %r3,96(%r12) + srl %r0,3 +3: mvc 0(8,%r2),0(%r3) # copy additional parameters + la %r2,8(%r2) + la %r3,8(%r3) + brct %r0,3b +4: lm %r2,%r6,32(%r12) # load register parameters + ld %f0,56(%r12) + ld %f2,64(%r12) + basr %r14,%r1 # call resolved function + stm %r2,%r3,72(%r12) + std %f0,80(%r12) + lm %r2,%r3,24(%r12) # load arguments saved by PLT + basr %r1,0 +5: l %r14,7f-5b(%r1) + la %r4,32(%r12) # pointer to struct La_s390_32_regs + la %r5,72(%r12) # pointer to struct La_s390_32_retval + basr %r14,%r1 # call _dl_call_pltexit + j 1b +6: .long _dl_profile_fixup - 0b +7: .long _dl_call_pltexit - 5b + cfi_endproc + .size _dl_runtime_profile, .-_dl_runtime_profile + diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h index 82ece0be0f..5026a2edad 100644 --- a/sysdeps/s390/s390-64/dl-machine.h +++ b/sysdeps/s390/s390-64/dl-machine.h @@ -1,6 +1,6 @@ /* Machine-dependent ELF dynamic relocation inline functions. 64 bit S/390 Version. - Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -105,7 +105,8 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) { got[2] = (Elf64_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. */ GL(dl_profile_map) = l; @@ -119,112 +120,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. */ - -/* s390: - Arguments are in register. - r2 - r7 holds the original parameters for the function call, fixup - and trampoline code use r0-r5 and r14-15. For the correct function - call r2-r5 and r14-15 must be restored. - Arguments from the PLT are stored at 48(r15) and 56(r15) - and must be moved to r2 and r3 for the fixup call (see elf32-s390.c - in the binutils for the PLT code). - Fixup function address in r2. -*/ -#ifndef PROF -#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ - asm ( "\ - .text\n\ - .globl _dl_runtime_resolve\n\ - .type _dl_runtime_resolve, @function\n\ - .align 16\n\ - " CFI_STARTPROC "\n\ -_dl_runtime_resolve:\n\ - # save registers\n\ - stmg 2,5,64(15)\n\ - stg 14,96(15)\n\ - lgr 0,15\n\ - aghi 15,-160\n\ - " CFI_ADJUST_CFA_OFFSET(160)"\n\ - stg 0,0(15)\n\ - # load args saved by PLT\n\ - lmg 2,3,208(15)\n\ - brasl 14,fixup # call fixup\n\ - lgr 1,2 # function addr returned in r2\n\ - # restore registers\n\ - aghi 15,160\n\ - " CFI_ADJUST_CFA_OFFSET(-160)" \n\ - lg 14,96(15)\n\ - lmg 2,5,64(15)\n\ - br 1\n\ - " CFI_ENDPROC "\n\ - .size _dl_runtime_resolve, .-_dl_runtime_resolve\n\ -\n\ - .globl _dl_runtime_profile\n\ - .type _dl_runtime_profile, @function\n\ - .align 16\n\ - " CFI_STARTPROC "\n\ -_dl_runtime_profile:\n\ - # save registers\n\ - stmg 2,5,64(15)\n\ - stg 14,96(15)\n\ - lgr 0,15\n\ - aghi 15,-160\n\ - " CFI_ADJUST_CFA_OFFSET(160)"\n\ - stg 0,0(15)\n\ - # load args saved by PLT\n\ - lmg 2,3,208(15)\n\ - # load return address as third parameter\n\ - lgr 4,14\n\ - brasl 14,profile_fixup # call fixup\n\ - lgr 1,2 # function addr returned in r2\n\ - # restore registers\n\ - aghi 15,160\n\ - " CFI_ADJUST_CFA_OFFSET(-160)" \n\ - lg 14,96(15)\n\ - lmg 2,5,64(15)\n\ - br 1\n\ - " CFI_ENDPROC "\n\ - .size _dl_runtime_profile, .-_dl_runtime_profile\n\ -"); -#else -#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ - asm ( "\ - .text\n\ - .globl _dl_runtime_resolve\n\ - .globl _dl_runtime_profile\n\ - .type _dl_runtime_resolve, @function\n\ - .type _dl_runtime_profile, @function\n\ - .align 16\n\ - " CFI_STARTPROC "\n\ -_dl_runtime_resolve:\n\ -_dl_runtime_profile:\n\ - # save registers\n\ - stmg 2,5,64(15)\n\ - stg 14,96(15)\n\ - lgr 0,15\n\ - aghi 15,-160\n\ - " CFI_ADJUST_CFA_OFFSET(160)"\n\ - stg 0,0(15)\n\ - # load args saved by PLT\n\ - lmg 2,3,208(15)\n\ - # load return address as third parameter\n\ - lgr 4,14\n\ - brasl 14,profile_fixup # call fixup\n\ - lgr 1,2 # function addr returned in r2\n\ - # restore registers\n\ - aghi 15,160\n\ - " CFI_ADJUST_CFA_OFFSET(-160)" \n\ - lg 14,96(15)\n\ - lmg 2,5,64(15)\n\ - br 1\n\ - " CFI_ENDPROC "\n\ - .size _dl_runtime_resolve, .-_dl_runtime_resolve\n\ - .size _dl_runtime_profile, .-_dl_runtime_profile\n\ -"); -#endif - /* Initial entry point code for the dynamic linker. The C function `_dl_start' is the real entry point; its return value is the user program's entry point. */ @@ -343,14 +238,19 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, return value; } +/* Names of the architecture-specific auditing callback functions. */ +#define ARCH_LA_PLTENTER s390_64_gnu_pltenter +#define ARCH_LA_PLTEXIT s390_64_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. */ -static inline void +auto inline void +__attribute__ ((always_inline)) elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, const Elf64_Sym *sym, const struct r_found_version *version, void *const reloc_addr_arg) @@ -384,17 +284,8 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, #ifndef RESOLVE_CONFLICT_FIND_MAP const Elf64_Sym *const refsym = sym; #endif -#if defined USE_TLS && !defined RTLD_BOOTSTRAP struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); Elf64_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; -#else - Elf64_Addr value = RESOLVE (&sym, version, r_type); - -# ifndef RTLD_BOOTSTRAP - if (sym) -# endif - value += sym->st_value; -#endif /* use TLS and !RTLD_BOOTSTRAP */ switch (r_type) { @@ -518,7 +409,8 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, } } -static inline void +auto inline void +__attribute__ ((always_inline)) elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, void *const reloc_addr_arg) { @@ -526,7 +418,8 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, *reloc_addr = l_addr + reloc->r_addend; } -static inline void +auto inline void +__attribute__ ((always_inline)) elf_machine_lazy_rel (struct link_map *map, Elf64_Addr l_addr, const Elf64_Rela *reloc) { @@ -546,4 +439,4 @@ elf_machine_lazy_rel (struct link_map *map, _dl_reloc_bad_type (map, r_type, 1); } -#endif /* RESOLVE */ +#endif /* RESOLVE_MAP */ diff --git a/sysdeps/s390/s390-64/dl-trampoline.S b/sysdeps/s390/s390-64/dl-trampoline.S new file mode 100644 index 0000000000..215d869803 --- /dev/null +++ b/sysdeps/s390/s390-64/dl-trampoline.S @@ -0,0 +1,126 @@ +/* PLT trampolines. s390 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. */ + +/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile + * with the following linkage: + * r2 - r6 : parameter registers + * f0, f2, f4, f6 : floating point parameter registers + * 24(r15), 28(r15) : PLT arguments PLT1, PLT2 + * 96(r15) : additional stack parameters + * The normal clobber rules for function calls apply: + * r0 - r5 : call clobbered + * r6 - r13 : call saved + * r14 : return address (call clobbered) + * r15 : stack pointer (call saved) + * f1, f3, f5, f7 : call saved + * f0 - f3, f5, f7 - f15 : call clobbered + */ + +#include + + .text + .globl _dl_runtime_resolve + .type _dl_runtime_resolve, @function + cfi_startproc + .align 16 +_dl_runtime_resolve: + stmg 2,5,64(15) # save registers + stg 14,96(15) + lgr 0,15 # create stack frame + aghi 15,-160 + cfi_adjust_cfa_offset (160) + stg 0,0(15) + lmg 2,3,208(15) # load args saved by PLT + brasl 14,_dl_fixup # call fixup + lgr 1,2 # function addr returned in r2 + aghi 15,160 # remove stack frame + cfi_adjust_cfa_offset (-160) + lg 14,96(15) # restore registers + lmg 2,5,64(15) + br 1 + cfi_endproc + .size _dl_runtime_resolve, .-_dl_runtime_resolve + + + .globl _dl_runtime_profile + .type _dl_runtime_profile, @function + cfi_startproc + .align 16 +_dl_runtime_profile: + stmg %r2,%r6,64(%r15) # save registers + std %f0,104(%r15) + std %f2,112(%r15) + std %f4,120(%r15) + std %f6,128(%r15) + stg %r6,16(%r15) + stg %r12,24(%r15) + stg %r14,32(%r15) + lgr %r12,%r15 # create stack frame + cfi_def_cfa_register (12) + aghi %r15,-160 + stg %r12,0(%r15) + lmg %r2,%r3,48(%r12) # load arguments saved by PLT + lgr %r4,%r14 # return address as third parameter + la %r5,64(%r12) # pointer to struct La_s390_32_regs + la %r6,40(%r12) # long int * framesize + brasl %r14,_dl_profile_fixup # call resolver + lgr %r1,%r2 # function addr returned in r2 + lg %r0,40(%r12) # load framesize + ltgr %r0,%r0 + jnm 1f + lmg %r2,%r6,64(%r12) + ld %f0,104(%r12) + ld %f2,112(%r12) + ld %f4,120(%r12) + ld %f6,128(%r12) + basr %r14,%r1 # call resolved function +0: lr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + lg %r14,32(%r15) # restore registers + lg %r12,24(%r15) + lg %r6,16(%r15) + br %r14 + cfi_def_cfa_register (12) +1: jz 4f # framesize == 0 ? + aghi %r0,7 # align framesize to 8 + nill %r0,0xfff8 + slgr %r15,%r0 # make room for framesize bytes + stg %r12,0(%r15) + la %r2,160(%r15) + la %r3,160(%r12) + srlg %r0,%r0,3 +3: mvc 0(8,%r2),0(%r3) # copy additional parameters + la %r2,8(%r2) + la %r3,8(%r3) + brctg %r0,3b +4: lmg %r2,%r6,64(%r12) # load register parameters + ld %f0,104(%r12) + ld %f2,112(%r12) + ld %f4,120(%r12) + ld %f6,128(%r12) + basr %r14,%r1 # call resolved function + stg %r2,136(%r12) + std %f0,144(%r12) + lmg %r2,%r3,48(%r12) # load arguments saved by PLT + la %r4,32(%r12) # pointer to struct La_s390_32_regs + la %r5,72(%r12) # pointer to struct La_s390_32_retval + brasl %r14,_dl_call_pltexit + j 0b + cfi_endproc + .size _dl_runtime_profile, .-_dl_runtime_profile -- cgit 1.4.1