int fdt_load_dtb_file(const char * filename) { struct preloaded_file *bfp, *oldbfp; int err; debugf("fdt_load_dtb_file(%s)\n", filename); oldbfp = file_findfile(NULL, "dtb"); /* Attempt to load and validate a new dtb from a file. */ if ((bfp = file_loadraw(filename, "dtb")) == NULL) { sprintf(command_errbuf, "failed to load file '%s'", filename); return (1); } if ((err = fdt_load_dtb(bfp->f_addr)) != 0) { file_discard(bfp); return (err); } /* A new dtb was validated, discard any previous file. */ if (oldbfp) file_discard(oldbfp); return (0); }
static int fdt_cmd_addr(int argc, char *argv[]) { struct preloaded_file *fp; struct fdt_header *hdr; const char *addr; char *cp; fdt_to_load = NULL; if (argc > 2) addr = argv[2]; else { sprintf(command_errbuf, "no address specified"); return (CMD_ERROR); } hdr = (struct fdt_header *)strtoul(addr, &cp, 16); if (cp == addr) { sprintf(command_errbuf, "Invalid address: %s", addr); return (CMD_ERROR); } while ((fp = file_findfile(NULL, "dtb")) != NULL) { file_discard(fp); } fdt_to_load = hdr; return (CMD_OK); }
/* * Load specified KLD. If path is omitted, then try to locate it via * search path. */ int file_loadkernel(char *filename, int argc, char *argv[]) { struct preloaded_file *fp, *last_file; int err; /* * Check if KLD already loaded */ fp = file_findfile(filename, NULL); if (fp) { command_seterr("warning: KLD '%s' already loaded", filename); free(filename); return (0); } for (last_file = preloaded_files; last_file != NULL && last_file->f_next != NULL; last_file = last_file->f_next) ; do { err = file_load(filename, loadaddr, &fp); if (err) break; fp->f_args = unargv(argc, argv); loadaddr = fp->f_addr + fp->f_size; file_insert_tail(fp); /* Add to the list of loaded files */ } while(0); if (err == EFTYPE) command_seterr("don't know how to load module '%s'", filename); if (err && fp) file_discard(fp); free(filename); return (err); }
Int abort_file(filec_t * file) { if (file != NULL) { close_file(file); file_discard(file, NULL); return F_SUCCESS; } return F_FAILURE; }
void close_files(void) { filec_t *file, *old; file = files; while (file) { close_file(file); old = file; file = file->next; file_discard(old, NULL); } }
void unload(void) { struct preloaded_file *fp; while (preloaded_files != NULL) { fp = preloaded_files; preloaded_files = preloaded_files->f_next; file_discard(fp); } loadaddr = 0; unsetenv("kernelname"); }
int command_unload(int argc, char *argv[]) { struct preloaded_file *fp; while (preloaded_files != NULL) { fp = preloaded_files; preloaded_files = preloaded_files->f_next; file_discard(fp); } loadaddr = 0; unsetenv("kernelname"); return(CMD_OK); }
/* * Attempt to load the file (file) as an ELF module. It will be stored at * (dest), and a pointer to a module structure describing the loaded object * will be saved in (result). */ int __elfN(obj_loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result) { struct preloaded_file *fp, *kfp; struct elf_file ef; Elf_Ehdr *hdr; int err; ssize_t bytes_read; fp = NULL; bzero(&ef, sizeof(struct elf_file)); /* * Open the image, read and validate the ELF header */ if (filename == NULL) /* can't handle nameless */ return(EFTYPE); if ((ef.fd = open(filename, O_RDONLY)) == -1) return(errno); hdr = &ef.hdr; bytes_read = read(ef.fd, hdr, sizeof(*hdr)); if (bytes_read != sizeof(*hdr)) { err = EFTYPE; /* could be EIO, but may be small file */ goto oerr; } /* Is it ELF? */ if (!IS_ELF(*hdr)) { err = EFTYPE; goto oerr; } if (hdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || /* Layout ? */ hdr->e_ident[EI_DATA] != ELF_TARG_DATA || hdr->e_ident[EI_VERSION] != EV_CURRENT || /* Version ? */ hdr->e_version != EV_CURRENT || hdr->e_machine != ELF_TARG_MACH || /* Machine ? */ hdr->e_type != ET_REL) { err = EFTYPE; goto oerr; } if (hdr->e_shnum * hdr->e_shentsize == 0 || hdr->e_shoff == 0 || hdr->e_shentsize != sizeof(Elf_Shdr)) { err = EFTYPE; goto oerr; } kfp = file_findfile(NULL, NULL); if (kfp == NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_obj_loadfile: can't load module before kernel\n"); err = EPERM; goto oerr; } if (strcmp(__elfN(obj_kerneltype), kfp->f_type)) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_obj_loadfile: can't load module with kernel type '%s'\n", kfp->f_type); err = EPERM; goto oerr; } if (archsw.arch_loadaddr != NULL) dest = archsw.arch_loadaddr(LOAD_ELF, hdr, dest); else dest = roundup(dest, PAGE_SIZE); /* * Ok, we think we should handle this. */ fp = file_alloc(); if (fp == NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_obj_loadfile: cannot allocate module info\n"); err = EPERM; goto out; } fp->f_name = strdup(filename); fp->f_type = strdup(__elfN(obj_moduletype)); printf("%s ", filename); fp->f_size = __elfN(obj_loadimage)(fp, &ef, dest); if (fp->f_size == 0 || fp->f_addr == 0) goto ioerr; /* save exec header as metadata */ file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*hdr), hdr); /* Load OK, return module pointer */ *result = (struct preloaded_file *)fp; err = 0; goto out; ioerr: err = EIO; oerr: file_discard(fp); out: close(ef.fd); if (ef.e_shdr != NULL) free(ef.e_shdr); return(err); }
cList *open_file(cStr * name, cStr * smode, Obj * obj) { char mode[4]; Int rw = 0; char *s = NULL; filec_t *fnew = file_new(); struct stat sbuf; /* parse the mode first, if the string pointer is NULL, set it readable */ if (smode != NULL) { s = smode->s; if (*s == '+') { rw = 1; fnew->f.readable = fnew->f.writable = 1; s++; } if (*s == '>') { s++; if (*s == '>') { s++; mode[0] = 'a'; } else { mode[0] = 'w'; } fnew->f.writable = 1; } else { if (*s == '<') s++; mode[0] = 'r'; fnew->f.readable = 1; } /* here is where we branch from perl, '-' is used to specify it as a 'binary' file (i.e. use buffers not cold strings) */ if (*s == '-') { s++; fnew->f.binary = 1; } } else { mode[0] = 'r'; fnew->f.readable = 1; } /* most systems ignore this, some need it */ mode[1] = 'b'; if (rw) { mode[2] = '+'; mode[3] = '\0'; } else { mode[2] = '\0'; } fnew->path = build_path(name->s, NULL, DISALLOW_DIR); if (fnew->path == NULL) return NULL; /* redundant, as build_path could have done this, but we have a special case which we need to handle differently */ if (stat(fnew->path->s, &sbuf) == F_SUCCESS) { /* Patch #6 -- Bruce Mitchener */ if (S_ISDIR(sbuf.st_mode)) { cthrow(directory_id, "\"%s\" is a directory.", fnew->path->s); file_discard(fnew, NULL); return NULL; } } fnew->fp = fopen(fnew->path->s, mode); if (fnew->fp == NULL) { if (GETERR() == ERR_NOMEM) panic("open_file(): %s", strerror(GETERR())); cthrow(file_id, "%s (%s)", strerror(GETERR()), name->s); file_discard(fnew, NULL); return NULL; } file_add(fnew); obj->file = fnew; fnew->objnum = obj->objnum; return statbuf_to_list(&sbuf); }
int __elfN(loadfile_raw)(char *filename, u_int64_t dest, struct preloaded_file **result, int multiboot) { struct preloaded_file *fp, *kfp; struct elf_file ef; Elf_Ehdr *ehdr; int err; fp = NULL; bzero(&ef, sizeof(struct elf_file)); ef.fd = -1; err = __elfN(load_elf_header)(filename, &ef); if (err != 0) return (err); ehdr = ef.ehdr; /* * Check to see what sort of module we are. */ kfp = file_findfile(NULL, __elfN(kerneltype)); #ifdef __powerpc__ /* * Kernels can be ET_DYN, so just assume the first loaded object is the * kernel. This assumption will be checked later. */ if (kfp == NULL) ef.kernel = 1; #endif if (ef.kernel || ehdr->e_type == ET_EXEC) { /* Looks like a kernel */ if (kfp != NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: kernel already loaded\n"); err = EPERM; goto oerr; } /* * Calculate destination address based on kernel entrypoint. * * For ARM, the destination address is independent of any values in the * elf header (an ARM kernel can be loaded at any 2MB boundary), so we * leave dest set to the value calculated by archsw.arch_loadaddr() and * passed in to this function. */ #ifndef __arm__ if (ehdr->e_type == ET_EXEC) dest = (ehdr->e_entry & ~PAGE_MASK); #endif if ((ehdr->e_entry & ~PAGE_MASK) == 0) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: not a kernel (maybe static binary?)\n"); err = EPERM; goto oerr; } ef.kernel = 1; } else if (ehdr->e_type == ET_DYN) { /* Looks like a kld module */ if (multiboot != 0) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module as multiboot\n"); err = EPERM; goto oerr; } if (kfp == NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module before kernel\n"); err = EPERM; goto oerr; } if (strcmp(__elfN(kerneltype), kfp->f_type)) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module with kernel type '%s'\n", kfp->f_type); err = EPERM; goto oerr; } /* Looks OK, got ahead */ ef.kernel = 0; } else { err = EFTYPE; goto oerr; } if (archsw.arch_loadaddr != NULL) dest = archsw.arch_loadaddr(LOAD_ELF, ehdr, dest); else dest = roundup(dest, PAGE_SIZE); /* * Ok, we think we should handle this. */ fp = file_alloc(); if (fp == NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: cannot allocate module info\n"); err = EPERM; goto out; } if (ef.kernel == 1 && multiboot == 0) setenv("kernelname", filename, 1); fp->f_name = strdup(filename); if (multiboot == 0) fp->f_type = strdup(ef.kernel ? __elfN(kerneltype) : __elfN(moduletype)); else fp->f_type = strdup("elf multiboot kernel"); #ifdef ELF_VERBOSE if (ef.kernel) printf("%s entry at 0x%jx\n", filename, (uintmax_t)ehdr->e_entry); #else printf("%s ", filename); #endif fp->f_size = __elfN(loadimage)(fp, &ef, dest); if (fp->f_size == 0 || fp->f_addr == 0) goto ioerr; /* save exec header as metadata */ file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*ehdr), ehdr); /* Load OK, return module pointer */ *result = (struct preloaded_file *)fp; err = 0; goto out; ioerr: err = EIO; oerr: file_discard(fp); out: if (ef.firstpage) free(ef.firstpage); if (ef.fd != -1) close(ef.fd); return(err); }
static int multiboot_loadfile(char *filename, u_int64_t dest, struct preloaded_file **result) { uint32_t *magic; int i, error; caddr_t header_search; ssize_t search_size; int fd; struct multiboot_header *header; struct preloaded_file *fp; if (filename == NULL) return (EFTYPE); /* is kernel already loaded? */ fp = file_findfile(NULL, NULL); if (fp != NULL) { return (EFTYPE); } if ((fd = open(filename, O_RDONLY)) == -1) return (errno); /* * Read MULTIBOOT_SEARCH size in order to search for the * multiboot magic header. */ header_search = malloc(MULTIBOOT_SEARCH); if (header_search == NULL) { close(fd); return (ENOMEM); } search_size = read(fd, header_search, MULTIBOOT_SEARCH); magic = (uint32_t *)header_search; header = NULL; for (i = 0; i < (search_size / sizeof(uint32_t)); i++) { if (magic[i] == MULTIBOOT_HEADER_MAGIC) { header = (struct multiboot_header *)&magic[i]; break; } } if (header == NULL) { error = EFTYPE; goto out; } /* Valid multiboot header has been found, validate checksum */ if (header->magic + header->flags + header->checksum != 0) { printf( "Multiboot checksum failed, magic: 0x%x flags: 0x%x checksum: 0x%x\n", header->magic, header->flags, header->checksum); error = EFTYPE; goto out; } if ((header->flags & ~MULTIBOOT_SUPPORTED_FLAGS) != 0) { printf("Unsupported multiboot flags found: 0x%x\n", header->flags); error = EFTYPE; goto out; } /* AOUT KLUDGE means we just load entire flat file as blob */ if (header->flags & MULTIBOOT_AOUT_KLUDGE) { vm_offset_t laddr; int got; dest = header->load_addr; if (lseek(fd, 0, SEEK_SET) == -1) { printf("lseek failed\n"); error = EIO; goto out; } laddr = dest; for (;;) { got = archsw.arch_readin(fd, laddr, 4096); if (got == 0) break; if (got < 0) { printf("error reading: %s", strerror(errno)); error = EIO; goto out; } laddr += got; } fp = file_alloc(); if (fp == NULL) { error = ENOMEM; goto out; } fp->f_name = strdup(filename); fp->f_type = strdup("aout multiboot kernel"); fp->f_addr = header->entry_addr; fp->f_size = laddr - dest; if (fp->f_size == 0) { file_discard(fp); error = EIO; goto out; } fp->f_metadata = NULL; error = 0; } else { error = elf32_loadfile_raw(filename, dest, &fp, 1); if (error != 0) { printf("elf32_loadfile_raw failed: %d unable to " "load multiboot kernel\n", error); goto out; } } setenv("kernelname", fp->f_name, 1); bios_addsmapdata(fp); *result = fp; out: free(header_search); close(fd); return (error); }
/* * Attempt to load the file (file) as an ELF module. It will be stored at * (dest), and a pointer to a module structure describing the loaded object * will be saved in (result). */ int __elfN(loadfile)(char *filename, u_int64_t dest, struct preloaded_file **result) { struct preloaded_file *fp, *kfp; struct elf_file ef; Elf_Ehdr *ehdr; int err; ssize_t bytes_read; fp = NULL; bzero(&ef, sizeof(struct elf_file)); /* * Open the image, read and validate the ELF header */ if (filename == NULL) /* can't handle nameless */ return(EFTYPE); if ((ef.fd = open(filename, O_RDONLY)) == -1) return(errno); ef.firstpage = malloc(PAGE_SIZE); if (ef.firstpage == NULL) { close(ef.fd); return(ENOMEM); } bytes_read = read(ef.fd, ef.firstpage, PAGE_SIZE); ef.firstlen = (size_t)bytes_read; if (bytes_read < 0 || ef.firstlen <= sizeof(Elf_Ehdr)) { err = EFTYPE; /* could be EIO, but may be small file */ goto oerr; } ehdr = ef.ehdr = (Elf_Ehdr *)ef.firstpage; /* Is it ELF? */ if (!IS_ELF(*ehdr)) { err = EFTYPE; goto oerr; } 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 ? */ err = EFTYPE; goto oerr; } /* * Check to see what sort of module we are. */ kfp = file_findfile(NULL, NULL); if (ehdr->e_type == ET_DYN) { /* Looks like a kld module */ if (kfp == NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module before kernel\n"); err = EPERM; goto oerr; } if (strcmp(__elfN(kerneltype), kfp->f_type)) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module with kernel type '%s'\n", kfp->f_type); err = EPERM; goto oerr; } /* Looks OK, got ahead */ ef.kernel = 0; } else if (ehdr->e_type == ET_EXEC) { /* Looks like a kernel */ if (kfp != NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: kernel already loaded\n"); err = EPERM; goto oerr; } /* * Calculate destination address based on kernel entrypoint */ dest = (ehdr->e_entry & ~PAGE_MASK); if (dest == 0) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: not a kernel (maybe static binary?)\n"); err = EPERM; goto oerr; } ef.kernel = 1; } else { err = EFTYPE; goto oerr; } if (archsw.arch_loadaddr != NULL) dest = archsw.arch_loadaddr(LOAD_ELF, ehdr, dest); else dest = roundup(dest, PAGE_SIZE); /* * Ok, we think we should handle this. */ fp = file_alloc(); if (fp == NULL) { printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: cannot allocate module info\n"); err = EPERM; goto out; } if (ef.kernel) setenv("kernelname", filename, 1); fp->f_name = strdup(filename); fp->f_type = strdup(ef.kernel ? __elfN(kerneltype) : __elfN(moduletype)); #ifdef ELF_VERBOSE if (ef.kernel) printf("%s entry at 0x%jx\n", filename, (uintmax_t)ehdr->e_entry); #else printf("%s ", filename); #endif fp->f_size = __elfN(loadimage)(fp, &ef, dest); if (fp->f_size == 0 || fp->f_addr == 0) goto ioerr; /* save exec header as metadata */ file_addmetadata(fp, MODINFOMD_ELFHDR, sizeof(*ehdr), ehdr); /* Load OK, return module pointer */ *result = (struct preloaded_file *)fp; err = 0; goto out; ioerr: err = EIO; oerr: file_discard(fp); out: if (ef.firstpage) free(ef.firstpage); close(ef.fd); return(err); }