diff options
94 files changed, 1871 insertions, 2150 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 901c54f..ef3e292 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,9 @@ # xargs -n1 | sort | uniq -d; # done +# 20180212: Obsolete forth files +OLD_FILES+=boot/efi.4th +OLD_FILES+=boot/pcibios.4th # 20180212: Remove libstand OLD_FILES+=usr/lib/libstand.a OLD_FILES+=usr/lib/libstand_p.a diff --git a/stand/arm/uboot/Makefile b/stand/arm/uboot/Makefile index 8c4023a..0c906c9 100644 --- a/stand/arm/uboot/Makefile +++ b/stand/arm/uboot/Makefile @@ -41,8 +41,8 @@ LDFLAGS+= -Wl,-znotext CFLAGS+= -fPIC -DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} -LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} +DPADD= ${LDR_INTERP} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} +LDADD= ${LDR_INTERP} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} OBJS+= ${SRCS:N*.h:R:S/$/.o/g} diff --git a/stand/arm/uboot/ldscript.arm b/stand/arm/uboot/ldscript.arm index 8eb604c..b768e00 100644 --- a/stand/arm/uboot/ldscript.arm +++ b/stand/arm/uboot/ldscript.arm @@ -32,6 +32,11 @@ SECTIONS .rela.got : { *(.rela.got) } .rela.got1 : { *(.rela.got1) } .rela.got2 : { *(.rela.got2) } + .dynamic : { *(.dynamic) } + PROVIDE (_GOT_START_ = .); + .got : { *(.got) } + .got.plt : { *(.got.plt) } + PROVIDE (_GOT_END_ = .); .rela.ctors : { *(.rela.ctors) } .rela.dtors : { *(.rela.dtors) } .rela.init : { *(.rela.init) } @@ -58,7 +63,6 @@ SECTIONS } .data1 : { *(.data1) } .got1 : { *(.got1) } - .dynamic : { *(.dynamic) } /* Put .ctors and .dtors next to the .got2 section, so that the pointers get relocated with -mrelocatable. Also put in the .fixup pointers. The current compiler no longer needs this, but keep it around for 2.7.2 */ @@ -74,10 +78,6 @@ SECTIONS .fixup : { *(.fixup) } PROVIDE (_FIXUP_END_ = .); PROVIDE (_GOT2_END_ = .); - PROVIDE (_GOT_START_ = .); - .got : { *(.got) } - .got.plt : { *(.got.plt) } - PROVIDE (_GOT_END_ = .); /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */ diff --git a/stand/common/boot.c b/stand/common/boot.c index 5ee9521..2084122 100644 --- a/stand/common/boot.c +++ b/stand/common/boot.c @@ -52,60 +52,60 @@ COMMAND_SET(boot, "boot", "boot a file or loaded kernel", command_boot); static int command_boot(int argc, char *argv[]) { - struct preloaded_file *fp; - - /* - * See if the user has specified an explicit kernel to boot. - */ - if ((argc > 1) && (argv[1][0] != '-')) { - - /* XXX maybe we should discard everything and start again? */ - if (file_findfile(NULL, NULL) != NULL) { - snprintf(command_errbuf, sizeof(command_errbuf), - "can't boot '%s', kernel module already loaded", argv[1]); - return(CMD_ERROR); + struct preloaded_file *fp; + + /* + * See if the user has specified an explicit kernel to boot. + */ + if ((argc > 1) && (argv[1][0] != '-')) { + + /* XXX maybe we should discard everything and start again? */ + if (file_findfile(NULL, NULL) != NULL) { + snprintf(command_errbuf, sizeof(command_errbuf), + "can't boot '%s', kernel module already loaded", argv[1]); + return(CMD_ERROR); + } + + /* find/load the kernel module */ + if (mod_loadkld(argv[1], argc - 2, argv + 2) != 0) + return(CMD_ERROR); + /* we have consumed all arguments */ + argc = 1; } - /* find/load the kernel module */ - if (mod_loadkld(argv[1], argc - 2, argv + 2) != 0) - return(CMD_ERROR); - /* we have consumed all arguments */ - argc = 1; - } - - /* - * See if there is a kernel module already loaded - */ - if (file_findfile(NULL, NULL) == NULL) - if (loadakernel(0, argc - 1, argv + 1)) - /* we have consumed all arguments */ - argc = 1; - - /* - * Loaded anything yet? - */ - if ((fp = file_findfile(NULL, NULL)) == NULL) { - command_errmsg = "no bootable kernel"; - return(CMD_ERROR); - } - - /* - * If we were given arguments, discard any previous. - * XXX should we merge arguments? Hard to DWIM. - */ - if (argc > 1) { - if (fp->f_args != NULL) - free(fp->f_args); - fp->f_args = unargv(argc - 1, argv + 1); - } - - /* Hook for platform-specific autoloading of modules */ - if (archsw.arch_autoload() != 0) - return(CMD_ERROR); + /* + * See if there is a kernel module already loaded + */ + if (file_findfile(NULL, NULL) == NULL) + if (loadakernel(0, argc - 1, argv + 1)) + /* we have consumed all arguments */ + argc = 1; + + /* + * Loaded anything yet? + */ + if ((fp = file_findfile(NULL, NULL)) == NULL) { + command_errmsg = "no bootable kernel"; + return(CMD_ERROR); + } + + /* + * If we were given arguments, discard any previous. + * XXX should we merge arguments? Hard to DWIM. + */ + if (argc > 1) { + if (fp->f_args != NULL) + free(fp->f_args); + fp->f_args = unargv(argc - 1, argv + 1); + } - /* Call the exec handler from the loader matching the kernel */ - file_formats[fp->f_loader]->l_exec(fp); - return(CMD_ERROR); + /* Hook for platform-specific autoloading of modules */ + if (archsw.arch_autoload() != 0) + return(CMD_ERROR); + + /* Call the exec handler from the loader matching the kernel */ + file_formats[fp->f_loader]->l_exec(fp); + return(CMD_ERROR); } @@ -118,29 +118,29 @@ COMMAND_SET(autoboot, "autoboot", "boot automatically after a delay", command_au static int command_autoboot(int argc, char *argv[]) { - int howlong; - char *cp, *prompt; - - prompt = NULL; - howlong = -1; - switch(argc) { - case 3: - prompt = argv[2]; - /* FALLTHROUGH */ - case 2: - howlong = strtol(argv[1], &cp, 0); - if (*cp != 0) { - snprintf(command_errbuf, sizeof(command_errbuf), - "bad delay '%s'", argv[1]); - return(CMD_ERROR); + int howlong; + char *cp, *prompt; + + prompt = NULL; + howlong = -1; + switch(argc) { + case 3: + prompt = argv[2]; + /* FALLTHROUGH */ + case 2: + howlong = strtol(argv[1], &cp, 0); + if (*cp != 0) { + snprintf(command_errbuf, sizeof(command_errbuf), + "bad delay '%s'", argv[1]); + return(CMD_ERROR); + } + /* FALLTHROUGH */ + case 1: + return(autoboot(howlong, prompt)); } - /* FALLTHROUGH */ - case 1: - return(autoboot(howlong, prompt)); - } - command_errmsg = "too many arguments"; - return(CMD_ERROR); + command_errmsg = "too many arguments"; + return(CMD_ERROR); } /* @@ -150,103 +150,103 @@ command_autoboot(int argc, char *argv[]) void autoboot_maybe() { - char *cp; + char *cp; - cp = getenv("autoboot_delay"); - if ((autoboot_tried == 0) && ((cp == NULL) || strcasecmp(cp, "NO"))) - autoboot(-1, NULL); /* try to boot automatically */ + cp = getenv("autoboot_delay"); + if ((autoboot_tried == 0) && ((cp == NULL) || strcasecmp(cp, "NO"))) + autoboot(-1, NULL); /* try to boot automatically */ } int autoboot(int timeout, char *prompt) { - time_t when, otime, ntime; - int c, yes; - char *argv[2], *cp, *ep; - char *kernelname; + time_t when, otime, ntime; + int c, yes; + char *argv[2], *cp, *ep; + char *kernelname; #ifdef BOOT_PROMPT_123 - const char *seq = "123", *p = seq; + const char *seq = "123", *p = seq; #endif - autoboot_tried = 1; + autoboot_tried = 1; - if (timeout == -1) { - timeout = 10; - /* try to get a delay from the environment */ - if ((cp = getenv("autoboot_delay"))) { - timeout = strtol(cp, &ep, 0); - if (cp == ep) - timeout = 10; /* Unparseable? Set default! */ + if (timeout == -1) { + timeout = 10; + /* try to get a delay from the environment */ + if ((cp = getenv("autoboot_delay"))) { + timeout = strtol(cp, &ep, 0); + if (cp == ep) + timeout = 10; /* Unparseable? Set default! */ + } } - } - kernelname = getenv("kernelname"); - if (kernelname == NULL) { - argv[0] = NULL; - loadakernel(0, 0, argv); kernelname = getenv("kernelname"); if (kernelname == NULL) { - command_errmsg = "no valid kernel found"; - return(CMD_ERROR); + argv[0] = NULL; + loadakernel(0, 0, argv); + kernelname = getenv("kernelname"); + if (kernelname == NULL) { + command_errmsg = "no valid kernel found"; + return(CMD_ERROR); + } } - } - if (timeout >= 0) { - otime = time(NULL); - when = otime + timeout; /* when to boot */ + if (timeout >= 0) { + otime = time(NULL); + when = otime + timeout; /* when to boot */ - yes = 0; + yes = 0; #ifdef BOOT_PROMPT_123 - printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or " - "1 2 3 sequence for command prompt." : prompt); + printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or " + "1 2 3 sequence for command prompt." : prompt); #else - printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or any other key for command prompt." : prompt); + printf("%s\n", (prompt == NULL) ? "Hit [Enter] to boot immediately, or any other key for command prompt." : prompt); #endif - for (;;) { - if (ischar()) { - c = getchar(); + for (;;) { + if (ischar()) { + c = getchar(); #ifdef BOOT_PROMPT_123 - if ((c == '\r') || (c == '\n')) { - yes = 1; - break; - } else if (c != *p++) - p = seq; - if (*p == 0) - break; + if ((c == '\r') || (c == '\n')) { + yes = 1; + break; + } else if (c != *p++) + p = seq; + if (*p == 0) + break; #else - if ((c == '\r') || (c == '\n')) - yes = 1; - break; + if ((c == '\r') || (c == '\n')) + yes = 1; + break; #endif - } - ntime = time(NULL); - if (ntime >= when) { - yes = 1; - break; - } - - if (ntime != otime) { - printf("\rBooting [%s] in %d second%s... ", - kernelname, (int)(when - ntime), - (when-ntime)==1?"":"s"); - otime = ntime; - } - } - } else { - yes = 1; - } - - if (yes) - printf("\rBooting [%s]... ", kernelname); - putchar('\n'); - if (yes) { - argv[0] = "boot"; - argv[1] = NULL; - return(command_boot(1, argv)); - } - return(CMD_OK); + } + ntime = time(NULL); + if (ntime >= when) { + yes = 1; + break; + } + + if (ntime != otime) { + printf("\rBooting [%s] in %d second%s... ", + kernelname, (int)(when - ntime), + (when-ntime)==1?"":"s"); + otime = ntime; + } + } + } else { + yes = 1; + } + + if (yes) + printf("\rBooting [%s]... ", kernelname); + putchar('\n'); + if (yes) { + argv[0] = "boot"; + argv[1] = NULL; + return(command_boot(1, argv)); + } + return(CMD_OK); } /* @@ -255,43 +255,43 @@ autoboot(int timeout, char *prompt) static char * getbootfile(int try) { - static char *name = NULL; - const char *spec, *ep; - size_t len; - - /* we use dynamic storage */ - if (name != NULL) { - free(name); - name = NULL; - } - - /* - * Try $bootfile, then try our builtin default - */ - if ((spec = getenv("bootfile")) == NULL) - spec = default_bootfiles; - - while ((try > 0) && (spec != NULL)) { - spec = strchr(spec, ';'); - if (spec) - spec++; /* skip over the leading ';' */ - try--; - } - if (spec != NULL) { - if ((ep = strchr(spec, ';')) != NULL) { - len = ep - spec; - } else { - len = strlen(spec); + static char *name = NULL; + const char *spec, *ep; + size_t len; + + /* we use dynamic storage */ + if (name != NULL) { + free(name); + name = NULL; + } + + /* + * Try $bootfile, then try our builtin default + */ + if ((spec = getenv("bootfile")) == NULL) + spec = default_bootfiles; + + while ((try > 0) && (spec != NULL)) { + spec = strchr(spec, ';'); + if (spec) + spec++; /* skip over the leading ';' */ + try--; } - name = malloc(len + 1); - strncpy(name, spec, len); - name[len] = 0; - } - if (name && name[0] == 0) { - free(name); - name = NULL; - } - return(name); + if (spec != NULL) { + if ((ep = strchr(spec, ';')) != NULL) { + len = ep - spec; + } else { + len = strlen(spec); + } + name = malloc(len + 1); + strncpy(name, spec, len); + name[len] = 0; + } + if (name && name[0] == 0) { + free(name); + name = NULL; + } + return(name); } /* @@ -307,104 +307,109 @@ getbootfile(int try) int getrootmount(char *rootdev) { - char lbuf[128], *cp, *ep, *dev, *fstyp, *options; - int fd, error; - - if (getenv("vfs.root.mountfrom") != NULL) - return(0); - - error = 1; - sprintf(lbuf, "%s/etc/fstab", rootdev); - if ((fd = open(lbuf, O_RDONLY)) < 0) - goto notfound; - - /* loop reading lines from /etc/fstab What was that about sscanf again? */ - while (fgetstr(lbuf, sizeof(lbuf), fd) >= 0) { - if ((lbuf[0] == 0) || (lbuf[0] == '#')) - continue; - - /* skip device name */ - for (cp = lbuf; (*cp != 0) && !isspace(*cp); cp++) - ; - if (*cp == 0) /* misformatted */ - continue; - /* delimit and save */ - *cp++ = 0; - dev = strdup(lbuf); - - /* skip whitespace up to mountpoint */ - while ((*cp != 0) && isspace(*cp)) - cp++; - /* must have /<space> to be root */ - if ((*cp == 0) || (*cp != '/') || !isspace(*(cp + 1))) - continue; - /* skip whitespace up to fstype */ - cp += 2; - while ((*cp != 0) && isspace(*cp)) - cp++; - if (*cp == 0) /* misformatted */ - continue; - /* skip text to end of fstype and delimit */ - ep = cp; - while ((*cp != 0) && !isspace(*cp)) - cp++; - *cp = 0; - fstyp = strdup(ep); - - /* skip whitespace up to mount options */ - cp += 1; - while ((*cp != 0) && isspace(*cp)) - cp++; - if (*cp == 0) /* misformatted */ - continue; - /* skip text to end of mount options and delimit */ - ep = cp; - while ((*cp != 0) && !isspace(*cp)) - cp++; - *cp = 0; - options = strdup(ep); - /* Build the <fstype>:<device> and save it in vfs.root.mountfrom */ - sprintf(lbuf, "%s:%s", fstyp, dev); + char lbuf[128], *cp, *ep, *dev, *fstyp, *options; + int fd, error; + + if (getenv("vfs.root.mountfrom") != NULL) + return(0); + + error = 1; + sprintf(lbuf, "%s/etc/fstab", rootdev); + if ((fd = open(lbuf, O_RDONLY)) < 0) + goto notfound; + + /* loop reading lines from /etc/fstab What was that about sscanf again? */ + fstyp = NULL; + dev = NULL; + while (fgetstr(lbuf, sizeof(lbuf), fd) >= 0) { + if ((lbuf[0] == 0) || (lbuf[0] == '#')) + continue; + + /* skip device name */ + for (cp = lbuf; (*cp != 0) && !isspace(*cp); cp++) + ; + if (*cp == 0) /* misformatted */ + continue; + /* delimit and save */ + *cp++ = 0; + free(dev); + dev = strdup(lbuf); + + /* skip whitespace up to mountpoint */ + while ((*cp != 0) && isspace(*cp)) + cp++; + /* must have /<space> to be root */ + if ((*cp == 0) || (*cp != '/') || !isspace(*(cp + 1))) + continue; + /* skip whitespace up to fstype */ + cp += 2; + while ((*cp != 0) && isspace(*cp)) + cp++; + if (*cp == 0) /* misformatted */ + continue; + /* skip text to end of fstype and delimit */ + ep = cp; + while ((*cp != 0) && !isspace(*cp)) + cp++; + *cp = 0; + free(fstyp); + fstyp = strdup(ep); + + /* skip whitespace up to mount options */ + cp += 1; + while ((*cp != 0) && isspace(*cp)) + cp++; + if (*cp == 0) /* misformatted */ + continue; + /* skip text to end of mount options and delimit */ + ep = cp; + while ((*cp != 0) && !isspace(*cp)) + cp++; + *cp = 0; + options = strdup(ep); + /* Build the <fstype>:<device> and save it in vfs.root.mountfrom */ + sprintf(lbuf, "%s:%s", fstyp, dev); + setenv("vfs.root.mountfrom", lbuf, 0); + + /* Don't override vfs.root.mountfrom.options if it is already set */ + if (getenv("vfs.root.mountfrom.options") == NULL) { + /* save mount options */ + setenv("vfs.root.mountfrom.options", options, 0); + } + free(options); + error = 0; + break; + } + close(fd); free(dev); free(fstyp); - setenv("vfs.root.mountfrom", lbuf, 0); - - /* Don't override vfs.root.mountfrom.options if it is already set */ - if (getenv("vfs.root.mountfrom.options") == NULL) { - /* save mount options */ - setenv("vfs.root.mountfrom.options", options, 0); - } - free(options); - error = 0; - break; - } - close(fd); notfound: - if (error) { - const char *currdev; - - currdev = getenv("currdev"); - if (currdev != NULL && strncmp("zfs:", currdev, 4) == 0) { - cp = strdup(currdev); - cp[strlen(cp) - 1] = '\0'; - setenv("vfs.root.mountfrom", cp, 0); - error = 0; + if (error) { + const char *currdev; + + currdev = getenv("currdev"); + if (currdev != NULL && strncmp("zfs:", currdev, 4) == 0) { + cp = strdup(currdev); + cp[strlen(cp) - 1] = '\0'; + setenv("vfs.root.mountfrom", cp, 0); + error = 0; + free(cp); + } } - } - return(error); + return(error); } static int loadakernel(int try, int argc, char* argv[]) { - char *cp; + char *cp; for (try = 0; (cp = getbootfile(try)) != NULL; try++) - if (mod_loadkld(cp, argc - 1, argv + 1) != 0) - printf("can't load '%s'\n", cp); - else - return 1; + if (mod_loadkld(cp, argc - 1, argv + 1) != 0) + printf("can't load '%s'\n", cp); + else + return 1; return 0; } diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h index a570720..2808117 100644 --- a/stand/common/bootstrap.h +++ b/stand/common/bootstrap.h @@ -46,7 +46,13 @@ extern char command_errbuf[COMMAND_ERRBUFSZ]; /* interp.c */ void interact(void); -int include(const char *filename); +void interp_emit_prompt(void); +int interp_builtin_cmd(int argc, char *argv[]); + +/* Called by interp.c for interp_*.c embedded interpreters */ +int interp_include(const char *filename); /* Execute commands from filename */ +void interp_init(void); /* Initialize interpreater */ +int interp_run(const char *line); /* Run a single command */ /* interp_backslash.c */ char *backslash(const char *str); @@ -54,10 +60,6 @@ char *backslash(const char *str); /* interp_parse.c */ int parse(int *argc, char ***argv, const char *str); -/* interp_forth.c */ -void bf_init(void); -int bf_run(char *line); - /* boot.c */ int autoboot(int timeout, char *prompt); void autoboot_maybe(void); @@ -315,6 +317,9 @@ struct arch_switch /* Probe ZFS pool(s), if needed. */ void (*arch_zfs_probe)(void); + + /* For kexec-type loaders, get ksegment structure */ + void (*arch_kexec_kseg_get)(int *nseg, void **kseg); }; extern struct arch_switch archsw; diff --git a/stand/common/commands.c b/stand/common/commands.c index def7ff2..1d5000b 100644 --- a/stand/common/commands.c +++ b/stand/common/commands.c @@ -91,10 +91,8 @@ help_getnext(int fd, char **topic, char **subtopic, char **desc) cp = ep; } if (*topic == NULL) { - if (*subtopic != NULL) - free(*subtopic); - if (*desc != NULL) - free(*desc); + free(*subtopic); + free(*desc); continue; } return(1); @@ -169,7 +167,7 @@ command_help(int argc, char *argv[]) } else if (strcmp(topic, t)) { /* topic mismatch */ - if(matched) /* nothing more on this topic, stop scanning */ + if (matched) /* nothing more on this topic, stop scanning */ break; } else { @@ -178,7 +176,7 @@ command_help(int argc, char *argv[]) if (((subtopic == NULL) && (s == NULL)) || ((subtopic != NULL) && (s != NULL) && !strcmp(subtopic, s))) { /* exact match, print text */ - while((fgetstr(buf, 80, hfd) >= 0) && (buf[0] != '#')) { + while ((fgetstr(buf, 80, hfd) >= 0) && (buf[0] != '#')) { if (pager_output(buf)) break; if (pager_output("\n")) @@ -193,24 +191,25 @@ command_help(int argc, char *argv[]) free(t); free(s); free(d); + t = s = d = NULL; } + free(t); + free(s); + free(d); pager_close(); close(hfd); if (!matched) { snprintf(command_errbuf, sizeof(command_errbuf), "no help available for '%s'", topic); free(topic); - if (subtopic) - free(subtopic); + free(subtopic); return(CMD_ERROR); } free(topic); - if (subtopic) - free(subtopic); + free(subtopic); return(CMD_OK); } - COMMAND_SET(commandlist, "?", "list commands", command_commandlist); /* diff --git a/stand/common/install.c b/stand/common/install.c index 8c19066..0ba73e4 100644 --- a/stand/common/install.c +++ b/stand/common/install.c @@ -286,7 +286,7 @@ install(char *pkgname) fd = open(s, O_RDONLY); if (fd != -1) { close(fd); - error = include(s); + error = inter_include(s); if (error == CMD_ERROR) goto fail; } diff --git a/stand/common/interp.c b/stand/common/interp.c index 6b1b8bb..8941101 100644 --- a/stand/common/interp.c +++ b/stand/common/interp.c @@ -37,102 +37,40 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include "bootstrap.h" -#ifdef BOOT_FORTH -#include "ficl.h" -extern FICL_VM *bf_vm; -#endif - #define MAXARGS 20 /* maximum number of arguments allowed */ -static void prompt(void); - -#ifndef BOOT_FORTH -/* - * Perform the command - */ -static int -perform(int argc, char *argv[]) -{ - int result; - struct bootblk_command **cmdp; - bootblk_cmd_t *cmd; - - if (argc < 1) - return(CMD_OK); - - /* set return defaults; a successful command will override these */ - command_errmsg = command_errbuf; - strcpy(command_errbuf, "no error message"); - cmd = NULL; - result = CMD_ERROR; - - /* search the command set for the command */ - SET_FOREACH(cmdp, Xcommand_set) { - if (((*cmdp)->c_name != NULL) && !strcmp(argv[0], (*cmdp)->c_name)) - cmd = (*cmdp)->c_fn; - } - if (cmd != NULL) { - result = (cmd)(argc, argv); - } else { - command_errmsg = "unknown command"; - } - return(result); -} -#endif /* ! BOOT_FORTH */ - /* * Interactive mode */ void interact(void) { - static char input[256]; /* big enough? */ -#ifndef BOOT_FORTH - int argc; - char **argv; -#endif - -#ifdef BOOT_FORTH - bf_init(); -#endif - - /* Read our default configuration. */ - include("/boot/loader.rc"); - - printf("\n"); - - /* - * Before interacting, we might want to autoboot. - */ - autoboot_maybe(); - - /* - * Not autobooting, go manual - */ - printf("\nType '?' for a list of commands, 'help' for more detailed help.\n"); - if (getenv("prompt") == NULL) - setenv("prompt", "${interpret}", 1); - if (getenv("interpret") == NULL) - setenv("interpret", "OK", 1); - - - for (;;) { - input[0] = '\0'; - prompt(); - ngets(input, sizeof(input)); -#ifdef BOOT_FORTH - bf_vm->sourceID.i = 0; - bf_run(input); -#else - if (!parse(&argc, &argv, input)) { - if (perform(argc, argv)) - printf("%s: %s\n", argv[0], command_errmsg); - free(argv); - } else { - printf("parse error\n"); + static char input[256]; /* big enough? */ + + interp_init(); + + printf("\n"); + + /* + * Before interacting, we might want to autoboot. + */ + autoboot_maybe(); + + /* + * Not autobooting, go manual + */ + printf("\nType '?' for a list of commands, 'help' for more detailed help.\n"); + if (getenv("prompt") == NULL) + setenv("prompt", "${interpret}", 1); + if (getenv("interpret") == NULL) + setenv("interpret", "OK", 1); + + for (;;) { + input[0] = '\0'; + interp_emit_prompt(); + ngets(input, sizeof(input)); + interp_run(input); } -#endif - } } /* @@ -149,214 +87,87 @@ COMMAND_SET(include, "include", "read commands from a file", command_include); static int command_include(int argc, char *argv[]) { - int i; - int res; - char **argvbuf; - - /* - * Since argv is static, we need to save it here. - */ - argvbuf = (char**) calloc((u_int)argc, sizeof(char*)); - for (i = 0; i < argc; i++) - argvbuf[i] = strdup(argv[i]); - - res=CMD_OK; - for (i = 1; (i < argc) && (res == CMD_OK); i++) - res = include(argvbuf[i]); - - for (i = 0; i < argc; i++) - free(argvbuf[i]); - free(argvbuf); - - return(res); + int i; + int res; + char **argvbuf; + + /* + * Since argv is static, we need to save it here. + */ + argvbuf = (char**) calloc((u_int)argc, sizeof(char*)); + for (i = 0; i < argc; i++) + argvbuf[i] = strdup(argv[i]); + + res=CMD_OK; + for (i = 1; (i < argc) && (res == CMD_OK); i++) + res = interp_include(argvbuf[i]); + + for (i = 0; i < argc; i++) + free(argvbuf[i]); + free(argvbuf); + + return(res); } /* - * Header prepended to each line. The text immediately follows the header. - * We try to make this short in order to save memory -- the loader has - * limited memory available, and some of the forth files are very long. + * Emit the current prompt; use the same syntax as the parser + * for embedding environment variables. Does not accept input. */ -struct includeline -{ - struct includeline *next; -#ifndef BOOT_FORTH - int flags; - int line; -#define SL_QUIET (1<<0) -#define SL_IGNOREERR (1<<1) -#endif - char text[0]; -}; - -int -include(const char *filename) +void +interp_emit_prompt(void) { - struct includeline *script, *se, *sp; - char input[256]; /* big enough? */ -#ifdef BOOT_FORTH - int res; - char *cp; - int prevsrcid, fd, line; -#else - int argc,res; - char **argv, *cp; - int fd, flags, line; -#endif - - if (((fd = open(filename, O_RDONLY)) == -1)) { - snprintf(command_errbuf, sizeof(command_errbuf), - "can't open '%s': %s", filename, strerror(errno)); - return(CMD_ERROR); - } - - /* - * Read the script into memory. - */ - script = se = NULL; - line = 0; - - while (fgetstr(input, sizeof(input), fd) >= 0) { - line++; -#ifdef BOOT_FORTH - cp = input; -#else - flags = 0; - /* Discard comments */ - if (strncmp(input+strspn(input, " "), "\\ ", 2) == 0) - continue; - cp = input; - /* Echo? */ - if (input[0] == '@') { - cp++; - flags |= SL_QUIET; - } - /* Error OK? */ - if (input[0] == '-') { - cp++; - flags |= SL_IGNOREERR; - } -#endif - /* Allocate script line structure and copy line, flags */ - if (*cp == '\0') - continue; /* ignore empty line, save memory */ - sp = malloc(sizeof(struct includeline) + strlen(cp) + 1); - /* On malloc failure (it happens!), free as much as possible and exit */ - if (sp == NULL) { - while (script != NULL) { - se = script; - script = script->next; - free(se); + char *pr, *p, *cp, *ev; + + if ((cp = getenv("prompt")) == NULL) + cp = ">"; + pr = p = strdup(cp); + + while (*p != 0) { + if ((*p == '$') && (*(p+1) == '{')) { + for (cp = p + 2; (*cp != 0) && (*cp != '}'); cp++) + ; + *cp = 0; + ev = getenv(p + 2); + + if (ev != NULL) + printf("%s", ev); + p = cp + 1; + continue; } - snprintf(command_errbuf, sizeof(command_errbuf), - "file '%s' line %d: memory allocation failure - aborting", - filename, line); - return (CMD_ERROR); - } - strcpy(sp->text, cp); -#ifndef BOOT_FORTH - sp->flags = flags; - sp->line = line; -#endif - sp->next = NULL; - - if (script == NULL) { - script = sp; - } else { - se->next = sp; + putchar(*p++); } - se = sp; - } - close(fd); - - /* - * Execute the script - */ -#ifndef BOOT_FORTH - argv = NULL; -#else - prevsrcid = bf_vm->sourceID.i; - bf_vm->sourceID.i = fd; -#endif - res = CMD_OK; - for (sp = script; sp != NULL; sp = sp->next) { - -#ifdef BOOT_FORTH - res = bf_run(sp->text); - if (res != VM_OUTOFTEXT) { - snprintf(command_errbuf, sizeof(command_errbuf), - "Error while including %s, in the line:\n%s", - filename, sp->text); - res = CMD_ERROR; - break; - } else - res = CMD_OK; -#else - /* print if not being quiet */ - if (!(sp->flags & SL_QUIET)) { - prompt(); - printf("%s\n", sp->text); - } - - /* Parse the command */ - if (!parse(&argc, &argv, sp->text)) { - if ((argc > 0) && (perform(argc, argv) != 0)) { - /* normal command */ - printf("%s: %s\n", argv[0], command_errmsg); - if (!(sp->flags & SL_IGNOREERR)) { - res=CMD_ERROR; - break; - } - } - free(argv); - argv = NULL; - } else { - printf("%s line %d: parse error\n", filename, sp->line); - res=CMD_ERROR; - break; - } -#endif - } -#ifndef BOOT_FORTH - if (argv != NULL) - free(argv); -#else - bf_vm->sourceID.i = prevsrcid; -#endif - while(script != NULL) { - se = script; - script = script->next; - free(se); - } - return(res); + putchar(' '); + free(pr); } /* - * Emit the current prompt; use the same syntax as the parser - * for embedding environment variables. + * Perform a builtin command */ -static void -prompt(void) +int +interp_builtin_cmd(int argc, char *argv[]) { - char *pr, *p, *cp, *ev; - - if ((cp = getenv("prompt")) == NULL) - cp = ">"; - pr = p = strdup(cp); - - while (*p != 0) { - if ((*p == '$') && (*(p+1) == '{')) { - for (cp = p + 2; (*cp != 0) && (*cp != '}'); cp++) - ; - *cp = 0; - ev = getenv(p + 2); - - if (ev != NULL) - printf("%s", ev); - p = cp + 1; - continue; + int result; + struct bootblk_command **cmdp; + bootblk_cmd_t *cmd; + + if (argc < 1) + return(CMD_OK); + + /* set return defaults; a successful command will override these */ + command_errmsg = command_errbuf; + strcpy(command_errbuf, "no error message"); + cmd = NULL; + result = CMD_ERROR; + + /* search the command set for the command */ + SET_FOREACH(cmdp, Xcommand_set) { + if (((*cmdp)->c_name != NULL) && !strcmp(argv[0], (*cmdp)->c_name)) + cmd = (*cmdp)->c_fn; + } + if (cmd != NULL) { + result = (cmd)(argc, argv); + } else { + command_errmsg = "unknown command"; } - putchar(*p++); - } - putchar(' '); - free(pr); + return(result); } diff --git a/stand/common/interp_backslash.c b/stand/common/interp_backslash.c index 30874bd..c75081b 100644 --- a/stand/common/interp_backslash.c +++ b/stand/common/interp_backslash.c @@ -30,138 +30,138 @@ __FBSDID("$FreeBSD$"); char * backslash(const char *str) { - /* - * Remove backslashes from the strings. Turn \040 etc. into a single - * character (we allow eight bit values). Currently NUL is not - * allowed. - * - * Turn "\n" and "\t" into '\n' and '\t' characters. Etc. - * - */ - char *new_str; - int seenbs = 0; - int i = 0; - - if ((new_str = strdup(str)) == NULL) - return NULL; - - while (*str) { - if (seenbs) { - seenbs = 0; - switch (*str) { - case '\\': - new_str[i++] = '\\'; - str++; - break; - - /* preserve backslashed quotes, dollar signs */ - case '\'': - case '"': - case '$': - new_str[i++] = '\\'; - new_str[i++] = *str++; - break; - - case 'b': - new_str[i++] = '\b'; - str++; - break; - - case 'f': - new_str[i++] = '\f'; - str++; - break; - - case 'r': - new_str[i++] = '\r'; - str++; - break; - - case 'n': - new_str[i++] = '\n'; - str++; - break; - - case 's': - new_str[i++] = ' '; - str++; - break; - - case 't': - new_str[i++] = '\t'; - str++; - break; - - case 'v': - new_str[i++] = '\13'; - str++; - break; - - case 'z': - str++; - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': { - char val; - - /* Three digit octal constant? */ - if (*str >= '0' && *str <= '3' && - *(str + 1) >= '0' && *(str + 1) <= '7' && - *(str + 2) >= '0' && *(str + 2) <= '7') { - - val = (DIGIT(*str) << 6) + (DIGIT(*(str + 1)) << 3) + - DIGIT(*(str + 2)); - - /* Allow null value if user really wants to shoot - at feet, but beware! */ - new_str[i++] = val; - str += 3; - break; + /* + * Remove backslashes from the strings. Turn \040 etc. into a single + * character (we allow eight bit values). Currently NUL is not + * allowed. + * + * Turn "\n" and "\t" into '\n' and '\t' characters. Etc. + * + */ + char *new_str; + int seenbs = 0; + int i = 0; + + if ((new_str = strdup(str)) == NULL) + return NULL; + + while (*str) { + if (seenbs) { + seenbs = 0; + switch (*str) { + case '\\': + new_str[i++] = '\\'; + str++; + break; + + /* preserve backslashed quotes, dollar signs */ + case '\'': + case '"': + case '$': + new_str[i++] = '\\'; + new_str[i++] = *str++; + break; + + case 'b': + new_str[i++] = '\b'; + str++; + break; + + case 'f': + new_str[i++] = '\f'; + str++; + break; + + case 'r': + new_str[i++] = '\r'; + str++; + break; + + case 'n': + new_str[i++] = '\n'; + str++; + break; + + case 's': + new_str[i++] = ' '; + str++; + break; + + case 't': + new_str[i++] = '\t'; + str++; + break; + + case 'v': + new_str[i++] = '\13'; + str++; + break; + + case 'z': + str++; + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + char val; + + /* Three digit octal constant? */ + if (*str >= '0' && *str <= '3' && + *(str + 1) >= '0' && *(str + 1) <= '7' && + *(str + 2) >= '0' && *(str + 2) <= '7') { + + val = (DIGIT(*str) << 6) + (DIGIT(*(str + 1)) << 3) + + DIGIT(*(str + 2)); + + /* Allow null value if user really wants to shoot + at feet, but beware! */ + new_str[i++] = val; + str += 3; + break; + } + + /* One or two digit hex constant? + * If two are there they will both be taken. + * Use \z to split them up if this is not wanted. + */ + if (*str == '0' && + (*(str + 1) == 'x' || *(str + 1) == 'X') && + isxdigit(*(str + 2))) { + val = DIGIT(*(str + 2)); + if (isxdigit(*(str + 3))) { + val = (val << 4) + DIGIT(*(str + 3)); + str += 4; + } + else + str += 3; + /* Yep, allow null value here too */ + new_str[i++] = val; + break; + } + } + break; + + default: + new_str[i++] = *str++; + break; + } } - - /* One or two digit hex constant? - * If two are there they will both be taken. - * Use \z to split them up if this is not wanted. - */ - if (*str == '0' && - (*(str + 1) == 'x' || *(str + 1) == 'X') && - isxdigit(*(str + 2))) { - val = DIGIT(*(str + 2)); - if (isxdigit(*(str + 3))) { - val = (val << 4) + DIGIT(*(str + 3)); - str += 4; - } - else - str += 3; - /* Yep, allow null value here too */ - new_str[i++] = val; - break; + else { + if (*str == '\\') { + seenbs = 1; + str++; + } + else + new_str[i++] = *str++; } - } - break; - - default: - new_str[i++] = *str++; - break; - } - } - else { - if (*str == '\\') { - seenbs = 1; - str++; - } - else - new_str[i++] = *str++; } - } - if (seenbs) { - /* - * The final character was a '\'. Put it in as a single backslash. - */ - new_str[i++] = '\\'; - } - new_str[i] = '\0'; - return new_str; + if (seenbs) { + /* + * The final character was a '\'. Put it in as a single backslash. + */ + new_str[i++] = '\\'; + } + new_str[i] = '\0'; + return new_str; } diff --git a/stand/common/interp_forth.c b/stand/common/interp_forth.c index d617ce8..f3a97e3 100644 --- a/stand/common/interp_forth.c +++ b/stand/common/interp_forth.c @@ -71,91 +71,91 @@ FICL_VM *bf_vm; static void bf_command(FICL_VM *vm) { - char *name, *line, *tail, *cp; - size_t len; - struct bootblk_command **cmdp; - bootblk_cmd_t *cmd; - int nstrings, i; - int argc, result; - char **argv; - - /* Get the name of the current word */ - name = vm->runningWord->name; - - /* Find our command structure */ - cmd = NULL; - SET_FOREACH(cmdp, Xcommand_set) { - if (((*cmdp)->c_name != NULL) && !strcmp(name, (*cmdp)->c_name)) - cmd = (*cmdp)->c_fn; - } - if (cmd == NULL) - panic("callout for unknown command '%s'", name); - - /* Check whether we have been compiled or are being interpreted */ - if (stackPopINT(vm->pStack)) { + char *name, *line, *tail, *cp; + size_t len; + struct bootblk_command **cmdp; + bootblk_cmd_t *cmd; + int nstrings, i; + int argc, result; + char **argv; + + /* Get the name of the current word */ + name = vm->runningWord->name; + + /* Find our command structure */ + cmd = NULL; + SET_FOREACH(cmdp, Xcommand_set) { + if (((*cmdp)->c_name != NULL) && !strcmp(name, (*cmdp)->c_name)) + cmd = (*cmdp)->c_fn; + } + if (cmd == NULL) + panic("callout for unknown command '%s'", name); + + /* Check whether we have been compiled or are being interpreted */ + if (stackPopINT(vm->pStack)) { + /* + * Get parameters from stack, in the format: + * an un ... a2 u2 a1 u1 n -- + * Where n is the number of strings, a/u are pairs of + * address/size for strings, and they will be concatenated + * in LIFO order. + */ + nstrings = stackPopINT(vm->pStack); + for (i = 0, len = 0; i < nstrings; i++) + len += stackFetch(vm->pStack, i * 2).i + 1; + line = malloc(strlen(name) + len + 1); + strcpy(line, name); + + if (nstrings) + for (i = 0; i < nstrings; i++) { + len = stackPopINT(vm->pStack); + cp = stackPopPtr(vm->pStack); + strcat(line, " "); + strncat(line, cp, len); + } + } else { + /* Get remainder of invocation */ + tail = vmGetInBuf(vm); + for (cp = tail, len = 0; cp != vm->tib.end && *cp != 0 && *cp != '\n'; cp++, len++) + ; + + line = malloc(strlen(name) + len + 2); + strcpy(line, name); + if (len > 0) { + strcat(line, " "); + strncat(line, tail, len); + vmUpdateTib(vm, tail + len); + } + } + DEBUG("cmd '%s'", line); + + command_errmsg = command_errbuf; + command_errbuf[0] = 0; + if (!parse(&argc, &argv, line)) { + result = (cmd)(argc, argv); + free(argv); + } else { + result=BF_PARSE; + } + + switch (result) { + case CMD_CRIT: + printf("%s\n", command_errmsg); + break; + case CMD_FATAL: + panic("%s\n", command_errmsg); + } + + free(line); /* - * Get parameters from stack, in the format: - * an un ... a2 u2 a1 u1 n -- - * Where n is the number of strings, a/u are pairs of - * address/size for strings, and they will be concatenated - * in LIFO order. + * If there was error during nested ficlExec(), we may no longer have + * valid environment to return. Throw all exceptions from here. */ - nstrings = stackPopINT(vm->pStack); - for (i = 0, len = 0; i < nstrings; i++) - len += stackFetch(vm->pStack, i * 2).i + 1; - line = malloc(strlen(name) + len + 1); - strcpy(line, name); - - if (nstrings) - for (i = 0; i < nstrings; i++) { - len = stackPopINT(vm->pStack); - cp = stackPopPtr(vm->pStack); - strcat(line, " "); - strncat(line, cp, len); - } - } else { - /* Get remainder of invocation */ - tail = vmGetInBuf(vm); - for (cp = tail, len = 0; cp != vm->tib.end && *cp != 0 && *cp != '\n'; cp++, len++) - ; - - line = malloc(strlen(name) + len + 2); - strcpy(line, name); - if (len > 0) { - strcat(line, " "); - strncat(line, tail, len); - vmUpdateTib(vm, tail + len); - } - } - DEBUG("cmd '%s'", line); - - command_errmsg = command_errbuf; - command_errbuf[0] = 0; - if (!parse(&argc, &argv, line)) { - result = (cmd)(argc, argv); - free(argv); - } else { - result=BF_PARSE; - } - - switch (result) { - case CMD_CRIT: - printf("%s\n", command_errmsg); - break; - case CMD_FATAL: - panic("%s\n", command_errmsg); - } - - free(line); - /* - * If there was error during nested ficlExec(), we may no longer have - * valid environment to return. Throw all exceptions from here. - */ - if (result != CMD_OK) - vmThrow(vm, result); - - /* This is going to be thrown!!! */ - stackPushINT(vm->pStack,result); + if (result != CMD_OK) + vmThrow(vm, result); + + /* This is going to be thrown!!! */ + stackPushINT(vm->pStack,result); } /* @@ -226,25 +226,25 @@ bf_command(FICL_VM *vm) * (if you edit this definition, pay attention to trailing spaces after * each word -- I warned you! :-) ) */ -#define BUILTIN_CONSTRUCTOR \ -": builtin: " \ - ">in @ " /* save the tib index pointer */ \ - "' " /* get next word's xt */ \ - "swap >in ! " /* point again to next word */ \ - "create " /* create a new definition of the next word */ \ - ", " /* save previous definition's xt */ \ - "immediate " /* make the new definition an immediate word */ \ - \ - "does> " /* Now, the *new* definition will: */ \ - "state @ if " /* if in compiling state: */ \ - "1 postpone literal " /* pass 1 flag to indicate compile */ \ - "@ compile, " /* compile in previous definition */ \ - "postpone throw " /* throw stack-returned result */ \ - "else " /* if in interpreting state: */ \ - "0 swap " /* pass 0 flag to indicate interpret */ \ - "@ execute " /* call previous definition */ \ - "throw " /* throw stack-returned result */ \ - "then ; " +#define BUILTIN_CONSTRUCTOR \ + ": builtin: " \ + ">in @ " /* save the tib index pointer */ \ + "' " /* get next word's xt */ \ + "swap >in ! " /* point again to next word */ \ + "create " /* create a new definition of the next word */ \ + ", " /* save previous definition's xt */ \ + "immediate " /* make the new definition an immediate word */ \ + \ + "does> " /* Now, the *new* definition will: */ \ + "state @ if " /* if in compiling state: */ \ + "1 postpone literal " /* pass 1 flag to indicate compile */ \ + "@ compile, " /* compile in previous definition */ \ + "postpone throw " /* throw stack-returned result */ \ + "else " /* if in interpreting state: */ \ + "0 swap " /* pass 0 flag to indicate interpret */ \ + "@ execute " /* call previous definition */ \ + "throw " /* throw stack-returned result */ \ + "then ; " /* * Initialise the Forth interpreter, create all our commands as words. @@ -252,76 +252,192 @@ bf_command(FICL_VM *vm) void bf_init(void) { - struct bootblk_command **cmdp; - char create_buf[41]; /* 31 characters-long builtins */ - int fd; - - bf_sys = ficlInitSystem(BF_DICTSIZE); - bf_vm = ficlNewVM(bf_sys); - - /* Put all private definitions in a "builtins" vocabulary */ - ficlExec(bf_vm, "vocabulary builtins also builtins definitions"); - - /* Builtin constructor word */ - ficlExec(bf_vm, BUILTIN_CONSTRUCTOR); - - /* make all commands appear as Forth words */ - SET_FOREACH(cmdp, Xcommand_set) { - ficlBuild(bf_sys, (char *)(*cmdp)->c_name, bf_command, FW_DEFAULT); - ficlExec(bf_vm, "forth definitions builtins"); - sprintf(create_buf, "builtin: %s", (*cmdp)->c_name); - ficlExec(bf_vm, create_buf); - ficlExec(bf_vm, "builtins definitions"); - } - ficlExec(bf_vm, "only forth definitions"); - - /* Export some version numbers so that code can detect the loader/host version */ - ficlSetEnv(bf_sys, "FreeBSD_version", __FreeBSD_version); - ficlSetEnv(bf_sys, "loader_version", bootprog_rev); - - /* try to load and run init file if present */ - if ((fd = open("/boot/boot.4th", O_RDONLY)) != -1) { - (void)ficlExecFD(bf_vm, fd); - close(fd); - } + struct bootblk_command **cmdp; + char create_buf[41]; /* 31 characters-long builtins */ + int fd; + + bf_sys = ficlInitSystem(BF_DICTSIZE); + bf_vm = ficlNewVM(bf_sys); + + /* Put all private definitions in a "builtins" vocabulary */ + ficlExec(bf_vm, "vocabulary builtins also builtins definitions"); + + /* Builtin constructor word */ + ficlExec(bf_vm, BUILTIN_CONSTRUCTOR); + + /* make all commands appear as Forth words */ + SET_FOREACH(cmdp, Xcommand_set) { + ficlBuild(bf_sys, (char *)(*cmdp)->c_name, bf_command, FW_DEFAULT); + ficlExec(bf_vm, "forth definitions builtins"); + sprintf(create_buf, "builtin: %s", (*cmdp)->c_name); + ficlExec(bf_vm, create_buf); + ficlExec(bf_vm, "builtins definitions"); + } + ficlExec(bf_vm, "only forth definitions"); + + /* Export some version numbers so that code can detect the loader/host version */ + ficlSetEnv(bf_sys, "FreeBSD_version", __FreeBSD_version); + ficlSetEnv(bf_sys, "loader_version", bootprog_rev); + + /* try to load and run init file if present */ + if ((fd = open("/boot/boot.4th", O_RDONLY)) != -1) { + (void)ficlExecFD(bf_vm, fd); + close(fd); + } } /* * Feed a line of user input to the Forth interpreter */ +static int +bf_run(const char *line) +{ + int result; + + /* + * ficl would require extensive changes to accept a const char * + * interface. Instead, cast it away here and hope for the best. + * We know at the present time the caller for us in the boot + * forth loader can tolerate the string being modified because + * the string is passed in here and then not touched again. + */ + result = ficlExec(bf_vm, __DECONST(char *, line)); + + DEBUG("ficlExec '%s' = %d", line, result); + switch (result) { + case VM_OUTOFTEXT: + case VM_ABORTQ: + case VM_QUIT: + case VM_ERREXIT: + break; + case VM_USEREXIT: + printf("No where to leave to!\n"); + break; + case VM_ABORT: + printf("Aborted!\n"); + break; + case BF_PARSE: + printf("Parse error!\n"); + break; + default: + if (command_errmsg != NULL) { + printf("%s\n", command_errmsg); + command_errmsg = NULL; + } + } + + if (result == VM_USEREXIT) + panic("interpreter exit"); + setenv("interpret", bf_vm->state ? "" : "OK", 1); + + return (result); +} + +void +interp_init(void) +{ + + setenv("script.lang", "forth", 1); + bf_init(); + /* Read our default configuration. */ + interp_include("/boot/loader.rc"); +} + +int +interp_run(const char *input) +{ + + bf_vm->sourceID.i = 0; + return bf_run(input); +} + +/* + * Header prepended to each line. The text immediately follows the header. + * We try to make this short in order to save memory -- the loader has + * limited memory available, and some of the forth files are very long. + */ +struct includeline +{ + struct includeline *next; + char text[0]; +}; + int -bf_run(char *line) +interp_include(const char *filename) { - int result; - - result = ficlExec(bf_vm, line); - - DEBUG("ficlExec '%s' = %d", line, result); - switch (result) { - case VM_OUTOFTEXT: - case VM_ABORTQ: - case VM_QUIT: - case VM_ERREXIT: - break; - case VM_USEREXIT: - printf("No where to leave to!\n"); - break; - case VM_ABORT: - printf("Aborted!\n"); - break; - case BF_PARSE: - printf("Parse error!\n"); - break; - default: - if (command_errmsg != NULL) { - printf("%s\n", command_errmsg); - command_errmsg = NULL; + struct includeline *script, *se, *sp; + char input[256]; /* big enough? */ + int res; + char *cp; + int prevsrcid, fd, line; + + if (((fd = open(filename, O_RDONLY)) == -1)) { + snprintf(command_errbuf, sizeof(command_errbuf), + "can't open '%s': %s", filename, strerror(errno)); + return(CMD_ERROR); } - } - - if (result == VM_USEREXIT) - panic("interpreter exit"); - setenv("interpret", bf_vm->state ? "" : "OK", 1); - return (result); + /* + * Read the script into memory. + */ + script = se = NULL; + line = 0; + + while (fgetstr(input, sizeof(input), fd) >= 0) { + line++; + cp = input; + /* Allocate script line structure and copy line, flags */ + if (*cp == '\0') + continue; /* ignore empty line, save memory */ + sp = malloc(sizeof(struct includeline) + strlen(cp) + 1); + /* On malloc failure (it happens!), free as much as possible and exit */ + if (sp == NULL) { + while (script != NULL) { + se = script; + script = script->next; + free(se); + } + snprintf(command_errbuf, sizeof(command_errbuf), + "file '%s' line %d: memory allocation failure - aborting", + filename, line); + close(fd); + return (CMD_ERROR); + } + strcpy(sp->text, cp); + sp->next = NULL; + + if (script == NULL) { + script = sp; + } else { + se->next = sp; + } + se = sp; + } + close(fd); + + /* + * Execute the script + */ + prevsrcid = bf_vm->sourceID.i; + bf_vm->sourceID.i = fd; + res = CMD_OK; + for (sp = script; sp != NULL; sp = sp->next) { + res = bf_run(sp->text); + if (res != VM_OUTOFTEXT) { + snprintf(command_errbuf, sizeof(command_errbuf), + "Error while including %s, in the line:\n%s", + filename, sp->text); + res = CMD_ERROR; + break; + } else + res = CMD_OK; + } + bf_vm->sourceID.i = prevsrcid; + + while (script != NULL) { + se = script; + script = script->next; + free(se); + } + return(res); } diff --git a/stand/common/interp_parse.c b/stand/common/interp_parse.c index 670273e..c46a497 100644 --- a/stand/common/interp_parse.c +++ b/stand/common/interp_parse.c @@ -50,143 +50,146 @@ static char *args[MAXARGS]; */ #define PARSE_FAIL(expr) \ -if (expr) { \ - printf("fail at line %d\n", __LINE__); \ - clean(); \ - free(copy); \ - free(buf); \ - return 1; \ -} + if (expr) { \ + printf("fail at line %d\n", __LINE__); \ + clean(); \ + free(copy); \ + free(buf); \ + return 1; \ + } /* Accept the usual delimiters for a variable, returning counterpart */ static char isdelim(int ch) { - if (ch == '{') - return '}'; - else if (ch == '(') - return ')'; - return '\0'; + + if (ch == '{') + return '}'; + else if (ch == '(') + return ')'; + return '\0'; } static int isquote(int ch) { - return (ch == '\''); + + return (ch == '\''); } static int isdquote(int ch) { - return (ch == '"'); + + return (ch == '"'); } int parse(int *argc, char ***argv, const char *str) { - int ac; - char *val, *p, *q, *copy = NULL; - size_t i = 0; - char token, tmp, quote, dquote, *buf; - enum { STR, VAR, WHITE } state; - - ac = *argc = 0; - dquote = quote = 0; - if (!str || (p = copy = backslash(str)) == NULL) - return 1; - - /* Initialize vector and state */ - clean(); - state = STR; - buf = (char *)malloc(PARSE_BUFSIZE); - token = 0; - - /* And awaaaaaaaaay we go! */ - while (*p) { - switch (state) { - case STR: - if ((*p == '\\') && p[1]) { - p++; - PARSE_FAIL(i == (PARSE_BUFSIZE - 1)); - buf[i++] = *p++; - } else if (isquote(*p)) { - quote = quote ? 0 : *p; - if (dquote) { /* keep quote */ - PARSE_FAIL(i == (PARSE_BUFSIZE - 1)); - buf[i++] = *p++; - } else - ++p; - } else if (isdquote(*p)) { - dquote = dquote ? 0 : *p; - if (quote) { /* keep dquote */ - PARSE_FAIL(i == (PARSE_BUFSIZE - 1)); - buf[i++] = *p++; - } else - ++p; - } else if (isspace(*p) && !quote && !dquote) { - state = WHITE; - if (i) { - buf[i] = '\0'; - PARSE_FAIL(insert(&ac, buf)); - i = 0; + int ac; + char *val, *p, *q, *copy = NULL; + size_t i = 0; + char token, tmp, quote, dquote, *buf; + enum { STR, VAR, WHITE } state; + + ac = *argc = 0; + dquote = quote = 0; + if (!str || (p = copy = backslash(str)) == NULL) + return 1; + + /* Initialize vector and state */ + clean(); + state = STR; + buf = (char *)malloc(PARSE_BUFSIZE); + token = 0; + + /* And awaaaaaaaaay we go! */ + while (*p) { + switch (state) { + case STR: + if ((*p == '\\') && p[1]) { + p++; + PARSE_FAIL(i == (PARSE_BUFSIZE - 1)); + buf[i++] = *p++; + } else if (isquote(*p)) { + quote = quote ? 0 : *p; + if (dquote) { /* keep quote */ + PARSE_FAIL(i == (PARSE_BUFSIZE - 1)); + buf[i++] = *p++; + } else + ++p; + } else if (isdquote(*p)) { + dquote = dquote ? 0 : *p; + if (quote) { /* keep dquote */ + PARSE_FAIL(i == (PARSE_BUFSIZE - 1)); + buf[i++] = *p++; + } else + ++p; + } else if (isspace(*p) && !quote && !dquote) { + state = WHITE; + if (i) { + buf[i] = '\0'; + PARSE_FAIL(insert(&ac, buf)); + i = 0; + } + ++p; + } else if (*p == '$' && !quote) { + token = isdelim(*(p + 1)); + if (token) + p += 2; + else + ++p; + state = VAR; + } else { + PARSE_FAIL(i == (PARSE_BUFSIZE - 1)); + buf[i++] = *p++; + } + break; + + case WHITE: + if (isspace(*p)) + ++p; + else + state = STR; + break; + + case VAR: + if (token) { + PARSE_FAIL((q = strchr(p, token)) == NULL); + } else { + q = p; + while (*q && !isspace(*q)) + ++q; + } + tmp = *q; + *q = '\0'; + if ((val = variable_lookup(p)) != NULL) { + size_t len = strlen(val); + + strncpy(buf + i, val, PARSE_BUFSIZE - (i + 1)); + i += min(len, PARSE_BUFSIZE - 1); + } + *q = tmp; /* restore value */ + p = q + (token ? 1 : 0); + state = STR; + break; } - ++p; - } else if (*p == '$' && !quote) { - token = isdelim(*(p + 1)); - if (token) - p += 2; - else - ++p; - state = VAR; - } else { - PARSE_FAIL(i == (PARSE_BUFSIZE - 1)); - buf[i++] = *p++; - } - break; - - case WHITE: - if (isspace(*p)) - ++p; - else - state = STR; - break; - - case VAR: - if (token) { - PARSE_FAIL((q = strchr(p, token)) == NULL); - } else { - q = p; - while (*q && !isspace(*q)) - ++q; - } - tmp = *q; - *q = '\0'; - if ((val = variable_lookup(p)) != NULL) { - size_t len = strlen(val); - - strncpy(buf + i, val, PARSE_BUFSIZE - (i + 1)); - i += min(len, PARSE_BUFSIZE - 1); - } - *q = tmp; /* restore value */ - p = q + (token ? 1 : 0); - state = STR; - break; } - } - /* missing terminating ' or " */ - PARSE_FAIL(quote || dquote); - /* If at end of token, add it */ - if (i && state == STR) { - buf[i] = '\0'; - PARSE_FAIL(insert(&ac, buf)); - } - args[ac] = NULL; - *argc = ac; - *argv = (char **)malloc((sizeof(char *) * ac + 1)); - bcopy(args, *argv, sizeof(char *) * ac + 1); - free(buf); - free(copy); - return 0; + /* missing terminating ' or " */ + PARSE_FAIL(quote || dquote); + /* If at end of token, add it */ + if (i && state == STR) { + buf[i] = '\0'; + PARSE_FAIL(insert(&ac, buf)); + } + args[ac] = NULL; + *argc = ac; + *argv = (char **)malloc((sizeof(char *) * ac + 1)); + bcopy(args, *argv, sizeof(char *) * ac + 1); + free(buf); + free(copy); + return 0; } #define MAXARGS 20 @@ -195,28 +198,30 @@ parse(int *argc, char ***argv, const char *str) static void clean(void) { - int i; + int i; - for (i = 0; i < MAXARGS; i++) { - if (args[i] != NULL) { - free(args[i]); - args[i] = NULL; + for (i = 0; i < MAXARGS; i++) { + if (args[i] != NULL) { + free(args[i]); + args[i] = NULL; + } } - } } static int insert(int *argcp, char *buf) { - if (*argcp >= MAXARGS) - return 1; - args[(*argcp)++] = strdup(buf); - return 0; + + if (*argcp >= MAXARGS) + return 1; + args[(*argcp)++] = strdup(buf); + return 0; } static char * variable_lookup(char *name) { - /* XXX search "special variable" space first? */ - return (char *)getenv(name); + + /* XXX search "special variable" space first? */ + return (char *)getenv(name); } diff --git a/stand/common/interp_simple.c b/stand/common/interp_simple.c new file mode 100644 index 0000000..83eb83c --- /dev/null +++ b/stand/common/interp_simple.c @@ -0,0 +1,192 @@ +/*- + * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +/* + * Simple commandline interpreter, toplevel and misc. + */ + +#include <stand.h> +#include <string.h> +#include "bootstrap.h" + +void +interp_init(void) +{ + + setenv("script.lang", "simple", 1); + /* Read our default configuration. */ + interp_include("/boot/loader.rc"); +} + +int +interp_run(const char *input) +{ + int argc; + char **argv; + + if (parse(&argc, &argv, input)) { + printf("parse error\n"); + return CMD_ERROR; + } + + if (interp_builtin_cmd(argc, argv)) { + printf("%s: %s\n", argv[0], command_errmsg); + free(argv); + return CMD_ERROR; + } + free(argv); + return CMD_OK; +} + +/* + * Header prepended to each line. The text immediately follows the header. + * We try to make this short in order to save memory -- the loader has + * limited memory available, and some of the forth files are very long. + */ +struct includeline +{ + struct includeline *next; + int flags; + int line; +#define SL_QUIET (1<<0) +#define SL_IGNOREERR (1<<1) + char text[0]; +}; + +int +interp_include(const char *filename) +{ + struct includeline *script, *se, *sp; + char input[256]; /* big enough? */ + int argc,res; + char **argv, *cp; + int fd, flags, line; + + if (((fd = open(filename, O_RDONLY)) == -1)) { + snprintf(command_errbuf, sizeof(command_errbuf), + "can't open '%s': %s", filename, strerror(errno)); + return(CMD_ERROR); + } + + /* + * Read the script into memory. + */ + script = se = NULL; + line = 0; + + while (fgetstr(input, sizeof(input), fd) >= 0) { + line++; + flags = 0; + /* Discard comments */ + if (strncmp(input+strspn(input, " "), "\\ ", 2) == 0) + continue; + cp = input; + /* Echo? */ + if (input[0] == '@') { + cp++; + flags |= SL_QUIET; + } + /* Error OK? */ + if (input[0] == '-') { + cp++; + flags |= SL_IGNOREERR; + } + + /* Allocate script line structure and copy line, flags */ + if (*cp == '\0') + continue; /* ignore empty line, save memory */ + sp = malloc(sizeof(struct includeline) + strlen(cp) + 1); + /* On malloc failure (it happens!), free as much as possible and exit */ + if (sp == NULL) { + while (script != NULL) { + se = script; + script = script->next; + free(se); + } + snprintf(command_errbuf, sizeof(command_errbuf), + "file '%s' line %d: memory allocation failure - aborting", + filename, line); + close(fd); + return (CMD_ERROR); + } + strcpy(sp->text, cp); + sp->flags = flags; + sp->line = line; + sp->next = NULL; + + if (script == NULL) { + script = sp; + } else { + se->next = sp; + } + se = sp; + } + close(fd); + + /* + * Execute the script + */ + argv = NULL; + res = CMD_OK; + for (sp = script; sp != NULL; sp = sp->next) { + + /* print if not being quiet */ + if (!(sp->flags & SL_QUIET)) { + interp_emit_prompt(); + printf("%s\n", sp->text); + } + + /* Parse the command */ + if (!parse(&argc, &argv, sp->text)) { + if ((argc > 0) && (interp_builtin_cmd(argc, argv) != 0)) { + /* normal command */ + printf("%s: %s\n", argv[0], command_errmsg); + if (!(sp->flags & SL_IGNOREERR)) { + res=CMD_ERROR; + break; + } + } + free(argv); + argv = NULL; + } else { + printf("%s line %d: parse error\n", filename, sp->line); + res=CMD_ERROR; + break; + } + } + if (argv != NULL) + free(argv); + + while (script != NULL) { + se = script; + script = script->next; + free(se); + } + return(res); +} diff --git a/stand/common/load_elf.c b/stand/common/load_elf.c index 4c1277b..89c0733 100644 --- a/stand/common/load_elf.c +++ b/stand/common/load_elf.c @@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> +#include <sys/endian.h> #include <sys/exec.h> #include <sys/linker.h> #include <sys/module.h> @@ -86,6 +87,112 @@ const char *__elfN(moduletype) = "elf module"; u_int64_t __elfN(relocation_offset) = 0; +extern void elf_wrong_field_size(void); +#define CONVERT_FIELD(b, f, e) \ + switch (sizeof((b)->f)) { \ + case 2: \ + (b)->f = e ## 16toh((b)->f); \ + break; \ + case 4: \ + (b)->f = e ## 32toh((b)->f); \ + break; \ + case 8: \ + (b)->f = e ## 64toh((b)->f); \ + break; \ + default: \ + /* Force a link time error. */ \ + elf_wrong_field_size(); \ + break; \ + } + +#define CONVERT_SWITCH(h, d, f) \ + switch ((h)->e_ident[EI_DATA]) { \ + case ELFDATA2MSB: \ + f(d, be); \ + break; \ + case ELFDATA2LSB: \ + f(d, le); \ + break; \ + default: \ + return (EINVAL); \ + } + + +static int elf_header_convert(Elf_Ehdr *ehdr) +{ + /* + * Fixup ELF header endianness. + * + * The Xhdr structure was loaded using block read call to optimize file + * accesses. It might happen, that the endianness of the system memory + * is different that endianness of the ELF header. Swap fields here to + * guarantee that Xhdr always contain valid data regardless of + * architecture. + */ +#define HEADER_FIELDS(b, e) \ + CONVERT_FIELD(b, e_type, e); \ + CONVERT_FIELD(b, e_machine, e); \ + CONVERT_FIELD(b, e_version, e); \ + CONVERT_FIELD(b, e_entry, e); \ + CONVERT_FIELD(b, e_phoff, e); \ + CONVERT_FIELD(b, e_shoff, e); \ + CONVERT_FIELD(b, e_flags, e); \ + CONVERT_FIELD(b, e_ehsize, e); \ + CONVERT_FIELD(b, e_phentsize, e); \ + CONVERT_FIELD(b, e_phnum, e); \ + CONVERT_FIELD(b, e_shentsize, e); \ + CONVERT_FIELD(b, e_shnum, e); \ + CONVERT_FIELD(b, e_shstrndx, e) + + CONVERT_SWITCH(ehdr, ehdr, HEADER_FIELDS); + +#undef HEADER_FIELDS + + return (0); +} + +static int elf_program_header_convert(const Elf_Ehdr *ehdr, Elf_Phdr *phdr) +{ +#define PROGRAM_HEADER_FIELDS(b, e) \ + CONVERT_FIELD(b, p_type, e); \ + CONVERT_FIELD(b, p_flags, e); \ + CONVERT_FIELD(b, p_offset, e); \ + CONVERT_FIELD(b, p_vaddr, e); \ + CONVERT_FIELD(b, p_paddr, e); \ + CONVERT_FIELD(b, p_filesz, e); \ + CONVERT_FIELD(b, p_memsz, e); \ + CONVERT_FIELD(b, p_align, e) + + CONVERT_SWITCH(ehdr, phdr, PROGRAM_HEADER_FIELDS); + +#undef PROGRAM_HEADER_FIELDS + + return (0); +} + +static int elf_section_header_convert(const Elf_Ehdr *ehdr, Elf_Shdr *shdr) +{ +#define SECTION_HEADER_FIELDS(b, e) \ + CONVERT_FIELD(b, sh_name, e); \ + CONVERT_FIELD(b, sh_type, e); \ + CONVERT_FIELD(b, sh_link, e); \ + CONVERT_FIELD(b, sh_info, e); \ + CONVERT_FIELD(b, sh_flags, e); \ + CONVERT_FIELD(b, sh_addr, e); \ + CONVERT_FIELD(b, sh_offset, e); \ + CONVERT_FIELD(b, sh_size, e); \ + CONVERT_FIELD(b, sh_addralign, e); \ + CONVERT_FIELD(b, sh_entsize, e) + + CONVERT_SWITCH(ehdr, shdr, SECTION_HEADER_FIELDS); + +#undef SECTION_HEADER_FIELDS + + return (0); +} +#undef CONVERT_SWITCH +#undef CONVERT_FIELD + static int __elfN(load_elf_header)(char *filename, elf_file_t ef) { @@ -118,11 +225,19 @@ __elfN(load_elf_header)(char *filename, elf_file_t ef) err = EFTYPE; goto error; } + if (ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || /* Layout ? */ ehdr->e_ident[EI_DATA] != ELF_TARG_DATA || - ehdr->e_ident[EI_VERSION] != EV_CURRENT || /* Version ? */ - ehdr->e_version != EV_CURRENT || - ehdr->e_machine != ELF_TARG_MACH) { /* Machine ? */ + ehdr->e_ident[EI_VERSION] != EV_CURRENT) /* Version ? */ { + err = EFTYPE; + goto error; + } + + err = elf_header_convert(ehdr); + if (err) + goto error; + + if (ehdr->e_version != EV_CURRENT || ehdr->e_machine != ELF_TARG_MACH) { /* Machine ? */ err = EFTYPE; goto error; } @@ -391,6 +506,9 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) phdr = (Elf_Phdr *)(ef->firstpage + ehdr->e_phoff); for (i = 0; i < ehdr->e_phnum; i++) { + if (elf_program_header_convert(ehdr, phdr)) + continue; + /* We want to load PT_LOAD segments only.. */ if (phdr[i].p_type != PT_LOAD) continue; @@ -465,6 +583,10 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) "_loadimage: failed to read section headers"); goto nosyms; } + + for (i = 0; i < ehdr->e_shnum; i++) + elf_section_header_convert(ehdr, &shdr[i]); + file_addmetadata(fp, MODINFOMD_SHDR, chunk, shdr); /* @@ -540,8 +662,15 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) break; } #endif - size = shdr[i].sh_size; +#if defined(__powerpc__) + #if __ELF_WORD_SIZE == 64 + size = htobe64(size); + #else + size = htobe32(size); + #endif +#endif + archsw.arch_copyin(&size, lastaddr, sizeof(size)); lastaddr += sizeof(size); @@ -582,6 +711,17 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) printf("]"); #endif +#if defined(__powerpc__) + /* On PowerPC we always need to provide BE data to the kernel */ + #if __ELF_WORD_SIZE == 64 + ssym = htobe64((uint64_t)ssym); + esym = htobe64((uint64_t)esym); + #else + ssym = htobe32((uint32_t)ssym); + esym = htobe32((uint32_t)esym); + #endif +#endif + file_addmetadata(fp, MODINFOMD_SSYM, sizeof(ssym), &ssym); file_addmetadata(fp, MODINFOMD_ESYM, sizeof(esym), &esym); diff --git a/stand/common/load_elf_obj.c b/stand/common/load_elf_obj.c index 57df57a..f053a45 100644 --- a/stand/common/load_elf_obj.c +++ b/stand/common/load_elf_obj.c @@ -280,6 +280,8 @@ __elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off) switch (shdr[i].sh_type) { case SHT_REL: case SHT_RELA: + if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0) + break; lastaddr = roundup(lastaddr, shdr[i].sh_addralign); shdr[i].sh_addr = (Elf_Addr)lastaddr; lastaddr += shdr[i].sh_size; diff --git a/stand/common/misc.c b/stand/common/misc.c index 9b938af..4c0273f 100644 --- a/stand/common/misc.c +++ b/stand/common/misc.c @@ -138,6 +138,7 @@ kern_pread(int fd, vm_offset_t dest, size_t len, off_t off) * Read the specified part of a file to a malloced buffer. The file * pointer is advanced to the end of the read data. */ +/* coverity[ -tainted_data_return ] */ void * alloc_pread(int fd, off_t off, size_t len) { diff --git a/stand/common/pnp.c b/stand/common/pnp.c index 6197776..31a0de9 100644 --- a/stand/common/pnp.c +++ b/stand/common/pnp.c @@ -17,9 +17,6 @@ __FBSDID("$FreeBSD$"); #include <stand.h> #include <string.h> #include <bootstrap.h> -#ifdef BOOT_FORTH -#include "ficl.h" -#endif static struct pnpinfo_stql pnp_devices; static int pnp_devices_initted = 0; @@ -187,50 +184,3 @@ pnp_eisaformat(u_int8_t *data) idbuf[7] = 0; return(idbuf); } - -#ifdef BOOT_FORTH -void -ficlPnpdevices(FICL_VM *pVM) -{ - static int pnp_devices_initted = 0; -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 0, 1); -#endif - - if(!pnp_devices_initted) { - STAILQ_INIT(&pnp_devices); - pnp_devices_initted = 1; - } - - stackPushPtr(pVM->pStack, &pnp_devices); - - return; -} - -void -ficlPnphandlers(FICL_VM *pVM) -{ -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 0, 1); -#endif - - stackPushPtr(pVM->pStack, pnphandlers); - - return; -} - -/* - * Glue function to add the appropriate forth words to access pnp BIOS - * functionality. - */ -static void ficlCompilePnp(FICL_SYSTEM *pSys) -{ - FICL_DICT *dp = pSys->dp; - assert (dp); - - dictAppendWord(dp, "pnpdevices",ficlPnpdevices, FW_DEFAULT); - dictAppendWord(dp, "pnphandlers",ficlPnphandlers, FW_DEFAULT); -} - -FICL_COMPILE_SET(ficlCompilePnp); -#endif diff --git a/stand/defs.mk b/stand/defs.mk index 79e5269..3b646c6 100644 --- a/stand/defs.mk +++ b/stand/defs.mk @@ -7,6 +7,15 @@ WARNS?=1 .if !defined(__BOOT_DEFS_MK__) __BOOT_DEFS_MK__=${MFILE} +MK_CTF= no +MK_SSP= no +MK_PROFILE= no +MAN= +.if !defined(PIC) +NO_PIC= +INTERNALLIB= +.endif + BOOTSRC= ${SRCTOP}/stand EFISRC= ${BOOTSRC}/efi EFIINC= ${EFISRC}/include diff --git a/stand/efi/boot1/Makefile b/stand/efi/boot1/Makefile index 7791b78..02ca947 100644 --- a/stand/efi/boot1/Makefile +++ b/stand/efi/boot1/Makefile @@ -1,12 +1,7 @@ # $FreeBSD$ -MAN= - .include <bsd.init.mk> -MK_SSP= no -MK_FORTH= no - PROG= boot1.sym INTERNALPROG= WARNS?= 6 @@ -110,7 +105,7 @@ boot1.efi: ${PROG} # The following inserts our objects into a template FAT file system # created by generate-fat.sh -.include "${.CURDIR}/Makefile.fat" +.include "Makefile.fat" boot1.efifat: boot1.efi @set -- `ls -l ${.ALLSRC}`; \ @@ -120,7 +115,7 @@ boot1.efifat: boot1.efi exit 1; \ fi echo ${.OBJDIR} - xz -d -c ${.CURDIR}/fat-${MACHINE}.tmpl.xz > ${.TARGET} + xz -d -c ${BOOTSRC}/efi/boot1/fat-${MACHINE}.tmpl.xz > ${.TARGET} ${DD} if=${.ALLSRC} of=${.TARGET} seek=${BOOT1_OFFSET} conv=notrunc CLEANFILES+= boot1.efi boot1.efifat diff --git a/stand/efi/boot1/boot1.c b/stand/efi/boot1/boot1.c index 7b51f03..35f3332d 100644 --- a/stand/efi/boot1/boot1.c +++ b/stand/efi/boot1/boot1.c @@ -55,6 +55,7 @@ static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL; static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL; static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; static EFI_GUID FreeBSDBootVarGUID = FREEBSD_BOOT_VAR_GUID; +static EFI_GUID GlobalBootVarGUID = UEFI_BOOT_VAR_GUID; /* * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures @@ -80,14 +81,33 @@ Free(void *buf, const char *file __unused, int line __unused) } static EFI_STATUS +efi_getenv(EFI_GUID *g, const char *v, void *data, size_t *len) +{ + size_t ul; + CHAR16 *uv; + UINT32 attr; + UINTN dl; + EFI_STATUS rv; + + uv = NULL; + if (utf8_to_ucs2(v, &uv, &ul) != 0) + return (EFI_OUT_OF_RESOURCES); + dl = *len; + rv = RS->GetVariable(uv, g, &attr, &dl, data); + if (rv == EFI_SUCCESS) + *len = dl; + free(uv); + return (rv); +} + +static EFI_STATUS efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr) { CHAR16 *var = NULL; size_t len; EFI_STATUS rv; - utf8_to_ucs2(varname, &var, &len); - if (var == NULL) + if (utf8_to_ucs2(varname, &var, &len) != 0) return (EFI_OUT_OF_RESOURCES); rv = RS->SetVariable(var, &FreeBSDBootVarGUID, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, @@ -411,6 +431,9 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab) SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL; UINTN i, max_dim, best_mode, cols, rows, hsize, nhandles; CHAR16 *text; + UINT16 boot_current; + size_t sz; + UINT16 boot_order[100]; /* Basic initialization*/ ST = Xsystab; @@ -480,12 +503,32 @@ efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab) } } + boot_current = 0; + sz = sizeof(boot_current); + efi_getenv(&GlobalBootVarGUID, "BootCurrent", &boot_current, &sz); + printf(" BootCurrent: %04x\n", boot_current); + + sz = sizeof(boot_order); + efi_getenv(&GlobalBootVarGUID, "BootOrder", &boot_order, &sz); + printf(" BootOrder:"); + for (i = 0; i < sz / sizeof(boot_order[0]); i++) + printf(" %04x", boot_order[i]); + printf("\n"); + +#ifdef TEST_FAILURE + /* + * For testing failover scenarios, it's nice to be able to fail fast. + * Define TEST_FAILURE to create a boot1.efi that always fails after + * reporting the boot manager protocol details. + */ + BS->Exit(IH, EFI_OUT_OF_RESOURCES, 0, NULL); +#endif + /* Get all the device handles */ hsize = (UINTN)NUM_HANDLES_INIT * sizeof(EFI_HANDLE); handles = malloc(hsize); - if (handles == NULL) { + if (handles == NULL) printf("Failed to allocate %d handles\n", NUM_HANDLES_INIT); - } status = BS->LocateHandle(ByProtocol, &BlockIoProtocolGUID, NULL, &hsize, handles); diff --git a/stand/efi/fdt/Makefile b/stand/efi/fdt/Makefile index 6bae439..8166f48 100644 --- a/stand/efi/fdt/Makefile +++ b/stand/efi/fdt/Makefile @@ -5,7 +5,6 @@ .PATH: ${LDRSRC} LIB= efi_fdt -INTERNALLIB= WARNS?= 6 SRCS= efi_fdt.c diff --git a/stand/efi/include/efi.h b/stand/efi/include/efi.h index a91e881..9164ec9 100644 --- a/stand/efi/include/efi.h +++ b/stand/efi/include/efi.h @@ -59,5 +59,7 @@ Revision History */ #define FREEBSD_BOOT_VAR_GUID \ { 0xCFEE69AD, 0xA0DE, 0x47A9, {0x93, 0xA8, 0xF6, 0x31, 0x06, 0xF8, 0xAE, 0x99} } +#define UEFI_BOOT_VAR_GUID \ + { 0x8be4df61, 0x93ca, 0x11d2, {0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c} } #endif diff --git a/stand/efi/include/efiapi.h b/stand/efi/include/efiapi.h index 8bab217..01a064b 100644 --- a/stand/efi/include/efiapi.h +++ b/stand/efi/include/efiapi.h @@ -840,6 +840,9 @@ typedef struct { #define SMBIOS_TABLE_GUID \ { 0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } +#define SMBIOS3_TABLE_GUID \ + { 0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94} } + #define SAL_SYSTEM_TABLE_GUID \ { 0xeb9d2d32, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } @@ -852,6 +855,15 @@ typedef struct { #define HOB_LIST_TABLE_GUID \ { 0x7739f24c, 0x93d7, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } +#define LZMA_DECOMPRESSION_GUID \ + { 0xee4e5898, 0x3914, 0x4259, {0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x3, 0xcf} } + +#define ARM_MP_CORE_INFO_TABLE_GUID \ + { 0xa4ee0728, 0xe5d7, 0x4ac5, {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} } + +#define ESRT_TABLE_GUID \ + { 0xb122a263, 0x3661, 0x4f68, {0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80} } + #define MEMORY_TYPE_INFORMATION_TABLE_GUID \ { 0x4c19049f, 0x4137, 0x4dd3, {0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa} } diff --git a/stand/efi/libefi/Makefile b/stand/efi/libefi/Makefile index f5cf71e..c88eb4d 100644 --- a/stand/efi/libefi/Makefile +++ b/stand/efi/libefi/Makefile @@ -2,12 +2,7 @@ .include <bsd.init.mk> -.if ${MK_FORTH} != "no" -.include "${BOOTSRC}/ficl.mk" -.endif - LIB= efi -INTERNALLIB= WARNS?= 2 SRCS= delay.c devpath.c efi_console.c efichar.c efinet.c efipart.c env.c errno.c \ diff --git a/stand/efi/libefi/efichar.c b/stand/efi/libefi/efichar.c index 15aa5ca..233027f 100644 --- a/stand/efi/libefi/efichar.c +++ b/stand/efi/libefi/efichar.c @@ -116,8 +116,10 @@ ucs2_to_utf8(const efi_char *nm, char **name) if (len >= sz) { /* Absent bugs, we'll never return EOVERFLOW */ - if (freeit) + if (freeit) { free(*name); + *name = NULL; + } return (EOVERFLOW); } *cp++ = '\0'; @@ -137,6 +139,8 @@ utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len) sz = strlen(name) * 2 + 2; if (*nmp == NULL) *nmp = malloc(sz); + if (*nmp == NULL) + return (ENOMEM); nm = *nmp; *len = sz; @@ -150,11 +154,8 @@ utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len) */ if ((c & 0xc0) != 0x80) { /* Initial characters. */ - if (bytes != 0) { - if (freeit) - free(nm); - return (EILSEQ); - } + if (bytes != 0) + goto ilseq; if ((c & 0xf8) == 0xf0) { ucs4 = c & 0x07; bytes = 3; @@ -173,29 +174,31 @@ utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len) if (bytes > 0) { ucs4 = (ucs4 << 6) + (c & 0x3f); bytes--; - } else if (bytes == 0) { - if (freeit) - free(nm); - return (EILSEQ); - } + } else if (bytes == 0) + goto ilseq; } if (bytes == 0) { - if (ucs4 > 0xffff) { - if (freeit) - free(nm); - return (EILSEQ); - } + if (ucs4 > 0xffff) + goto ilseq; *nm++ = (efi_char)ucs4; sz -= 2; } } if (sz < 2) { - if (freeit) + if (freeit) { free(nm); + *nmp = NULL; + } return (EDOOFUS); } sz -= 2; *nm = 0; *len -= sz; return (0); +ilseq: + if (freeit) { + free(nm); + *nmp = NULL; + } + return (EILSEQ); } diff --git a/stand/efi/libefi/env.c b/stand/efi/libefi/env.c index ceec7b2..6b2d176 100644 --- a/stand/efi/libefi/env.c +++ b/stand/efi/libefi/env.c @@ -34,9 +34,6 @@ __FBSDID("$FreeBSD$"); #include <uuid.h> #include <stdbool.h> #include "bootstrap.h" -#ifdef BOOT_FORTH -#include "ficl.h" -#endif /* * Simple wrappers to the underlying UEFI functions. @@ -375,160 +372,3 @@ command_efi_unset(int argc, char *argv[]) } return (CMD_OK); } - -#ifdef BOOT_FORTH -/* - * FreeBSD's loader interaction words and extras - * - * efi-setenv ( value n name n guid n attr -- 0 | -1) - * efi-getenv ( guid n addr n -- addr' n' | -1 ) - * efi-unsetenv ( name n guid n'' -- ) - */ - -/* - * efi-setenv - * efi-setenv ( value n name n guid n attr -- 0 | -1) - * - * Set environment variables using the SetVariable EFI runtime service. - * - * Value and guid are passed through in binary form (so guid needs to be - * converted to binary form from its string form). Name is converted from - * ASCII to CHAR16. Since ficl doesn't have support for internationalization, - * there's no native CHAR16 interface provided. - * - * attr is an int in the bitmask of the following attributes for this variable. - * - * 1 Non volatile - * 2 Boot service access - * 4 Run time access - * (corresponding to the same bits in the UEFI spec). - */ -static void -ficlEfiSetenv(FICL_VM *pVM) -{ - char *value = NULL, *guid = NULL; - CHAR16 *name = NULL; - int i; - char *namep, *valuep, *guidp; - int names, values, guids, attr; - EFI_STATUS status; - uuid_t u; - uint32_t ustatus; - bool error = true; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 6, 0); -#endif - attr = stackPopINT(pVM->pStack); - guids = stackPopINT(pVM->pStack); - guidp = (char*)stackPopPtr(pVM->pStack); - names = stackPopINT(pVM->pStack); - namep = (char*)stackPopPtr(pVM->pStack); - values = stackPopINT(pVM->pStack); - valuep = (char*)stackPopPtr(pVM->pStack); - - guid = (char*)ficlMalloc(guids); - if (guid == NULL) - goto out; - memcpy(guid, guidp, guids); - uuid_from_string(guid, &u, &ustatus); - if (ustatus != uuid_s_ok) { - stackPushINT(pVM->pStack, -1); - goto out; - } - - name = ficlMalloc((names + 1) * sizeof(CHAR16)); - if (name == NULL) - goto out; - for (i = 0; i < names; i++) - name[i] = namep[i]; - name[names] = 0; - - value = ficlMalloc(values + 1); - if (value == NULL) - goto out; - memcpy(value, valuep, values); - - status = efi_set_variable(name, (EFI_GUID *)&u, attr, values, value); - if (status == EFI_SUCCESS) - stackPushINT(pVM->pStack, 0); - else - stackPushINT(pVM->pStack, -1); - error = false; -out: - ficlFree(name); - ficlFree(value); - ficlFree(guid); - - if (error == true) - vmThrowErr(pVM, "Error: out of memory"); -} - -static void -ficlEfiGetenv(FICL_VM *pVM) -{ - char *name, *value; - char *namep; - int names; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 2, 2); -#endif - names = stackPopINT(pVM->pStack); - namep = (char*) stackPopPtr(pVM->pStack); - - name = (char*) ficlMalloc(names+1); - if (name == NULL) - vmThrowErr(pVM, "Error: out of memory"); - strncpy(name, namep, names); - name[names] = '\0'; - - value = getenv(name); - ficlFree(name); - - if(value != NULL) { - stackPushPtr(pVM->pStack, value); - stackPushINT(pVM->pStack, strlen(value)); - } else - stackPushINT(pVM->pStack, -1); -} - -static void -ficlEfiUnsetenv(FICL_VM *pVM) -{ - char *name; - char *namep; - int names; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 2, 0); -#endif - names = stackPopINT(pVM->pStack); - namep = (char*) stackPopPtr(pVM->pStack); - - name = (char*) ficlMalloc(names+1); - if (name == NULL) - vmThrowErr(pVM, "Error: out of memory"); - strncpy(name, namep, names); - name[names] = '\0'; - - unsetenv(name); - ficlFree(name); -} - -/************************************************************************** -** Add FreeBSD UEFI platform extensions into the system dictionary -**************************************************************************/ -void ficlEfiCompilePlatform(FICL_SYSTEM *pSys) -{ - FICL_DICT *dp = pSys->dp; - assert (dp); - - dictAppendWord(dp, "efi-setenv", ficlEfiSetenv, FW_DEFAULT); - dictAppendWord(dp, "efi-getenv", ficlEfiGetenv, FW_DEFAULT); - dictAppendWord(dp, "efi-unsetenv", ficlEfiUnsetenv, FW_DEFAULT); -} - -FICL_COMPILE_SET(ficlEfiCompilePlatform); - -#endif /* BOOT_FORTH */ diff --git a/stand/efi/loader/Makefile b/stand/efi/loader/Makefile index 7102555..ea920b8 100644 --- a/stand/efi/loader/Makefile +++ b/stand/efi/loader/Makefile @@ -1,7 +1,5 @@ # $FreeBSD$ -MAN= - LOADER_NET_SUPPORT?= yes LOADER_MSDOS_SUPPORT?= yes LOADER_UFS_SUPPORT?= yes @@ -10,8 +8,6 @@ LOADER_EXT2FS_SUPPORT?= no .include <bsd.init.mk> -MK_SSP= no - PROG= loader.sym INTERNALPROG= WARNS?= 3 @@ -129,8 +125,8 @@ loader.efi: ${PROG} LIBEFI= ${BOOTOBJ}/efi/libefi/libefi.a -DPADD= ${LIBFICL} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBZFSBOOT} ${LIBSA} \ +DPADD= ${LDR_INTERP} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBZFSBOOT} ${LIBSA} \ ${LDSCRIPT} -LDADD= ${LIBFICL} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBZFSBOOT} ${LIBSA} +LDADD= ${LDR_INTERP} ${LIBEFI} ${LIBFDT} ${LIBEFI_FDT} ${LIBZFSBOOT} ${LIBSA} .include <bsd.prog.mk> diff --git a/stand/efi/loader/arch/arm/ldscript.arm b/stand/efi/loader/arch/arm/ldscript.arm index 9f6e7c2..68775a8 100644 --- a/stand/efi/loader/arch/arm/ldscript.arm +++ b/stand/efi/loader/arch/arm/ldscript.arm @@ -35,6 +35,7 @@ SECTIONS . = ALIGN(4); PROVIDE (__bss_end = .); } + .dynamic : { *(.dynamic) } /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */ @@ -54,7 +55,6 @@ SECTIONS } __gp = .; .plt : { *(.plt) } - .dynamic : { *(.dynamic) } .reloc : { *(.reloc) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } diff --git a/stand/efi/loader/arch/i386/bootinfo.c b/stand/efi/loader/arch/i386/bootinfo.c deleted file mode 100644 index cbd6e4e..0000000 --- a/stand/efi/loader/arch/i386/bootinfo.c +++ /dev/null @@ -1,275 +0,0 @@ -/*- - * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> - * Copyright (c) 2006 Marcel Moolenaar - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stand.h> -#include <string.h> -#include <sys/param.h> -#include <sys/reboot.h> -#include <sys/linker.h> -#include <sys/boot.h> - -#include <efi.h> -#include <efilib.h> - -#include "bootstrap.h" -#include "libi386.h" -#include <machine/bootinfo.h> - -static const char howto_switches[] = "aCdrgDmphsv"; -static int howto_masks[] = { - RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE, - RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE -}; - -int -bi_getboothowto(char *kargs) -{ - const char *sw; - char *opts; - int howto, i; - - howto = 0; - - /* Get the boot options from the environment first. */ - for (i = 0; howto_names[i].ev != NULL; i++) { - if (getenv(howto_names[i].ev) != NULL) - howto |= howto_names[i].mask; - } - - /* Parse kargs */ - if (kargs == NULL) - return (howto); - - opts = strchr(kargs, '-'); - while (opts != NULL) { - while (*(++opts) != '\0') { - sw = strchr(howto_switches, *opts); - if (sw == NULL) - break; - howto |= howto_masks[sw - howto_switches]; - } - opts = strchr(opts, '-'); - } - - return (howto); -} - -/* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as <name>=<value>, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -vm_offset_t -bi_copyenv(vm_offset_t start) -{ - struct env_var *ep; - vm_offset_t addr, last; - size_t len; - - addr = last = start; - - /* Traverse the environment. */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - len = strlen(ep->ev_name); - if (i386_copyin(ep->ev_name, addr, len) != len) - break; - addr += len; - if (i386_copyin("=", addr, 1) != 1) - break; - addr++; - if (ep->ev_value != NULL) { - len = strlen(ep->ev_value); - if (i386_copyin(ep->ev_value, addr, len) != len) - break; - addr += len; - } - if (i386_copyin("", addr, 1) != 1) - break; - last = ++addr; - } - - if (i386_copyin("", last++, 1) != 1) - last = start; - return(last); -} - -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ARGS (variable) module parameters (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ -#define COPY32(v, a) { \ - u_int32_t x = (v); \ - i386_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s) { \ - COPY32(t, a); \ - COPY32(strlen(s) + 1, a); \ - i386_copyin(s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(u_int64_t));\ -} - -#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s) -#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s) -#define MOD_ARGS(a, s) MOD_STR(MODINFO_ARGS, a, s) - -#define MOD_VAR(t, a, s) { \ - COPY32(t, a); \ - COPY32(sizeof(s), a); \ - i386_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(u_int64_t)); \ -} - -#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s) -#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s) - -#define MOD_METADATA(a, mm) { \ - COPY32(MODINFO_METADATA | mm->md_type, a); \ - COPY32(mm->md_size, a); \ - i386_copyin(mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(u_int64_t));\ -} - -#define MOD_END(a) { \ - COPY32(MODINFO_END, a); \ - COPY32(0, a); \ -} - -vm_offset_t -bi_copymodules(vm_offset_t addr) -{ - struct preloaded_file *fp; - struct file_metadata *md; - - /* Start with the first module on the list, should be the kernel. */ - for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) { - /* The name field must come first. */ - MOD_NAME(addr, fp->f_name); - MOD_TYPE(addr, fp->f_type); - if (fp->f_args) - MOD_ARGS(addr, fp->f_args); - MOD_ADDR(addr, fp->f_addr); - MOD_SIZE(addr, fp->f_size); - for (md = fp->f_metadata; md != NULL; md = md->md_next) { - if (!(md->md_type & MODINFOMD_NOCOPY)) - MOD_METADATA(addr, md); - } - } - MOD_END(addr); - return(addr); -} - -/* - * Load the information expected by the kernel. - * - * - The kernel environment is copied into kernel space. - * - Module metadata are formatted and placed in kernel space. - */ -int -bi_load(struct preloaded_file *fp, uint64_t *bi_addr) -{ - struct bootinfo bi; - struct preloaded_file *xp; - struct file_metadata *md; - struct devdesc *rootdev; - char *rootdevname; - vm_offset_t addr, ssym, esym; - - bzero(&bi, sizeof(struct bootinfo)); - bi.bi_version = 1; -// bi.bi_boothowto = bi_getboothowto(fp->f_args); - - /* - * Allow the environment variable 'rootdev' to override the supplied - * device. This should perhaps go to MI code and/or have $rootdev - * tested/set by MI code before launching the kernel. - */ - rootdevname = getenv("rootdev"); - i386_getdev((void**)&rootdev, rootdevname, NULL); - if (rootdev != NULL) { - /* Try reading /etc/fstab to select the root device. */ - getrootmount(i386_fmtdev(rootdev)); - free(rootdev); - } - - md = file_findmetadata(fp, MODINFOMD_SSYM); - ssym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0; - md = file_findmetadata(fp, MODINFOMD_ESYM); - esym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0; - if (ssym != 0 && esym != 0) { - bi.bi_symtab = ssym; - bi.bi_esymtab = esym; - } - - /* Find the last module in the chain. */ - addr = 0; - for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) { - if (addr < (xp->f_addr + xp->f_size)) - addr = xp->f_addr + xp->f_size; - } - - addr = (addr + 15) & ~15; - - /* Copy module list and metadata. */ - bi.bi_modulep = addr; - addr = bi_copymodules(addr); - if (addr <= bi.bi_modulep) { - addr = bi.bi_modulep; - bi.bi_modulep = 0; - } - - addr = (addr + 15) & ~15; - - /* Copy our environment. */ - bi.bi_envp = addr; - addr = bi_copyenv(addr); - if (addr <= bi.bi_envp) { - addr = bi.bi_envp; - bi.bi_envp = 0; - } - - addr = (addr + PAGE_MASK) & ~PAGE_MASK; - bi.bi_kernend = addr; - - return (ldr_bootinfo(&bi, bi_addr)); -} diff --git a/stand/efi/loader/main.c b/stand/efi/loader/main.c index 516c47e..9b5dfd8 100644 --- a/stand/efi/loader/main.c +++ b/stand/efi/loader/main.c @@ -65,8 +65,12 @@ EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; EFI_GUID mps = MPS_TABLE_GUID; EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL; EFI_GUID smbios = SMBIOS_TABLE_GUID; +EFI_GUID smbios3 = SMBIOS3_TABLE_GUID; EFI_GUID dxe = DXE_SERVICES_TABLE_GUID; EFI_GUID hoblist = HOB_LIST_TABLE_GUID; +EFI_GUID lzmadecomp = LZMA_DECOMPRESSION_GUID; +EFI_GUID mpcore = ARM_MP_CORE_INFO_TABLE_GUID; +EFI_GUID esrt = ESRT_TABLE_GUID; EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID; EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID; EFI_GUID fdtdtb = FDT_TABLE_GUID; @@ -655,10 +659,18 @@ command_configuration(int argc, char *argv[]) else if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) printf("SMBIOS Table %p", ST->ConfigurationTable[i].VendorTable); + else if (!memcmp(guid, &smbios3, sizeof(EFI_GUID))) + printf("SMBIOS3 Table"); else if (!memcmp(guid, &dxe, sizeof(EFI_GUID))) printf("DXE Table"); else if (!memcmp(guid, &hoblist, sizeof(EFI_GUID))) printf("HOB List Table"); + else if (!memcmp(guid, &lzmadecomp, sizeof(EFI_GUID))) + printf("LZMA Compression"); + else if (!memcmp(guid, &mpcore, sizeof(EFI_GUID))) + printf("ARM MpCore Information Table"); + else if (!memcmp(guid, &esrt, sizeof(EFI_GUID))) + printf("ESRT Table"); else if (!memcmp(guid, &memtype, sizeof(EFI_GUID))) printf("Memory Type Information Table"); else if (!memcmp(guid, &debugimg, sizeof(EFI_GUID))) diff --git a/stand/fdt/Makefile b/stand/fdt/Makefile index 3e13441..b4767ed 100644 --- a/stand/fdt/Makefile +++ b/stand/fdt/Makefile @@ -5,7 +5,6 @@ .PATH: ${SYSDIR}/contrib/libfdt/ LIB= fdt -INTERNALLIB= # Vendor sources of libfdt. SRCS+= fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c \ diff --git a/stand/ficl.mk b/stand/ficl.mk index 14ae631..3fe7109 100644 --- a/stand/ficl.mk +++ b/stand/ficl.mk @@ -17,5 +17,4 @@ CFLAGS+= -fPIC .endif CFLAGS+= -I${FICLSRC} -I${FICLSRC}/${FICL_CPUARCH} -I${LDRSRC} -CFLAGS+= -DBOOT_FORTH CFLAGS+= -DBF_DICTSIZE=15000 diff --git a/stand/ficl/Makefile b/stand/ficl/Makefile index a3aad2c..1e64ae0 100644 --- a/stand/ficl/Makefile +++ b/stand/ficl/Makefile @@ -20,7 +20,6 @@ PROG= testmain .include <bsd.prog.mk> .else LIB= ficl -INTERNALLIB= .include <bsd.lib.mk> .endif diff --git a/stand/forth/Makefile b/stand/forth/Makefile index 74d9ed7..3d79dc1 100644 --- a/stand/forth/Makefile +++ b/stand/forth/Makefile @@ -19,7 +19,6 @@ FILES+= brand-fbsd.4th FILES+= check-password.4th FILES+= color.4th FILES+= delay.4th -FILES+= efi.4th FILES+= frames.4th FILES+= loader.4th FILES+= logo-beastie.4th @@ -30,7 +29,6 @@ FILES+= logo-orbbw.4th FILES+= menu.4th FILES+= menu-commands.4th FILES+= menusets.4th -FILES+= pcibios.4th FILES+= screen.4th FILES+= shortcuts.4th FILES+= support.4th diff --git a/stand/forth/loader.4th b/stand/forth/loader.4th index 9486237..6c2f7b3 100644 --- a/stand/forth/loader.4th +++ b/stand/forth/loader.4th @@ -46,9 +46,6 @@ include /boot/support.4th include /boot/color.4th include /boot/delay.4th include /boot/check-password.4th -s" efi-version" getenv? [if] - include /boot/efi.4th -[then] only forth definitions diff --git a/stand/forth/pcibios.4th b/stand/forth/pcibios.4th deleted file mode 100644 index 71702da..0000000 --- a/stand/forth/pcibios.4th +++ /dev/null @@ -1,47 +0,0 @@ -\ Copyright (c) 2014 M. Warner Losh <imp@FreeBSD.org> -\ All rights reserved. -\ -\ Redistribution and use in source and binary forms, with or without -\ modification, are permitted provided that the following conditions -\ are met: -\ 1. Redistributions of source code must retain the above copyright -\ notice, this list of conditions and the following disclaimer. -\ 2. Redistributions in binary form must reproduce the above copyright -\ notice, this list of conditions and the following disclaimer in the -\ documentation and/or other materials provided with the distribution. -\ -\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -\ SUCH DAMAGE. -\ -\ $FreeBSD$ - -only forth also support-functions also builtins definitions - -\ pci-device-count pci-id -\ -\ Counts the number of instances of pci-id in the system and reports -\ it to the user. -: pci-device-count - 0= if ( interpreted ) get_arguments then - - 0= if ." Need an argument" cr abort then - \ First argument is 0 when we're interprated. See support.4th - \ for get_arguments reading the rest of the line and parsing it - \ stack: argN lenN ... arg1 len1 N - hex ?number decimal - 0= if ." Bad pci-id given (must be legal hex value)" cr abort then - dup pcibios-device-count ." Found " . ." instances of " hex . decimal cr -; - -also forth definitions also builtins - -builtin: pci-device-count diff --git a/stand/forth/pnp.4th b/stand/forth/pnp.4th deleted file mode 100644 index 5ce2355..0000000 --- a/stand/forth/pnp.4th +++ /dev/null @@ -1,205 +0,0 @@ -\ Copyright (c) 2000 Daniel C. Sobral <dcs@FreeBSD.org> -\ All rights reserved. -\ -\ Redistribution and use in source and binary forms, with or without -\ modification, are permitted provided that the following conditions -\ are met: -\ 1. Redistributions of source code must retain the above copyright -\ notice, this list of conditions and the following disclaimer. -\ 2. Redistributions in binary form must reproduce the above copyright -\ notice, this list of conditions and the following disclaimer in the -\ documentation and/or other materials provided with the distribution. -\ -\ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -\ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -\ SUCH DAMAGE. -\ -\ $FreeBSD$ - - -\ The following pnp code is used in pnp.4th and pnp.c -structure: STAILQ_HEAD - ptr stqh_first \ type* - ptr stqh_last \ type** -;structure - -structure: STAILQ_ENTRY - ptr stqe_next \ type* -;structure - -structure: pnphandler - ptr pnph.name - ptr pnph.enumerate -;structure - -structure: pnpident - ptr pnpid.ident \ char* - sizeof STAILQ_ENTRY cells member: pnpid.link \ pnpident -;structure - -structure: pnpinfo \ sync with stand/config/bootstrap.h - ptr pnpi.desc - int pnpi.revision - ptr pnpi.module \ (char*) module args - int pnpi.argc - ptr pnpi.argv - ptr pnpi.handler \ pnphandler - sizeof STAILQ_HEAD member: pnpi.ident \ pnpident - sizeof STAILQ_ENTRY member: pnpi.link \ pnpinfo -;structure -\ end of pnp support - -pnpdevices drop - -: enumerate - pnphandlers begin - dup @ - while - ." Probing " dup @ pnph.name @ dup strlen type ." ..." cr - 0 over @ pnph.enumerate @ ccall drop - cell+ - repeat -; - -: summary - ." PNP scan summary:" cr - pnpdevices stqh_first @ - begin - dup - while - dup pnpi.ident stqh_first @ pnpid.ident @ dup strlen type - dup pnpi.desc @ ?dup if - ." : " - dup strlen type - then - cr - pnpi.link stqe_next @ - repeat - drop -; - -: compare-pnpid ( addr addr' -- flag ) - begin - over c@ over c@ <> if drop drop false exit then - over c@ over c@ and - while - char+ swap char+ swap - repeat - c@ swap c@ or 0= -; - -: search-pnpid ( id -- flag ) - >r - pnpdevices stqh_first @ - begin ( pnpinfo ) - dup - while - dup pnpi.ident stqh_first @ - begin ( pnpinfo pnpident ) - dup pnpid.ident @ r@ compare-pnpid - if - r> drop - \ XXX Temporary debugging message - ." Found " pnpid.ident @ dup strlen type - pnpi.desc @ ?dup if - ." : " dup strlen type - then cr - \ drop drop - true - exit - then - pnpid.link stqe_next @ - ?dup 0= - until - pnpi.link stqe_next @ - repeat - r> drop - drop - false -; - -: skip-space ( addr -- addr' ) - begin - dup c@ bl = - over c@ 9 = or - while - char+ - repeat -; - -: skip-to-space ( addr -- addr' ) - begin - dup c@ bl <> - over c@ 9 <> and - over c@ and - while - char+ - repeat -; - -: premature-end? ( addr -- addr flag ) - postpone dup postpone c@ postpone 0= - postpone if postpone exit postpone then -; immediate - -0 value filename -0 value timestamp -0 value id - -only forth also support-functions - -: (load) load ; - -: check-pnpid ( -- ) - line_buffer .addr @ - \ Search for filename - skip-space premature-end? - dup to filename - \ Search for end of filename - skip-to-space premature-end? - 0 over c! char+ - \ Search for timestamp - skip-space premature-end? - dup to timestamp - skip-to-space premature-end? - 0 over c! char+ - \ Search for ids - begin - skip-space premature-end? - dup to id - skip-to-space dup c@ >r - 0 over c! char+ - id search-pnpid if - filename dup strlen 1 ['] (load) catch if - drop drop drop - ." Error loading " filename dup strlen type cr - then - r> drop exit - then - r> 0= - until -; - -: load-pnp - 0 to end_of_file? - reset_line_reading - s" /boot/pnpid.conf" O_RDONLY fopen fd ! - fd @ -1 <> if - begin - end_of_file? 0= - while - read_line - check-pnpid - repeat - fd @ fclose - then -; - diff --git a/stand/geli/Makefile b/stand/geli/Makefile index ce54f82..24faf12 100644 --- a/stand/geli/Makefile +++ b/stand/geli/Makefile @@ -1,16 +1,11 @@ # $FreeBSD$ # libgeliboot -MAN= DO32=1 .include <bsd.init.mk> -MK_SSP= no LIB= geliboot -INTERNALLIB= -MK_PROFILE= no -NO_PIC= # Our password input method SRCS+= pwgets.c diff --git a/stand/i386/boot0/Makefile b/stand/i386/boot0/Makefile index 39c0072..82eb9ee 100644 --- a/stand/i386/boot0/Makefile +++ b/stand/i386/boot0/Makefile @@ -3,7 +3,6 @@ PROG?= boot0 STRIP= BINMODE=${NOBINMODE} -MAN= SRCS= ${PROG}.S # Additional options that you can specify with make OPTS="..." diff --git a/stand/i386/btx/btx/Makefile b/stand/i386/btx/btx/Makefile index f42e20d..8afe98f 100644 --- a/stand/i386/btx/btx/Makefile +++ b/stand/i386/btx/btx/Makefile @@ -4,7 +4,6 @@ PROG= btx INTERNALPROG= -MAN= SRCS= btx.S .if defined(BOOT_BTX_NOHANG) diff --git a/stand/i386/btx/btxldr/Makefile b/stand/i386/btx/btxldr/Makefile index 3279597..6a11276 100644 --- a/stand/i386/btx/btxldr/Makefile +++ b/stand/i386/btx/btxldr/Makefile @@ -4,7 +4,6 @@ PROG= btxldr INTERNALPROG= -MAN= SRCS= btxldr.S CFLAGS+=-DLOADER_ADDRESS=${LOADER_ADDRESS} diff --git a/stand/i386/btx/lib/Makefile b/stand/i386/btx/lib/Makefile index 8de6255..2988f42 100644 --- a/stand/i386/btx/lib/Makefile +++ b/stand/i386/btx/lib/Makefile @@ -4,7 +4,6 @@ PROG= crt0.o INTERNALPROG= -MAN= SRCS= btxcsu.S btxsys.s btxv86.s CFLAGS+=-I${BOOTSRC}/i386/common LDFLAGS+=-Wl,-r diff --git a/stand/i386/cdboot/Makefile b/stand/i386/cdboot/Makefile index 7acd404..093ec49 100644 --- a/stand/i386/cdboot/Makefile +++ b/stand/i386/cdboot/Makefile @@ -5,7 +5,6 @@ PROG= cdboot STRIP= BINMODE=${NOBINMODE} -MAN= SRCS= ${PROG}.S CFLAGS+=-I${BOOTSRC}/i386/common diff --git a/stand/i386/kgzldr/Makefile b/stand/i386/kgzldr/Makefile index 5a03b83..82136f9 100644 --- a/stand/i386/kgzldr/Makefile +++ b/stand/i386/kgzldr/Makefile @@ -6,7 +6,6 @@ PROG= kgzldr.o STRIP= BINMODE=${LIBMODE} BINDIR= ${LIBDIR} -MAN= SRCS= start.s boot.c inflate.c lib.c crt.s sio.s CFLAGS= -Os diff --git a/stand/i386/libfirewire/Makefile b/stand/i386/libfirewire/Makefile index f6e594f..6a34efd 100644 --- a/stand/i386/libfirewire/Makefile +++ b/stand/i386/libfirewire/Makefile @@ -3,7 +3,6 @@ .include <bsd.init.mk> LIB= firewire -INTERNALLIB= .PATH: ${SYSDIR}/dev/dcons ${SYSDIR}/dev/firewire SRCS+= firewire.c fwohci.c dconsole.c diff --git a/stand/i386/libfirewire/firewire.c b/stand/i386/libfirewire/firewire.c index 4840325..e0b0bf9 100644 --- a/stand/i386/libfirewire/firewire.c +++ b/stand/i386/libfirewire/firewire.c @@ -108,11 +108,11 @@ fw_probe(int index, struct fwohci_softc *sc) biospci_write_config(sc->locator, 0x4 /* command */, 0x6 /* enable bus master and memory mapped I/O */, - 1 /* word */); + BIOSPCI_16BITS); - biospci_read_config(sc->locator, 0x00 /*devid*/, 2 /*dword*/, + biospci_read_config(sc->locator, 0x00 /*devid*/, BIOSPCI_32BITS, &sc->devid); - biospci_read_config(sc->locator, 0x10 /*base_addr*/, 2 /*dword*/, + biospci_read_config(sc->locator, 0x10 /*base_addr*/, BIOSPCI_32BITS, &sc->base_addr); sc->handle = (uint32_t)PTOV(sc->base_addr); diff --git a/stand/i386/libi386/Makefile b/stand/i386/libi386/Makefile index f54052c..6825d17 100644 --- a/stand/i386/libi386/Makefile +++ b/stand/i386/libi386/Makefile @@ -5,7 +5,6 @@ HAVE_GELI= yes .include <bsd.init.mk> LIB= i386 -INTERNALLIB= SRCS= biosacpi.c bioscd.c biosdisk.c biosmem.c biospnp.c \ biospci.c biossmap.c bootinfo.c bootinfo32.c bootinfo64.c \ diff --git a/stand/i386/libi386/biospci.c b/stand/i386/libi386/biospci.c index 098e30c..e13a5b9 100644 --- a/stand/i386/libi386/biospci.c +++ b/stand/i386/libi386/biospci.c @@ -38,9 +38,6 @@ __FBSDID("$FreeBSD$"); #include <isapnp.h> #include <btxv86.h> #include "libi386.h" -#ifdef BOOT_FORTH -#include "ficl.h" -#endif /* * Stupid PCI BIOS interface doesn't let you simply enumerate everything @@ -285,7 +282,7 @@ biospci_enumerate(void) break; /* Read the device identifier from the nominated device */ - err = biospci_read_config(locator, 0, 2, &devid); + err = biospci_read_config(locator, 0, BIOSPCI_32BITS, &devid); if (err != 0) break; @@ -406,183 +403,3 @@ biospci_locator(int8_t bus, uint8_t device, uint8_t function) return ((bus << 8) | ((device & 0x1f) << 3) | (function & 0x7)); } - -/* - * Counts the number of instances of devid we have in the system, as least as - * far as the PCI BIOS is able to tell. - */ -static int -biospci_count_device_type(uint32_t devid) -{ - int i; - - for (i = 0; 1; i++) { - v86.ctl = V86_FLAGS; - v86.addr = PCI_INT; - v86.eax = FIND_PCI_DEVICE; - v86.edx = devid & 0xffff; /* EDX - Vendor ID */ - v86.ecx = (devid >> 16) & 0xffff; /* ECX - Device ID */ - v86.esi = i; - v86int(); - if (V86_CY(v86.efl) || (v86.eax & 0xff00)) - break; - - } - return i; -} - -#ifdef BOOT_FORTH -/* - * pcibios-device-count (devid -- count) - * - * Returns the PCI BIOS' count of how many devices matching devid are in the system. - * devid is the 32-bit vendor + device. - */ -static void -ficlPciBiosCountDevices(FICL_VM *pVM) -{ - uint32_t devid; - int i; - - devid = stackPopINT(pVM->pStack); - - i = biospci_count_device_type(devid); - - stackPushINT(pVM->pStack, i); -} - -/* - * pcibios-write-config (locator offset width value -- ) - * - * Writes the specified config register. - * Locator is bus << 8 | device << 3 | fuction - * offset is the pci config register - * width is 0 for byte, 1 for word, 2 for dword - * value is the value to write - */ -static void -ficlPciBiosWriteConfig(FICL_VM *pVM) -{ - uint32_t value, width, offset, locator; - - value = stackPopINT(pVM->pStack); - width = stackPopINT(pVM->pStack); - offset = stackPopINT(pVM->pStack); - locator = stackPopINT(pVM->pStack); - - biospci_write_config(locator, offset, width, value); -} - -/* - * pcibios-read-config (locator offset width -- value) - * - * Reads the specified config register. - * Locator is bus << 8 | device << 3 | fuction - * offset is the pci config register - * width is 0 for byte, 1 for word, 2 for dword - * value is the value to read from the register - */ -static void -ficlPciBiosReadConfig(FICL_VM *pVM) -{ - uint32_t value, width, offset, locator; - - width = stackPopINT(pVM->pStack); - offset = stackPopINT(pVM->pStack); - locator = stackPopINT(pVM->pStack); - - biospci_read_config(locator, offset, width, &value); - - stackPushINT(pVM->pStack, value); -} - -/* - * pcibios-find-devclass (class index -- locator) - * - * Finds the index'th instance of class in the pci tree. - * must be an exact match. - * class is the class to search for. - * index 0..N (set to 0, increment until error) - * - * Locator is bus << 8 | device << 3 | fuction (or -1 on error) - */ -static void -ficlPciBiosFindDevclass(FICL_VM *pVM) -{ - uint32_t index, class, locator; - - index = stackPopINT(pVM->pStack); - class = stackPopINT(pVM->pStack); - - if (biospci_find_devclass(class, index, &locator)) - locator = 0xffffffff; - - stackPushINT(pVM->pStack, locator); -} - -/* - * pcibios-find-device(devid index -- locator) - * - * Finds the index'th instance of devid in the pci tree. - * must be an exact match. - * class is the class to search for. - * index 0..N (set to 0, increment until error) - * - * Locator is bus << 8 | device << 3 | fuction (or -1 on error) - */ -static void -ficlPciBiosFindDevice(FICL_VM *pVM) -{ - uint32_t index, devid, locator; - - index = stackPopINT(pVM->pStack); - devid = stackPopINT(pVM->pStack); - - if (biospci_find_device(devid, index, &locator)) - locator = 0xffffffff; - - stackPushINT(pVM->pStack, locator); -} - -/* - * pcibios-find-device(bus device function -- locator) - * - * converts bus, device, function to locator. - * - * Locator is bus << 8 | device << 3 | fuction - */ -static void -ficlPciBiosLocator(FICL_VM *pVM) -{ - uint32_t bus, device, function, locator; - - function = stackPopINT(pVM->pStack); - device = stackPopINT(pVM->pStack); - bus = stackPopINT(pVM->pStack); - - locator = biospci_locator(bus, device, function); - - stackPushINT(pVM->pStack, locator); -} - -/* - * Glue function to add the appropriate forth words to access pci bios - * functionality. - */ -static void ficlCompilePciBios(FICL_SYSTEM *pSys) -{ - FICL_DICT *dp = pSys->dp; - assert (dp); - - dictAppendWord(dp, "pcibios-device-count", ficlPciBiosCountDevices, FW_DEFAULT); - dictAppendWord(dp, "pcibios-read-config", ficlPciBiosReadConfig, FW_DEFAULT); - dictAppendWord(dp, "pcibios-write-config", ficlPciBiosWriteConfig, FW_DEFAULT); - dictAppendWord(dp, "pcibios-find-devclass", ficlPciBiosFindDevclass, FW_DEFAULT); - dictAppendWord(dp, "pcibios-find-device", ficlPciBiosFindDevice, FW_DEFAULT); - dictAppendWord(dp, "pcibios-locator", ficlPciBiosLocator, FW_DEFAULT); - - ficlSetEnv(pSys, "pcibios-version", biospci_version); -} - -FICL_COMPILE_SET(ficlCompilePciBios); -#endif diff --git a/stand/i386/libi386/comconsole.c b/stand/i386/libi386/comconsole.c index f98a1f7..b9fcf03 100644 --- a/stand/i386/libi386/comconsole.c +++ b/stand/i386/libi386/comconsole.c @@ -263,7 +263,7 @@ comc_pcidev_handle(uint32_t locator) uint32_t port; if (biospci_read_config(locator & 0xffff, - (locator & 0xff0000) >> 16, 2, &port) == -1) { + (locator & 0xff0000) >> 16, BIOSPCI_32BITS, &port) == -1) { printf("Cannot read bar at 0x%x\n", locator); return (CMD_ERROR); } diff --git a/stand/i386/libi386/libi386.h b/stand/i386/libi386/libi386.h index e65a060..297d493 100644 --- a/stand/i386/libi386/libi386.h +++ b/stand/i386/libi386/libi386.h @@ -135,6 +135,13 @@ extern vm_offset_t memtop_copyin; /* memtop less heap size for the cases */ extern uint32_t high_heap_size; /* extended memory region available */ extern vm_offset_t high_heap_base; /* for use as the heap */ +/* + * Values for width parameter to biospci_{read,write}_config + */ +#define BIOSPCI_8BITS 0 +#define BIOSPCI_16BITS 1 +#define BIOSPCI_32BITS 2 + void biospci_detect(void); int biospci_find_devclass(uint32_t class, int index, uint32_t *locator); int biospci_read_config(uint32_t locator, int offset, int width, uint32_t *val); diff --git a/stand/i386/loader/Makefile b/stand/i386/loader/Makefile index ca0d822..92ac5b9 100644 --- a/stand/i386/loader/Makefile +++ b/stand/i386/loader/Makefile @@ -14,11 +14,8 @@ LOADER_BZIP2_SUPPORT?= yes .include <bsd.init.mk> -MK_SSP= no - LOADER?= loader PROG= ${LOADER}.sym -MAN= INTERNALPROG= NEWVERSWHAT?= "bootstrap loader" x86 VERSION_FILE= ${.CURDIR}/../loader/version @@ -74,8 +71,8 @@ FILESMODE_${LOADER}= ${BINMODE} -b # XXX crt0.o needs to be first for pxeboot(8) to work OBJS= ${BTXCRT} -DPADD= ${LIBFICL32} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32} -LDADD= ${LIBFICL32} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32} +DPADD= ${LDR_INTERP32} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32} +LDADD= ${LDR_INTERP32} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSA32} .if ${MACHINE_CPUARCH} == "amd64" CFLAGS+= -DLOADER_PREFER_AMD64 diff --git a/stand/i386/mbr/Makefile b/stand/i386/mbr/Makefile index 9bfa0bd..26018ff 100644 --- a/stand/i386/mbr/Makefile +++ b/stand/i386/mbr/Makefile @@ -3,7 +3,6 @@ PROG= mbr STRIP= BINMODE=${NOBINMODE} -MAN= SRCS= ${PROG}.s # MBR flags: 0x80 -- try packet interface (also known as EDD or LBA) diff --git a/stand/i386/pmbr/Makefile b/stand/i386/pmbr/Makefile index 1bfe0ee..bfd6209 100644 --- a/stand/i386/pmbr/Makefile +++ b/stand/i386/pmbr/Makefile @@ -3,7 +3,6 @@ PROG= pmbr STRIP= BINMODE=${NOBINMODE} -MAN= SRCS= ${PROG}.s ORG= 0x600 diff --git a/stand/kshim/bsd_kernel.h b/stand/kshim/bsd_kernel.h index 66106ac..4dfe307 100644 --- a/stand/kshim/bsd_kernel.h +++ b/stand/kshim/bsd_kernel.h @@ -50,6 +50,8 @@ #define USB_BUS_EXPLORE_PROC(bus) (usb_process + 0) #define USB_BUS_CONTROL_XFER_PROC(bus) (usb_process + 1) #define SYSCTL_DECL(...) +struct sysctl_ctx_list { +}; struct sysctl_req { void *newptr; }; @@ -59,6 +61,13 @@ struct sysctl_req { #define SYSCTL_INT(...) #define SYSCTL_UINT(...) #define SYSCTL_PROC(...) +#define SYSCTL_ADD_NODE(...) NULL +#define SYSCTL_ADD_U16(...) NULL +#define SYSCTL_ADD_PROC(...) NULL +#define sysctl_handle_int(...) EOPNOTSUPP +#define sysctl_handle_string(...) EOPNOTSUPP +#define sysctl_ctx_init(ctx) do { (void)(ctx); } while (0) +#define sysctl_ctx_free(ctx) do { (void)(ctx); } while (0) #define TUNABLE_INT(...) #define MALLOC_DECLARE(...) #define MALLOC_DEFINE(...) @@ -178,6 +187,10 @@ struct thread; struct malloc_type; struct usb_process; +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff +#endif + #ifndef HAVE_STANDARD_DEFS #define _UINT8_T_DECLARED typedef unsigned char uint8_t; diff --git a/stand/libsa/Makefile b/stand/libsa/Makefile index ff50dd6..988ac30 100644 --- a/stand/libsa/Makefile +++ b/stand/libsa/Makefile @@ -6,18 +6,12 @@ # quite large. # -PACKAGE=lib${LIB} -MK_PROFILE= no -MK_SSP= no - .include <bsd.init.mk> -INTERNALLIB= LIBSA_CPUARCH?=${MACHINE_CPUARCH} LIBC_SRC= ${SRCTOP}/lib/libc LIB?= sa -NO_PIC= # standalone components and stuff we have modified locally SRCS+= gzguts.h zutil.h __main.c abort.c assert.c bcd.c environment.c getopt.c gets.c \ diff --git a/stand/libsa/environment.c b/stand/libsa/environment.c index 83349f1..36409cc 100644 --- a/stand/libsa/environment.c +++ b/stand/libsa/environment.c @@ -138,6 +138,7 @@ env_setenv(const char *name, int flags, const void *value, return(0); } +/* coverity[ -tainted_string_return_content ] */ char * getenv(const char *name) { diff --git a/stand/libsa/libstand.3 b/stand/libsa/libsa.3 index acb979f..0c9fbf6 100644 --- a/stand/libsa/libstand.3 +++ b/stand/libsa/libsa.3 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 6, 2004 +.Dd February 1, 2018 .Dt LIBSTAND 3 .Os .Sh NAME @@ -161,6 +161,10 @@ may be used to prevent a variable being unset. .Bl -hang -width 10n .It Xo .Ft int +.Fn abs "int i" +.Xc +.It Xo +.Ft int .Fn getopt "int argc" "char * const *argv" "const char *optstring" .Xc .It Xo @@ -168,8 +172,20 @@ may be used to prevent a variable being unset. .Fn strtol "const char *nptr" "char **endptr" "int base" .Xc .It Xo +.Ft long long +.Fn strtoll "const char *nptr" "char **endptr" "int base" +.Xc +.It Xo +.Ft long +.Fn strtoul "const char *nptr" "char **endptr" "int base" +.Xc +.It Xo +.Ft long long +.Fn strtoull "const char *nptr" "char **endptr" "int base" +.Xc +.It Xo .Ft void -.Fn srandom "unsigned long seed" +.Fn srandom "unsigned int seed" .Xc .It Xo .Ft "long" @@ -350,6 +366,22 @@ ptr, .Xc .It Xo .Ft int +.Fn isalnum "int c" +.Xc +.It Xo +.Ft int +.Fn iscntrl "int c" +.Xc +.It Xo +.Ft int +.Fn isgraph "int c" +.Xc +.It Xo +.Ft int +.Fn ispunct "int c" +.Xc +.It Xo +.Ft int .Fn toupper "int c" .Xc .It Xo @@ -583,6 +615,14 @@ The device driver itself will already have been called for the close; this call should clean up any allocation made by devopen only. .It Xo .Ft void +.Fn abort +.Xc +.Pp +Calls +.Fn panic +with a fixed string. +.It Xo +.Ft void .Fn panic "const char *msg" "..." .Xc .Pp diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h index dd94b48..6968c3e 100644 --- a/stand/libsa/stand.h +++ b/stand/libsa/stand.h @@ -68,6 +68,7 @@ /* this header intentionally exports NULL from <string.h> */ #include <string.h> +#define strcoll(a, b) strcmp((a), (b)) #define CHK(fmt, args...) printf("%s(%d): " fmt "\n", __func__, __LINE__ , ##args) #define PCHK(fmt, args...) {printf("%s(%d): " fmt "\n", __func__, __LINE__ , ##args); getchar();} diff --git a/stand/loader.mk b/stand/loader.mk index b811c93..e2c4718 100644 --- a/stand/loader.mk +++ b/stand/loader.mk @@ -61,6 +61,8 @@ SRCS+= pnp.c .if ${MK_FORTH} != "no" SRCS+= interp_forth.c .include "${BOOTSRC}/ficl.mk" +.else +SRCS+= interp_simple.c .endif .if defined(BOOT_PROMPT_123) @@ -128,14 +130,15 @@ LIBZFSBOOT= ${BOOTOBJ}/zfs/libzfsboot.a .endif .endif -# NB: The makefiles depend on these being empty when we don't build forth. -.if ${MK_FORTH} != "no" LIBFICL= ${BOOTOBJ}/ficl/libficl.a .if ${MACHINE} == "i386" LIBFICL32= ${LIBFICL} .else LIBFICL32= ${BOOTOBJ}/ficl32/libficl.a .endif +.if ${MK_FORTH} != no +LDR_INTERP= ${LIBFICL} +LDR_INTERP32= ${LIBFICL32} .endif CLEANFILES+= vers.c diff --git a/stand/mips/beri/boot2/Makefile b/stand/mips/beri/boot2/Makefile index ce09b6e..f4b433c 100644 --- a/stand/mips/beri/boot2/Makefile +++ b/stand/mips/beri/boot2/Makefile @@ -43,8 +43,6 @@ SRCS= relocate.S \ cfi.c \ sdcard.c -MAN= - AFLAGS= -G0 CFLAGS+= -I${LDRSRC} \ diff --git a/stand/mips/beri/boot2/boot2.c b/stand/mips/beri/boot2/boot2.c index 4e15b64..3c8cc3d 100644 --- a/stand/mips/beri/boot2/boot2.c +++ b/stand/mips/beri/boot2/boot2.c @@ -118,8 +118,6 @@ static const unsigned char flags[NOPT] = { static const char *const dev_nm[] = {"dram", "cfi", "sdcard"}; static const u_int dev_nm_count = nitems(dev_nm); -static struct dmadat __dmadat; - static struct dsk { unsigned type; /* BOOTINFO_DEV_TYPE_x object type. */ uintptr_t unitptr; /* Unit number or pointer to object. */ @@ -148,10 +146,11 @@ static int dskread(void *, unsigned, unsigned); static int xputc(int); static int xgetc(int); - #define UFS_SMALL_CGBASE #include "ufsread.c" +static struct dmadat __dmadat; + static inline int xfsread(ufs_ino_t inode, void *buf, size_t nbyte) { diff --git a/stand/mips/beri/loader/Makefile b/stand/mips/beri/loader/Makefile index 46b927f..f8c1bd9 100644 --- a/stand/mips/beri/loader/Makefile +++ b/stand/mips/beri/loader/Makefile @@ -38,9 +38,6 @@ LOADER_BZIP2_SUPPORT?= yes .include <bsd.init.mk> -MK_SSP= no -MAN= - PROG?= loader NEWVERSWHAT= "BERI loader" ${MACHINE_CPUARCH} INSTALLFLAGS= -b @@ -90,8 +87,8 @@ LDFLAGS+= -static \ -L${.CURDIR} \ -e __start -DPADD= ${LIBFICL} ${LIBSA} -LDADD= ${LIBFICL} ${LIBSA} +DPADD= ${LDR_INTERP} ${LIBSA} +LDADD= ${LDR_INTERP} ${LIBSA} .if defined(LOADER_USB_SUPPORT) # Do garbage collection diff --git a/stand/mips/beri/loader/exec.c b/stand/mips/beri/loader/exec.c index 68e149d..3c1b7a6 100644 --- a/stand/mips/beri/loader/exec.c +++ b/stand/mips/beri/loader/exec.c @@ -80,14 +80,14 @@ beri_elf64_exec(struct preloaded_file *fp) md = file_findmetadata(fp, MODINFOMD_ELFHDR); if (md == NULL) { - printf("%s: file_findmetadata failed\n"); + printf("%s: file_findmetadata failed\n", fp->f_name); return (EFTYPE); } ehdr = (Elf_Ehdr *)md->md_data; error = md_load64(fp->f_args, &mdp); if (error) { - printf("%s: md_load64 failed\n"); + printf("%s: md_load64 failed\n", fp->f_name); return (error); } diff --git a/stand/mips/uboot/Makefile b/stand/mips/uboot/Makefile index 4a7350a..4323f45 100644 --- a/stand/mips/uboot/Makefile +++ b/stand/mips/uboot/Makefile @@ -35,8 +35,8 @@ LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.${MACHINE_CPUARCH} .include "${BOOTSRC}/uboot.mk" -DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} -LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} +DPADD= ${LDR_INTERP} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} +LDADD= ${LDR_INTERP} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} OBJS+= ${SRCS:N*.h:R:S/$/.o/g} diff --git a/stand/ofw/common/main.c b/stand/ofw/common/main.c index 128542c9..b8c7a17 100644 --- a/stand/ofw/common/main.c +++ b/stand/ofw/common/main.c @@ -42,23 +42,17 @@ u_int32_t acells, scells; static char bootargs[128]; -#define HEAP_SIZE 0x100000 +#define HEAP_SIZE 0x800000 +static char heap[HEAP_SIZE]; // In BSS, so uses no space #define OF_puts(fd, text) OF_write(fd, text, strlen(text)) void init_heap(void) { - void *base; - ihandle_t stdout; + bzero(heap, HEAP_SIZE); - if ((base = ofw_alloc_heap(HEAP_SIZE)) == (void *)0xffffffff) { - OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)); - OF_puts(stdout, "Heap memory claim failed!\n"); - OF_enter(); - } - - setheap(base, (void *)((int)base + HEAP_SIZE)); + setheap(heap, (void *)((int)heap + HEAP_SIZE)); } uint64_t diff --git a/stand/ofw/libofw/Makefile b/stand/ofw/libofw/Makefile index 6818e27..80ca993 100644 --- a/stand/ofw/libofw/Makefile +++ b/stand/ofw/libofw/Makefile @@ -3,7 +3,6 @@ .include <bsd.init.mk> LIB= ofw -INTERNALLIB= SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_disk.c \ ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \ diff --git a/stand/ofw/libofw/elf_freebsd.c b/stand/ofw/libofw/elf_freebsd.c index a2e48a7..456b0cd 100644 --- a/stand/ofw/libofw/elf_freebsd.c +++ b/stand/ofw/libofw/elf_freebsd.c @@ -87,7 +87,6 @@ __elfN(ofw_exec)(struct preloaded_file *fp) printf("Kernel entry at 0x%lx ...\n", e->e_entry); dev_cleanup(); - ofw_release_heap(); if (dtbp != 0) { OF_quiesce(); ((int (*)(u_long, u_long, u_long, void *, u_long))entry)(dtbp, 0, 0, diff --git a/stand/ofw/libofw/libofw.h b/stand/ofw/libofw/libofw.h index b8c4014..24a5d08 100644 --- a/stand/ofw/libofw/libofw.h +++ b/stand/ofw/libofw/libofw.h @@ -58,8 +58,6 @@ extern int ofw_boot(void); extern int ofw_autoload(void); void ofw_memmap(int); -void *ofw_alloc_heap(unsigned int); -void ofw_release_heap(void); struct preloaded_file; struct file_format; diff --git a/stand/ofw/libofw/ofw_copy.c b/stand/ofw/libofw/ofw_copy.c index ffd6987..d83dbed 100644 --- a/stand/ofw/libofw/ofw_copy.c +++ b/stand/ofw/libofw/ofw_copy.c @@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$"); #define READIN_BUF (4 * 1024) #define PAGE_SIZE 0x1000 #define PAGE_MASK 0x0fff -#define MAPMEM_PAGE_INC 16 +#define MAPMEM_PAGE_INC 128 /* Half-MB at a time */ #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) diff --git a/stand/ofw/libofw/ofw_memory.c b/stand/ofw/libofw/ofw_memory.c index 5616184..f05881e 100644 --- a/stand/ofw/libofw/ofw_memory.c +++ b/stand/ofw/libofw/ofw_memory.c @@ -35,9 +35,6 @@ __FBSDID("$FreeBSD$"); #include "libofw.h" #include "openfirm.h" -static void *heap_base = NULL; -static unsigned int heap_size = 0; - struct ofw_mapping { vm_offset_t va; int len; @@ -115,32 +112,3 @@ ofw_memmap(int acells) pager_close(); } -void * -ofw_alloc_heap(unsigned int size) -{ - phandle_t memoryp, root; - cell_t available[4]; - cell_t acells; - - root = OF_finddevice("/"); - acells = 1; - OF_getprop(root, "#address-cells", &acells, sizeof(acells)); - - memoryp = OF_instance_to_package(memory); - OF_getprop(memoryp, "available", available, sizeof(available)); - - heap_base = OF_claim((void *)available[acells-1], size, - sizeof(register_t)); - - if (heap_base != (void *)-1) { - heap_size = size; - } - - return (heap_base); -} - -void -ofw_release_heap(void) -{ - OF_release(heap_base, heap_size); -} diff --git a/stand/ofw/libofw/ppc64_elf_freebsd.c b/stand/ofw/libofw/ppc64_elf_freebsd.c index 9132e9d..6d85029 100644 --- a/stand/ofw/libofw/ppc64_elf_freebsd.c +++ b/stand/ofw/libofw/ppc64_elf_freebsd.c @@ -90,7 +90,6 @@ ppc64_ofw_elf_exec(struct preloaded_file *fp) printf("Kernel entry at 0x%lx ...\n", entry); dev_cleanup(); - ofw_release_heap(); if (dtbp != 0) { OF_quiesce(); diff --git a/stand/powerpc/boot1.chrp/Makefile b/stand/powerpc/boot1.chrp/Makefile index d865248..8fbc1e5 100644 --- a/stand/powerpc/boot1.chrp/Makefile +++ b/stand/powerpc/boot1.chrp/Makefile @@ -9,8 +9,6 @@ INSTALLFLAGS= -b FILES= boot1.hfs SRCS= boot1.c ashldi3.c syncicache.c -MAN= - CFLAGS+=-I${LDRSRC} LDFLAGS=-nostdlib -static -Wl,-N diff --git a/stand/powerpc/kboot/Makefile b/stand/powerpc/kboot/Makefile index e91421d..d5b2025 100644 --- a/stand/powerpc/kboot/Makefile +++ b/stand/powerpc/kboot/Makefile @@ -11,8 +11,6 @@ LOADER_GZIP_SUPPORT?= yes LOADER_BZIP2_SUPPORT?= no .include <bsd.init.mk> -MK_SSP= no -MAN= PROG= loader.kboot NEWVERSWHAT= "kboot loader" ${MACHINE_ARCH} @@ -41,7 +39,7 @@ LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc # 64-bit bridge extensions CFLAGS+= -Wa,-mppc64bridge -DPADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSA} -LDADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSA} +DPADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA} +LDADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA} .include <bsd.prog.mk> diff --git a/stand/powerpc/kboot/conf.c b/stand/powerpc/kboot/conf.c index 104dd93..22562e8 100644 --- a/stand/powerpc/kboot/conf.c +++ b/stand/powerpc/kboot/conf.c @@ -78,6 +78,7 @@ struct fs_ops *file_system[] = { #if defined(LOADER_BZIP2_SUPPORT) &bzipfs_fsops, #endif + &dosfs_fsops, NULL }; diff --git a/stand/powerpc/kboot/host_syscall.S b/stand/powerpc/kboot/host_syscall.S index 3607fdb..1cb9016 100644 --- a/stand/powerpc/kboot/host_syscall.S +++ b/stand/powerpc/kboot/host_syscall.S @@ -14,7 +14,6 @@ ENTRY(host_read) li %r3, 0 blr - ENTRY(host_write) li %r0, 4 # SYS_write sc @@ -28,6 +27,11 @@ ENTRY(host_seek) sc blr +ENTRY(host_llseek) + li %r0, 140 # SYS_llseek + sc + blr + ENTRY(host_open) li %r0, 5 # SYS_open sc @@ -47,6 +51,11 @@ ENTRY(host_mmap) sc blr +ENTRY(host_uname) + li %r0, 122 # SYS_uname + sc + blr + ENTRY(host_gettimeofday) li %r0, 78 # SYS_gettimeofday sc diff --git a/stand/powerpc/kboot/host_syscall.h b/stand/powerpc/kboot/host_syscall.h index 349c54e..50b0725 100644 --- a/stand/powerpc/kboot/host_syscall.h +++ b/stand/powerpc/kboot/host_syscall.h @@ -34,9 +34,18 @@ ssize_t host_read(int fd, void *buf, size_t nbyte); ssize_t host_write(int fd, const void *buf, size_t nbyte); ssize_t host_seek(int fd, int64_t offset, int whence); int host_open(const char *path, int flags, int mode); +ssize_t host_llseek(int fd, int32_t offset_high, int32_t offset_lo, uint64_t *result, int whence); int host_close(int fd); void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, int); #define host_getmem(size) host_mmap(0, size, 3 /* RW */, 0x22 /* ANON */, -1, 0); +struct old_utsname { + char sysname[65]; + char nodename[65]; + char release[65]; + char version[65]; + char machine[65]; +}; +int host_uname(struct old_utsname *); struct host_timeval { int tv_sec; int tv_usec; @@ -44,8 +53,8 @@ struct host_timeval { int host_gettimeofday(struct host_timeval *a, void *b); int host_select(int nfds, long *readfds, long *writefds, long *exceptfds, struct host_timeval *timeout); -int kexec_load(vm_offset_t start, int nsegs, void *segs); -int host_reboot(int, int, int, void *); +int kexec_load(uint32_t start, int nsegs, uint32_t segs); +int host_reboot(int, int, int, uint32_t); int host_getdents(int fd, void *dirp, int count); #endif diff --git a/stand/powerpc/kboot/hostdisk.c b/stand/powerpc/kboot/hostdisk.c index 26d3959..3c36f2d 100644 --- a/stand/powerpc/kboot/hostdisk.c +++ b/stand/powerpc/kboot/hostdisk.c @@ -64,10 +64,14 @@ hostdisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size, struct devdesc *desc = devdata; daddr_t pos; int n; - + uint64_t res; + uint32_t posl, posh; + pos = dblk * 512; - if (host_seek(desc->d_unit, pos, 0) < 0) { + posl = pos & 0xffffffff; + posh = (pos >> 32) & 0xffffffff; + if (host_llseek(desc->d_unit, posh, posl, &res, 0) < 0) { printf("Seek error\n"); return (EIO); } diff --git a/stand/powerpc/kboot/kerneltramp.S b/stand/powerpc/kboot/kerneltramp.S index a394c95..15fdfc2 100644 --- a/stand/powerpc/kboot/kerneltramp.S +++ b/stand/powerpc/kboot/kerneltramp.S @@ -20,6 +20,18 @@ CNAME(kerneltramp): bl 2f .space 24 /* branch address, r3-r7 */ +/* + * MUST BE IN SYNC WITH: + * struct trampoline_data { + * uint32_t kernel_entry; + * uint32_t dtb; + * uint32_t phys_mem_offset; + * uint32_t of_entry; + * uint32_t mdp; + * uint32_t mdp_size; + * }; + */ + . = kerneltramp + 0x40 /* AP spinlock */ .long 0 @@ -36,18 +48,53 @@ CNAME(kerneltramp): sync ba 0x100 -2: /* Continuation of kerneltramp */ +2: /* Continuation of kerneltramp */ mflr %r8 mtlr %r9 - lwz %r3,0(%r8) - mtctr %r3 + + mfmsr %r10 + andi. %r10, %r10, 1 /* test MSR_LE */ + bne little_endian + +/* We're starting in BE */ +big_endian: lwz %r3,4(%r8) lwz %r4,8(%r8) lwz %r5,12(%r8) lwz %r6,16(%r8) lwz %r7,20(%r8) + + lwz %r10, 0(%r8) + mtctr %r10 bctr - + +/* We're starting in LE */ +little_endian: + + /* Entries are BE, swap them during load. */ + li %r10, 4 + lwbrx %r3, %r8, %r10 + li %r10, 8 + lwbrx %r4, %r8, %r10 + li %r10, 12 + lwbrx %r5, %r8, %r10 + li %r10, 16 + lwbrx %r6, %r8, %r10 + li %r10, 20 + lwbrx %r7, %r8, %r10 + + /* Clear MSR_LE flag to enter the BE world */ + mfmsr %r10 + clrrdi %r10, %r10, 1 + mtsrr1 %r10 + + /* Entry is at 0(%r8) */ + li %r10, 0 + lwbrx %r10, %r8, %r10 + mtsrr0 %r10 + + rfid + endkerneltramp: .data diff --git a/stand/powerpc/kboot/main.c b/stand/powerpc/kboot/main.c index cbd1161..d4f59ab 100644 --- a/stand/powerpc/kboot/main.c +++ b/stand/powerpc/kboot/main.c @@ -27,6 +27,7 @@ __FBSDID("$FreeBSD$"); #include <stand.h> +#include <sys/endian.h> #include <sys/param.h> #include <fdt_platform.h> @@ -35,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include "bootstrap.h" #include "host_syscall.h" + struct arch_switch archsw; extern void *_end; @@ -47,9 +49,170 @@ ssize_t kboot_readin(const int fd, vm_offset_t dest, const size_t len); int kboot_autoload(void); uint64_t kboot_loadaddr(u_int type, void *data, uint64_t addr); int kboot_setcurrdev(struct env_var *ev, int flags, const void *value); +static void kboot_kseg_get(int *nseg, void **ptr); extern int command_fdt_internal(int argc, char *argv[]); +struct region_desc { + uint64_t start; + uint64_t end; +}; + +static uint64_t +kboot_get_phys_load_segment(void) +{ + int fd; + uint64_t entry[2]; + static uint64_t load_segment = ~(0UL); + uint64_t val_64; + uint32_t val_32; + struct region_desc rsvd_reg[32]; + int rsvd_reg_cnt = 0; + int ret, a, b; + uint64_t start, end; + + if (load_segment == ~(0UL)) { + + /* Default load address is 0x00000000 */ + load_segment = 0UL; + + /* Read reserved regions */ + fd = host_open("/proc/device-tree/reserved-ranges", O_RDONLY, 0); + if (fd >= 0) { + while (host_read(fd, &entry[0], sizeof(entry)) == sizeof(entry)) { + rsvd_reg[rsvd_reg_cnt].start = be64toh(entry[0]); + rsvd_reg[rsvd_reg_cnt].end = + be64toh(entry[1]) + rsvd_reg[rsvd_reg_cnt].start - 1; + rsvd_reg_cnt++; + } + host_close(fd); + } + /* Read where the kernel ends */ + fd = host_open("/proc/device-tree/chosen/linux,kernel-end", O_RDONLY, 0); + if (fd >= 0) { + ret = host_read(fd, &val_64, sizeof(val_64)); + + if (ret == sizeof(uint64_t)) { + rsvd_reg[rsvd_reg_cnt].start = 0; + rsvd_reg[rsvd_reg_cnt].end = be64toh(val_64) - 1; + } else { + memcpy(&val_32, &val_64, sizeof(val_32)); + rsvd_reg[rsvd_reg_cnt].start = 0; + rsvd_reg[rsvd_reg_cnt].end = be32toh(val_32) - 1; + } + rsvd_reg_cnt++; + + host_close(fd); + } + /* Read memory size (SOCKET0 only) */ + fd = host_open("/proc/device-tree/memory@0/reg", O_RDONLY, 0); + if (fd < 0) + fd = host_open("/proc/device-tree/memory/reg", O_RDONLY, 0); + if (fd >= 0) { + ret = host_read(fd, &entry, sizeof(entry)); + + /* Memory range in start:length format */ + entry[0] = be64toh(entry[0]); + entry[1] = be64toh(entry[1]); + + /* Reserve everything what is before start */ + if (entry[0] != 0) { + rsvd_reg[rsvd_reg_cnt].start = 0; + rsvd_reg[rsvd_reg_cnt].end = entry[0] - 1; + rsvd_reg_cnt++; + } + /* Reserve everything what is after end */ + if (entry[1] != 0xffffffffffffffffUL) { + rsvd_reg[rsvd_reg_cnt].start = entry[0] + entry[1]; + rsvd_reg[rsvd_reg_cnt].end = 0xffffffffffffffffUL; + rsvd_reg_cnt++; + } + + host_close(fd); + } + + /* Sort entries in ascending order (bubble) */ + for (a = rsvd_reg_cnt - 1; a > 0; a--) { + for (b = 0; b < a; b++) { + if (rsvd_reg[b].start > rsvd_reg[b + 1].start) { + struct region_desc tmp; + tmp = rsvd_reg[b]; + rsvd_reg[b] = rsvd_reg[b + 1]; + rsvd_reg[b + 1] = tmp; + } + } + } + + /* Join overlapping/adjacent regions */ + for (a = 0; a < rsvd_reg_cnt - 1; ) { + + if ((rsvd_reg[a + 1].start >= rsvd_reg[a].start) && + ((rsvd_reg[a + 1].start - 1) <= rsvd_reg[a].end)) { + /* We have overlapping/adjacent regions! */ + rsvd_reg[a].end = + MAX(rsvd_reg[a].end, rsvd_reg[a + a].end); + + for (b = a + 1; b < rsvd_reg_cnt - 1; b++) + rsvd_reg[b] = rsvd_reg[b + 1]; + rsvd_reg_cnt--; + } else + a++; + } + + /* Find the first free region */ + if (rsvd_reg_cnt > 0) { + start = 0; + end = rsvd_reg[0].start; + for (a = 0; a < rsvd_reg_cnt - 1; a++) { + if ((start >= rsvd_reg[a].start) && + (start <= rsvd_reg[a].end)) { + start = rsvd_reg[a].end + 1; + end = rsvd_reg[a + 1].start; + } else + break; + } + + if (start != end) { + uint64_t align = 64UL*1024UL*1024UL; + + /* Align both to 64MB boundary */ + start = (start + align - 1UL) & ~(align - 1UL); + end = ((end + 1UL) & ~(align - 1UL)) - 1UL; + + if (start < end) + load_segment = start; + } + } + } + + return (load_segment); +} + +uint8_t +kboot_get_kernel_machine_bits(void) +{ + static uint8_t bits = 0; + struct old_utsname utsname; + int ret; + + if (bits == 0) { + /* Default is 32-bit kernel */ + bits = 32; + + /* Try to get system type */ + memset(&utsname, 0, sizeof(utsname)); + ret = host_uname(&utsname); + if (ret == 0) { + if (strcmp(utsname.machine, "ppc64") == 0) + bits = 64; + else if (strcmp(utsname.machine, "ppc64le") == 0) + bits = 64; + } + } + + return (bits); +} + int kboot_getdev(void **vdev, const char *devspec, const char **path) { @@ -94,7 +257,7 @@ main(int argc, const char **argv) { void *heapbase; const size_t heapsize = 15*1024*1024; - const char *bootdev = argv[1]; + const char *bootdev; /* * Set the heap to one page after the end of the loader. @@ -107,6 +270,12 @@ main(int argc, const char **argv) */ cons_probe(); + /* Choose bootdev if provided */ + if (argc > 1) + bootdev = argv[1]; + else + bootdev = ""; + printf("Boot device: %s\n", bootdev); archsw.arch_getdev = kboot_getdev; @@ -115,6 +284,7 @@ main(int argc, const char **argv) archsw.arch_readin = kboot_readin; archsw.arch_autoload = kboot_autoload; archsw.arch_loadaddr = kboot_loadaddr; + archsw.arch_kexec_kseg_get = kboot_kseg_get; printf("\n%s", bootprog_info); @@ -181,7 +351,7 @@ static ssize_t get_phys_buffer(vm_offset_t dest, const size_t len, void **buf) { int i = 0; - const size_t segsize = 2*1024*1024; + const size_t segsize = 4*1024*1024; for (i = 0; i < nkexec_segments; i++) { if (dest >= (vm_offset_t)loaded_segments[i].mem && @@ -194,6 +364,7 @@ get_phys_buffer(vm_offset_t dest, const size_t len, void **buf) loaded_segments[nkexec_segments].bufsz = segsize; loaded_segments[nkexec_segments].mem = (void *)rounddown2(dest,segsize); loaded_segments[nkexec_segments].memsz = segsize; + i = nkexec_segments; nkexec_segments++; @@ -283,19 +454,34 @@ kboot_autoload(void) uint64_t kboot_loadaddr(u_int type, void *data, uint64_t addr) { - /* - * Need to stay out of the way of Linux. /chosen/linux,kernel-end does - * a better job here, but use a fixed offset for now. - */ if (type == LOAD_ELF) addr = roundup(addr, PAGE_SIZE); else - addr += 64*1024*1024; /* Stay out of the way of Linux */ + addr += kboot_get_phys_load_segment(); return (addr); } +static void +kboot_kseg_get(int *nseg, void **ptr) +{ +#if 0 + int a; + + for (a = 0; a < nkexec_segments; a++) { + printf("kseg_get: %jx %jx %jx %jx\n", + (uintmax_t)loaded_segments[a].buf, + (uintmax_t)loaded_segments[a].bufsz, + (uintmax_t)loaded_segments[a].mem, + (uintmax_t)loaded_segments[a].memsz); + } +#endif + + *nseg = nkexec_segments; + *ptr = &loaded_segments[0]; +} + void _start(int argc, const char **argv, char **env) { diff --git a/stand/powerpc/kboot/metadata.c b/stand/powerpc/kboot/metadata.c index 1e8c314..2892ce506 100644 --- a/stand/powerpc/kboot/metadata.c +++ b/stand/powerpc/kboot/metadata.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include <stand.h> #include <sys/param.h> +#include <sys/endian.h> #include <sys/reboot.h> #include <sys/linker.h> #include <sys/boot.h> @@ -157,7 +158,7 @@ md_copyenv(vm_offset_t addr) static int align; #define COPY32(v, a, c) { \ - u_int32_t x = (v); \ + u_int32_t x = htobe32(v); \ if (c) \ archsw.arch_copyin(&x, a, sizeof(x)); \ a += sizeof(x); \ @@ -254,11 +255,12 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) vm_offset_t fdtp; vm_offset_t size; uint64_t scratch64; + uint32_t scratch32; char *rootdevname; int howto; align = kern64 ? 8 : 4; - howto = md_getboothowto(args); + howto = htobe32(md_getboothowto(args)); /* * Allow the environment variable 'rootdev' to override the supplied device @@ -300,16 +302,19 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) panic("can't find kernel file"); file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto); if (kern64) { - scratch64 = envp; + scratch64 = htobe64(envp); file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch64, &scratch64); - scratch64 = fdtp; + scratch64 = htobe64(fdtp); file_addmetadata(kfp, MODINFOMD_DTBP, sizeof scratch64, &scratch64); - scratch64 = kernend; + scratch64 = htobe64(kernend); file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof scratch64, &scratch64); } else { - file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp); - file_addmetadata(kfp, MODINFOMD_DTBP, sizeof fdtp, &fdtp); - file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend); + scratch32 = htobe32(envp); + file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch32, &scratch32); + scratch32 = htobe32(fdtp); + file_addmetadata(kfp, MODINFOMD_DTBP, sizeof scratch32, &scratch32); + scratch32 = htobe32(kernend); + file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof scratch32, &scratch32); } *modulep = addr; @@ -318,7 +323,7 @@ md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64) md = file_findmetadata(kfp, MODINFOMD_KERNEND); if (kern64) { - scratch64 = kernend; + scratch64 = htobe64(kernend); bcopy(&scratch64, md->md_data, sizeof scratch64); } else { bcopy(&kernend, md->md_data, sizeof kernend); diff --git a/stand/powerpc/kboot/ppc64_elf_freebsd.c b/stand/powerpc/kboot/ppc64_elf_freebsd.c index 987565e..9547077 100644 --- a/stand/powerpc/kboot/ppc64_elf_freebsd.c +++ b/stand/powerpc/kboot/ppc64_elf_freebsd.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #define __ELF_WORD_SIZE 64 #include <sys/param.h> +#include <sys/endian.h> #include <sys/linker.h> #include <machine/metadata.h> @@ -43,8 +44,15 @@ __FBSDID("$FreeBSD$"); extern char end[]; extern void *kerneltramp; extern size_t szkerneltramp; -extern int nkexec_segments; -extern void * loaded_segments; + +struct trampoline_data { + uint32_t kernel_entry; + uint32_t dtb; + uint32_t phys_mem_offset; + uint32_t of_entry; + uint32_t mdp; + uint32_t mdp_size; +}; vm_offset_t md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb); @@ -70,53 +78,90 @@ ppc64_elf_exec(struct preloaded_file *fp) int error; uint32_t *trampoline; uint64_t entry; - vm_offset_t trampolinebase; + uint64_t trampolinebase; + struct trampoline_data *trampoline_data; + int nseg; + void *kseg; if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) { return(EFTYPE); } e = (Elf_Ehdr *)&fmp->md_data; - /* Figure out where to put it */ + /* + * Figure out where to put it. + * + * Linux does not allow to do kexec_load into + * any part of memory. Ask arch_loadaddr to + * resolve the first available chunk of physical + * memory where loading is possible (load_addr). + * + * Memory organization is shown below. + * It is assumed, that text segment offset of + * kernel ELF (KERNPHYSADDR) is non-zero, + * which is true for PPC/PPC64 architectures, + * where default is 0x100000. + * + * load_addr: trampoline code + * load_addr + KERNPHYSADDR: kernel text segment + */ trampolinebase = archsw.arch_loadaddr(LOAD_RAW, NULL, 0); - + printf("Load address at %#jx\n", (uintmax_t)trampolinebase); + printf("Relocation offset is %#jx\n", (uintmax_t)elf64_relocation_offset); + /* Set up loader trampoline */ trampoline = malloc(szkerneltramp); memcpy(trampoline, &kerneltramp, szkerneltramp); + /* Parse function descriptor for ELFv1 kernels */ if ((e->e_flags & 3) == 2) entry = e->e_entry; - else + else { archsw.arch_copyout(e->e_entry + elf64_relocation_offset, &entry, 8); - trampoline[2] = entry + elf64_relocation_offset; - trampoline[4] = 0; /* Phys. mem offset */ - trampoline[5] = 0; /* OF entry point */ + entry = be64toh(entry); + } + + /* + * Placeholder for trampoline data is at trampolinebase + 0x08 + * CAUTION: all data must be Big Endian + */ + trampoline_data = (void*)&trampoline[2]; + trampoline_data->kernel_entry = htobe32(entry + elf64_relocation_offset); + trampoline_data->phys_mem_offset = htobe32(0); + trampoline_data->of_entry = htobe32(0); if ((error = md_load64(fp->f_args, &mdp, &dtb)) != 0) return (error); - trampoline[3] = dtb; - trampoline[6] = mdp; - trampoline[7] = 0xfb5d104d; - printf("Kernel entry at %#jx (%#x) ...\n", e->e_entry, trampoline[2]); - printf("DTB at %#x, mdp at %#x\n", dtb, mdp); + trampoline_data->dtb = htobe32(dtb); + trampoline_data->mdp = htobe32(mdp); + trampoline_data->mdp_size = htobe32(0xfb5d104d); + + printf("Kernel entry at %#jx (%#x) ...\n", + entry, be32toh(trampoline_data->kernel_entry)); + printf("DTB at %#x, mdp at %#x\n", + be32toh(trampoline_data->dtb), be32toh(trampoline_data->mdp)); dev_cleanup(); archsw.arch_copyin(trampoline, trampolinebase, szkerneltramp); free(trampoline); - error = kexec_load(trampolinebase, nkexec_segments, &loaded_segments); + if (archsw.arch_kexec_kseg_get == NULL) + panic("architecture did not provide kexec segment mapping"); + archsw.arch_kexec_kseg_get(&nseg, &kseg); + + error = kexec_load(trampolinebase, nseg, (uintptr_t)kseg); if (error != 0) panic("kexec_load returned error: %d", error); + error = host_reboot(0xfee1dead, 672274793, - 0x45584543 /* LINUX_REBOOT_CMD_KEXEC */, NULL); + 0x45584543 /* LINUX_REBOOT_CMD_KEXEC */, (uintptr_t)NULL); if (error != 0) panic("reboot returned error: %d", error); - while (1) {} - panic("exec returned"); + while (1) {} } struct file_format ppc_elf64 = diff --git a/stand/powerpc/ofw/Makefile b/stand/powerpc/ofw/Makefile index e24b7af..ce24844 100644 --- a/stand/powerpc/ofw/Makefile +++ b/stand/powerpc/ofw/Makefile @@ -11,8 +11,6 @@ LOADER_GZIP_SUPPORT?= yes LOADER_BZIP2_SUPPORT?= no .include <bsd.init.mk> -MK_SSP= no -MAN= PROG= loader NEWVERSWHAT= "Open Firmware loader" ${MACHINE_ARCH} @@ -48,7 +46,7 @@ LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc LIBOFW= ${BOOTOBJ}/ofw/libofw/libofw.a CFLAGS+= -I${BOOTSRC}/ofw/libofw -DPADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSA} -LDADD= ${LIBFICL} ${LIBOFW} ${LIBFDT} ${LIBSA} +DPADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA} +LDADD= ${LDR_INTERP} ${LIBOFW} ${LIBFDT} ${LIBSA} .include <bsd.prog.mk> diff --git a/stand/powerpc/ofw/ldscript.powerpc b/stand/powerpc/ofw/ldscript.powerpc index 3a27650..e0dc5e2 100644 --- a/stand/powerpc/ofw/ldscript.powerpc +++ b/stand/powerpc/ofw/ldscript.powerpc @@ -9,7 +9,7 @@ PROVIDE (__stack = 0); SECTIONS { /* Read-only sections, merged into text segment: */ - . = 0x01c00000 + SIZEOF_HEADERS; + . = 0x02c00000 + SIZEOF_HEADERS; .interp : { *(.interp) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } diff --git a/stand/powerpc/uboot/Makefile b/stand/powerpc/uboot/Makefile index 623c464..8d9d8e3 100644 --- a/stand/powerpc/uboot/Makefile +++ b/stand/powerpc/uboot/Makefile @@ -14,7 +14,6 @@ LOADER_BZIP2_SUPPORT?= no PROG= ubldr NEWVERSWHAT= "U-Boot loader" ${MACHINE_ARCH} INSTALLFLAGS= -b -MAN= # Architecture-specific loader code SRCS= start.S conf.c vers.c @@ -28,7 +27,7 @@ LDFLAGS= -nostdlib -static -T ${.CURDIR}/ldscript.powerpc .include "${BOOTSRC}/uboot.mk" -DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} -LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} +DPADD= ${LDR_INTERP} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} +LDADD= ${LDR_INTERP} ${LIBUBOOT} ${LIBFDT} ${LIBUBOOT_FDT} ${LIBSA} .include <bsd.prog.mk> diff --git a/stand/sparc64/boot1/Makefile b/stand/sparc64/boot1/Makefile index 97bfa67..7dbd297 100644 --- a/stand/sparc64/boot1/Makefile +++ b/stand/sparc64/boot1/Makefile @@ -4,7 +4,6 @@ PROG= boot1.elf INTERNALPROG= -MAN= FILES?= boot1 SRCS= _start.s boot1.c CLEANFILES+=${FILES} boot1.aout diff --git a/stand/sparc64/loader/Makefile b/stand/sparc64/loader/Makefile index 5b7c09a..7f57409 100644 --- a/stand/sparc64/loader/Makefile +++ b/stand/sparc64/loader/Makefile @@ -13,8 +13,6 @@ LOADER_BZIP2_SUPPORT?= no LOADER_DEBUG?= no .include <bsd.init.mk> -MK_SSP= no -MAN= PROG?= loader NEWVERSWHAT?= "bootstrap loader" sparc64 @@ -42,7 +40,7 @@ LDFLAGS+= -static LIBOFW= ${BOOTOBJ}/ofw/libofw/libofw.a CFLAGS+= -I${BOOTSRC}/ofw/libofw/ -DPADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} ${LIBSA} -LDADD= ${LIBFICL} ${LIBZFSBOOT} ${LIBOFW} ${LIBSA} +DPADD= ${LDR_INTERP} ${LIBZFSBOOT} ${LIBOFW} ${LIBSA} +LDADD= ${LDR_INTERP} ${LIBZFSBOOT} ${LIBOFW} ${LIBSA} .include <bsd.prog.mk> diff --git a/stand/uboot/fdt/Makefile b/stand/uboot/fdt/Makefile index d88789d..b1e9f8e 100644 --- a/stand/uboot/fdt/Makefile +++ b/stand/uboot/fdt/Makefile @@ -5,7 +5,6 @@ .PATH: ${LDRSRC} LIB= uboot_fdt -INTERNALLIB= WARNS?= 2 SRCS= uboot_fdt.c diff --git a/stand/uboot/lib/Makefile b/stand/uboot/lib/Makefile index 5e8a5f4..19e4d3a 100644 --- a/stand/uboot/lib/Makefile +++ b/stand/uboot/lib/Makefile @@ -5,7 +5,6 @@ .PATH: ${LDRSRC} LIB= uboot -INTERNALLIB= WARNS?= 2 SRCS= console.c copy.c devicename.c elf_freebsd.c glue.c diff --git a/stand/usb/Makefile.test b/stand/usb/test/Makefile index decee69..c82b5ba 100644 --- a/stand/usb/Makefile.test +++ b/stand/usb/test/Makefile @@ -30,9 +30,9 @@ # .PATH: ${.CURDIR} +.SUFFIXES: .a PROG= usbloader -MAN= SRCS= CFLAGS+= -Wall @@ -46,12 +46,15 @@ LDFLAGS+= -Wl,--gc-sections SRCS+= bsd_usbloader_test.c -LDADD+= libusbboot.a -DPADD+= libusbboot.a +USBLIB?= ${.OBJDIR}/../libusbboot.a + +LDADD+= ${USBLIB} +DPADD+= ${USBLIB} + +MAN= .include <bsd.prog.mk> -${PROG}: libusbboot.a +${USBLIB}: + make -C ${.CURDIR}/.. USBCOREDIR=${.CURDIR}/.. -libusbboot.a: - make -f Makefile diff --git a/stand/usb/bsd_usbloader_test.c b/stand/usb/test/bsd_usbloader_test.c index 35140b8..35140b8 100644 --- a/stand/usb/bsd_usbloader_test.c +++ b/stand/usb/test/bsd_usbloader_test.c diff --git a/stand/usb/usbcore.mk b/stand/usb/usbcore.mk index 153a1d4..b43d9d2 100644 --- a/stand/usb/usbcore.mk +++ b/stand/usb/usbcore.mk @@ -32,7 +32,7 @@ # USBCOREDIR:= ${.PARSEDIR} -S=${USBCOREDIR}/../.. +S=${USBCOREDIR}/../../sys MACHDEP_DIRS= diff --git a/stand/userboot/test/Makefile b/stand/userboot/test/Makefile index e40a7bc..7c88f26 100644 --- a/stand/userboot/test/Makefile +++ b/stand/userboot/test/Makefile @@ -1,10 +1,6 @@ # $FreeBSD$ - -MAN= - .include <bsd.init.mk> -MK_SSP= no PROG= test INTERNALPROG= diff --git a/stand/userboot/userboot/Makefile b/stand/userboot/userboot/Makefile index 5946257..2aa4161 100644 --- a/stand/userboot/userboot/Makefile +++ b/stand/userboot/userboot/Makefile @@ -1,18 +1,14 @@ # $FreeBSD$ -MAN= - LOADER_MSDOS_SUPPORT?= yes LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= no LOADER_EXT2FS_SUPPORT?= no +PIC=yes .include <bsd.init.mk> -MK_SSP= no - SHLIB_NAME= userboot.so -MK_CTF= no STRIP= LIBDIR= /boot @@ -48,10 +44,10 @@ CFLAGS+= -DUSERBOOT_ZFS_SUPPORT LIBZFSBOOT= ${BOOTOBJ}/zfs/libzfsboot.a .endif -# Always add MI sources +# Always add MI sources .include "${BOOTSRC}/loader.mk" CFLAGS+= -I. -DPADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSA} -LDADD+= ${LIBFICL} ${LIBZFSBOOT} ${LIBSA} +DPADD+= ${LDR_INTERP} ${LIBZFSBOOT} ${LIBSA} +LDADD+= ${LDR_INTERP} ${LIBZFSBOOT} ${LIBSA} .include <bsd.lib.mk> diff --git a/stand/zfs/Makefile b/stand/zfs/Makefile index e86c84b..3116b32 100644 --- a/stand/zfs/Makefile +++ b/stand/zfs/Makefile @@ -3,7 +3,6 @@ .include <bsd.init.mk> LIB= zfsboot -INTERNALLIB= .PATH: ${ZFSSRC} SRCS+= zfs.c skein.c skein_block.c diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index 08ae922..fa8a02d 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -267,9 +267,17 @@ link_elf_link_preload(linker_class_t cls, const char *filename, symstrindex = shdr[i].sh_link; break; case SHT_REL: + /* + * Ignore relocation tables for sections not + * loaded by the loader. + */ + if (shdr[shdr[i].sh_info].sh_addr == 0) + break; ef->nreltab++; break; case SHT_RELA: + if (shdr[shdr[i].sh_info].sh_addr == 0) + break; ef->nrelatab++; break; } @@ -391,12 +399,16 @@ link_elf_link_preload(linker_class_t cls, const char *filename, pb++; break; case SHT_REL: + if (shdr[shdr[i].sh_info].sh_addr == 0) + break; ef->reltab[rl].rel = (Elf_Rel *)shdr[i].sh_addr; ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel); ef->reltab[rl].sec = shdr[i].sh_info; rl++; break; case SHT_RELA: + if (shdr[shdr[i].sh_info].sh_addr == 0) + break; ef->relatab[ra].rela = (Elf_Rela *)shdr[i].sh_addr; ef->relatab[ra].nrela = shdr[i].sh_size / sizeof(Elf_Rela); @@ -607,9 +619,17 @@ link_elf_load_file(linker_class_t cls, const char *filename, symstrindex = shdr[i].sh_link; break; case SHT_REL: + /* + * Ignore relocation tables for unallocated + * sections. + */ + if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0) + break; ef->nreltab++; break; case SHT_RELA: + if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0) + break; ef->nrelatab++; break; case SHT_STRTAB: @@ -863,6 +883,8 @@ link_elf_load_file(linker_class_t cls, const char *filename, pb++; break; case SHT_REL: + if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0) + break; ef->reltab[rl].rel = malloc(shdr[i].sh_size, M_LINKER, M_WAITOK); ef->reltab[rl].nrel = shdr[i].sh_size / sizeof(Elf_Rel); @@ -881,6 +903,8 @@ link_elf_load_file(linker_class_t cls, const char *filename, rl++; break; case SHT_RELA: + if ((shdr[shdr[i].sh_info].sh_flags & SHF_ALLOC) == 0) + break; ef->relatab[ra].rela = malloc(shdr[i].sh_size, M_LINKER, M_WAITOK); ef->relatab[ra].nrela = |