1 /* $NetBSD: kobj_machdep.c,v 1.9 2023/04/28 07:33:56 skrll Exp $ */ 2 3 /*- 4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software developed for The NetBSD Foundation 8 * by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /*- 33 * Copyright 1996-1998 John D. Polstra. 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 48 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 51 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 52 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 53 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 54 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55 */ 56 57 #include <sys/cdefs.h> 58 __KERNEL_RCSID(0, "$NetBSD: kobj_machdep.c,v 1.9 2023/04/28 07:33:56 skrll Exp $"); 59 60 #define ELFSIZE ARCH_ELFSIZE 61 62 #include <sys/param.h> 63 #include <sys/systm.h> 64 #include <sys/kernel.h> 65 #include <sys/kobj.h> 66 #include <sys/exec.h> 67 #include <sys/exec_elf.h> 68 #include <sys/xcall.h> 69 70 #include <machine/cpufunc.h> 71 72 int 73 kobj_reloc(kobj_t ko, uintptr_t relocbase, const void *data, 74 bool isrela, bool local) 75 { 76 Elf_Addr *where; 77 Elf_Addr addr; 78 Elf_Addr addend; 79 Elf_Word rtype, symidx; 80 const Elf_Rel *rel; 81 const Elf_Rela *rela; 82 int error; 83 84 if (isrela) { 85 rela = (const Elf_Rela *)data; 86 where = (Elf_Addr *) (relocbase + rela->r_offset); 87 addend = rela->r_addend; 88 rtype = ELF_R_TYPE(rela->r_info); 89 symidx = ELF_R_SYM(rela->r_info); 90 } else { 91 rel = (const Elf_Rel *)data; 92 where = (Elf_Addr *) (relocbase + rel->r_offset); 93 addend = *where; 94 rtype = ELF_R_TYPE(rel->r_info); 95 symidx = ELF_R_SYM(rel->r_info); 96 } 97 98 const Elf_Sym *sym = kobj_symbol(ko, symidx); 99 100 if (!local && ELF_ST_BIND(sym->st_info) == STB_LOCAL) { 101 return 0; 102 } 103 104 switch (rtype) { 105 case R_386_NONE: /* none */ 106 return 0; 107 108 case R_386_32: /* S + A */ 109 error = kobj_sym_lookup(ko, symidx, &addr); 110 if (error) 111 return -1; 112 addr += addend; 113 break; 114 115 case R_386_PC32: /* S + A - P */ 116 error = kobj_sym_lookup(ko, symidx, &addr); 117 if (error) 118 return -1; 119 addr += addend - (Elf_Addr)where; 120 break; 121 122 case R_386_GLOB_DAT: /* S */ 123 error = kobj_sym_lookup(ko, symidx, &addr); 124 if (error) 125 return -1; 126 break; 127 128 case R_386_RELATIVE: 129 addr = relocbase + addend; 130 break; 131 132 default: 133 printf("kobj_reloc: unexpected relocation type %d\n", rtype); 134 return -1; 135 } 136 137 *where = addr; 138 return 0; 139 } 140 141 int 142 kobj_machdep(kobj_t ko, void *base, size_t size, bool load) 143 { 144 uint64_t where; 145 146 /* 147 * Currently we want this to invalidate the Pentium 4 trace cache. 148 * Other caches are snoopably coherent. 149 */ 150 if (load) { 151 if (cold) { 152 wbinvd(); 153 } else { 154 where = xc_broadcast(0, (xcfunc_t)wbinvd, NULL, NULL); 155 xc_wait(where); 156 } 157 } 158 159 return 0; 160 } 161