1 /* $NetBSD: kobj_machdep.c,v 1.9 2023/04/28 07:33:55 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:55 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 Elf64_Addr *where, val;
77 Elf32_Addr *where32, val32;
78 Elf64_Addr addr;
79 Elf64_Addr addend;
80 uintptr_t rtype, symidx;
81 const Elf_Rel *rel;
82 const Elf_Rela *rela;
83 int error;
84
85 if (isrela) {
86 rela = (const Elf_Rela *)data;
87 where = (Elf64_Addr *)(relocbase + rela->r_offset);
88 addend = rela->r_addend;
89 rtype = ELF_R_TYPE(rela->r_info);
90 symidx = ELF_R_SYM(rela->r_info);
91 } else {
92 rel = (const Elf_Rel *)data;
93 where = (Elf64_Addr *)(relocbase + rel->r_offset);
94 rtype = ELF_R_TYPE(rel->r_info);
95 symidx = ELF_R_SYM(rel->r_info);
96 /* Addend is 32 bit on 32 bit relocs */
97 switch (rtype) {
98 case R_X86_64_PC32:
99 case R_X86_64_32:
100 case R_X86_64_32S:
101 addend = *(Elf32_Addr *)where;
102 break;
103 default:
104 addend = *where;
105 break;
106 }
107 }
108
109 const Elf_Sym *sym = kobj_symbol(ko, symidx);
110
111 if (!local && ELF_ST_BIND(sym->st_info) == STB_LOCAL) {
112 return 0;
113 }
114
115 switch (rtype) {
116 case R_X86_64_NONE: /* none */
117 break;
118
119 case R_X86_64_64: /* S + A */
120 error = kobj_sym_lookup(ko, symidx, &addr);
121 if (error)
122 return -1;
123 val = addr + addend;
124 memcpy(where, &val, sizeof(val));
125 break;
126
127 case R_X86_64_PC32: /* S + A - P */
128 case R_X86_64_PLT32:
129 error = kobj_sym_lookup(ko, symidx, &addr);
130 if (error)
131 return -1;
132 where32 = (Elf32_Addr *)where;
133 val32 = (Elf32_Addr)(addr + addend - (Elf64_Addr)where);
134 memcpy(where32, &val32, sizeof(val32));
135 break;
136
137 case R_X86_64_32: /* S + A */
138 case R_X86_64_32S: /* S + A sign extend */
139 error = kobj_sym_lookup(ko, symidx, &addr);
140 if (error)
141 return -1;
142 val32 = (Elf32_Addr)(addr + addend);
143 where32 = (Elf32_Addr *)where;
144 memcpy(where32, &val32, sizeof(val32));
145 break;
146
147 case R_X86_64_GLOB_DAT: /* S */
148 case R_X86_64_JUMP_SLOT:/* XXX need addend + offset */
149 error = kobj_sym_lookup(ko, symidx, &addr);
150 if (error)
151 return -1;
152 memcpy(where, &addr, sizeof(addr));
153 break;
154
155 case R_X86_64_RELATIVE: /* B + A */
156 addr = relocbase + addend;
157 val = addr;
158 memcpy(where, &val, sizeof(val));
159 break;
160
161 default:
162 printf("kobj_reloc: unexpected relocation type %ld\n", rtype);
163 return -1;
164 }
165
166 return 0;
167 }
168
169 int
kobj_machdep(kobj_t ko,void * base,size_t size,bool load)170 kobj_machdep(kobj_t ko, void *base, size_t size, bool load)
171 {
172 uint64_t where;
173
174 if (load) {
175 if (cold) {
176 wbinvd();
177 } else {
178 where = xc_broadcast(0, (xcfunc_t)wbinvd, NULL, NULL);
179 xc_wait(where);
180 }
181 }
182
183 return 0;
184 }
185