📄 load.c
字号:
/* * Roadrunner/pk * Copyright (C) 1989-2001 Cornfed Systems, Inc. * * The Roadrunner/pk operating system is free software; you can * redistribute and/or modify it under the terms of the GNU General * Public License, version 2, as published by the Free Software * Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * More information about the Roadrunner/pk operating system of * which this file is a part is available on the World-Wide Web * at: http://www.cornfed.com. * */#include <errno.h>#include <fcntl.h>#include <fs.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys.h>#include <sys/ioctl.h>#include <sys/load.h>static intstart_sym_search(sections_t s, char *start_sym, char **start){ int i; for (i = 1; i < s->symtabentries; i++) if (strcmp(s->strtab + s->symtab[i].st_name, start_sym) == 0) { *start = (char *) (s->textoff + s->symtab[i].st_value - s->shdrtab[s->textndx].sh_addr);#if _DEBUG kprintf("%s %08x\n", start_sym, (u_int) * start);#endif return 1; }#if _DEBUG kprintf("start_sym_search: %s not found\n", start_sym);#endif return 0;}intload(char *path, char **prog, u_long * size, char **start){ file_t file; u_long filesize; char *filebuf; struct sections s; int i, result, undefcnt; u_long *PICPID_DELTA; if (path == NULL || prog == NULL || size == NULL || start == NULL) return EINVAL; result = file_open(path, O_RDONLY, &file); if (result < 0) {#if _DEBUG kprintf("load: could not open %s (%s)\n", path, strerror(result));#endif return result; } result = file_ioctl(file, GET_FILE_SIZE, &filesize); if (result < 0) {#if _DEBUG kprintf("load: could not get file size (%s)\n", strerror(result));#endif file_close(file); return result; } filebuf = (char *) malloc(filesize); if (filebuf == NULL) {#if _DEBUG kprintf("load: could not allocate file buffer\n");#endif file_close(file); return ENOMEM; } /* XXX Read program file into memory in its entirety */ result = file_read(file, filebuf, (int *) &filesize); if (result < 0) {#if _DEBUG kprintf("load: could not read program file (%s)\n", strerror(result));#endif free(filebuf); file_close(file); return result; } file_close(file); /* Determine program section information */ result = init_sections(filebuf, &s); /* Search for undefined symbols */ for (undefcnt = 0, i = 1; i < s.symtabentries; i++) if (s.symtab[i].st_shndx == SHN_UNDEF) { if (undefcnt++ == 0) kprintf("load: undefined symbols:"); kprintf(" %s", s.strtab + s.symtab[i].st_name); } if (undefcnt > 0) { kprintf("\n"); return ENOEXEC; } /* Determine amount of memory needed to load the program */ *size = s.shdrtab[s.textndx].sh_size; if (s.datandx1 >= 0) *size += s.shdrtab[s.datandx1].sh_size; if (s.datandx2 >= 0) *size += s.shdrtab[s.datandx2].sh_size; if (s.datandx3 >= 0) *size += s.shdrtab[s.datandx3].sh_size; if (s.datandx4 >= 0) *size += s.shdrtab[s.datandx4].sh_size; /* Allocate and zero program memory */ *prog = malloc(*size); if (*prog == NULL) {#if _DEBUG kprintf("load: could not allocate program memory\n");#endif free(filebuf); return ENOMEM; } bzero(*prog, *size); /* Load program sections into their executable locations */ load_sections(&s, filebuf, *prog); /* Find start symbol */ if (!start_sym_search(&s, STARTUP, start)) {#if _DEBUG kprintf("load: no start symbol\n");#endif free(filebuf); return ENOEXEC; } // PICPID_DELTA 程序LOAD的偏移值 PICPID_DELTA = (u_long *)(*start + 2); *PICPID_DELTA = (u_long)*prog - s.shdrtab[s.textndx].sh_addr; free(filebuf); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -