1 /*
2 * Copyright (c) 2010 Kip Macy. All rights reserved.
3 * Copyright (C) 2017-2021 THL A29 Limited, a Tencent company.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice, this
10 * list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * Derived in part from libplebnet's pn_compat.c.
27 *
28 */
29
30 #include <sys/param.h>
31 #include <sys/kernel.h>
32 #include <sys/kthread.h>
33 #include <sys/refcount.h>
34 #include <sys/stat.h>
35 #include <sys/stdint.h>
36 #include <sys/time.h>
37 #include <sys/ucred.h>
38 #include <sys/uio.h>
39 #include <sys/proc.h>
40 #include <sys/tty.h>
41 #include <sys/sx.h>
42 #include <sys/linker.h>
43 #include <sys/racct.h>
44 #include <sys/malloc.h>
45 #include <sys/syscallsubr.h>
46 #include <sys/libkern.h>
47 #include <sys/random.h>
48 #include <sys/mman.h>
49 #include <sys/vdso.h>
50
51 #include <machine/elf.h>
52 #include <machine/md_var.h>
53
54 #include "ff_host_interface.h"
55
56 TAILQ_HEAD(prisonlist, prison);
57
58 __thread struct thread *pcurthread;
59
60 struct cdev;
61 struct vnode *rootvnode;
62 extern struct proc proc0;
63 struct proclist allproc;
64 struct sx allproc_lock;
65 struct sx allprison_lock;
66 struct prisonlist allprison;
67
68 MALLOC_DEFINE(M_FADVISE, "fadvise", "posix_fadvise(2) information");
69 int async_io_version;
70 extern unsigned int rand_r(unsigned int *seed);
71 unsigned int seed = 0;
72
73 #define M_ZERO 0x0100 /* bzero the allocation */
74
75 int vttoif_tab[10] = {
76 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK,
77 S_IFSOCK, S_IFIFO, S_IFMT, S_IFMT
78 };
79
80 void ff_init_thread0(void);
81
82 void
resettodr(void)83 resettodr(void)
84 {
85
86 }
87
88 void
ff_init_thread0(void)89 ff_init_thread0(void)
90 {
91 pcurthread = &thread0;
92 }
93
94 int
kproc_kthread_add(void (* start_routine)(void *),void * arg,struct proc ** p,struct thread ** tdp,int flags,int pages,const char * procname,const char * str,...)95 kproc_kthread_add(void (*start_routine)(void *), void *arg,
96 struct proc **p, struct thread **tdp,
97 int flags, int pages,
98 const char *procname, const char *str, ...)
99 {
100 return 0;
101 }
102
103 int
kthread_add(void (* start_routine)(void *),void * arg,struct proc * p,struct thread ** tdp,int flags,int pages,const char * str,...)104 kthread_add(void (*start_routine)(void *), void *arg, struct proc *p,
105 struct thread **tdp, int flags, int pages,
106 const char *str, ...)
107 {
108 return 0;
109 }
110
111 void
kthread_exit(void)112 kthread_exit(void)
113 {
114 panic("kthread_exit unsupported");
115 }
116
117 void
tdsignal(struct thread * td,int sig)118 tdsignal(struct thread *td, int sig)
119 {
120 return;
121 }
122
123 dev_t
tty_udev(struct tty * tp)124 tty_udev(struct tty *tp)
125 {
126 return (NODEV);
127 }
128
129 int
p_candebug(struct thread * td,struct proc * p)130 p_candebug(struct thread *td, struct proc *p)
131 {
132 return (0);
133 }
134
135 const char *
devtoname(struct cdev * dev)136 devtoname(struct cdev *dev)
137 {
138 return (NULL);
139 }
140
141 #ifdef RACCT
142 uint64_t
racct_get_limit(struct proc * p,int resource)143 racct_get_limit(struct proc *p, int resource)
144 {
145 return (UINT64_MAX);
146 }
147 #endif
148
149 int
kern_openat(struct thread * td,int fd,const char * path,enum uio_seg pathseg,int flags,int mode)150 kern_openat(struct thread *td, int fd, const char *path, enum uio_seg pathseg,
151 int flags, int mode)
152 {
153 return (-1);
154 }
155
156 /* Process one elf relocation with addend. */
157 static int
elf_reloc_internal(linker_file_t lf,Elf_Addr relocbase,const void * data,int type,int local,elf_lookup_fn lookup)158 elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
159 int type, int local, elf_lookup_fn lookup)
160 {
161 Elf64_Addr *where, val;
162 Elf32_Addr *where32, val32;
163 Elf_Addr addr;
164 Elf_Addr addend;
165 Elf_Size rtype, symidx;
166 const Elf_Rel *rel;
167 const Elf_Rela *rela;
168 int error;
169
170 switch (type) {
171 case ELF_RELOC_REL:
172 rel = (const Elf_Rel *)data;
173 where = (Elf_Addr *) (relocbase + rel->r_offset);
174 rtype = ELF_R_TYPE(rel->r_info);
175 symidx = ELF_R_SYM(rel->r_info);
176 /* Addend is 32 bit on 32 bit relocs */
177 switch (rtype) {
178 case R_X86_64_PC32:
179 case R_X86_64_32S:
180 addend = *(Elf32_Addr *)where;
181 break;
182 default:
183 addend = *where;
184 break;
185 }
186 break;
187 case ELF_RELOC_RELA:
188 rela = (const Elf_Rela *)data;
189 where = (Elf_Addr *) (relocbase + rela->r_offset);
190 addend = rela->r_addend;
191 rtype = ELF_R_TYPE(rela->r_info);
192 symidx = ELF_R_SYM(rela->r_info);
193 break;
194 default:
195 panic("unknown reloc type %d\n", type);
196 }
197
198 switch (rtype) {
199 case R_X86_64_NONE: /* none */
200 break;
201
202 case R_X86_64_64: /* S + A */
203 error = lookup(lf, symidx, 1, &addr);
204 val = addr + addend;
205 if (error != 0)
206 return -1;
207 if (*where != val)
208 *where = val;
209 break;
210
211 case R_X86_64_PC32: /* S + A - P */
212 error = lookup(lf, symidx, 1, &addr);
213 where32 = (Elf32_Addr *)where;
214 val32 = (Elf32_Addr)(addr + addend - (Elf_Addr)where);
215 if (error != 0)
216 return -1;
217 if (*where32 != val32)
218 *where32 = val32;
219 break;
220
221 case R_X86_64_32S: /* S + A sign extend */
222 error = lookup(lf, symidx, 1, &addr);
223 val32 = (Elf32_Addr)(addr + addend);
224 where32 = (Elf32_Addr *)where;
225 if (error != 0)
226 return -1;
227 if (*where32 != val32)
228 *where32 = val32;
229 break;
230
231 case R_X86_64_COPY: /* none */
232 /*
233 * There shouldn't be copy relocations in kernel
234 * objects.
235 */
236 printf("kldload: unexpected R_COPY relocation\n");
237 return -1;
238 break;
239
240 case R_X86_64_GLOB_DAT: /* S */
241 case R_X86_64_JMP_SLOT: /* XXX need addend + offset */
242 error = lookup(lf, symidx, 1, &addr);
243 if (error != 0)
244 return -1;
245 if (*where != addr)
246 *where = addr;
247 break;
248
249 case R_X86_64_RELATIVE: /* B + A */
250 addr = relocbase + addend;
251 val = addr;
252 if (*where != val)
253 *where = val;
254 break;
255
256 default:
257 printf("kldload: unexpected relocation type %ld\n",
258 rtype);
259 return -1;
260 }
261 return(0);
262 }
263
264 int
elf_reloc(linker_file_t lf,Elf_Addr relocbase,const void * data,int type,elf_lookup_fn lookup)265 elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
266 elf_lookup_fn lookup)
267 {
268 return (elf_reloc_internal(lf, relocbase, data, type, 0, lookup));
269 }
270
271 int
elf_reloc_local(linker_file_t lf,Elf_Addr relocbase,const void * data,int type,elf_lookup_fn lookup)272 elf_reloc_local(linker_file_t lf, Elf_Addr relocbase, const void *data,
273 int type, elf_lookup_fn lookup)
274 {
275 return (elf_reloc_internal(lf, relocbase, data, type, 1, lookup));
276 }
277
278 int
elf_cpu_load_file(linker_file_t lf __unused)279 elf_cpu_load_file(linker_file_t lf __unused)
280 {
281 return (0);
282 }
283
284 int
elf_cpu_unload_file(linker_file_t lf __unused)285 elf_cpu_unload_file(linker_file_t lf __unused)
286 {
287 return (0);
288 }
289
290 void
arc4rand(void * ptr,unsigned int len,int reseed)291 arc4rand(void *ptr, unsigned int len, int reseed)
292 {
293 ff_arc4rand(ptr, len, reseed);
294 }
295
296 uint32_t
arc4random(void)297 arc4random(void)
298 {
299 if (seed == 0) {
300 seed = ff_arc4random();
301 }
302 return (uint32_t)rand_r(&seed);
303 }
304
305 #if 0
306 void
307 random_harvest_queue(const void *entropy, u_int size,
308 enum random_entropy_source origin)
309 {
310 ;
311 }
312 #endif
313
314 void
read_random(void * buf,u_int count)315 read_random(void *buf, u_int count)
316 {
317 arc4rand(buf, count, 0);
318 }
319
320 void
arc4random_buf(void * ptr,size_t len)321 arc4random_buf(void *ptr, size_t len)
322 {
323 arc4rand(ptr, len, 0);
324 }
325
326 int
fubyte(volatile const void * base)327 fubyte(volatile const void *base)
328 {
329 return (*(volatile const uint8_t *)base);
330 }
331
332 int
fueword(volatile const void * base,long * val)333 fueword(volatile const void *base, long *val)
334 {
335 *val = (*(volatile const long *)base);
336 return 0;
337 }
338
339 void
timekeep_push_vdso(void)340 timekeep_push_vdso(void)
341 {
342 ;
343 }
344
345 uint32_t
cpu_fill_vdso_timehands(struct vdso_timehands * vdso_th,struct timecounter * tc)346 cpu_fill_vdso_timehands(struct vdso_timehands *vdso_th, struct timecounter *tc)
347 {
348 return (0);
349 }
350
351