Blame sysdeps/hppa/dl-trampoline.S

Packit Service 82fcde
/* PLT trampolines. hppa version.
Packit Service 82fcde
   Copyright (C) 2005-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library.  If not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <sysdep.h>
Packit Service 82fcde
Packit Service 82fcde
/* This code gets called via the .plt stub, and is used in
Packit Service 82fcde
   dl-runtime.c to call the `_dl_fixup' function and then redirect
Packit Service 82fcde
   to the address it returns. `_dl_fixup' takes two arguments, however
Packit Service 82fcde
   `_dl_profile_fixup' takes a number of parameters for use with
Packit Service 82fcde
   library auditing (LA).
Packit Service 82fcde
Packit Service 82fcde
   WARNING: This template is also used by gcc's __cffc, and expects
Packit Service 82fcde
   that the "bl" for _dl_runtime_resolve exist at a particular offset.
Packit Service 82fcde
   Do not change this template without changing gcc, while the prefix
Packit Service 82fcde
   "bl" should fix everything so gcc finds the right spot, it will
Packit Service 82fcde
   slow down __cffc when it attempts to call fixup to resolve function
Packit Service 82fcde
   descriptor references. Please refer to gcc/gcc/config/pa/fptr.c
Packit Service 82fcde
Packit Service 82fcde
   Enter with r19 = reloc offset, r20 = got-8, r21 = fixup ltp.  */
Packit Service 82fcde
Packit Service 82fcde
	/* RELOCATION MARKER: bl to provide gcc's __cffc with fixup loc. */
Packit Service 82fcde
	.text
Packit Service 82fcde
	/* THIS CODE DOES NOT EXECUTE */
Packit Service 82fcde
	bl	_dl_fixup, %r2
Packit Service 82fcde
        .text
Packit Service 82fcde
        .global _dl_runtime_resolve
Packit Service 82fcde
        .type _dl_runtime_resolve,@function
Packit Service 82fcde
	cfi_startproc
Packit Service 82fcde
        .align 4
Packit Service 82fcde
_dl_runtime_resolve:
Packit Service 82fcde
        .PROC
Packit Service 82fcde
        .CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=3
Packit Service 82fcde
        .ENTRY
Packit Service 82fcde
        /* SAVE_RP says we do */
Packit Service 82fcde
        stw	%rp, -20(%sp)
Packit Service 82fcde
Packit Service 82fcde
	/* Save static link register */
Packit Service 82fcde
	stw	%r29,-16(%sp)
Packit Service 82fcde
	/* Save argument registers */
Packit Service 82fcde
	stw	%r26,-36(%sp)
Packit Service 82fcde
	stw	%r25,-40(%sp)
Packit Service 82fcde
	stw	%r24,-44(%sp)
Packit Service 82fcde
	stw	%r23,-48(%sp)
Packit Service 82fcde
Packit Service 82fcde
	/* Build a call frame, and save structure pointer. */
Packit Service 82fcde
	copy	%sp, %r1	/* Copy previous sp */
Packit Service 82fcde
	/* Save function result address (on entry) */
Packit Service 82fcde
	stwm	%r28,128(%sp)
Packit Service 82fcde
	/* Fillin some frame info to follow ABI */
Packit Service 82fcde
	stw	%r1,-4(%sp)	/* Previous sp */
Packit Service 82fcde
	stw	%r21,-32(%sp)	/* PIC register value */
Packit Service 82fcde
Packit Service 82fcde
	/* Save input floating point registers. This must be done
Packit Service 82fcde
	   in the new frame since the previous frame doesn't have
Packit Service 82fcde
	   enough space */
Packit Service 82fcde
	ldo	-56(%sp),%r1
Packit Service 82fcde
	fstd,ma	%fr4,-8(%r1)
Packit Service 82fcde
	fstd,ma	%fr5,-8(%r1)
Packit Service 82fcde
	fstd,ma	%fr6,-8(%r1)
Packit Service 82fcde
	fstd,ma	%fr7,-8(%r1)
Packit Service 82fcde
Packit Service 82fcde
	/* Set up args to fixup func, needs only two arguments  */
Packit Service 82fcde
	ldw	8+4(%r20),%r26		/* (1) got[1] == struct link_map */
Packit Service 82fcde
	copy	%r19,%r25		/* (2) reloc offset  */
Packit Service 82fcde
Packit Service 82fcde
	/* Call the real address resolver. */
Packit Service 82fcde
	bl	_dl_fixup,%rp
Packit Service 82fcde
	copy	%r21,%r19		/* set fixup func ltp */
Packit Service 82fcde
Packit Service 82fcde
	/* While the linker will set a function pointer to NULL when it
Packit Service 82fcde
	   encounters an undefined weak function, we need to dynamically
Packit Service 82fcde
	   detect removed weak functions.  The issue arises because a weak
Packit Service 82fcde
	   __gmon_start__ function was added to shared executables to work
Packit Service 82fcde
	   around issues in _init that are now resolved.  The presence of
Packit Service 82fcde
	   __gmon_start__ in every shared library breaks the linker
Packit Service 82fcde
	   `--as-needed' option.  This __gmon_start__ function does nothing
Packit Service 82fcde
	   but removal is tricky.  Depending on the binding, removal can
Packit Service 82fcde
	   cause an application using it to fault.  The call to _dl_fixup
Packit Service 82fcde
	   returns NULL when a function isn't resolved.  In order to help
Packit Service 82fcde
	   with __gmon_start__ removal, we return directly to the caller
Packit Service 82fcde
	   when _dl_fixup returns NULL.  This check could be removed when
Packit Service 82fcde
	   BZ 19170 is fixed.  */
Packit Service 82fcde
	comib,=	0,%r28,1f
Packit Service 82fcde
Packit Service 82fcde
	/* Load up the returned func descriptor */
Packit Service 82fcde
	copy	%r28, %r22
Packit Service 82fcde
	copy	%r29, %r19
Packit Service 82fcde
Packit Service 82fcde
	/* Reload arguments fp args */
Packit Service 82fcde
	ldo	-56(%sp),%r1
Packit Service 82fcde
	fldd,ma	-8(%r1),%fr4
Packit Service 82fcde
	fldd,ma	-8(%r1),%fr5
Packit Service 82fcde
	fldd,ma	-8(%r1),%fr6
Packit Service 82fcde
	fldd,ma	-8(%r1),%fr7
Packit Service 82fcde
Packit Service 82fcde
	/* Adjust sp, and restore function result address*/
Packit Service 82fcde
	ldwm	-128(%sp),%r28
Packit Service 82fcde
Packit Service 82fcde
	/* Reload static link register */
Packit Service 82fcde
	ldw	-16(%sp),%r29
Packit Service 82fcde
	/* Reload general args */
Packit Service 82fcde
	ldw	-36(%sp),%r26
Packit Service 82fcde
	ldw	-40(%sp),%r25
Packit Service 82fcde
	ldw	-44(%sp),%r24
Packit Service 82fcde
	ldw	-48(%sp),%r23
Packit Service 82fcde
Packit Service 82fcde
	/* Jump to new function, but return to previous function */
Packit Service 82fcde
	bv	%r0(%r22)
Packit Service 82fcde
	ldw	-20(%sp),%rp
Packit Service 82fcde
Packit Service 82fcde
1:
Packit Service 82fcde
	/* Return to previous function */
Packit Service 82fcde
	ldw	-148(%sp),%rp
Packit Service 82fcde
	bv	%r0(%rp)
Packit Service 82fcde
	ldo	-128(%sp),%sp
Packit Service 82fcde
Packit Service 82fcde
        .EXIT
Packit Service 82fcde
        .PROCEND
Packit Service 82fcde
	cfi_endproc
Packit Service 82fcde
	.size   _dl_runtime_resolve, . - _dl_runtime_resolve
Packit Service 82fcde
Packit Service 82fcde
        .text
Packit Service 82fcde
        .global _dl_runtime_profile
Packit Service 82fcde
        .type _dl_runtime_profile,@function
Packit Service 82fcde
	cfi_startproc
Packit Service 82fcde
        .align 4
Packit Service 82fcde
_dl_runtime_profile:
Packit Service 82fcde
        .PROC
Packit Service 82fcde
        .CALLINFO FRAME=192,CALLS,SAVE_RP,ENTRY_GR=3
Packit Service 82fcde
        .ENTRY
Packit Service 82fcde
Packit Service 82fcde
        /* SAVE_RP says we do */
Packit Service 82fcde
        stw	%rp, -20(%sp)
Packit Service 82fcde
	/* Save static link register */
Packit Service 82fcde
	stw	%r29,-16(%sp)
Packit Service 82fcde
Packit Service 82fcde
	/* Build a call frame, and save structure pointer. */
Packit Service 82fcde
	copy	%sp, %r1	/* Copy previous sp */
Packit Service 82fcde
	/* Save function result address (on entry) */
Packit Service 82fcde
	stwm	%r28,192(%sp)
Packit Service 82fcde
	/* Fillin some frame info to follow ABI */
Packit Service 82fcde
	stw	%r1,-4(%sp)	/* Previous sp */
Packit Service 82fcde
	stw	%r21,-32(%sp)	/* PIC register value */
Packit Service 82fcde
Packit Service 82fcde
	/* Create La_hppa_retval */
Packit Service 82fcde
	/* -140, lrv_r28
Packit Service 82fcde
           -136, lrv_r29
Packit Service 82fcde
           -132, 4 byte pad
Packit Service 82fcde
           -128, lr_fr4 (8 bytes) */
Packit Service 82fcde
Packit Service 82fcde
	/* Create save space for _dl_profile_fixup arguments
Packit Service 82fcde
	   -120, Saved reloc offset
Packit Service 82fcde
	   -116, Saved struct link_map
Packit Service 82fcde
	   -112, *framesizep */
Packit Service 82fcde
Packit Service 82fcde
	/* Create La_hppa_regs */
Packit Service 82fcde
	/* 32-bit registers */
Packit Service 82fcde
	stw	%r26,-108(%sp)
Packit Service 82fcde
	stw	%r25,-104(%sp)
Packit Service 82fcde
	stw	%r24,-100(%sp)
Packit Service 82fcde
	stw	%r23,-96(%sp)
Packit Service 82fcde
	/* -92, 4 byte pad */
Packit Service 82fcde
	/* 64-bit floating point registers */
Packit Service 82fcde
	ldo	-88(%sp),%r1
Packit Service 82fcde
	fstd,ma	%fr4,8(%r1)
Packit Service 82fcde
	fstd,ma	%fr5,8(%r1)
Packit Service 82fcde
	fstd,ma	%fr6,8(%r1)
Packit Service 82fcde
	fstd,ma	%fr7,8(%r1)
Packit Service 82fcde
	/* 32-bit stack pointer and return register */
Packit Service 82fcde
	stw	%sp,-56(%sp)
Packit Service 82fcde
	stw	%r2,-52(%sp)
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
	/* Set up args to fixup func, needs five arguments  */
Packit Service 82fcde
	ldw	8+4(%r20),%r26		/* (1) got[1] == struct link_map */
Packit Service 82fcde
	stw	%r26,-116(%sp)		/* Save struct link_map */
Packit Service 82fcde
	copy	%r19,%r25		/* (2) reloc offset  */
Packit Service 82fcde
	stw	%r25,-120(%sp)		/* Save reloc offset */
Packit Service 82fcde
	copy    %rp,%r24		/* (3) profile_fixup needs rp */
Packit Service 82fcde
	ldo	-56(%sp),%r23		/* (4) La_hppa_regs */
Packit Service 82fcde
	ldo	-112(%sp), %r1
Packit Service 82fcde
	stw	%r1, -52(%sp)		/* (5) long int *framesizep */
Packit Service 82fcde
Packit Service 82fcde
	/* Call the real address resolver. */
Packit Service 82fcde
	bl	_dl_profile_fixup,%rp
Packit Service 82fcde
	copy	%r21,%r19		/* set fixup func ltp */
Packit Service 82fcde
Packit Service 82fcde
	/* Load up the returned function descriptor */
Packit Service 82fcde
	copy	%r28, %r22
Packit Service 82fcde
	copy	%r29, %r19
Packit Service 82fcde
Packit Service 82fcde
	/* Restore gr/fr/sp/rp */
Packit Service 82fcde
	ldw	-108(%sp),%r26
Packit Service 82fcde
	ldw	-104(%sp),%r25
Packit Service 82fcde
	ldw	-100(%sp),%r24
Packit Service 82fcde
	ldw	-96(%sp),%r23
Packit Service 82fcde
	/* -92, 4 byte pad, skip */
Packit Service 82fcde
	ldo	-88(%sp),%r1
Packit Service 82fcde
	fldd,ma	8(%r1),%fr4
Packit Service 82fcde
	fldd,ma	8(%r1),%fr5
Packit Service 82fcde
	fldd,ma	8(%r1),%fr6
Packit Service 82fcde
	fldd,ma	8(%r1),%fr7
Packit Service 82fcde
	ldw	-52(%sp),%rp
Packit Service 82fcde
Packit Service 82fcde
	/* Reload static link register -(192+16) without adjusting stack */
Packit Service 82fcde
	ldw	-208(%sp),%r29
Packit Service 82fcde
Packit Service 82fcde
	/* *framesizep is >= 0 if we have to run pltexit */
Packit Service 82fcde
	ldw	-112(%sp),%r28
Packit Service 82fcde
	cmpb,>>=,N %r0,%r28,L(cpe)
Packit Service 82fcde
Packit Service 82fcde
	/* Adjust sp, and restore function result address*/
Packit Service 82fcde
	ldwm	-192(%sp),%r28
Packit Service 82fcde
	/* Jump to new function, but return to previous function */
Packit Service 82fcde
	bv	%r0(%r22)
Packit Service 82fcde
	ldw	-20(%sp),%rp
Packit Service 82fcde
	/* NO RETURN */
Packit Service 82fcde
Packit Service 82fcde
L(nf):
Packit Service 82fcde
	/* Call the returned function descriptor */
Packit Service 82fcde
	bv	%r0(%r22)
Packit Service 82fcde
	nop
Packit Service 82fcde
	b,n	L(cont)
Packit Service 82fcde
Packit Service 82fcde
L(cpe):
Packit Service 82fcde
	/* We are going to call the resolved function, but we have a
Packit Service 82fcde
	   stack frame in the middle. We use the value of framesize to
Packit Service 82fcde
	   guess how much extra frame we need, and how much frame to
Packit Service 82fcde
	   copy forward. */
Packit Service 82fcde
Packit Service 82fcde
	/* Round to nearest multiple of 64 */
Packit Service 82fcde
	addi	63, %r28, %r28
Packit Service 82fcde
	depi	0, 27, 6, %r28
Packit Service 82fcde
Packit Service 82fcde
	/* Calcualte start of stack copy */
Packit Service 82fcde
	ldo	-192(%sp),%r2
Packit Service 82fcde
Packit Service 82fcde
	/* Increate the stack by *framesizep */
Packit Service 82fcde
	copy	%sp, %r1
Packit Service 82fcde
	add	%sp, %r28, %sp
Packit Service 82fcde
	/* Save stack pointer */
Packit Service 82fcde
	stw	%r1, -4(%sp)
Packit Service 82fcde
Packit Service 82fcde
	/* Single byte copy of prevous stack onto newly allocated stack */
Packit Service 82fcde
1:	ldb	%r28(%r2), %r1
Packit Service 82fcde
	add	%r28, %sp, %r26
Packit Service 82fcde
	stb	%r1, 0(%r26)
Packit Service 82fcde
	addi,<	-1,%r28,%r28
Packit Service 82fcde
	b,n	1b
Packit Service 82fcde
Packit Service 82fcde
	/* Retore r28 and r27 and r2 already points at -192(%sp) */
Packit Service 82fcde
	ldw	0(%r2),%r28
Packit Service 82fcde
	ldw	84(%r2),%r26
Packit Service 82fcde
Packit Service 82fcde
	/* Calculate address of L(cont) */
Packit Service 82fcde
	b,l	L(nf),%r2
Packit Service 82fcde
	depwi 0,31,2,%r2
Packit Service 82fcde
L(cont):
Packit Service 82fcde
	/* Undo fake stack */
Packit Service 82fcde
	ldw	-4(%sp),%r1
Packit Service 82fcde
	copy	%r1, %sp
Packit Service 82fcde
Packit Service 82fcde
	/* Arguments to _dl_call_pltexit */
Packit Service 82fcde
	ldw	-116(%sp), %r26		/* (1) got[1] == struct link_map */
Packit Service 82fcde
	ldw	-120(%sp), %r25		/* (2) reloc offsets */
Packit Service 82fcde
	ldo	-56(%sp), %r24		/* (3) *La_hppa_regs */
Packit Service 82fcde
	ldo	-124(%sp), %r23		/* (4) *La_hppa_retval */
Packit Service 82fcde
Packit Service 82fcde
	/* Fill *La_hppa_retval */
Packit Service 82fcde
	stw	%r28,-140(%sp)
Packit Service 82fcde
	stw	%r29,-136(%sp)
Packit Service 82fcde
	ldo	-128(%sp), %r1
Packit Service 82fcde
	fstd	%fr4,0(%r1)
Packit Service 82fcde
Packit Service 82fcde
	/* Call _dl_call_pltexit */
Packit Service 82fcde
	bl	_dl_call_pltexit,%rp
Packit Service 82fcde
	nop
Packit Service 82fcde
Packit Service 82fcde
	/* Restore *La_hppa_retval */
Packit Service 82fcde
	ldw	-140(%sp), %r28
Packit Service 82fcde
	ldw	-136(%sp), %r29
Packit Service 82fcde
	ldo	-128(%sp), %r1
Packit Service 82fcde
	fldd	0(%r1), %fr4
Packit Service 82fcde
Packit Service 82fcde
	/* Unwind the stack */
Packit Service 82fcde
	ldo	192(%sp),%sp
Packit Service 82fcde
	/* Retore callers rp */
Packit Service 82fcde
        ldw -20(%sp),%rp
Packit Service 82fcde
	/* Return */
Packit Service 82fcde
	bv,n	0(%r2)
Packit Service 82fcde
        .EXIT
Packit Service 82fcde
        .PROCEND
Packit Service 82fcde
	cfi_endproc
Packit Service 82fcde
	.size   _dl_runtime_profile, . - _dl_runtime_profile