diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2012-07-01 02:12:43 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2012-07-01 02:12:43 +0000 |
commit | 13ea39a34766fcbecd96ab94bcdf798b08e9bb60 (patch) | |
tree | 1e1463b03838a6f36868a4dafc7e652358a51857 /serverboot/load.c | |
parent | 1f8d504f631531c199d7c6154a0dc442d80ea4a7 (diff) | |
parent | 7e15f3d69a83a34ac62cbbee944a0bfbfa92724e (diff) | |
download | hurd-13ea39a34766fcbecd96ab94bcdf798b08e9bb60.tar.gz hurd-13ea39a34766fcbecd96ab94bcdf798b08e9bb60.tar.bz2 hurd-13ea39a34766fcbecd96ab94bcdf798b08e9bb60.zip |
Merge branch 'master' into xkb
Conflicts:
config.make.in
configure.in
Diffstat (limited to 'serverboot/load.c')
-rw-r--r-- | serverboot/load.c | 555 |
1 files changed, 0 insertions, 555 deletions
diff --git a/serverboot/load.c b/serverboot/load.c deleted file mode 100644 index aa481943..00000000 --- a/serverboot/load.c +++ /dev/null @@ -1,555 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988 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. - */ - -#include <stddef.h> -#include <assert.h> -#include <mach/mach_interface.h> -#include "mach-exec.h" -#include "../boot/boot_script.h" - -#include <file_io.h> - - -boolean_t load_protect_text = TRUE; - - -struct stuff -{ - struct file *fp; - task_t user_task; - - /* uncompressed image */ - vm_offset_t image_addr; - vm_size_t image_size; - - vm_offset_t aout_symtab_ofs; - vm_size_t aout_symtab_size; - vm_offset_t aout_strtab_ofs; - vm_size_t aout_strtab_size; -}; - -char *set_regs( - mach_port_t user_task, - mach_port_t user_thread, - struct exec_info *info, - int arg_size); - -static void read_symtab_from_file( - struct file *fp, - mach_port_t host_port, - task_t task, - char * symtab_name, - struct stuff *st); - -/* Callback functions for reading the executable file. */ -static int prog_read(void *handle, vm_offset_t file_ofs, void *buf, vm_size_t size, - vm_size_t *out_actual) -{ - struct stuff *st = handle; - vm_size_t resid; - int result; - - result = read_file(st->fp, file_ofs, buf, size, &resid); - if (result) - return result; - *out_actual = size - resid; - return 0; -} - -static int prog_read_exec(void *handle, vm_offset_t file_ofs, vm_size_t file_size, - vm_offset_t mem_addr, vm_size_t mem_size, - exec_sectype_t sec_type) -{ - struct stuff *st = handle; - vm_offset_t page_start = trunc_page(mem_addr); - vm_offset_t page_end = round_page(mem_addr + mem_size); - vm_prot_t mem_prot = sec_type & EXEC_SECTYPE_PROT_MASK; - vm_offset_t area_start; - int result; - - if (sec_type & EXEC_SECTYPE_AOUT_SYMTAB) - { - st->aout_symtab_ofs = file_ofs; - st->aout_symtab_size = file_size; - } - if (sec_type & EXEC_SECTYPE_AOUT_STRTAB) - { - st->aout_strtab_ofs = file_ofs; - st->aout_strtab_size = file_size; - } - - if (!(sec_type & EXEC_SECTYPE_ALLOC)) - return 0; - - assert(mem_size > 0); - assert(mem_size > file_size); - - /* - printf("section %08x-%08x-%08x prot %08x (%08x-%08x)\n", - mem_addr, mem_addr+file_size, mem_addr+mem_size, mem_prot, page_start, page_end); - */ - - result = vm_allocate(mach_task_self(), &area_start, page_end - page_start, TRUE); - if (result) return (result); - - if (file_size > 0) - { - vm_size_t resid; - - result = read_file(st->fp, file_ofs, area_start + (mem_addr - page_start), - file_size, &resid); - if (result) return result; - if (resid) return EX_CORRUPT; - } - - if (mem_size > file_size) - { - bzero((void*)area_start + (mem_addr + file_size - page_start), - mem_size - file_size); - } - - result = vm_allocate(st->user_task, &page_start, page_end - page_start, FALSE); - if (result) return (result); - assert(page_start == trunc_page(mem_addr)); - - result = vm_write(st->user_task, page_start, area_start, page_end - page_start); - if (result) return (result); - - result = vm_deallocate(mach_task_self(), area_start, page_end - page_start); - if (result) return (result); - - /* - * Protect the segment. - */ - if (load_protect_text && (mem_prot != VM_PROT_ALL)) { - result = vm_protect(st->user_task, page_start, page_end - page_start, - FALSE, mem_prot); - if (result) return (result); - } - - return 0; -} - -/* Callback functions for reading the uncompressed image. */ -static int image_read(void *handle, vm_offset_t file_ofs, void *buf, - vm_size_t size, vm_size_t *out_actual) -{ - struct stuff *st = handle; - bcopy(st->image_addr + file_ofs, buf, size); - *out_actual = size; - return 0; -} - -static int image_read_exec(void *handle, vm_offset_t file_ofs, - vm_size_t file_size, vm_offset_t mem_addr, - vm_size_t mem_size, exec_sectype_t sec_type) -{ - struct stuff *st = handle; - vm_offset_t page_start = trunc_page(mem_addr); - vm_offset_t page_end = round_page(mem_addr + mem_size); - vm_prot_t mem_prot = sec_type & EXEC_SECTYPE_PROT_MASK; - vm_offset_t area_start; - int result; - - if (sec_type & EXEC_SECTYPE_AOUT_SYMTAB) - { - st->aout_symtab_ofs = file_ofs; - st->aout_symtab_size = file_size; - } - if (sec_type & EXEC_SECTYPE_AOUT_STRTAB) - { - st->aout_strtab_ofs = file_ofs; - st->aout_strtab_size = file_size; - } - - if (!(sec_type & EXEC_SECTYPE_ALLOC)) - return 0; - - assert(mem_size > 0); - assert(mem_size > file_size); - - /* - printf("section %08x-%08x-%08x prot %08x (%08x-%08x)\n", - mem_addr, mem_addr+file_size, mem_addr+mem_size, mem_prot, page_start, page_end); - */ - - result = vm_allocate(mach_task_self(), &area_start, page_end - page_start, TRUE); - if (result) return (result); - - if (file_size > 0) - { - bcopy(st->image_addr + file_ofs, area_start + (mem_addr - page_start), - file_size); - } - - if (mem_size > file_size) - { - bzero((void*)area_start + (mem_addr + file_size - page_start), - mem_size - file_size); - } - - result = vm_allocate(st->user_task, &page_start, page_end - page_start, FALSE); - if (result) return (result); - assert(page_start == trunc_page(mem_addr)); - - result = vm_write(st->user_task, page_start, area_start, page_end - page_start); - if (result) return (result); - - result = vm_deallocate(mach_task_self(), area_start, page_end - page_start); - if (result) return (result); - - /* - * Protect the segment. - */ - if (load_protect_text && (mem_prot != VM_PROT_ALL)) { - result = vm_protect(st->user_task, page_start, page_end - page_start, - FALSE, mem_prot); - if (result) return (result); - } - - return 0; -} - -mach_port_t boot_script_read_file (const char *file) -{ return MACH_PORT_NULL; } /* XXX */ - -int -boot_script_exec_cmd (void *hook, - task_t user_task, - char *file_name, - int arg_count, char **argv, - char *argstrings, int argslen) -{ - extern mach_port_t bootstrap_master_device_port, bootstrap_master_host_port; - extern char *root_name; - extern char **environ; - int envc, env_len; - - int arg_len = argslen; - char *arg_pos; - - kern_return_t result; - thread_t user_thread; - struct file file; - char namebuf[MAXPATHLEN+1]; - - struct stuff st; - struct exec_info info; - - extern char * strbuild(); - - if (strcmp (file_name, "/dev/")) - (void) strbuild(namebuf, "/dev/", root_name, "/", file_name, - (char *)0); - else - strcpy (namebuf, file_name); - - /* - * Open the file - */ - bzero((char *)&file, sizeof(file)); - - result = open_file(bootstrap_master_device_port, namebuf, &file); - if (result != 0) { - panic ("%s: %s", namebuf, strerror (result)); - } - - env_len = 0; - for (envc = 0; environ[envc]; ++envc) - env_len += strlen (environ[envc]) + 1; - - /* - * Add space for: - * arg_count - * pointers to arguments - * trailing 0 pointer - * environment variables - * trailing 0 pointer - * and align to integer boundary - */ - arg_len += sizeof(integer_t) + (envc + 2 + arg_count) * sizeof(char *); - arg_len += env_len; - arg_len = (arg_len + (sizeof(integer_t) - 1)) & ~(sizeof(integer_t)-1); - - /* - * We refrain from checking IEXEC bits to make - * things a little easier when things went bad. - * Say you have ftp(1) but chmod(1) is gone. - */ - if (!file_is_regular(&file)) - panic("boot_load_program: %s is not a regular file", namebuf); - - /* - * Load the executable file. - */ - st.fp = &file; - st.user_task = user_task; - st.aout_symtab_size = 0; - st.aout_strtab_size = 0; - result = exec_load(prog_read, prog_read_exec, &st, &info); -#ifdef GZIP - if (result) - { - /* - * It might be gzip file. - */ - int err; - extern int serverboot_gunzip(struct file *, - vm_offset_t *, size_t *); - - err = serverboot_gunzip(st.fp, - &(st.image_addr), - &(st.image_size)); - if (!err) - { - result = exec_load(image_read, - image_read_exec, - &st, - &info); - vm_deallocate(mach_task_self(), - st.image_addr, - st.image_size); - } - } -#endif /* GZIP */ -#ifdef BZIP2 - if (result) - { - /* - * It might be bzip2 file. - */ - int err; - extern int serverboot_bunzip2(struct file *, - vm_offset_t *, size_t *); - - err = serverboot_bunzip2(st.fp, - &(st.image_addr), - &(st.image_size)); - if (!err) - { - result = exec_load(image_read, - image_read_exec, - &st, - &info); - vm_deallocate(mach_task_self(), - st.image_addr, - st.image_size); - } - } -#endif /* BZIP2 */ - if (result) - panic ("cannot load %s: %s", namebuf, strerror (result)); -#if 0 - printf("(serverboot): loaded %s; entrypoint %08x\n", namebuf, info.entry); -#endif - - /* - * Set up the stack and user registers. - */ - result = thread_create (user_task, &user_thread); - if (result) - panic ("can't create user thread for %s: %s", namebuf, - strerror (result)); - arg_pos = set_regs(user_task, user_thread, &info, arg_len); - - /* - * Read symbols from the executable file. - */ -#if 0 - printf("(serverboot): loading symbols from %s\n", namebuf); - read_symtab_from_file(&file, bootstrap_master_host_port, user_task, namebuf, &st); -#endif - - /* - * Copy out the arguments. - */ - { - vm_offset_t u_arg_start; - /* user start of argument list block */ - vm_offset_t k_arg_start; - /* kernel start of argument list block */ - vm_offset_t u_arg_page_start; - /* user start of args, page-aligned */ - vm_size_t arg_page_size; - /* page_aligned size of args */ - vm_offset_t k_arg_page_start; - /* kernel start of args, page-aligned */ - - register - char ** k_ap; /* kernel arglist address */ - char * u_cp; /* user argument string address */ - register - char * k_cp; /* kernel argument string address */ - register - int i; - - /* - * Get address of argument list in user space - */ - u_arg_start = (vm_offset_t)arg_pos; - - /* - * Round to page boundaries, and allocate kernel copy - */ - u_arg_page_start = trunc_page(u_arg_start); - arg_page_size = (vm_size_t)(round_page(u_arg_start + arg_len) - - u_arg_page_start); - - result = vm_allocate(mach_task_self(), - &k_arg_page_start, - (vm_size_t)arg_page_size, - TRUE); - if (result) - panic("boot_load_program: arg size"); - - /* - * Set up addresses corresponding to user pointers - * in the kernel block - */ - k_arg_start = k_arg_page_start + (u_arg_start - u_arg_page_start); - - k_ap = (char **)k_arg_start; - - /* - * Start the strings after the arg-count and pointers - */ - u_cp = (char *)u_arg_start + arg_count * sizeof(char *) - + envc * sizeof(char *) - + 2 * sizeof(char *) - + sizeof(integer_t); - k_cp = (char *)k_arg_start + arg_count * sizeof(char *) - + envc * sizeof(char *) - + 2 * sizeof(char *) - + sizeof(integer_t); - - /* - * first the argument count - */ - *k_ap++ = (char *)(intptr_t)arg_count; - - /* - * Then the strings and string pointers for each argument - */ - for (i = 0; i < arg_count; i++) - *k_ap++ = argv[i] - argstrings + u_cp; - *k_ap++ = (char *)0; - bcopy (argstrings, k_cp, argslen); - k_cp += argslen; - u_cp += argslen; - - for (i = 0; i < envc; i++) - *k_ap++ = environ[i] - environ[0] + u_cp; - *k_ap = (char *)0; - bcopy (environ[0], k_cp, env_len); - - /* - * Now write all of this to user space. - */ - (void) vm_write(user_task, - u_arg_page_start, - k_arg_page_start, - arg_page_size); - - (void) vm_deallocate(mach_task_self(), - k_arg_page_start, - arg_page_size); - } - - /* - * Close the file. - */ - close_file(&file); - - /* Resume the thread. */ - thread_resume (user_thread); - mach_port_deallocate (mach_task_self (), user_thread); - - return (0); -} - -/* - * Load symbols from file into kernel debugger. - */ -static void read_symtab_from_file( - struct file *fp, - mach_port_t host_port, - task_t task, - char * symtab_name, - struct stuff *st) -{ - vm_size_t resid; - kern_return_t result; - vm_size_t table_size; - vm_offset_t symtab; - -#if 0 - - if (!st->aout_symtab_size || !st->aout_strtab_size) - return; - - /* - * Allocate space for the symbol table. - */ - table_size = sizeof(vm_size_t) - + st->aout_symtab_size - + st->aout_strtab_size; - result= vm_allocate(mach_task_self(), - &symtab, - table_size, - TRUE); - if (result) { - printf("[ error %d allocating space for %s symbol table ]\n", - result, symtab_name); - return; - } - - /* - * Set the symbol table length word, - * then read in the symbol table and string table. - */ - *(vm_size_t*)symtab = st->aout_symtab_size; - result = read_file(fp, st->aout_symtab_ofs, - symtab + sizeof(vm_size_t), - st->aout_symtab_size + st->aout_strtab_size, - &resid); - if (result || resid) { - printf("[ no valid symbol table present for %s ]\n", - symtab_name); - } - else { - /* - * Load the symbols into the kernel. - */ - result = host_load_symbol_table( - host_port, - task, - symtab_name, - symtab, - table_size); - } - (void) vm_deallocate(mach_task_self(), symtab, table_size); -#endif -} |