1 /* $NetBSD: loadfile.c,v 1.10 2000/12/03 02:53:04 tsutsui Exp $ */ 2 /* $OpenBSD: loadfile_elf.c,v 1.26 2017/03/27 00:28:04 deraadt 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 #include <sys/exec_elf.h> 89 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 <errno.h> 98 #include <stddef.h> 99 100 #include <machine/vmmvar.h> 101 #include <machine/biosvar.h> 102 #include <machine/segments.h> 103 #include <machine/pte.h> 104 105 #include "loadfile.h" 106 #include "vmd.h" 107 108 union { 109 Elf32_Ehdr elf32; 110 Elf64_Ehdr elf64; 111 } hdr; 112 113 #ifdef __i386__ 114 typedef uint32_t pt_entry_t; 115 static void setsegment(struct segment_descriptor *, uint32_t, 116 size_t, int, int, int, int); 117 #else 118 static void setsegment(struct mem_segment_descriptor *, uint32_t, 119 size_t, int, int, int, int); 120 #endif 121 static int elf32_exec(FILE *, Elf32_Ehdr *, u_long *, int); 122 static int elf64_exec(FILE *, Elf64_Ehdr *, u_long *, int); 123 static size_t create_bios_memmap(struct vm_create_params *, bios_memmap_t *); 124 static uint32_t push_bootargs(bios_memmap_t *, size_t); 125 static size_t push_stack(uint32_t, uint32_t, uint32_t, uint32_t); 126 static void push_gdt(void); 127 static void push_pt(void); 128 static void marc4random_buf(paddr_t, int); 129 static void mbzero(paddr_t, int); 130 static void mbcopy(void *, paddr_t, int); 131 132 extern char *__progname; 133 extern int vm_id; 134 135 /* 136 * setsegment 137 * 138 * Initializes a segment selector entry with the provided descriptor. 139 * For the purposes of the bootloader mimiced by vmd(8), we only need 140 * memory-type segment descriptor support. 141 * 142 * This function was copied from machdep.c 143 * 144 * Parameters: 145 * sd: Address of the entry to initialize 146 * base: base of the segment 147 * limit: limit of the segment 148 * type: type of the segment 149 * dpl: privilege level of the egment 150 * def32: default 16/32 bit size of the segment 151 * gran: granularity of the segment (byte/page) 152 */ 153 #ifdef __i386__ 154 static void 155 setsegment(struct segment_descriptor *sd, uint32_t base, size_t limit, 156 int type, int dpl, int def32, int gran) 157 #else 158 static void 159 setsegment(struct mem_segment_descriptor *sd, uint32_t base, size_t limit, 160 int type, int dpl, int def32, int gran) 161 #endif 162 { 163 sd->sd_lolimit = (int)limit; 164 sd->sd_lobase = (int)base; 165 sd->sd_type = type; 166 sd->sd_dpl = dpl; 167 sd->sd_p = 1; 168 sd->sd_hilimit = (int)limit >> 16; 169 #ifdef __i386__ 170 sd->sd_xx = 0; 171 #else 172 sd->sd_avl = 0; 173 sd->sd_long = 0; 174 #endif 175 sd->sd_def32 = def32; 176 sd->sd_gran = gran; 177 sd->sd_hibase = (int)base >> 24; 178 } 179 180 /* 181 * push_gdt 182 * 183 * Allocates and populates a page in the guest phys memory space to hold 184 * the boot-time GDT. Since vmd(8) is acting as the bootloader, we need to 185 * create the same GDT that a real bootloader would have created. 186 * This is loaded into the guest phys RAM space at address GDT_PAGE. 187 */ 188 static void 189 push_gdt(void) 190 { 191 uint8_t gdtpage[PAGE_SIZE]; 192 #ifdef __i386__ 193 struct segment_descriptor *sd; 194 #else 195 struct mem_segment_descriptor *sd; 196 #endif 197 198 memset(&gdtpage, 0, sizeof(gdtpage)); 199 200 #ifdef __i386__ 201 sd = (struct segment_descriptor *)&gdtpage; 202 #else 203 sd = (struct mem_segment_descriptor *)&gdtpage; 204 #endif 205 206 /* 207 * Create three segment descriptors: 208 * 209 * GDT[0] : null desriptor. "Created" via memset above. 210 * GDT[1] (selector @ 0x8): Executable segment, for CS 211 * GDT[2] (selector @ 0x10): RW Data segment, for DS/ES/SS 212 */ 213 setsegment(&sd[1], 0, 0xffffffff, SDT_MEMERA, SEL_KPL, 1, 1); 214 setsegment(&sd[2], 0, 0xffffffff, SDT_MEMRWA, SEL_KPL, 1, 1); 215 216 write_mem(GDT_PAGE, gdtpage, PAGE_SIZE); 217 } 218 219 /* 220 * push_pt 221 * 222 * Create an identity-mapped page directory hierarchy mapping the first 223 * 1GB of physical memory. This is used during bootstrapping VMs on 224 * CPUs without unrestricted guest capability. 225 */ 226 static void 227 push_pt(void) 228 { 229 pt_entry_t ptes[NPTE_PG]; 230 uint64_t i; 231 232 #ifdef __i386__ 233 memset(ptes, 0, sizeof(ptes)); 234 for (i = 0 ; i < NPTE_PG; i++) { 235 ptes[i] = PG_V | PG_PS | (NBPD * i); 236 } 237 write_mem(PML4_PAGE, ptes, PAGE_SIZE); 238 #else 239 /* PML3 [0] - first 1GB */ 240 memset(ptes, 0, sizeof(ptes)); 241 ptes[0] = PG_V | PML3_PAGE; 242 write_mem(PML4_PAGE, ptes, PAGE_SIZE); 243 244 /* PML3 [0] - first 1GB */ 245 memset(ptes, 0, sizeof(ptes)); 246 ptes[0] = PG_V | PG_RW | PG_u | PML2_PAGE; 247 write_mem(PML3_PAGE, ptes, PAGE_SIZE); 248 249 /* PML2 [0..511] - first 1GB (in 2MB pages) */ 250 memset(ptes, 0, sizeof(ptes)); 251 for (i = 0 ; i < NPTE_PG; i++) { 252 ptes[i] = PG_V | PG_RW | PG_u | PG_PS | (NBPD_L2 * i); 253 } 254 write_mem(PML2_PAGE, ptes, PAGE_SIZE); 255 #endif 256 } 257 258 /* 259 * loadfile_elf 260 * 261 * Loads an ELF kernel to it's defined load address in the guest VM. 262 * The kernel is loaded to its defined start point as set in the ELF header. 263 * 264 * Parameters: 265 * fp: file of a kernel file to load 266 * vcp: the VM create parameters, holding the exact memory map 267 * (out) vrs: register state to set on init for this kernel 268 * bootdev: the optional non-default boot device 269 * howto: optionel boot flags for the kernel 270 * 271 * Return values: 272 * 0 if successful 273 * various error codes returned from read(2) or loadelf functions 274 */ 275 int 276 loadfile_elf(FILE *fp, struct vm_create_params *vcp, 277 struct vcpu_reg_state *vrs, uint32_t bootdev, uint32_t howto) 278 { 279 int r; 280 uint32_t bootargsz; 281 size_t n, stacksize; 282 u_long marks[MARK_MAX]; 283 bios_memmap_t memmap[VMM_MAX_MEM_RANGES + 1]; 284 285 if ((r = fread(&hdr, 1, sizeof(hdr), fp)) != sizeof(hdr)) 286 return 1; 287 288 memset(&marks, 0, sizeof(marks)); 289 if (memcmp(hdr.elf32.e_ident, ELFMAG, SELFMAG) == 0 && 290 hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) { 291 r = elf32_exec(fp, &hdr.elf32, marks, LOAD_ALL); 292 } else if (memcmp(hdr.elf64.e_ident, ELFMAG, SELFMAG) == 0 && 293 hdr.elf64.e_ident[EI_CLASS] == ELFCLASS64) { 294 r = elf64_exec(fp, &hdr.elf64, marks, LOAD_ALL); 295 } else 296 errno = ENOEXEC; 297 298 if (r) 299 return (r); 300 301 push_gdt(); 302 push_pt(); 303 n = create_bios_memmap(vcp, memmap); 304 bootargsz = push_bootargs(memmap, n); 305 stacksize = push_stack(bootargsz, marks[MARK_END], bootdev, howto); 306 307 #ifdef __i386__ 308 vrs->vrs_gprs[VCPU_REGS_EIP] = (uint32_t)marks[MARK_ENTRY]; 309 vrs->vrs_gprs[VCPU_REGS_ESP] = (uint32_t)(STACK_PAGE + PAGE_SIZE) - stacksize; 310 #else 311 vrs->vrs_gprs[VCPU_REGS_RIP] = (uint64_t)marks[MARK_ENTRY]; 312 vrs->vrs_gprs[VCPU_REGS_RSP] = (uint64_t)(STACK_PAGE + PAGE_SIZE) - stacksize; 313 #endif 314 vrs->vrs_gdtr.vsi_base = GDT_PAGE; 315 316 log_debug("%s: loaded ELF kernel", __func__); 317 318 return (0); 319 } 320 321 /* 322 * create_bios_memmap 323 * 324 * Construct a memory map as returned by the BIOS INT 0x15, e820 routine. 325 * 326 * Parameters: 327 * vcp: the VM create parameters, containing the memory map passed to vmm(4) 328 * memmap (out): the BIOS memory map 329 * 330 * Return values: 331 * Number of bios_memmap_t entries, including the terminating nul-entry. 332 */ 333 static size_t 334 create_bios_memmap(struct vm_create_params *vcp, bios_memmap_t *memmap) 335 { 336 size_t i, n = 0, sz; 337 paddr_t gpa; 338 struct vm_mem_range *vmr; 339 340 for (i = 0; i < vcp->vcp_nmemranges; i++) { 341 vmr = &vcp->vcp_memranges[i]; 342 gpa = vmr->vmr_gpa; 343 sz = vmr->vmr_size; 344 345 /* 346 * Make sure that we do not mark the ROM/video RAM area in the 347 * low memory as physcal memory available to the kernel. 348 */ 349 if (gpa < 0x100000 && gpa + sz > LOWMEM_KB * 1024) { 350 if (gpa >= LOWMEM_KB * 1024) 351 sz = 0; 352 else 353 sz = LOWMEM_KB * 1024 - gpa; 354 } 355 356 if (sz != 0) { 357 memmap[n].addr = gpa; 358 memmap[n].size = sz; 359 memmap[n].type = 0x1; /* Type 1 : Normal memory */ 360 n++; 361 } 362 } 363 364 /* Null mem map entry to denote the end of the ranges */ 365 memmap[n].addr = 0x0; 366 memmap[n].size = 0x0; 367 memmap[n].type = 0x0; 368 n++; 369 370 return (n); 371 } 372 373 /* 374 * push_bootargs 375 * 376 * Creates the boot arguments page in the guest address space. 377 * Since vmd(8) is acting as the bootloader, we need to create the same boot 378 * arguments page that a real bootloader would have created. This is loaded 379 * into the guest phys RAM space at address BOOTARGS_PAGE. 380 * 381 * Parameters: 382 * memmap: the BIOS memory map 383 * n: number of entries in memmap 384 * 385 * Return values: 386 * The size of the bootargs 387 */ 388 static uint32_t 389 push_bootargs(bios_memmap_t *memmap, size_t n) 390 { 391 uint32_t memmap_sz, consdev_sz, i; 392 bios_consdev_t consdev; 393 uint32_t ba[1024]; 394 395 memmap_sz = 3 * sizeof(int) + n * sizeof(bios_memmap_t); 396 ba[0] = 0x0; /* memory map */ 397 ba[1] = memmap_sz; 398 ba[2] = memmap_sz; /* next */ 399 memcpy(&ba[3], memmap, n * sizeof(bios_memmap_t)); 400 i = memmap_sz / sizeof(int); 401 402 /* Serial console device, COM1 @ 0x3f8 */ 403 consdev.consdev = makedev(8, 0); /* com1 @ 0x3f8 */ 404 consdev.conspeed = 9600; 405 consdev.consaddr = 0x3f8; 406 consdev.consfreq = 0; 407 408 consdev_sz = 3 * sizeof(int) + sizeof(bios_consdev_t); 409 ba[i] = 0x5; /* consdev */ 410 ba[i + 1] = consdev_sz; 411 ba[i + 2] = consdev_sz; 412 memcpy(&ba[i + 3], &consdev, sizeof(bios_consdev_t)); 413 i = i + 3 + (sizeof(bios_consdev_t) / 4); 414 415 ba[i] = 0xFFFFFFFF; /* BOOTARG_END */ 416 417 write_mem(BOOTARGS_PAGE, ba, PAGE_SIZE); 418 419 return (memmap_sz + consdev_sz); 420 } 421 422 /* 423 * push_stack 424 * 425 * Creates the boot stack page in the guest address space. When using a real 426 * bootloader, the stack will be prepared using the following format before 427 * transitioning to kernel start, so vmd(8) needs to mimic the same stack 428 * layout. The stack content is pushed to the guest phys RAM at address 429 * STACK_PAGE. The bootloader operates in 32 bit mode; each stack entry is 430 * 4 bytes. 431 * 432 * Stack Layout: (TOS == Top Of Stack) 433 * TOS location of boot arguments page 434 * TOS - 0x4 size of the content in the boot arguments page 435 * TOS - 0x8 size of low memory (biosbasemem: kernel uses BIOS map only if 0) 436 * TOS - 0xc size of high memory (biosextmem, not used by kernel at all) 437 * TOS - 0x10 kernel 'end' symbol value 438 * TOS - 0x14 version of bootarg API 439 * 440 * Parameters: 441 * bootargsz: size of boot arguments 442 * end: kernel 'end' symbol value 443 * bootdev: the optional non-default boot device 444 * howto: optionel boot flags for the kernel 445 * 446 * Return values: 447 * size of the stack 448 */ 449 static size_t 450 push_stack(uint32_t bootargsz, uint32_t end, uint32_t bootdev, uint32_t howto) 451 { 452 uint32_t stack[1024]; 453 uint16_t loc; 454 455 memset(&stack, 0, sizeof(stack)); 456 loc = 1024; 457 458 if (bootdev == 0) 459 bootdev = MAKEBOOTDEV(0x4, 0, 0, 0, 0); /* bootdev: sd0a */ 460 461 stack[--loc] = BOOTARGS_PAGE; 462 stack[--loc] = bootargsz; 463 stack[--loc] = 0; /* biosbasemem */ 464 stack[--loc] = 0; /* biosextmem */ 465 stack[--loc] = end; 466 stack[--loc] = 0x0e; 467 stack[--loc] = bootdev; 468 stack[--loc] = howto; 469 470 write_mem(STACK_PAGE, &stack, PAGE_SIZE); 471 472 return (1024 - (loc - 1)) * sizeof(uint32_t); 473 } 474 475 /* 476 * mread 477 * 478 * Reads 'sz' bytes from the file whose descriptor is provided in 'fd' 479 * into the guest address space at paddr 'addr'. 480 * 481 * Parameters: 482 * fd: file descriptor of the kernel image file to read from. 483 * addr: guest paddr_t to load to 484 * sz: number of bytes to load 485 * 486 * Return values: 487 * returns 'sz' if successful, or 0 otherwise. 488 */ 489 size_t 490 mread(FILE *fp, paddr_t addr, size_t sz) 491 { 492 size_t ct; 493 size_t i, rd, osz; 494 char buf[PAGE_SIZE]; 495 496 /* 497 * break up the 'sz' bytes into PAGE_SIZE chunks for use with 498 * write_mem 499 */ 500 ct = 0; 501 rd = 0; 502 osz = sz; 503 if ((addr & PAGE_MASK) != 0) { 504 memset(buf, 0, sizeof(buf)); 505 if (sz > PAGE_SIZE) 506 ct = PAGE_SIZE - (addr & PAGE_MASK); 507 else 508 ct = sz; 509 510 if (fread(buf, 1, ct, fp) != ct) { 511 log_warn("%s: error %d in mread", __progname, errno); 512 return (0); 513 } 514 rd += ct; 515 516 if (write_mem(addr, buf, ct)) 517 return (0); 518 519 addr += ct; 520 } 521 522 sz = sz - ct; 523 524 if (sz == 0) 525 return (osz); 526 527 for (i = 0; i < sz; i += PAGE_SIZE, addr += PAGE_SIZE) { 528 memset(buf, 0, sizeof(buf)); 529 if (i + PAGE_SIZE > sz) 530 ct = sz - i; 531 else 532 ct = PAGE_SIZE; 533 534 if (fread(buf, 1, ct, fp) != ct) { 535 log_warn("%s: error %d in mread", __progname, errno); 536 return (0); 537 } 538 rd += ct; 539 540 if (write_mem(addr, buf, ct)) 541 return (0); 542 } 543 544 return (osz); 545 } 546 547 /* 548 * marc4random_buf 549 * 550 * load 'sz' bytes of random data into the guest address space at paddr 551 * 'addr'. 552 * 553 * Parameters: 554 * addr: guest paddr_t to load random bytes into 555 * sz: number of random bytes to load 556 * 557 * Return values: 558 * nothing 559 */ 560 static void 561 marc4random_buf(paddr_t addr, int sz) 562 { 563 int i, ct; 564 char buf[PAGE_SIZE]; 565 566 /* 567 * break up the 'sz' bytes into PAGE_SIZE chunks for use with 568 * write_mem 569 */ 570 ct = 0; 571 if (addr % PAGE_SIZE != 0) { 572 memset(buf, 0, sizeof(buf)); 573 ct = PAGE_SIZE - (addr % PAGE_SIZE); 574 575 arc4random_buf(buf, ct); 576 577 if (write_mem(addr, buf, ct)) 578 return; 579 580 addr += ct; 581 } 582 583 for (i = 0; i < sz; i+= PAGE_SIZE, addr += PAGE_SIZE) { 584 memset(buf, 0, sizeof(buf)); 585 if (i + PAGE_SIZE > sz) 586 ct = sz - i; 587 else 588 ct = PAGE_SIZE; 589 590 arc4random_buf(buf, ct); 591 592 if (write_mem(addr, buf, ct)) 593 return; 594 } 595 } 596 597 /* 598 * mbzero 599 * 600 * load 'sz' bytes of zeros into the guest address space at paddr 601 * 'addr'. 602 * 603 * Parameters: 604 * addr: guest paddr_t to zero 605 * sz: number of zero bytes to store 606 * 607 * Return values: 608 * nothing 609 */ 610 static void 611 mbzero(paddr_t addr, int sz) 612 { 613 int i, ct; 614 char buf[PAGE_SIZE]; 615 616 /* 617 * break up the 'sz' bytes into PAGE_SIZE chunks for use with 618 * write_mem 619 */ 620 ct = 0; 621 memset(buf, 0, sizeof(buf)); 622 if (addr % PAGE_SIZE != 0) { 623 ct = PAGE_SIZE - (addr % PAGE_SIZE); 624 625 if (write_mem(addr, buf, ct)) 626 return; 627 628 addr += ct; 629 } 630 631 for (i = 0; i < sz; i+= PAGE_SIZE, addr += PAGE_SIZE) { 632 if (i + PAGE_SIZE > sz) 633 ct = sz - i; 634 else 635 ct = PAGE_SIZE; 636 637 if (write_mem(addr, buf, ct)) 638 return; 639 } 640 } 641 642 /* 643 * mbcopy 644 * 645 * copies 'sz' bytes from buffer 'src' to guest paddr 'dst'. 646 * 647 * Parameters: 648 * src: source buffer to copy from 649 * dst: destination guest paddr_t to copy to 650 * sz: number of bytes to copy 651 * 652 * Return values: 653 * nothing 654 */ 655 static void 656 mbcopy(void *src, paddr_t dst, int sz) 657 { 658 write_mem(dst, src, sz); 659 } 660 661 /* 662 * elf64_exec 663 * 664 * Load the kernel indicated by 'fd' into the guest physical memory 665 * space, at the addresses defined in the ELF header. 666 * 667 * This function is used for 64 bit kernels. 668 * 669 * Parameters: 670 * fd: file descriptor of the kernel to load 671 * elf: ELF header of the kernel 672 * marks: array to store the offsets of various kernel structures 673 * (start, bss, etc) 674 * flags: flag value to indicate which section(s) to load (usually 675 * LOAD_ALL) 676 * 677 * Return values: 678 * 0 if successful 679 * 1 if unsuccessful 680 */ 681 static int 682 elf64_exec(FILE *fp, Elf64_Ehdr *elf, u_long *marks, int flags) 683 { 684 Elf64_Shdr *shp; 685 Elf64_Phdr *phdr; 686 Elf64_Off off; 687 int i; 688 size_t sz; 689 int first; 690 int havesyms, havelines; 691 paddr_t minp = ~0, maxp = 0, pos = 0; 692 paddr_t offset = marks[MARK_START], shpp, elfp; 693 694 sz = elf->e_phnum * sizeof(Elf64_Phdr); 695 phdr = malloc(sz); 696 697 if (fseeko(fp, (off_t)elf->e_phoff, SEEK_SET) == -1) { 698 free(phdr); 699 return 1; 700 } 701 702 if (fread(phdr, 1, sz, fp) != sz) { 703 free(phdr); 704 return 1; 705 } 706 707 for (first = 1, i = 0; i < elf->e_phnum; i++) { 708 if (phdr[i].p_type == PT_OPENBSD_RANDOMIZE) { 709 int m; 710 711 /* Fill segment if asked for. */ 712 if (flags & LOAD_RANDOM) { 713 for (pos = 0; pos < phdr[i].p_filesz; 714 pos += m) { 715 m = phdr[i].p_filesz - pos; 716 marc4random_buf(phdr[i].p_paddr + pos, 717 m); 718 } 719 } 720 if (flags & (LOAD_RANDOM | COUNT_RANDOM)) { 721 marks[MARK_RANDOM] = LOADADDR(phdr[i].p_paddr); 722 marks[MARK_ERANDOM] = 723 marks[MARK_RANDOM] + phdr[i].p_filesz; 724 } 725 continue; 726 } 727 728 if (phdr[i].p_type != PT_LOAD || 729 (phdr[i].p_flags & (PF_W|PF_R|PF_X)) == 0) 730 continue; 731 732 #define IS_TEXT(p) (p.p_flags & PF_X) 733 #define IS_DATA(p) ((p.p_flags & PF_X) == 0) 734 #define IS_BSS(p) (p.p_filesz < p.p_memsz) 735 /* 736 * XXX: Assume first address is lowest 737 */ 738 if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) || 739 (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) { 740 741 /* Read in segment. */ 742 if (fseeko(fp, (off_t)phdr[i].p_offset, 743 SEEK_SET) == -1) { 744 free(phdr); 745 return 1; 746 } 747 if (mread(fp, phdr[i].p_paddr, phdr[i].p_filesz) != 748 phdr[i].p_filesz) { 749 free(phdr); 750 return 1; 751 } 752 753 first = 0; 754 } 755 756 if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT | COUNT_TEXT))) || 757 (IS_DATA(phdr[i]) && (flags & (LOAD_DATA | COUNT_TEXT)))) { 758 pos = phdr[i].p_paddr; 759 if (minp > pos) 760 minp = pos; 761 pos += phdr[i].p_filesz; 762 if (maxp < pos) 763 maxp = pos; 764 } 765 766 /* Zero out BSS. */ 767 if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) { 768 mbzero((phdr[i].p_paddr + phdr[i].p_filesz), 769 phdr[i].p_memsz - phdr[i].p_filesz); 770 } 771 if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) { 772 pos += phdr[i].p_memsz - phdr[i].p_filesz; 773 if (maxp < pos) 774 maxp = pos; 775 } 776 } 777 free(phdr); 778 779 /* 780 * Copy the ELF and section headers. 781 */ 782 elfp = maxp = roundup(maxp, sizeof(Elf64_Addr)); 783 if (flags & (LOAD_HDR | COUNT_HDR)) 784 maxp += sizeof(Elf64_Ehdr); 785 786 if (flags & (LOAD_SYM | COUNT_SYM)) { 787 if (fseeko(fp, (off_t)elf->e_shoff, SEEK_SET) == -1) { 788 WARN(("lseek section headers")); 789 return 1; 790 } 791 sz = elf->e_shnum * sizeof(Elf64_Shdr); 792 shp = malloc(sz); 793 794 if (fread(shp, 1, sz, fp) != sz) { 795 free(shp); 796 return 1; 797 } 798 799 shpp = maxp; 800 maxp += roundup(sz, sizeof(Elf64_Addr)); 801 802 size_t shstrsz = shp[elf->e_shstrndx].sh_size; 803 char *shstr = malloc(shstrsz); 804 if (fseeko(fp, (off_t)shp[elf->e_shstrndx].sh_offset, 805 SEEK_SET) == -1) { 806 free(shstr); 807 free(shp); 808 return 1; 809 } 810 if (fread(shstr, 1, shstrsz, fp) != shstrsz) { 811 free(shstr); 812 free(shp); 813 return 1; 814 } 815 816 /* 817 * Now load the symbol sections themselves. Make sure the 818 * sections are aligned. Don't bother with string tables if 819 * there are no symbol sections. 820 */ 821 off = roundup((sizeof(Elf64_Ehdr) + sz), sizeof(Elf64_Addr)); 822 823 for (havesyms = havelines = i = 0; i < elf->e_shnum; i++) 824 if (shp[i].sh_type == SHT_SYMTAB) 825 havesyms = 1; 826 827 for (first = 1, i = 0; i < elf->e_shnum; i++) { 828 if (shp[i].sh_type == SHT_SYMTAB || 829 shp[i].sh_type == SHT_STRTAB || 830 !strcmp(shstr + shp[i].sh_name, ".debug_line") || 831 !strcmp(shstr + shp[i].sh_name, ELF_CTF)) { 832 if (havesyms && (flags & LOAD_SYM)) { 833 if (fseeko(fp, (off_t)shp[i].sh_offset, 834 SEEK_SET) == -1) { 835 free(shstr); 836 free(shp); 837 return 1; 838 } 839 if (mread(fp, maxp, 840 shp[i].sh_size) != shp[i].sh_size) { 841 free(shstr); 842 free(shp); 843 return 1; 844 } 845 } 846 maxp += roundup(shp[i].sh_size, 847 sizeof(Elf64_Addr)); 848 shp[i].sh_offset = off; 849 shp[i].sh_flags |= SHF_ALLOC; 850 off += roundup(shp[i].sh_size, 851 sizeof(Elf64_Addr)); 852 first = 0; 853 } 854 } 855 if (flags & LOAD_SYM) { 856 mbcopy(shp, shpp, sz); 857 } 858 free(shstr); 859 free(shp); 860 } 861 862 /* 863 * Frob the copied ELF header to give information relative 864 * to elfp. 865 */ 866 if (flags & LOAD_HDR) { 867 elf->e_phoff = 0; 868 elf->e_shoff = sizeof(Elf64_Ehdr); 869 elf->e_phentsize = 0; 870 elf->e_phnum = 0; 871 mbcopy(elf, elfp, sizeof(*elf)); 872 } 873 874 marks[MARK_START] = LOADADDR(minp); 875 marks[MARK_ENTRY] = LOADADDR(elf->e_entry); 876 marks[MARK_NSYM] = 1; /* XXX: Kernel needs >= 0 */ 877 marks[MARK_SYM] = LOADADDR(elfp); 878 marks[MARK_END] = LOADADDR(maxp); 879 880 return 0; 881 } 882 883 /* 884 * elf32_exec 885 * 886 * Load the kernel indicated by 'fd' into the guest physical memory 887 * space, at the addresses defined in the ELF header. 888 * 889 * This function is used for 32 bit kernels. 890 * 891 * Parameters: 892 * fd: file descriptor of the kernel to load 893 * elf: ELF header of the kernel 894 * marks: array to store the offsets of various kernel structures 895 * (start, bss, etc) 896 * flags: flag value to indicate which section(s) to load (usually 897 * LOAD_ALL) 898 * 899 * Return values: 900 * 0 if successful 901 * 1 if unsuccessful 902 */ 903 static int 904 elf32_exec(FILE *fp, Elf32_Ehdr *elf, u_long *marks, int flags) 905 { 906 Elf32_Shdr *shp; 907 Elf32_Phdr *phdr; 908 Elf32_Off off; 909 int i; 910 size_t sz; 911 int first; 912 int havesyms, havelines; 913 paddr_t minp = ~0, maxp = 0, pos = 0; 914 paddr_t offset = marks[MARK_START], shpp, elfp; 915 916 sz = elf->e_phnum * sizeof(Elf32_Phdr); 917 phdr = malloc(sz); 918 919 if (fseeko(fp, (off_t)elf->e_phoff, SEEK_SET) == -1) { 920 free(phdr); 921 return 1; 922 } 923 924 if (fread(phdr, 1, sz, fp) != sz) { 925 free(phdr); 926 return 1; 927 } 928 929 for (first = 1, i = 0; i < elf->e_phnum; i++) { 930 if (phdr[i].p_type == PT_OPENBSD_RANDOMIZE) { 931 int m; 932 933 /* Fill segment if asked for. */ 934 if (flags & LOAD_RANDOM) { 935 for (pos = 0; pos < phdr[i].p_filesz; 936 pos += m) { 937 m = phdr[i].p_filesz - pos; 938 marc4random_buf(phdr[i].p_paddr + pos, 939 m); 940 } 941 } 942 if (flags & (LOAD_RANDOM | COUNT_RANDOM)) { 943 marks[MARK_RANDOM] = LOADADDR(phdr[i].p_paddr); 944 marks[MARK_ERANDOM] = 945 marks[MARK_RANDOM] + phdr[i].p_filesz; 946 } 947 continue; 948 } 949 950 if (phdr[i].p_type != PT_LOAD || 951 (phdr[i].p_flags & (PF_W|PF_R|PF_X)) == 0) 952 continue; 953 954 #define IS_TEXT(p) (p.p_flags & PF_X) 955 #define IS_DATA(p) ((p.p_flags & PF_X) == 0) 956 #define IS_BSS(p) (p.p_filesz < p.p_memsz) 957 /* 958 * XXX: Assume first address is lowest 959 */ 960 if ((IS_TEXT(phdr[i]) && (flags & LOAD_TEXT)) || 961 (IS_DATA(phdr[i]) && (flags & LOAD_DATA))) { 962 963 /* Read in segment. */ 964 if (fseeko(fp, (off_t)phdr[i].p_offset, 965 SEEK_SET) == -1) { 966 free(phdr); 967 return 1; 968 } 969 if (mread(fp, phdr[i].p_paddr, phdr[i].p_filesz) != 970 phdr[i].p_filesz) { 971 free(phdr); 972 return 1; 973 } 974 975 first = 0; 976 } 977 978 if ((IS_TEXT(phdr[i]) && (flags & (LOAD_TEXT | COUNT_TEXT))) || 979 (IS_DATA(phdr[i]) && (flags & (LOAD_DATA | COUNT_TEXT)))) { 980 pos = phdr[i].p_paddr; 981 if (minp > pos) 982 minp = pos; 983 pos += phdr[i].p_filesz; 984 if (maxp < pos) 985 maxp = pos; 986 } 987 988 /* Zero out BSS. */ 989 if (IS_BSS(phdr[i]) && (flags & LOAD_BSS)) { 990 mbzero((phdr[i].p_paddr + phdr[i].p_filesz), 991 phdr[i].p_memsz - phdr[i].p_filesz); 992 } 993 if (IS_BSS(phdr[i]) && (flags & (LOAD_BSS|COUNT_BSS))) { 994 pos += phdr[i].p_memsz - phdr[i].p_filesz; 995 if (maxp < pos) 996 maxp = pos; 997 } 998 } 999 free(phdr); 1000 1001 /* 1002 * Copy the ELF and section headers. 1003 */ 1004 elfp = maxp = roundup(maxp, sizeof(Elf32_Addr)); 1005 if (flags & (LOAD_HDR | COUNT_HDR)) 1006 maxp += sizeof(Elf32_Ehdr); 1007 1008 if (flags & (LOAD_SYM | COUNT_SYM)) { 1009 if (fseeko(fp, (off_t)elf->e_shoff, SEEK_SET) == -1) { 1010 WARN(("lseek section headers")); 1011 return 1; 1012 } 1013 sz = elf->e_shnum * sizeof(Elf32_Shdr); 1014 shp = malloc(sz); 1015 1016 if (fread(shp, 1, sz, fp) != sz) { 1017 free(shp); 1018 return 1; 1019 } 1020 1021 shpp = maxp; 1022 maxp += roundup(sz, sizeof(Elf32_Addr)); 1023 1024 size_t shstrsz = shp[elf->e_shstrndx].sh_size; 1025 char *shstr = malloc(shstrsz); 1026 if (fseeko(fp, (off_t)shp[elf->e_shstrndx].sh_offset, 1027 SEEK_SET) == -1) { 1028 free(shstr); 1029 free(shp); 1030 return 1; 1031 } 1032 if (fread(shstr, 1, shstrsz, fp) != shstrsz) { 1033 free(shstr); 1034 free(shp); 1035 return 1; 1036 } 1037 1038 /* 1039 * Now load the symbol sections themselves. Make sure the 1040 * sections are aligned. Don't bother with string tables if 1041 * there are no symbol sections. 1042 */ 1043 off = roundup((sizeof(Elf32_Ehdr) + sz), sizeof(Elf32_Addr)); 1044 1045 for (havesyms = havelines = i = 0; i < elf->e_shnum; i++) 1046 if (shp[i].sh_type == SHT_SYMTAB) 1047 havesyms = 1; 1048 1049 for (first = 1, i = 0; i < elf->e_shnum; i++) { 1050 if (shp[i].sh_type == SHT_SYMTAB || 1051 shp[i].sh_type == SHT_STRTAB || 1052 !strcmp(shstr + shp[i].sh_name, ".debug_line")) { 1053 if (havesyms && (flags & LOAD_SYM)) { 1054 if (fseeko(fp, (off_t)shp[i].sh_offset, 1055 SEEK_SET) == -1) { 1056 free(shstr); 1057 free(shp); 1058 return 1; 1059 } 1060 if (mread(fp, maxp, 1061 shp[i].sh_size) != shp[i].sh_size) { 1062 free(shstr); 1063 free(shp); 1064 return 1; 1065 } 1066 } 1067 maxp += roundup(shp[i].sh_size, 1068 sizeof(Elf32_Addr)); 1069 shp[i].sh_offset = off; 1070 shp[i].sh_flags |= SHF_ALLOC; 1071 off += roundup(shp[i].sh_size, 1072 sizeof(Elf32_Addr)); 1073 first = 0; 1074 } 1075 } 1076 if (flags & LOAD_SYM) { 1077 mbcopy(shp, shpp, sz); 1078 } 1079 free(shstr); 1080 free(shp); 1081 } 1082 1083 /* 1084 * Frob the copied ELF header to give information relative 1085 * to elfp. 1086 */ 1087 if (flags & LOAD_HDR) { 1088 elf->e_phoff = 0; 1089 elf->e_shoff = sizeof(Elf32_Ehdr); 1090 elf->e_phentsize = 0; 1091 elf->e_phnum = 0; 1092 mbcopy(elf, elfp, sizeof(*elf)); 1093 } 1094 1095 marks[MARK_START] = LOADADDR(minp); 1096 marks[MARK_ENTRY] = LOADADDR(elf->e_entry); 1097 marks[MARK_NSYM] = 1; /* XXX: Kernel needs >= 0 */ 1098 marks[MARK_SYM] = LOADADDR(elfp); 1099 marks[MARK_END] = LOADADDR(maxp); 1100 1101 return 0; 1102 } 1103