/* $OpenBSD: ldasm.S,v 1.24 2017/08/27 21:59:52 deraadt Exp $ */ /* * Copyright (c) 2004 Michael Shalayeff * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #define _LOCORE #include #include #undef _LOCORE ENTRY(_dl_start,32) copy r3, r1 copy sp, r3 stwm r1, HPPA_FRAME_SIZE+16*4(sp) stw %arg0, HPPA_FRAME_ARG(0)(r3) /* ps_strings */ #define ADDR(s,r) \ bl 4, t1 !\ depi 0, 31, 2, t1 /* kill pl bits */ !\ b s /* cold brunch -- never done */ !\ ldw 0(t1), t2 /* cat(w,w1,w2{10},w2{0..9}) << 2 */ !\ extru t2, 28, 10, t3 /* w2{0..9} */ !\ extru t2, 26, 16, r /* w1 */ !\ dep t3, 31, 11, r !\ extru,= t2, 31, 1, r0 /* w */ !\ depi 1, 15, 1, r !\ extru,= t2, 29, 1, r0 /* w2{10} */ !\ depi 1, 21, 1, r !\ sh2add r, t1, r /* plus the base */ !\ addi 8, r, r /* bl target is -8 */ ADDR(_GLOBAL_OFFSET_TABLE_, r19) ADDR(_DYNAMIC, arg2) stw arg2, HPPA_FRAME_ARG(1)(r3) /* make sure to get a fault until it's set proper */ ldi -1, %dp ldw 0(arg0), arg0 ldo 4(r3), arg1 /* dl_data */ bl _dl_boot_bind, rp ldo -4(arg0), arg0 ldw HPPA_FRAME_ARG(1)(r3), arg1 /* &_DYNAMIC */ ldw HPPA_FRAME_ARG(0)(r3), arg3 /* ps_strings */ ldw 0(r19), arg2 sub arg1, arg2, arg2 /* loff */ ldw 0(arg3), arg0 /* argv */ ldw 8(arg3), arg1 /* envp */ bl _dl_boot, rp ldo 4(r3), arg3 /* dl_data */ ldw HPPA_FRAME_ARG(0)(r3), arg0 /* ps_strings */ ADDR(_hppa_dl_dtors_plabel, arg1) ldw 0(arg1), arg1 /* cleanup */ ldo HPPA_FRAME_SIZE(r3), sp copy r0, rp bv r0(ret0) ldwm -HPPA_FRAME_SIZE(sp), r3 EXIT(_dl_start) /* * void _hppa_dl_dtors(void); */ ENTRY(_hppa_dl_dtors,0) ADDR(_GLOBAL_OFFSET_TABLE_, r19) b _dl_dtors nop EXIT(_hppa_dl_dtors) .section .data .align 4 _hppa_dl_dtors_plabel: .word P%_hppa_dl_dtors .previous LEAF_ENTRY(_hppa_dl_set_dp) bv r0(rp) copy arg0, r27 EXIT(_hppa_dl_set_dp) /* * This is a magic branch instruction that is used by GCC's * __canonicalize_funcptr_for_compare() function to fixup relocations * in order to do function pointer comparisons. */ bl _dl_bind, rp ENTRY(_dl_bind_start,32) copy r3, r1 copy sp, r3 stwm r1, HPPA_FRAME_SIZE(sp) stw rp, HPPA_FRAME_CRP(r3) stw arg0, HPPA_FRAME_ARG(0)(r3) stw arg1, HPPA_FRAME_ARG(1)(r3) stw arg2, HPPA_FRAME_ARG(2)(r3) stw arg3, HPPA_FRAME_ARG(3)(r3) stw t1, 4(r3) stw ret0, 8(r3) stw ret1, 12(r3) ldw 12(r20), arg0 copy r19, arg1 bl _dl_bind, rp copy r21, r19 copy ret0, r21 /* &func */ copy ret1, r19 /* sl */ ldw HPPA_FRAME_ARG(0)(r3), arg0 ldw HPPA_FRAME_ARG(1)(r3), arg1 ldw HPPA_FRAME_ARG(2)(r3), arg2 ldw HPPA_FRAME_ARG(3)(r3), arg3 ldw 4(r3), t1 ldw 8(r3), ret0 ldw 12(r3), ret1 ldw HPPA_FRAME_CRP(r3), rp ldo HPPA_FRAME_SIZE(r3), sp bv r0(r21) ldwm -HPPA_FRAME_SIZE(sp), r3 EXIT(_dl_bind_start) .end