int check_ecoff(const char *mappedfile, size_t mappedsize) { const struct ecoff_exechdr *exechdrp; int rv; rv = 0; if (check(0, sizeof *exechdrp)) BAD; exechdrp = (const struct ecoff_exechdr *)&mappedfile[0]; if (ECOFF_BADMAG(exechdrp)) BAD; out: return (rv); }
int ecoff_check(char *file) { int fd, ret = 1; if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0) return (0); if (read(fd,(char *)&ecoff_ex, sizeof(ecoff_ex)) != sizeof(ecoff_ex)) ret = 0; if (ret) { if (ECOFF_BADMAG(&ecoff_ex)) ret = 0; } close(fd); return (ret); }
void ecoff_loadkernel(char *file) { int fd; off_t beg, cur, end; if ((fd = open(file, O_RDONLY | O_EXLOCK, 0)) < 0) err(1, "%s", file); if (read(fd, (char *)&ecoff_ex, sizeof(ecoff_ex)) != sizeof(ecoff_ex)) errx(1, "can't read ecoff header"); if (ECOFF_BADMAG(&ecoff_ex)) errx(1, "bad ecoff magic"); ecoff_psz = ecoff_ex.a.tsize + ecoff_ex.a.dsize; beg = lseek(fd, ECOFF_TXTOFF(&ecoff_ex), SEEK_SET); ecoff_bsz = (int)beg; ecoff_b = emalloc(ecoff_bsz); ecoff_p = emalloc(ecoff_psz); if (read(fd, ecoff_p, ecoff_psz) != ecoff_psz) errx(1, "can't read ecoff text and data"); cur = lseek(fd, (off_t)0, SEEK_CUR); end = lseek(fd, (off_t)0, SEEK_END); (void)lseek(fd, (off_t)0, SEEK_SET); if (read(fd, ecoff_b, ecoff_bsz) != ecoff_bsz) errx(1, "can't read begining of file %s", file); (void)lseek(fd, cur, SEEK_SET); ecoff_rsz = (int)(end - cur); ecoff_r = emalloc(ecoff_rsz); if (read(fd, ecoff_r, ecoff_rsz) != ecoff_rsz) errx(1, "can't read rest of file %s", file); close(fd); }
int check_ecoff(int fd, const char *filename) { struct ecoff_exechdr eh; struct stat sb; /* * Check the header to make sure it's an ECOFF file (of the * appropriate size). */ if (fstat(fd, &sb) == -1) return 0; if (sb.st_size < (off_t)sizeof eh) return 0; if (read(fd, &eh, sizeof eh) != sizeof eh) return 0; if (ECOFF_BADMAG(&eh)) return 0; return 1; }
/* * Open 'filename', read in program and and return 0 if ok 1 on error. * Fill in marks */ int loadfile(const char *fname, u_long *marks, int flags) { union { #ifdef BOOT_ECOFF struct ecoff_exechdr coff; #endif #ifdef BOOT_ELF Elf_Ehdr elf; #endif #ifdef BOOT_AOUT struct exec aout; #endif } hdr; ssize_t nr; int fd, rval; /* Open the file. */ if ((fd = open(fname, 0)) < 0) { WARN(("open %s", fname ? fname : "<default>")); return -1; } /* Read the exec header. */ if ((nr = read(fd, &hdr, sizeof(hdr))) != sizeof(hdr)) { WARN(("read header")); goto err; } #ifdef BOOT_ECOFF if (!ECOFF_BADMAG(&hdr.coff)) { rval = coff_exec(fd, &hdr.coff, marks, flags); } else #endif #ifdef BOOT_ELF if (memcmp(hdr.elf.e_ident, ELFMAG, SELFMAG) == 0 && hdr.elf.e_ident[EI_CLASS] == ELFCLASS) { #ifdef BOOT_ZBOOT rval = zboot_exec(fd, marks, flags); #else rval = elf_exec(fd, &hdr.elf, marks, flags); #endif } else #endif #ifdef BOOT_AOUT if (OKMAGIC(N_GETMAGIC(hdr.aout)) #ifndef NO_MID_CHECK && N_GETMID(hdr.aout) == MID_MACHINE #endif ) { rval = aout_exec(fd, &hdr.aout, marks, flags); } else #endif { rval = 1; errno = EFTYPE; WARN(("%s", fname ? fname : "<default>")); } if (rval == 0) { PROGRESS(("=0x%lx\n", marks[MARK_END] - marks[MARK_START])); return fd; } err: (void)close(fd); return -1; }
void hide_syms(char *filename) { int inf, outf, rc; struct stat infstat; struct relocation_info *relp; struct nlist *symp; char *buf; u_char zero = 0; /* * Open the file and do some error checking. */ if ((inf = open(filename, O_RDWR)) == -1) { perror(filename); return; } if (fstat(inf, &infstat) == -1) { perror(filename); close(inf); return; } if (infstat.st_size < sizeof(struct exec)) { fprintf(stderr, "%s: short file\n", filename); close(inf); return; } if ((buf = mmap(NULL, infstat.st_size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, inf, 0)) == MAP_FAILED) { fprintf(stderr, "%s: cannot map\n", filename); close(inf); return; } #ifdef _NLIST_DO_ELF if (buf[0] == 0x7f && (buf[1] == 'E' || buf[1] == 'O') && buf[2] == 'L' && buf[3] == 'F') { elf_hide(inf, buf); return; } #endif /* _NLIST_DO_ELF */ #ifdef _NLIST_DO_ECOFF if (!ECOFF_BADMAG((struct ecoff_exechdr *) buf)) { ecoff_hide(inf, buf); return; } #endif /* _NLIST_DO_ECOFF */ #ifdef DO_AOUT aoutdata = buf; /* * Check the header and calculate offsets and sizes from it. */ hdrp = (struct exec *) aoutdata; if (N_BADMAG(*hdrp)) { fprintf(stderr, "%s: bad magic: not an a.out, ecoff or elf file\n", filename); close(inf); return; } textrel = (struct relocation_info *) (aoutdata + N_TRELOFF(*hdrp)); datarel = (struct relocation_info *) (aoutdata + N_DRELOFF(*hdrp)); symbase = (struct nlist *) (aoutdata + N_SYMOFF(*hdrp)); strbase = (char *) (aoutdata + N_STROFF(*hdrp)); ntextrel = hdrp->a_trsize / sizeof(struct relocation_info); ndatarel = hdrp->a_drsize / sizeof(struct relocation_info); nsyms = hdrp->a_syms / sizeof(struct nlist); /* * Zap the type field of all globally-defined symbols. The linker will * subsequently ignore these entries. Don't zap any symbols in the * keep list. */ for (symp = symbase; symp < symbase + nsyms; symp++) if (IS_GLOBAL_DEFINED(symp) && !in_keep_list(SYMSTR(symp))) { /* * XXX Our VM system has some problems, so * avoid the VM system.... */ lseek(inf, (off_t) ((void *) &symp->n_type - (void *) buf), SEEK_SET); write(inf, &zero, sizeof zero); symp->n_type = 0; } /* * Check whether the relocation entries reference any symbols that we * just zapped. I don't know whether ld can handle this case, but I * haven't encountered it yet. These checks are here so that the program * doesn't fail silently should such symbols be encountered. */ for (relp = textrel; relp < textrel + ntextrel; relp++) check_reloc(filename, relp); for (relp = datarel; relp < datarel + ndatarel; relp++) check_reloc(filename, relp); msync(buf, infstat.st_size, MS_SYNC); munmap(buf, infstat.st_size); close(inf); #endif /* DO_AOUT */ }
int __ecoff_fdnlist(int fd, struct nlist *list) { struct nlist *p; struct ecoff_exechdr *exechdrp; struct ecoff_symhdr *symhdrp; struct ecoff_extsym *esyms; struct stat st; char *mappedfile; size_t mappedsize; u_long symhdroff, extstroff; u_int symhdrsize; int rv, nent; long i, nesyms; rv = -3; if (fstat(fd, &st) < 0) BAD; if (st.st_size > SIZE_T_MAX) { errno = EFBIG; BAD; } mappedsize = st.st_size; mappedfile = mmap(NULL, mappedsize, PROT_READ, MAP_SHARED|MAP_FILE, fd, 0); if (mappedfile == MAP_FAILED) BAD; if (check(0, sizeof *exechdrp)) BADUNMAP; exechdrp = (struct ecoff_exechdr *)&mappedfile[0]; if (ECOFF_BADMAG(exechdrp)) BADUNMAP; symhdroff = exechdrp->f.f_symptr; symhdrsize = exechdrp->f.f_nsyms; if (check(symhdroff, sizeof *symhdrp) || sizeof *symhdrp != symhdrsize) BADUNMAP; symhdrp = (struct ecoff_symhdr *)&mappedfile[symhdroff]; nesyms = symhdrp->esymMax; if (check(symhdrp->cbExtOffset, nesyms * sizeof *esyms)) BADUNMAP; esyms = (struct ecoff_extsym *)&mappedfile[symhdrp->cbExtOffset]; extstroff = symhdrp->cbSsExtOffset; /* * clean out any left-over information for all valid entries. * Type and value defined to be 0 if not found; historical * versions cleared other and desc as well. * * XXX clearing anything other than n_type and n_value violates * the semantics given in the man page. */ nent = 0; for (p = list; !ISLAST(p); ++p) { p->n_type = 0; p->n_other = 0; p->n_desc = 0; p->n_value = 0; ++nent; } for (i = 0; i < nesyms; i++) { for (p = list; !ISLAST(p); p++) { char *nlistname; char *symtabname; nlistname = p->n_un.n_name; if (*nlistname == '_') nlistname++; symtabname = &mappedfile[extstroff + esyms[i].es_strindex]; if (!strcmp(symtabname, nlistname)) { p->n_value = esyms[i].es_value; p->n_type = N_EXT; /* XXX */ p->n_desc = 0; /* XXX */ p->n_other = 0; /* XXX */ if (--nent <= 0) break; } } } rv = nent; unmap: munmap(mappedfile, mappedsize); out: return (rv); }
/* * Read in program from the given file descriptor. * Return error code (0 on success). * Fill in marks. */ int fdloadfile(int fd, u_long *marks, int flags) { union { #ifdef BOOT_ECOFF struct ecoff_exechdr coff; #endif #ifdef BOOT_ELF32 Elf32_Ehdr elf32; #endif #ifdef BOOT_ELF64 Elf64_Ehdr elf64; #endif #ifdef BOOT_AOUT struct exec aout; #endif } hdr; ssize_t nr; int rval; /* Read the exec header. */ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) goto err; nr = read(fd, &hdr, sizeof(hdr)); if (nr == -1) { WARN(("read header failed")); goto err; } if (nr != sizeof(hdr)) { WARN(("read header short")); errno = EFTYPE; goto err; } #ifdef BOOT_ECOFF if (!ECOFF_BADMAG(&hdr.coff)) { rval = loadfile_coff(fd, &hdr.coff, marks, flags); } else #endif #ifdef BOOT_ELF32 if (memcmp(hdr.elf32.e_ident, ELFMAG, SELFMAG) == 0 && hdr.elf32.e_ident[EI_CLASS] == ELFCLASS32) { netbsd_elf_class = ELFCLASS32; rval = loadfile_elf32(fd, &hdr.elf32, marks, flags); } else #endif #ifdef BOOT_ELF64 if (memcmp(hdr.elf64.e_ident, ELFMAG, SELFMAG) == 0 && hdr.elf64.e_ident[EI_CLASS] == ELFCLASS64) { netbsd_elf_class = ELFCLASS64; rval = loadfile_elf64(fd, &hdr.elf64, marks, flags); } else #endif #ifdef BOOT_AOUT if (OKMAGIC(N_GETMAGIC(hdr.aout)) #ifndef NO_MID_CHECK && N_GETMID(hdr.aout) == MID_MACHINE #endif ) { rval = loadfile_aout(fd, &hdr.aout, marks, flags); } else #endif { rval = 1; errno = EFTYPE; } if (rval == 0) { if ((flags & LOAD_ALL) != 0) PROGRESS(("=0x%lx\n", marks[MARK_END] - marks[MARK_START])); return 0; } err: return errno; }