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 83 resettodr(void) 84 { 85 86 } 87 88 void 89 ff_init_thread0(void) 90 { 91 pcurthread = &thread0; 92 } 93 94 int 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 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 112 kthread_exit(void) 113 { 114 panic("kthread_exit unsupported"); 115 } 116 117 void 118 tdsignal(struct thread *td, int sig) 119 { 120 return; 121 } 122 123 dev_t 124 tty_udev(struct tty *tp) 125 { 126 return (NODEV); 127 } 128 129 int 130 p_candebug(struct thread *td, struct proc *p) 131 { 132 return (0); 133 } 134 135 const char * 136 devtoname(struct cdev *dev) 137 { 138 return (NULL); 139 } 140 141 #ifdef RACCT 142 uint64_t 143 racct_get_limit(struct proc *p, int resource) 144 { 145 return (UINT64_MAX); 146 } 147 #endif 148 149 int 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 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 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 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 279 elf_cpu_load_file(linker_file_t lf __unused) 280 { 281 return (0); 282 } 283 284 int 285 elf_cpu_unload_file(linker_file_t lf __unused) 286 { 287 return (0); 288 } 289 290 void 291 arc4rand(void *ptr, unsigned int len, int reseed) 292 { 293 ff_arc4rand(ptr, len, reseed); 294 } 295 296 uint32_t 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 315 read_random(void *buf, u_int count) 316 { 317 arc4rand(buf, count, 0); 318 } 319 320 void 321 arc4random_buf(void *ptr, size_t len) 322 { 323 arc4rand(ptr, len, 0); 324 } 325 326 int 327 fubyte(volatile const void *base) 328 { 329 return (*(volatile const uint8_t *)base); 330 } 331 332 int 333 fueword(volatile const void *base, long *val) 334 { 335 *val = (*(volatile const long *)base); 336 return 0; 337 } 338 339 void 340 timekeep_push_vdso(void) 341 { 342 ; 343 } 344 345 uint32_t 346 cpu_fill_vdso_timehands(struct vdso_timehands *vdso_th, struct timecounter *tc) 347 { 348 return (0); 349 } 350 351