/* PLT trampolines. Alpha 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 .set noat .globl _dl_runtime_resolve .ent _dl_runtime_resolve #undef FRAMESIZE #define FRAMESIZE 44*8 _dl_runtime_resolve: lda $30, -FRAMESIZE($30) .frame $30, FRAMESIZE, $26 /* Preserve all registers that C normally doesn't. */ stq $26, 0*8($30) stq $0, 1*8($30) stq $1, 2*8($30) stq $2, 3*8($30) stq $3, 4*8($30) stq $4, 5*8($30) stq $5, 6*8($30) stq $6, 7*8($30) stq $7, 8*8($30) stq $8, 9*8($30) stq $16, 10*8($30) stq $17, 11*8($30) stq $18, 12*8($30) stq $19, 13*8($30) stq $20, 14*8($30) stq $21, 15*8($30) stq $22, 16*8($30) stq $23, 17*8($30) stq $24, 18*8($30) stq $25, 19*8($30) stq $29, 20*8($30) stt $f0, 21*8($30) stt $f1, 22*8($30) stt $f10, 23*8($30) stt $f11, 24*8($30) stt $f12, 25*8($30) stt $f13, 26*8($30) stt $f14, 27*8($30) stt $f15, 28*8($30) stt $f16, 29*8($30) stt $f17, 30*8($30) stt $f18, 31*8($30) stt $f19, 32*8($30) stt $f20, 33*8($30) stt $f21, 34*8($30) stt $f22, 35*8($30) stt $f23, 36*8($30) stt $f24, 37*8($30) stt $f25, 38*8($30) stt $f26, 39*8($30) stt $f27, 40*8($30) stt $f28, 41*8($30) stt $f29, 42*8($30) stt $f30, 43*8($30) .mask 0x27ff01ff, -FRAMESIZE .fmask 0xfffffc03, -FRAMESIZE+21*8 /* Set up our GP. */ br $29, .+4 ldgp $29, 0($29) .prologue 0 /* Set up the arguments for _dl_fixup: $16 = link_map out of plt0 $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24 $18 = return address */ subq $28, $27, $17 ldq $16, 8($27) subq $17, 20, $17 mov $26, $18 addq $17, $17, $17 bsr $26, _dl_fixup !samegp /* Move the destination address into position. */ mov $0, $27 /* Restore program registers. */ ldq $26, 0*8($30) ldq $0, 1*8($30) ldq $1, 2*8($30) ldq $2, 3*8($30) ldq $3, 4*8($30) ldq $4, 5*8($30) ldq $5, 6*8($30) ldq $6, 7*8($30) ldq $7, 8*8($30) ldq $8, 9*8($30) ldq $16, 10*8($30) ldq $17, 11*8($30) ldq $18, 12*8($30) ldq $19, 13*8($30) ldq $20, 14*8($30) ldq $21, 15*8($30) ldq $22, 16*8($30) ldq $23, 17*8($30) ldq $24, 18*8($30) ldq $25, 19*8($30) ldq $29, 20*8($30) ldt $f0, 21*8($30) ldt $f1, 22*8($30) ldt $f10, 23*8($30) ldt $f11, 24*8($30) ldt $f12, 25*8($30) ldt $f13, 26*8($30) ldt $f14, 27*8($30) ldt $f15, 28*8($30) ldt $f16, 29*8($30) ldt $f17, 30*8($30) ldt $f18, 31*8($30) ldt $f19, 32*8($30) ldt $f20, 33*8($30) ldt $f21, 34*8($30) ldt $f22, 35*8($30) ldt $f23, 36*8($30) ldt $f24, 37*8($30) ldt $f25, 38*8($30) ldt $f26, 39*8($30) ldt $f27, 40*8($30) ldt $f28, 41*8($30) ldt $f29, 42*8($30) ldt $f30, 43*8($30) /* Flush the Icache after having modified the .plt code. */ imb /* Clean up and turn control to the destination */ lda $30, FRAMESIZE($30) jmp $31, ($27) .end _dl_runtime_resolve .globl _dl_runtime_profile .usepv _dl_runtime_profile, no .type _dl_runtime_profile, @function /* We save the registers in a different order than desired by .mask/.fmask, so we have to use explicit cfi directives. */ cfi_startproc .macro savei regno, offset stq $\regno, \offset($30) cfi_rel_offset(\regno, \offset) .endm .macro savef regno, offset stt $f\regno, \offset($30) cfi_rel_offset(\regno+32, \offset) .endm #undef FRAMESIZE #define FRAMESIZE 50*8 _dl_runtime_profile: lda $30, -FRAMESIZE($30) cfi_adjust_cfa_offset (FRAMESIZE) /* Preserve all argument registers. This also constructs the La_alpha_regs structure. */ savei 26, 0*8 savei 16, 2*8 savei 17, 3*8 savei 18, 4*8 savei 19, 5*8 savei 20, 6*8 savei 21, 7*8 lda $16, FRAMESIZE($30) savef 16, 8*8 savef 17, 9*8 savef 18, 10*8 savef 19, 11*8 savef 20, 12*8 savef 21, 13*8 stq $16, 1*8($30) /* Preserve all registers that C normally doesn't. */ savei 0, 14*8 savei 1, 15*8 savei 2, 16*8 savei 3, 17*8 savei 4, 18*8 savei 5, 19*8 savei 6, 20*8 savei 7, 21*8 savei 8, 22*8 savei 22, 23*8 savei 23, 24*8 savei 24, 25*8 savei 25, 26*8 savei 29, 27*8 savef 0, 28*8 savef 1, 29*8 savef 10, 30*8 savef 11, 31*8 savef 12, 32*8 savef 13, 33*8 savef 14, 34*8 savef 15, 35*8 savef 22, 36*8 savef 23, 37*8 savef 24, 38*8 savef 25, 39*8 savef 26, 40*8 savef 27, 41*8 savef 28, 42*8 savef 29, 43*8 savef 30, 44*8 /* Set up our GP. */ br $29, .+4 ldgp $29, 0($29) /* Set up the arguments for _dl_profile_fixup: $16 = link_map out of plt0 $17 = offset of reloc entry = ($28 - $27 - 20) /12 * 24 $18 = return address $19 = La_alpha_regs address $20 = framesize address */ subq $28, $27, $17 ldq $16, 8($27) subq $17, 20, $17 mov $26, $18 addq $17, $17, $17 lda $19, 0($30) lda $20, 45*8($30) stq $16, 48*8($30) stq $17, 49*8($30) bsr $26, _dl_profile_fixup !samegp /* Discover if we're wrapping this call. */ ldq $18, 45*8($30) bge $18, 1f /* Move the destination address into position. */ mov $0, $27 /* Restore program registers. */ ldq $26, 0*8($30) ldq $16, 2*8($30) ldq $17, 3*8($30) ldq $18, 4*8($30) ldq $19, 5*8($30) ldq $20, 6*8($30) ldq $21, 7*8($30) ldt $f16, 8*8($30) ldt $f17, 9*8($30) ldt $f18, 10*8($30) ldt $f19, 11*8($30) ldt $f20, 12*8($30) ldt $f21, 13*8($30) ldq $0, 14*8($30) ldq $1, 15*8($30) ldq $2, 16*8($30) ldq $3, 17*8($30) ldq $4, 18*8($30) ldq $5, 19*8($30) ldq $6, 20*8($30) ldq $7, 21*8($30) ldq $8, 22*8($30) ldq $22, 23*8($30) ldq $23, 24*8($30) ldq $24, 25*8($30) ldq $25, 26*8($30) ldq $29, 27*8($30) ldt $f0, 28*8($30) ldt $f1, 29*8($30) ldt $f10, 30*8($30) ldt $f11, 31*8($30) ldt $f12, 32*8($30) ldt $f13, 33*8($30) ldt $f14, 34*8($30) ldt $f15, 35*8($30) ldt $f22, 36*8($30) ldt $f23, 37*8($30) ldt $f24, 38*8($30) ldt $f25, 39*8($30) ldt $f26, 40*8($30) ldt $f27, 41*8($30) ldt $f28, 42*8($30) ldt $f29, 43*8($30) ldt $f30, 44*8($30) /* Clean up and turn control to the destination. */ lda $30, FRAMESIZE($30) jmp $31, ($27) 1: /* Create a frame pointer and allocate a new argument frame. */ savei 15, 45*8 mov $30, $15 cfi_def_cfa_register (15) addq $18, 15, $18 bic $18, 15, $18 subq $30, $18, $30 /* Save the call destination around memcpy. */ stq $0, 46*8($30) /* Copy the stack arguments into place. */ lda $16, 0($30) lda $17, FRAMESIZE($15) jsr $26, memcpy ldgp $29, 0($26) /* Reload the argument registers. */ ldq $27, 46*8($30) ldq $16, 2*8($15) ldq $17, 3*8($15) ldq $18, 4*8($15) ldq $19, 5*8($15) ldq $20, 6*8($15) ldq $21, 7*8($15) ldt $f16, 8*8($15) ldt $f17, 9*8($15) ldt $f18, 10*8($15) ldt $f19, 11*8($15) ldt $f20, 12*8($15) ldt $f21, 13*8($15) jsr $26, ($27), 0 ldgp $29, 0($26) /* Set up for call to _dl_call_pltexit. */ ldq $16, 48($15) ldq $17, 49($15) stq $0, 46*8($15) lda $18, 0($15) stq $1, 47*8($15) lda $19, 46*8($15) stt $f0, 48*8($15) stt $f1, 49*8($15) bsr $26, _dl_call_pltexit !samegp mov $15, $30 cfi_def_cfa_register (30) ldq $26, 0($30) ldq $15, 45*8($30) lda $30, FRAMESIZE($30) ret cfi_endproc .size _dl_runtime_profile, .-_dl_runtime_profile