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
kobj_reloc(kobj_t ko,uintptr_t relocbase,const void * data,bool isrela,bool local)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
kobj_machdep(kobj_t ko,void * base,size_t size,bool load)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