1 /* $NetBSD: loadfile.c,v 1.10 2000/12/03 02:53:04 tsutsui Exp $ */ 2 /* $OpenBSD: loadfile_elf.c,v 1.48 2024/07/09 09:31:37 dv Exp $ */ 3 4 /*- 5 * Copyright (c) 1997 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10 * NASA Ames Research Center and by Christos Zoulas. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Copyright (c) 1992, 1993 36 * The Regents of the University of California. All rights reserved. 37 * 38 * This code is derived from software contributed to Berkeley by 39 * Ralph Campbell. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. Neither the name of the University nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * @(#)boot.c 8.1 (Berkeley) 6/10/93 66 */ 67 68 /* 69 * Copyright (c) 2015 Mike Larkin <mlarkin@openbsd.org> 70 * 71 * Permission to use, copy, modify, and distribute this software for any 72 * purpose with or without fee is hereby granted, provided that the above 73 * copyright notice and this permission notice appear in all copies. 74 * 75 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 76 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 77 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 78 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 79 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 80 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 81 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 82 */ 83 84 #include <sys/param.h> /* PAGE_SIZE PAGE_MASK roundup */ 85 #include <sys/ioctl.h> 86 #include <sys/reboot.h> 87 #include <sys/exec.h> 88 89 #include <elf.h> 90 #include <stdio.h> 91 #include <string.h> 92 #include <errno.h> 93 #include <stdlib.h> 94 #include <unistd.h> 95 #include <fcntl.h> 96 #include <err.h> 97 #include <stddef.h> 98 99 #include <dev/vmm/vmm.h> 100 101 #include <machine/biosvar.h> 102 #include <machine/segments.h> 103 #include <machine/specialreg.h> 104 #include <machine/pte.h> 105 106 #include "loadfile.h" 107 #include "vmd.h" 108 109 #define LOADADDR(a) ((((u_long)(a)) + offset)&0xfffffff) 110 111 union { 112 Elf32_Ehdr elf32; 113 Elf64_Ehdr elf64; 114 } hdr; 115 116 static void setsegment(struct mem_segment_descriptor *, uint32_t, 117 size_t, int, int, int, int); 118 static int elf32_exec(gzFile, Elf32_Ehdr *, u_long *, int); 119 static int elf64_exec(gzFile, Elf64_Ehdr *, u_long *, int); 120 static size_t create_bios_memmap(struct vm_create_params *, bios_memmap_t *); 121 static uint32_t push_bootargs(bios_memmap_t *, size_t, bios_bootmac_t *); 122 static size_t push_stack(uint32_t, uint32_t); 123 static void push_gdt(void); 124 static void push_pt_32(void); 125 static void push_pt_64(void); 126 static void marc4random_buf(paddr_t, int); 127 static void mbzero(paddr_t, int); 128 static void mbcopy(void *, paddr_t, int); 129 130 extern char *__progname; 131 extern int vm_id; 132 133 /* 134 * setsegment 135 * 136 * Initializes a segment selector entry with the provided descriptor. 137 * For the purposes of the bootloader mimiced by vmd(8), we only need 138 * memory-type segment descriptor support. 139 * 140 * This function was copied from machdep.c 141 * 142 * Parameters: 143 * sd: Address of the entry to initialize 144 * base: base of the segment 145 * limit: limit of the segment 146 * type: type of the segment 147 * dpl: privilege level of the egment 148 * def32: default 16/32 bit size of the segment 149 * gran: granularity of the segment (byte/page) 150 */ 151 static void 152 setsegment(struct mem_segment_descriptor *sd, uint32_t base, size_t limit, 153 int type, int dpl, int def32, int gran) 154 { 155 sd->sd_lolimit = (int)limit; 156 sd->sd_lobase = (int)base; 157 sd->sd_type = type; 158 sd->sd_dpl = dpl; 159 sd->sd_p = 1; 160 sd->sd_hilimit = (int)limit >> 16; 161 sd->sd_avl = 0; 162 sd->sd_long = 0; 163 sd->sd_def32 = def32; 164 sd->sd_gran = gran; 165 sd->sd_hibase = (int)base >> 24; 166 } 167 168 /* 169 * push_gdt 170 * 171 * Allocates and populates a page in the guest phys memory space to hold 172 * the boot-time GDT. Since vmd(8) is acting as the bootloader, we need to 173 * create the same GDT that a real bootloader would have created. 174 * This is loaded into the guest phys RAM space at address GDT_PAGE. 175 */ 176 static void 177 push_gdt(void) 178 { 179 uint8_t gdtpage[PAGE_SIZE]; 180 struct mem_segment_descriptor *sd; 181 182 memset(&gdtpage, 0, sizeof(gdtpage)); 183 184 sd = (struct mem_segment_descriptor *)&gdtpage; 185 186 /* 187 * Create three segment descriptors: 188 * 189 * GDT[0] : null descriptor. "Created" via memset above. 190 * GDT[1] (selector @ 0x8): Executable segment, for CS 191 * GDT[2] (selector @ 0x10): RW Data segment, for DS/ES/SS 192 */ 193 setsegment(&sd[1], 0, 0xffffffff, SDT_MEMERA, SEL_KPL, 1, 1); 194 setsegment(&sd[2], 0, 0xffffffff, SDT_MEMRWA, SEL_KPL, 1, 1); 195 196 write_mem(GDT_PAGE, gdtpage, PAGE_SIZE); 197 } 198 199 /* 200 * push_pt_32 201 * 202 * Create an identity-mapped page directory hierarchy mapping the first 203 * 4GB of physical memory. This is used during bootstrapping i386 VMs on 204 * CPUs without unrestricted guest capability. 205 */ 206 static void 207 push_pt_32(void) 208 { 209 uint32_t ptes[1024], i; 210 211 memset(ptes, 0, sizeof(ptes)); 212 for (i = 0 ; i < 1024; i++) { 213 ptes[i] = PG_V | PG_RW | PG_u | PG_PS | ((4096 * 1024) * i); 214 } 215 write_mem(PML3_PAGE, ptes, PAGE_SIZE); 216 } 217 218 /* 219 * push_pt_64 220 * 221 * Create an identity-mapped page directory hierarchy mapping the first 222 * 1GB of physical memory. This is used during bootstrapping 64 bit VMs on 223 * CPUs without unrestricted guest capability. 224 */ 225 static void 226 push_pt_64(void) 227 { 228 uint64_t ptes[512], i; 229 230 /* PDPDE0 - first 1GB */ 231 memset(ptes, 0, sizeof(ptes)); 232 ptes[0] = PG_V | PML3_PAGE; 233 write_mem(PML4_PAGE, ptes, PAGE_SIZE); 234 235 /* PDE0 - first 1GB */ 236 memset(ptes, 0, sizeof(ptes)); 237 ptes[0] = PG_V | PG_RW | PG_u | PML2_PAGE; 238 write_mem(PML3_PAGE, ptes, PAGE_SIZE); 239 240 /* First 1GB (in 2MB pages) */ 241 memset(ptes, 0, sizeof(ptes)); 242 for (i = 0 ; i < 512; i++) { 243 ptes[i] = PG_V | PG_RW | PG_u | PG_PS | ((2048 * 1024) * i); 244 } 245 write_mem(PML2_PAGE, ptes, PAGE_SIZE); 246 } 247 248 /* 249 * loadfile_elf 250 * 251 * Loads an ELF kernel to its defined load address in the guest VM. 252 * The kernel is loaded to its defined start point as set in the ELF header. 253 * 254 * Parameters: 255 * fp: file of a kernel file to load 256 * vcp: the VM create parameters, holding the exact memory map 257 * (out) vrs: register state to set on init for this kernel 258 * bootdev: the optional non-default boot device 259 * howto: optional boot flags for the kernel 260 * 261 * Return values: 262 * 0 if successful 263 * various error codes returned from gzread(3) or loadelf functions 264 */ 265 int 266 loadfile_elf(gzFile fp, struct vmd_vm *vm, struct vcpu_reg_state *vrs, 267 unsigned int bootdevice) 268 { 269 int r, is_i386 = 0; 270 uint32_t bootargsz; 271 size_t n, stacksize; 272 u_long marks[MARK_MAX]; 273 bios_memmap_t memmap[VMM_MAX_MEM_RANGES + 1]; 274 bios_bootmac_t bm, *bootmac = NULL; 275 struct vm_create_params *vcp = &vm->vm_params.vmc_params; 276 277 if ((r = gzread(fp, &hdr, sizeof(hdr))) != sizeof(hdr)) 278 return 1; 279 280 memset(&marks, 0, sizeof(marks)); 281 if (memcmp(hdr.elf32.e_ident, ELFMAG, SELFMAG) == 0 && 282 hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) { 283 r = elf32_exec(fp, &hdr.elf32, marks, LOAD_ALL); 284 is_i386 = 1; 285 } else if (memcmp(hdr.elf64.e_ident, ELFMAG, SELFMAG) == 0 && 286 hdr.elf64.e_ident[EI_CLASS] == ELFCLASS64) { 287 r = elf64_exec(fp, &hdr.elf64, marks, LOAD_ALL); 288 } else 289 errno = ENOEXEC; 290 291 if (r) 292 return (r); 293 294 push_gdt(); 295 296 if (is_i386) { 297 push_pt_32(); 298 /* Reconfigure the default flat-64 register set for 32 bit */ 299 vrs->vrs_crs[VCPU_REGS_CR3] = PML3_PAGE; 300 vrs->vrs_crs[VCPU_REGS_CR4] = CR4_PSE; 301 vrs->vrs_msrs[VCPU_REGS_EFER] = 0ULL; 302 } 303 else 304 push_pt_64(); 305 306 if (bootdevice == VMBOOTDEV_NET) { 307 bootmac = &bm; 308 memcpy(bootmac, vm->vm_params.vmc_macs[0], ETHER_ADDR_LEN); 309 } 310 n = create_bios_memmap(vcp, memmap); 311 bootargsz = push_bootargs(memmap, n, bootmac); 312 stacksize = push_stack(bootargsz, marks[MARK_END]); 313 314 vrs->vrs_gprs[VCPU_REGS_RIP] = (uint64_t)marks[MARK_ENTRY]; 315 vrs->vrs_gprs[VCPU_REGS_RSP] = (uint64_t)(STACK_PAGE + PAGE_SIZE) - stacksize; 316 vrs->vrs_gdtr.vsi_base = GDT_PAGE; 317 318 log_debug("%s: loaded ELF kernel", __func__); 319 320 return (0); 321 } 322 323 /* 324 * create_bios_memmap 325 * 326 * Construct a memory map as returned by the BIOS INT 0x15, e820 routine. 327 * 328 * Parameters: 329 * vcp: the VM create parameters, containing the memory map passed to vmm(4) 330 * memmap (out): the BIOS memory map 331 * 332 * Return values: 333 * Number of bios_memmap_t entries, including the terminating nul-entry. 334 */ 335 static size_t 336 create_bios_memmap(struct vm_create_params *vcp, bios_memmap_t *memmap) 337 { 338 size_t i, n = 0; 339 struct vm_mem_range *vmr; 340 341 for (i = 0; i < vcp->vcp_nmemranges; i++, n++) { 342 vmr = &vcp->vcp_memranges[i]; 343 memmap[n].addr = vmr->vmr_gpa; 344 memmap[n].size = vmr->vmr_size; 345 if (vmr->vmr_type == VM_MEM_RAM) 346 memmap[n].type = BIOS_MAP_FREE; 347 else 348 memmap[n].type = BIOS_MAP_RES; 349 } 350 351 /* Null mem map entry to denote the end of the ranges */ 352 memmap[n].addr = 0x0; 353 memmap[n].size = 0x0; 354 memmap[n].type = BIOS_MAP_END; 355 n++; 356 357 return (n); 358 } 359 360 /* 361 * push_bootargs 362 * 363 * Creates the boot arguments page in the guest address space. 364 * Since vmd(8) is acting as the bootloader, we need to create the same boot 365 * arguments page that a real bootloader would have created. This is loaded 366 * into the guest phys RAM space at address BOOTARGS_PAGE. 367 * 368 * Parameters: 369 * memmap: the BIOS memory map 370 * n: number of entries in memmap 371 * bootmac: optional PXE boot MAC address 372 * 373 * Return values: 374 * The size of the bootargs in bytes 375 */ 376 static uint32_t 377 push_bootargs(bios_memmap_t *memmap, size_t n, bios_bootmac_t *bootmac) 378 { 379 uint32_t memmap_sz, consdev_sz, bootmac_sz, i; 380 bios_consdev_t consdev; 381 uint32_t ba[1024]; 382 383 memmap_sz = 3 * sizeof(uint32_t) + n * sizeof(bios_memmap_t); 384 ba[0] = BOOTARG_MEMMAP; 385 ba[1] = memmap_sz; 386 ba[2] = memmap_sz; 387 memcpy(&ba[3], memmap, n * sizeof(bios_memmap_t)); 388 i = memmap_sz / sizeof(uint32_t); 389 390 /* Serial console device, COM1 @ 0x3f8 */ 391 memset(&consdev, 0, sizeof(consdev)); 392 consdev.consdev = makedev(8, 0); 393 consdev.conspeed = 115200; 394 consdev.consaddr = 0x3f8; 395 396 consdev_sz = 3 * sizeof(uint32_t) + sizeof(bios_consdev_t); 397 ba[i] = BOOTARG_CONSDEV; 398 ba[i + 1] = consdev_sz; 399 ba[i + 2] = consdev_sz; 400 memcpy(&ba[i + 3], &consdev, sizeof(bios_consdev_t)); 401 i += consdev_sz / sizeof(uint32_t); 402 403 if (bootmac) { 404 bootmac_sz = 3 * sizeof(uint32_t) + 405 (sizeof(bios_bootmac_t) + 3) & ~3; 406 ba[i] = BOOTARG_BOOTMAC; 407 ba[i + 1] = bootmac_sz; 408 ba[i + 2] = bootmac_sz; 409 memcpy(&ba[i + 3], bootmac, sizeof(bios_bootmac_t)); 410 i += bootmac_sz / sizeof(uint32_t); 411 } 412 413 ba[i++] = 0xFFFFFFFF; /* BOOTARG_END */ 414 415 write_mem(BOOTARGS_PAGE, ba, PAGE_SIZE); 416 417 return (i * sizeof(uint32_t)); 418 } 419 420 /* 421 * push_stack 422 * 423 * Creates the boot stack page in the guest address space. When using a real 424 * bootloader, the stack will be prepared using the following format before 425 * transitioning to kernel start, so vmd(8) needs to mimic the same stack 426 * layout. The stack content is pushed to the guest phys RAM at address 427 * STACK_PAGE. The bootloader operates in 32 bit mode; each stack entry is 428 * 4 bytes. 429 * 430 * Stack Layout: (TOS == Top Of Stack) 431 * TOS location of boot arguments page 432 * TOS - 0x4 size of the content in the boot arguments page 433 * TOS - 0x8 size of low memory (biosbasemem: kernel uses BIOS map only if 0) 434 * TOS - 0xc size of high memory (biosextmem, not used by kernel at all) 435 * TOS - 0x10 kernel 'end' symbol value 436 * TOS - 0x14 version of bootarg API 437 * 438 * Parameters: 439 * bootargsz: size of boot arguments 440 * end: kernel 'end' symbol value 441 * bootdev: the optional non-default boot device 442 * howto: optional boot flags for the kernel 443 * 444 * Return values: 445 * size of the stack 446 */ 447 static size_t 448 push_stack(uint32_t bootargsz, uint32_t end) 449 { 450 uint32_t stack[1024]; 451 uint16_t loc; 452 453 memset(&stack, 0, sizeof(stack)); 454 loc = 1024; 455 456 stack[--loc] = BOOTARGS_PAGE; 457 stack[--loc] = bootargsz; 458 stack[--loc] = 0; /* biosbasemem */ 459 stack[--loc] = 0; /* biosextmem */ 460 stack[--loc] = end; 461 stack[--loc] = 0x0e; 462 stack[--loc] = MAKEBOOTDEV(0x4, 0, 0, 0, 0); /* bootdev: sd0a */ 463 stack[--loc] = 0; 464 465 write_mem(STACK_PAGE, &stack, PAGE_SIZE); 466 467 return (1024 - (loc - 1)) * sizeof(uint32_t); 468 } 469 470 /* 471 * mread 472 * 473 * Reads 'sz' bytes from the file whose descriptor is provided in 'fd' 474 * into the guest address space at paddr 'addr'. 475 * 476 * Parameters: 477 * fp: kernel image file to read from. 478 * addr: guest paddr_t to load to 479 * sz: number of bytes to load 480 * 481 * Return values: 482 * returns 'sz' if successful, or 0 otherwise. 483 */ 484 size_t 485 mread(gzFile fp, paddr_t addr, size_t sz) 486 { 487 const char *errstr = NULL; 488 int errnum = 0; 489 size_t ct; 490 size_t i, osz; 491 char buf[PAGE_SIZE]; 492 493 /* 494 * break up the 'sz' bytes into PAGE_SIZE chunks for use with 495 * write_mem 496 */ 497 ct = 0; 498 osz = sz; 499 if ((addr & PAGE_MASK) != 0) { 500 memset(buf, 0, sizeof(buf)); 501 if (sz > PAGE_SIZE) 502 ct = PAGE_SIZE - (addr & PAGE_MASK); 503 else 504 ct = sz; 505 506 if ((size_t)gzread(fp, buf, ct) != ct) { 507 errstr = gzerror(fp, &errnum); 508 if (errnum == Z_ERRNO) 509 errnum = errno; 510 log_warnx("%s: error %d in mread, %s", __progname, 511 errnum, errstr); 512 return (0); 513 } 514 515 if (write_mem(addr, buf, ct)) 516 return (0); 517 518 addr += ct; 519 } 520 521 sz = sz - ct; 522 523 if (sz == 0) 524 return (osz); 525 526 for (i = 0; i < sz; i += PAGE_SIZE, addr += PAGE_SIZE) { 527 memset(buf, 0, sizeof(buf)); 528 if (i + PAGE_SIZE > sz) 529 ct = sz - i; 530 else 531 ct = PAGE_SIZE; 532 533 if ((size_t)gzread(fp, buf, ct) != ct) { 534 errstr = gzerror(fp, &errnum); 535 if (errnum == Z_ERRNO) 536 errnum = errno; 537 log_warnx("%s: error %d in mread, %s", __progname, 538 errnum, errstr); 539 return (0); 540 } 541 542 if (write_mem(addr, buf, ct)) 543 return (0); 544 } 545 546 return (osz); 547 } 548 549 /* 550 * marc4random_buf 551 * 552 * load 'sz' bytes of random data into the guest address space at paddr 553 * 'addr'. 554 * 555 * Parameters: 556 * addr: guest paddr_t to load random bytes into 557 * sz: number of random bytes to load 558 * 559 * Return values: 560 * nothing 561 */ 562 static void 563 marc4random_buf(paddr_t addr, int sz) 564 { 565 int i, ct; 566 char buf[PAGE_SIZE]; 567 568 /* 569 * break up the 'sz' bytes into PAGE_SIZE chunks for use with 570 * write_mem 571 */ 572 ct = 0; 573 if (addr % PAGE_SIZE != 0) { 574 memset(buf, 0, sizeof(buf)); 575 ct = PAGE_SIZE - (addr % PAGE_SIZE); 576 577 arc4random_buf(buf, ct); 578 579 if (write_mem(addr, buf, ct)) 580 return; 581 582 addr += ct; 583 } 584 585 for (i = 0; i < sz; i+= PAGE_SIZE, addr += PAGE_SIZE) { 586 memset(buf, 0, sizeof(buf)); 587 if (i + PAGE_SIZE > sz) 588 ct = sz - i; 589 else 590 ct = PAGE_SIZE; 591 592 arc4random_buf(buf, ct); 593 594 if (write_mem(addr, buf, ct)) 595 return; 596 } 597 } 598 599 /* 600 * mbzero 601 * 602 * load 'sz' bytes of zeros into the guest address space at paddr 603 * 'addr'. 604 * 605 * Parameters: 606 * addr: guest paddr_t to zero 607 * sz: number of zero bytes to store 608 * 609 * Return values: 610 * nothing 611 */ 612 static void 613 mbzero(paddr_t addr, int sz) 614 { 615 if (write_mem(addr, NULL, sz)) 616 return; 617 } 618 619 /* 620 * mbcopy 621 * 622 * copies 'sz' bytes from buffer 'src' to guest paddr 'dst'. 623 * 624 * Parameters: 625 * src: source buffer to copy from 626 * dst: destination guest paddr_t to copy to 627 * sz: number of bytes to copy 628 * 629 * Return values: 630 * nothing 631 */ 632 static void 633 mbcopy(void *src, paddr_t dst, int sz) 634 { 635 write_mem(dst, src, sz); 636 } 637 638 /* 639 * elf64_exec 640 * 641 * Load the kernel indicated by 'fp' into the guest physical memory 642 * space, at the addresses defined in the ELF header. 643 * 644 * This function is used for 64 bit kernels. 645 * 646 * Parameters: 647 * fp: kernel image file to load 648 * elf: ELF header of the kernel 649 * marks: array to store the offsets of various kernel structures 650 * (start, bss, etc) 651 * flags: flag value to indicate which section(s) to load (usually 652 * LOAD_ALL) 653 * 654 * Return values: 655 * 0 if successful 656 * 1 if unsuccessful 657 */ 658 static int 659 elf64_exec(gzFile fp, Elf64_Ehdr *elf, u_long *marks, int flags) 660 { 661 Elf64_Shdr *shp; 662 Elf64_Phdr *phdr; 663 Elf64_Off off; 664 int i; 665 size_t sz; 666 int havesyms; 667 paddr_t minp = ~0, maxp = 0, pos = 0; 668 paddr_t offset = marks[MARK_START], shpp, elfp; 669 670 sz = elf->e_phnum * sizeof(Elf64_Phdr); 671 phdr = malloc(sz); 672 673 if (gzseek(fp, (off_t)elf->e_phoff, SEEK_SET) == -1) { 674 free(phdr); 675 return 1; 676 } 677 678 if ((size_t)gzread(fp, phdr, sz) != sz) { 679 free(phdr); 680 return 1; 681 } 682 683 for (i = 0; i < elf->e_phnum; i++) { 684 if (phdr[i].p_type == PT_OPENBSD_RANDOMIZE) { 685 int m; 686 687 /* Fill segment if asked for. */ 688 if (flags & LOAD_RANDOM) { 689 for (pos = 0; pos < phdr[i].p_filesz; 690 pos += m) { 691 m = phdr[i].p_filesz - pos; 692 marc4random_buf(phdr[i].p_paddr + pos, 693 m); 694 } 695 } 696 if (flags & (LOAD_RANDOM | COUNT_RANDOM)) { 697 marks[MARK_RANDOM] = LOADADDR(phdr[i].p_paddr); 698 marks[MARK_ERANDOM] = 699 marks[MARK_RANDOM] + phdr[i].p_filesz; 700 } 701 continue; 702 } 703 704 if (phdr[i].p_type != PT_LOAD || 705 (phdr[i].p_flags & (PF_W|PF_R|PF_X)) == 0) 706 continue; 707 708 #define IS_TEXT(p) (p.p_flags & PF_X) 709 #define IS_DATA(p) ((p.p_flags & PF_X) == 0) 710 #define IS_BSS(p) (p.p_filesz < p.p_memsz) 711 /* 712 * XXX: Assume first address is lowest 713 */ 714 if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) || 715 (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) { 716 717 /* Read in segment. */ 718 if (gzseek(fp, (off_t)phdr[i].p_offset, 719 SEEK_SET) == -1) { 720 free(phdr); 721 return 1; 722 } 723 if (mread(fp, phdr[i].p_paddr, phdr[i].p_filesz) != 724 phdr[i].p_filesz) { 725 free(phdr); 726 return 1; 727 } 728 } 729 730 if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT | COUNT_TEXT))) || 731 (IS_DATA(phdr[i]) && (flags & (LOAD_DATA | COUNT_TEXT)))) { 732 pos = phdr[i].p_paddr; 733 if (minp > pos) 734 minp = pos; 735 pos += phdr[i].p_filesz; 736 if (maxp < pos) 737 maxp = pos; 738 } 739 740 /* Zero out BSS. */ 741 if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) { 742 mbzero((phdr[i].p_paddr + phdr[i].p_filesz), 743 phdr[i].p_memsz - phdr[i].p_filesz); 744 } 745 if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) { 746 pos += phdr[i].p_memsz - phdr[i].p_filesz; 747 if (maxp < pos) 748 maxp = pos; 749 } 750 } 751 free(phdr); 752 753 /* 754 * Copy the ELF and section headers. 755 */ 756 elfp = maxp = roundup(maxp, sizeof(Elf64_Addr)); 757 if (flags & (LOAD_HDR | COUNT_HDR)) 758 maxp += sizeof(Elf64_Ehdr); 759 760 if (flags & (LOAD_SYM | COUNT_SYM)) { 761 if (gzseek(fp, (off_t)elf->e_shoff, SEEK_SET) == -1) { 762 warn("gzseek section headers"); 763 return 1; 764 } 765 sz = elf->e_shnum * sizeof(Elf64_Shdr); 766 shp = malloc(sz); 767 768 if ((size_t)gzread(fp, shp, sz) != sz) { 769 free(shp); 770 return 1; 771 } 772 773 shpp = maxp; 774 maxp += roundup(sz, sizeof(Elf64_Addr)); 775 776 size_t shstrsz = shp[elf->e_shstrndx].sh_size; 777 char *shstr = malloc(shstrsz); 778 if (gzseek(fp, (off_t)shp[elf->e_shstrndx].sh_offset, 779 SEEK_SET) == -1) { 780 free(shstr); 781 free(shp); 782 return 1; 783 } 784 if ((size_t)gzread(fp, shstr, shstrsz) != shstrsz) { 785 free(shstr); 786 free(shp); 787 return 1; 788 } 789 790 /* 791 * Now load the symbol sections themselves. Make sure the 792 * sections are aligned. Don't bother with string tables if 793 * there are no symbol sections. 794 */ 795 off = roundup((sizeof(Elf64_Ehdr) + sz), sizeof(Elf64_Addr)); 796 797 for (havesyms = i = 0; i < elf->e_shnum; i++) 798 if (shp[i].sh_type == SHT_SYMTAB) 799 havesyms = 1; 800 801 for (i = 0; i < elf->e_shnum; i++) { 802 if (shp[i].sh_type == SHT_SYMTAB || 803 shp[i].sh_type == SHT_STRTAB || 804 !strcmp(shstr + shp[i].sh_name, ".debug_line") || 805 !strcmp(shstr + shp[i].sh_name, ELF_CTF)) { 806 if (havesyms && (flags & LOAD_SYM)) { 807 if (gzseek(fp, (off_t)shp[i].sh_offset, 808 SEEK_SET) == -1) { 809 free(shstr); 810 free(shp); 811 return 1; 812 } 813 if (mread(fp, maxp, 814 shp[i].sh_size) != shp[i].sh_size) { 815 free(shstr); 816 free(shp); 817 return 1; 818 } 819 } 820 maxp += roundup(shp[i].sh_size, 821 sizeof(Elf64_Addr)); 822 shp[i].sh_offset = off; 823 shp[i].sh_flags |= SHF_ALLOC; 824 off += roundup(shp[i].sh_size, 825 sizeof(Elf64_Addr)); 826 } 827 } 828 if (flags & LOAD_SYM) { 829 mbcopy(shp, shpp, sz); 830 } 831 free(shstr); 832 free(shp); 833 } 834 835 /* 836 * Frob the copied ELF header to give information relative 837 * to elfp. 838 */ 839 if (flags & LOAD_HDR) { 840 elf->e_phoff = 0; 841 elf->e_shoff = sizeof(Elf64_Ehdr); 842 elf->e_phentsize = 0; 843 elf->e_phnum = 0; 844 mbcopy(elf, elfp, sizeof(*elf)); 845 } 846 847 marks[MARK_START] = LOADADDR(minp); 848 marks[MARK_ENTRY] = LOADADDR(elf->e_entry); 849 marks[MARK_NSYM] = 1; /* XXX: Kernel needs >= 0 */ 850 marks[MARK_SYM] = LOADADDR(elfp); 851 marks[MARK_END] = LOADADDR(maxp); 852 853 return 0; 854 } 855 856 /* 857 * elf32_exec 858 * 859 * Load the kernel indicated by 'fp' into the guest physical memory 860 * space, at the addresses defined in the ELF header. 861 * 862 * This function is used for 32 bit kernels. 863 * 864 * Parameters: 865 * fp: kernel image file to load 866 * elf: ELF header of the kernel 867 * marks: array to store the offsets of various kernel structures 868 * (start, bss, etc) 869 * flags: flag value to indicate which section(s) to load (usually 870 * LOAD_ALL) 871 * 872 * Return values: 873 * 0 if successful 874 * 1 if unsuccessful 875 */ 876 static int 877 elf32_exec(gzFile fp, Elf32_Ehdr *elf, u_long *marks, int flags) 878 { 879 Elf32_Shdr *shp; 880 Elf32_Phdr *phdr; 881 Elf32_Off off; 882 int i; 883 size_t sz; 884 int havesyms; 885 paddr_t minp = ~0, maxp = 0, pos = 0; 886 paddr_t offset = marks[MARK_START], shpp, elfp; 887 888 sz = elf->e_phnum * sizeof(Elf32_Phdr); 889 phdr = malloc(sz); 890 891 if (gzseek(fp, (off_t)elf->e_phoff, SEEK_SET) == -1) { 892 free(phdr); 893 return 1; 894 } 895 896 if ((size_t)gzread(fp, phdr, sz) != sz) { 897 free(phdr); 898 return 1; 899 } 900 901 for (i = 0; i < elf->e_phnum; i++) { 902 if (phdr[i].p_type == PT_OPENBSD_RANDOMIZE) { 903 int m; 904 905 /* Fill segment if asked for. */ 906 if (flags & LOAD_RANDOM) { 907 for (pos = 0; pos < phdr[i].p_filesz; 908 pos += m) { 909 m = phdr[i].p_filesz - pos; 910 marc4random_buf(phdr[i].p_paddr + pos, 911 m); 912 } 913 } 914 if (flags & (LOAD_RANDOM | COUNT_RANDOM)) { 915 marks[MARK_RANDOM] = LOADADDR(phdr[i].p_paddr); 916 marks[MARK_ERANDOM] = 917 marks[MARK_RANDOM] + phdr[i].p_filesz; 918 } 919 continue; 920 } 921 922 if (phdr[i].p_type != PT_LOAD || 923 (phdr[i].p_flags & (PF_W|PF_R|PF_X)) == 0) 924 continue; 925 926 #define IS_TEXT(p) (p.p_flags & PF_X) 927 #define IS_DATA(p) ((p.p_flags & PF_X) == 0) 928 #define IS_BSS(p) (p.p_filesz < p.p_memsz) 929 /* 930 * XXX: Assume first address is lowest 931 */ 932 if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) || 933 (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) { 934 935 /* Read in segment. */ 936 if (gzseek(fp, (off_t)phdr[i].p_offset, 937 SEEK_SET) == -1) { 938 free(phdr); 939 return 1; 940 } 941 if (mread(fp, phdr[i].p_paddr, phdr[i].p_filesz) != 942 phdr[i].p_filesz) { 943 free(phdr); 944 return 1; 945 } 946 } 947 948 if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT | COUNT_TEXT))) || 949 (IS_DATA(phdr[i]) && (flags & (LOAD_DATA | COUNT_TEXT)))) { 950 pos = phdr[i].p_paddr; 951 if (minp > pos) 952 minp = pos; 953 pos += phdr[i].p_filesz; 954 if (maxp < pos) 955 maxp = pos; 956 } 957 958 /* Zero out BSS. */ 959 if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) { 960 mbzero((phdr[i].p_paddr + phdr[i].p_filesz), 961 phdr[i].p_memsz - phdr[i].p_filesz); 962 } 963 if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) { 964 pos += phdr[i].p_memsz - phdr[i].p_filesz; 965 if (maxp < pos) 966 maxp = pos; 967 } 968 } 969 free(phdr); 970 971 /* 972 * Copy the ELF and section headers. 973 */ 974 elfp = maxp = roundup(maxp, sizeof(Elf32_Addr)); 975 if (flags & (LOAD_HDR | COUNT_HDR)) 976 maxp += sizeof(Elf32_Ehdr); 977 978 if (flags & (LOAD_SYM | COUNT_SYM)) { 979 if (gzseek(fp, (off_t)elf->e_shoff, SEEK_SET) == -1) { 980 warn("lseek section headers"); 981 return 1; 982 } 983 sz = elf->e_shnum * sizeof(Elf32_Shdr); 984 shp = malloc(sz); 985 986 if ((size_t)gzread(fp, shp, sz) != sz) { 987 free(shp); 988 return 1; 989 } 990 991 shpp = maxp; 992 maxp += roundup(sz, sizeof(Elf32_Addr)); 993 994 size_t shstrsz = shp[elf->e_shstrndx].sh_size; 995 char *shstr = malloc(shstrsz); 996 if (gzseek(fp, (off_t)shp[elf->e_shstrndx].sh_offset, 997 SEEK_SET) == -1) { 998 free(shstr); 999 free(shp); 1000 return 1; 1001 } 1002 if ((size_t)gzread(fp, shstr, shstrsz) != shstrsz) { 1003 free(shstr); 1004 free(shp); 1005 return 1; 1006 } 1007 1008 /* 1009 * Now load the symbol sections themselves. Make sure the 1010 * sections are aligned. Don't bother with string tables if 1011 * there are no symbol sections. 1012 */ 1013 off = roundup((sizeof(Elf32_Ehdr) + sz), sizeof(Elf32_Addr)); 1014 1015 for (havesyms = i = 0; i < elf->e_shnum; i++) 1016 if (shp[i].sh_type == SHT_SYMTAB) 1017 havesyms = 1; 1018 1019 for (i = 0; i < elf->e_shnum; i++) { 1020 if (shp[i].sh_type == SHT_SYMTAB || 1021 shp[i].sh_type == SHT_STRTAB || 1022 !strcmp(shstr + shp[i].sh_name, ".debug_line")) { 1023 if (havesyms && (flags & LOAD_SYM)) { 1024 if (gzseek(fp, (off_t)shp[i].sh_offset, 1025 SEEK_SET) == -1) { 1026 free(shstr); 1027 free(shp); 1028 return 1; 1029 } 1030 if (mread(fp, maxp, 1031 shp[i].sh_size) != shp[i].sh_size) { 1032 free(shstr); 1033 free(shp); 1034 return 1; 1035 } 1036 } 1037 maxp += roundup(shp[i].sh_size, 1038 sizeof(Elf32_Addr)); 1039 shp[i].sh_offset = off; 1040 shp[i].sh_flags |= SHF_ALLOC; 1041 off += roundup(shp[i].sh_size, 1042 sizeof(Elf32_Addr)); 1043 } 1044 } 1045 if (flags & LOAD_SYM) { 1046 mbcopy(shp, shpp, sz); 1047 } 1048 free(shstr); 1049 free(shp); 1050 } 1051 1052 /* 1053 * Frob the copied ELF header to give information relative 1054 * to elfp. 1055 */ 1056 if (flags & LOAD_HDR) { 1057 elf->e_phoff = 0; 1058 elf->e_shoff = sizeof(Elf32_Ehdr); 1059 elf->e_phentsize = 0; 1060 elf->e_phnum = 0; 1061 mbcopy(elf, elfp, sizeof(*elf)); 1062 } 1063 1064 marks[MARK_START] = LOADADDR(minp); 1065 marks[MARK_ENTRY] = LOADADDR(elf->e_entry); 1066 marks[MARK_NSYM] = 1; /* XXX: Kernel needs >= 0 */ 1067 marks[MARK_SYM] = LOADADDR(elfp); 1068 marks[MARK_END] = LOADADDR(maxp); 1069 1070 return 0; 1071 } 1072