1/* $OpenBSD: ldasm.S,v 1.29 2019/02/03 02:20:36 guenther Exp $ */ 2 3/* 4 * Copyright (c) 2013 Miodrag Vallat. 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18/* 19 * Copyright (c) 2006 Dale Rahn 20 * 21 * Redistribution and use in source and binary forms, with or without 22 * modification, are permitted provided that the following conditions 23 * are met: 24 * 1. Redistributions of source code must retain the above copyright 25 * notice, this list of conditions and the following disclaimer. 26 * 2. Redistributions in binary form must reproduce the above copyright 27 * notice, this list of conditions and the following disclaimer in the 28 * documentation and/or other materials provided with the distribution. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 31 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 32 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 34 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 40 * SUCH DAMAGE. 41 * 42 */ 43 44#include <machine/asm.h> 45#include <sys/syscall.h> 46 47#define AUX_base 7 48#define AUX_entry 9 49 50/* 51 * ld.so entry point. 52 * On entry: r31 points to the kernel argument struct (argv, argv, environ). 53 * The environment pointers list is followed by an array of AuxInfo 54 * structs filled by the kernel. 55 */ 56ENTRY(_dl_start) 57 /* 58 * Two nop because execution may skip up to two instructions. 59 * See setregs() in the kernel for details. 60 * 61 * Note that I have been hacking m88k for years and still fall 62 * into this trap, every time. -- miod 63 */ 64 or %r0, %r0, %r0 65 or %r0, %r0, %r0 66 67 /* 68 * Get some room for the contiguous AUX pointers array. 69 */ 70 or %r30, %r31, 0 71 subu %r31, %r31, (4 * (AUX_entry + 1)) 72 73 /* 74 * Align the stack to a 16 byte boundary. 75 */ 76 clr %r31, %r31, 4<0> 77 78 /* 79 * Invoke _dl_boot_bind 80 */ 81 or %r2, %r30, 0 | kernel args 82 or %r3, %r31, 0 | array base 83 bsr 1f | the following instruction is skipped 84 bsr _DYNAMIC | but gives us the pc-relative offset 851: ld %r6, %r1, 0 | fetch branch instruction 86 mak %r5, %r6, 26<2> | pick branch offset and shift left by 2 87 addu %r4, %r5, %r1 88 bsr _dl_boot_bind 89 90 ld %r2, %r30, 0 | argc 91 addu %r6, %r30, 4 + 4 92 lda %r3, %r6[%r2] | envp 93 ld %r4, %r31, 4 * AUX_base| ldoff 94 or %r5, %r31, 0 | array base 95 bsr.n _dl_boot 96 addu %r2, %r30, 4 | argv 97 98 or %r31, %r30, 0 99 bsr 1f | the following instruction is skipped 100 bcnd eq0, %r0, _dl_dtors | but gives us the pc-relative offset 1011: ld.h %r5, %r1, 2 | fetch branch offset (low 16 bits) 102 jmp.n %r2 103 lda %r5, %r1[%r5] | cleanup 104END(_dl_start) 105 106/* 107 * PLT resolver entry point. 108 * Invoked with the following stack frame: 109 * r31(0x00) zero 110 * r31(0x04) ELF object 111 * r31(0x08) saved r11 112 * r31(0x0c) saved r1 113 * All registers but r1 and r11 must be preserved. The resolver must return 114 * to the resolved address with r1 restored. 115 */ 116#define OBJECT_OFFSET (4 * 1) 117#define R11_OFFSET (4 * 2) 118#define R1_OFFSET (4 * 3) 119#define PLT_FRAME_SIZE (4 * 4) 120#define REG_SIZE (4 * 12) 121ENTRY(_dl_bind_start) 122 /* 123 * Preserve caller-saved registers. 124 */ 125 subu %r31, %r31, REG_SIZE 126 st.d %r2, %r31, 4 * 0 127 st.d %r4, %r31, 4 * 2 128 st.d %r6, %r31, 4 * 4 129 st.d %r8, %r31, 4 * 6 130 st %r10, %r31, 4 * 8 131 st.d %r12, %r31, 4 * 10 132 133 /* 134 * Invoke resolver entry point. 135 */ 136 ld %r2, %r31, REG_SIZE + OBJECT_OFFSET 137 bsr.n _dl_bind 138 ld %r3, %r31, REG_SIZE + R11_OFFSET | reloff 139 140 /* 141 * Preserve return address. 142 */ 143 or %r11, %r2, %r0 144 145 /* 146 * Restore caller-saved registers. 147 */ 148 ld.d %r12, %r31, 4 * 10 149 ld %r10, %r31, 4 * 8 150 ld.d %r8, %r31, 4 * 6 151 ld.d %r6, %r31, 4 * 4 152 ld.d %r4, %r31, 4 * 2 153 ld.d %r2, %r31, 4 * 0 154 ld %r1, %r31, REG_SIZE + R1_OFFSET 155 156 jmp.n %r11 157 addu %r31, %r31, REG_SIZE + PLT_FRAME_SIZE 158END(_dl_bind_start) 159 160ENTRY(_dl_cacheflush) 161 tb0 0, %r0, 451 162 or %r0, %r0, %r0 | never hit 163 jmp %r1 164END(_dl_cacheflush) 165