elf.c revision 76d05dc695b06c4e987bb8078f78032441e1430c
176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* ----------------------------------------------------------------------- * 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Permission is hereby granted, free of charge, to any person 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * obtaining a copy of this software and associated documentation 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * files (the "Software"), to deal in the Software without 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * restriction, including without limitation the rights to use, 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * copy, modify, merge, publish, distribute, sublicense, and/or 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * sell copies of the Software, and to permit persons to whom 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * the Software is furnished to do so, subject to the following 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * conditions: 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * The above copyright notice and this permission notice shall 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * be included in all copies or substantial portions of the Software. 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * OTHER DEALINGS IN THE SOFTWARE. 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * ----------------------------------------------------------------------- */ 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * elf.c 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Module to load a protected-mode ELF kernel 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdio.h> 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdlib.h> 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <inttypes.h> 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h> 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <fcntl.h> 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <unistd.h> 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <errno.h> 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <minmax.h> 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <sys/stat.h> 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <elf.h> 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <console.h> 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <dprintf.h> 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <syslinux/loadfile.h> 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <syslinux/movebits.h> 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <syslinux/bootpm.h> 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* If we don't have this much memory for the stack, signal failure */ 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define MIN_STACK 512 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void error(const char *msg) 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fputs(msg, stderr); 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint boot_elf(void *ptr, size_t len, char **argv) 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char *cptr = ptr; 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Elf32_Ehdr *eh = ptr; 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman Elf32_Phdr *ph; 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int i; 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct syslinux_movelist *ml = NULL; 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct syslinux_memmap *mmap = NULL, *amap = NULL; 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct syslinux_pm_regs regs; 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int argc; 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addr_t argsize; 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char **argp; 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addr_t lstart, llen; 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char *stack_frame = NULL; 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addr_t stack_frame_size; 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addr_t stack_pointer; 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman uint32_t *spp; 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char *sfp; 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addr_t sfa; 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset(®s, 0, sizeof regs); 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Note: mmap is the memory map (containing free and zeroed regions) 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * needed by syslinux_shuffle_boot_pm(); amap is a map where we keep 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * track ourselves which target memory ranges have already been 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * allocated. 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (len < sizeof(Elf32_Ehdr)) 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Must be ELF, 32-bit, littleendian, version 1 */ 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (memcmp(eh->e_ident, "\x7f" "ELF\1\1\1", 6)) 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Is this a worthwhile test? In particular x86-64 normally 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman would imply ELF64 support, which we could do as long as 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman the addresses are 32-bit addresses, and entry is 32 bits. 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 64-bit addresses would take a lot more work. */ 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (eh->e_machine != EM_386 && eh->e_machine != EM_486 && 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman eh->e_machine != EM_X86_64) 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (eh->e_version != EV_CURRENT) 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (eh->e_ehsize < sizeof(Elf32_Ehdr) || eh->e_ehsize >= len) 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (eh->e_phentsize < sizeof(Elf32_Phdr)) 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!eh->e_phnum) 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (eh->e_phoff + eh->e_phentsize * eh->e_phnum > len) 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman mmap = syslinux_memory_map(); 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman amap = syslinux_dup_memmap(mmap); 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!mmap || !amap) 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dprintf("Initial memory map:\n"); 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman syslinux_dump_memmap(mmap); 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ph = (Elf32_Phdr *) (cptr + eh->e_phoff); 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (i = 0; i < eh->e_phnum; i++) { 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ph->p_type == PT_LOAD || ph->p_type == PT_PHDR) { 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* This loads at p_paddr, which is arguably the correct semantics. 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman The SysV spec says that SysV loads at p_vaddr (and thus Linux does, 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman too); that is, however, a major brainfuckage in the spec. */ 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addr_t addr = ph->p_paddr; 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addr_t msize = ph->p_memsz; 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addr_t dsize = min(msize, ph->p_filesz); 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dprintf("Segment at 0x%08x data 0x%08x len 0x%08x\n", 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addr, dsize, msize); 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (syslinux_memmap_type(amap, addr, msize) != SMT_FREE) { 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf("Memory segment at 0x%08x (len 0x%08x) is unavailable\n", 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman addr, msize); 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; /* Memory region unavailable */ 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Mark this region as allocated in the available map */ 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (syslinux_add_memmap(&amap, addr, dsize, SMT_ALLOC)) 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (ph->p_filesz) { 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Data present region. Create a move entry for it. */ 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (syslinux_add_movelist 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (&ml, addr, (addr_t) cptr + ph->p_offset, dsize)) 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (msize > dsize) { 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Zero-filled region. Mark as a zero region in the memory map. */ 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (syslinux_add_memmap 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman (&mmap, addr + dsize, msize - dsize, SMT_ZERO)) 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } else { 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Ignore this program header */ 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ph = (Elf32_Phdr *) ((char *)ph + eh->e_phentsize); 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Create the invocation record (initial stack frame) */ 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman argsize = argc = 0; 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (argp = argv; *argp; argp++) { 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dprintf("argv[%2d] = \"%s\"\n", argc, *argp); 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman argc++; 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman argsize += strlen(*argp) + 1; 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* We need the argument strings, argument pointers, 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman argc, plus four zero-word terminators. */ 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman stack_frame_size = argsize + argc * sizeof(char *) + 5 * sizeof(long); 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman stack_frame_size = (stack_frame_size + 15) & ~15; 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman stack_frame = calloc(stack_frame_size, 1); 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (!stack_frame) 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dprintf("Right before syslinux_memmap_largest()...\n"); 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman syslinux_dump_memmap(amap); 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (syslinux_memmap_largest(amap, SMT_FREE, &lstart, &llen)) 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; /* NO free memory?! */ 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (llen < stack_frame_size + MIN_STACK + 16) 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; /* Insufficient memory */ 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Initial stack pointer address */ 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman stack_pointer = (lstart + llen - stack_frame_size) & ~15; 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dprintf("Stack frame at 0x%08x len 0x%08x\n", 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman stack_pointer, stack_frame_size); 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Create the stack frame. sfp is the pointer in current memory for 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman the next argument string, sfa is the address in its final resting place. 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman spp is the pointer into the argument array in current memory. */ 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman spp = (uint32_t *) stack_frame; 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sfp = stack_frame + argc * sizeof(char *) + 5 * sizeof(long); 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sfa = stack_pointer + argc * sizeof(char *) + 5 * sizeof(long); 20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *spp++ = argc; 20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman for (argp = argv; *argp; argp++) { 21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int bytes = strlen(*argp) + 1; /* Including final null */ 21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman *spp++ = sfa; 21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memcpy(sfp, *argp, bytes); 21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sfp += bytes; 21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman sfa += bytes; 21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Zero fields are aready taken care of by calloc() */ 21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* ... and we'll want to move it into the right place... */ 21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if DEBUG 22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (syslinux_memmap_type(amap, stack_pointer, stack_frame_size) 22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman != SMT_FREE) { 22276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dprintf("Stack frame area not free (how did that happen?)!\n"); 22376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; /* Memory region unavailable */ 22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 22776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (syslinux_add_memmap(&amap, stack_pointer, stack_frame_size, SMT_ALLOC)) 22876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 22976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (syslinux_add_movelist(&ml, stack_pointer, (addr_t) stack_frame, 23176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman stack_frame_size)) 23276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto bail; 23376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman memset(®s, 0, sizeof regs); 23576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman regs.eip = eh->e_entry; 23676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman regs.esp = stack_pointer; 23776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 23876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dprintf("Final memory map:\n"); 23976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman syslinux_dump_memmap(mmap); 24076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dprintf("Final available map:\n"); 24276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman syslinux_dump_memmap(amap); 24376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman dprintf("Movelist:\n"); 24576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman syslinux_dump_movelist(ml); 24676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 24776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* This should not return... */ 24876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman fputs("Booting...\n", stdout); 24976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman syslinux_shuffle_boot_pm(ml, mmap, 0, ®s); 25076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanbail: 25276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (stack_frame) 25376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman free(stack_frame); 25476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman syslinux_free_memmap(amap); 25576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman syslinux_free_memmap(mmap); 25676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman syslinux_free_movelist(ml); 25776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 25876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return -1; 25976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 26076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanint main(int argc, char *argv[]) 26276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{ 26376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman void *data; 26476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size_t data_len; 26576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 26676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (argc < 2) { 26776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman error("Usage: elf.c32 elf_file arguments...\n"); 26876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 26976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 27076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if (zloadfile(argv[1], &data, &data_len)) { 27276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman error("Unable to load file\n"); 27376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 27476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 27576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 27676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman boot_elf(data, data_len, &argv[1]); 27776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman error("Invalid ELF file or insufficient memory\n"); 27876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 1; 27976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 280