diff options
-rw-r--r-- | serverboot/elf-load.c | 152 | ||||
-rw-r--r-- | serverboot/exec.c | 73 |
2 files changed, 165 insertions, 60 deletions
diff --git a/serverboot/elf-load.c b/serverboot/elf-load.c index a30124a2..af11635e 100644 --- a/serverboot/elf-load.c +++ b/serverboot/elf-load.c @@ -1,22 +1,22 @@ /* - * Copyright (c) 1995, 1994, 1993, 1992, 1991, 1990 - * Open Software Foundation, Inc. - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies and - * that both the copyright notice and this permission notice appear in - * supporting documentation, and that the name of ("OSF") or Open Software - * Foundation not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior permission. - * - * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL OSF BE LIABLE FOR ANY - * SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE + * Copyright (c) 1995, 1994, 1993, 1992, 1991, 1990 + * Open Software Foundation, Inc. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appears in all copies and + * that both the copyright notice and this permission notice appear in + * supporting documentation, and that the name of ("OSF") or Open Software + * Foundation not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * + * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL OSF BE LIABLE FOR ANY + * SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE */ /* * OSF Research Institute MK6.1 (unencumbered) 1/31/1995 @@ -31,9 +31,7 @@ int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec, void *handle, exec_info_t *out_info) { vm_size_t actual; - Elf32_Ehdr x; - Elf32_Phdr *phdr, *ph; - vm_size_t phsize; + union { Elf32_Ehdr h; Elf64_Ehdr h64; } x; int i; int result; @@ -43,50 +41,98 @@ int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec, if (actual < sizeof(x)) return EX_NOT_EXECUTABLE; - if ((x.e_ident[EI_MAG0] != ELFMAG0) || - (x.e_ident[EI_MAG1] != ELFMAG1) || - (x.e_ident[EI_MAG2] != ELFMAG2) || - (x.e_ident[EI_MAG3] != ELFMAG3)) + if ((x.h.e_ident[EI_MAG0] != ELFMAG0) || + (x.h.e_ident[EI_MAG1] != ELFMAG1) || + (x.h.e_ident[EI_MAG2] != ELFMAG2) || + (x.h.e_ident[EI_MAG3] != ELFMAG3)) return EX_NOT_EXECUTABLE; /* Make sure the file is of the right architecture. */ #ifdef i386 - if ((x.e_ident[EI_CLASS] != ELFCLASS32) || - (x.e_ident[EI_DATA] != ELFDATA2LSB) || - (x.e_machine != EM_386)) - return EX_WRONG_ARCH; +# define MY_CLASS ELFCLASS32 +# define MY_DATA ELFDATA2LSB +# define MY_MACHINE EM_386 +#elif defined __alpha__ +# define MY_CLASS ELFCLASS64 +# define MY_DATA ELFDATA2LSB +# define MY_MACHINE EM_ALPHA #else #error Not ported to this architecture! #endif - /* XXX others */ - out_info->entry = (vm_offset_t) x.e_entry; + if ((x.h.e_ident[EI_CLASS] != ELFCLASS64) || + (x.h.e_ident[EI_DATA] != ELFDATA2LSB) || + (x.h.e_machine != EM_ALPHA)) + return EX_WRONG_ARCH; - phsize = x.e_phnum * x.e_phentsize; - phdr = (Elf32_Phdr *)alloca(phsize); + if (MY_CLASS == ELFCLASS64) + { + Elf64_Phdr *phdr, *ph; + vm_size_t phsize; - result = (*read)(handle, x.e_phoff, phdr, phsize, &actual); - if (result) - return result; - if (actual < phsize) - return EX_CORRUPT; + /* XXX others */ + out_info->entry = (vm_offset_t) x.h64.e_entry; + out_info->init_dp = 0; /* ? */ - for (i = 0; i < x.e_phnum; i++) - { - ph = (Elf32_Phdr *)((vm_offset_t)phdr + i * x.e_phentsize); + phsize = x.h64.e_phnum * x.h64.e_phentsize; + phdr = (Elf64_Phdr *)alloca(phsize); + + result = (*read)(handle, x.h64.e_phoff, phdr, phsize, &actual); + if (result) + return result; + if (actual < phsize) + return EX_CORRUPT; + + for (i = 0; i < x.h64.e_phnum; i++) + { + ph = (Elf64_Phdr *)((vm_offset_t)phdr + i * x.h64.e_phentsize); if (ph->p_type == PT_LOAD) - { - exec_sectype_t type = EXEC_SECTYPE_ALLOC | - EXEC_SECTYPE_LOAD; - if (ph->p_flags & PF_R) type |= EXEC_SECTYPE_READ; - if (ph->p_flags & PF_W) type |= EXEC_SECTYPE_WRITE; - if (ph->p_flags & PF_X) type |= EXEC_SECTYPE_EXECUTE; - result = (*read_exec)(handle, - ph->p_offset, ph->p_filesz, - ph->p_vaddr, ph->p_memsz, type); - } - } + { + exec_sectype_t type = EXEC_SECTYPE_ALLOC | + EXEC_SECTYPE_LOAD; + if (ph->p_flags & PF_R) type |= EXEC_SECTYPE_READ; + if (ph->p_flags & PF_W) type |= EXEC_SECTYPE_WRITE; + if (ph->p_flags & PF_X) type |= EXEC_SECTYPE_EXECUTE; + result = (*read_exec)(handle, + ph->p_offset, ph->p_filesz, + ph->p_vaddr, ph->p_memsz, type); + } + } + } + else + { + Elf32_Phdr *phdr, *ph; + vm_size_t phsize; + + /* XXX others */ + out_info->entry = (vm_offset_t) x.h.e_entry; + out_info->init_dp = 0; /* ? */ + + phsize = x.h.e_phnum * x.h.e_phentsize; + phdr = (Elf32_Phdr *)alloca(phsize); + + result = (*read)(handle, x.h.e_phoff, phdr, phsize, &actual); + if (result) + return result; + if (actual < phsize) + return EX_CORRUPT; + + for (i = 0; i < x.h.e_phnum; i++) + { + ph = (Elf32_Phdr *)((vm_offset_t)phdr + i * x.h.e_phentsize); + if (ph->p_type == PT_LOAD) + { + exec_sectype_t type = EXEC_SECTYPE_ALLOC | + EXEC_SECTYPE_LOAD; + if (ph->p_flags & PF_R) type |= EXEC_SECTYPE_READ; + if (ph->p_flags & PF_W) type |= EXEC_SECTYPE_WRITE; + if (ph->p_flags & PF_X) type |= EXEC_SECTYPE_EXECUTE; + result = (*read_exec)(handle, + ph->p_offset, ph->p_filesz, + ph->p_vaddr, ph->p_memsz, type); + } + } + } return 0; } - diff --git a/serverboot/exec.c b/serverboot/exec.c index a0773f4c..a487fb5d 100644 --- a/serverboot/exec.c +++ b/serverboot/exec.c @@ -1,25 +1,25 @@ -/* +/* * Mach Operating System * Copyright (c) 1993-1989 Carnegie Mellon University * All Rights Reserved. - * + * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. - * + * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * + * * Carnegie Mellon requests users of this software to return to - * + * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 - * + * * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ @@ -29,11 +29,14 @@ #include <mach.h> #include <mach/machine/vm_param.h> -#include <mach/machine/eflags.h> #include "mach-exec.h" #include <file_io.h> +#ifdef i386 + +#include <mach/machine/eflags.h> + /* * Machine-dependent portions of execve() for the i386. */ @@ -86,3 +89,59 @@ char *set_regs( return (char *)regs.uesp; } +#elif defined __alpha__ + + +/* + * Object: + * set_regs EXPORTED function + * + * Initialize enough state for a thread to run, including + * stack memory and stack pointer, and program counter. + * + */ +#define STACK_SIZE (vm_size_t)(128*1024) + +char *set_regs( + mach_port_t user_task, + mach_port_t user_thread, + struct exec_info *info, + int arg_size) +{ + vm_offset_t stack_start; + vm_offset_t stack_end; + struct alpha_thread_state regs; + + natural_t reg_size; + + /* + * Allocate stack. + */ + stack_end = VM_MAX_ADDRESS; + stack_start = stack_end - STACK_SIZE; + (void)vm_allocate(user_task, + &stack_start, + (vm_size_t)(STACK_SIZE), + FALSE); + + reg_size = ALPHA_THREAD_STATE_COUNT; + (void)thread_get_state(user_thread, + ALPHA_THREAD_STATE, + (thread_state_t)®s, + ®_size); + + regs.pc = info->entry; + regs.r29 = info->init_dp; + regs.r30 = (integer_t)((stack_end - arg_size) & ~(sizeof(integer_t)-1)); + + (void)thread_set_state(user_thread, + ALPHA_THREAD_STATE, + (thread_state_t)®s, + reg_size); + + return (char *)regs.r30; +} + +#else +# error "Not ported to this architecture!" +#endif |