Exemplo n.º 1
0
static int
is_aout_shared_lib(const char *name)
{
	struct exec ex;
	struct stat st;
	int fd;

	if (stat(name, &st) < 0)
		return 0;
	if ((st.st_mode & (S_IFREG|S_IFLNK)) == 0)
		return 0;

	fd = open(name, O_RDONLY);
	if (fd < 0) {
		return 0;
	}
	if (read(fd, &ex, sizeof ex) - sizeof ex != 0) {
		close(fd);
		return 0;
	}
	close(fd);
	if (N_GETMAGIC(ex) != ZMAGIC ||
	    (N_GETFLAG(ex) & EX_DYNAMIC) == 0)
		return 0;

	return 1;
}
Exemplo n.º 2
0
static int
exec_simple(int fd, const char *path, char *const argv[],
	    char *const envp[], struct Env *e, u_int flags)
{
  struct exec hdr;
  int r;

  if (lseek(fd, 0, SEEK_SET) == -1 ||
      read(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
    return 0;

  if (N_GETMAGIC(hdr) == EXOS_MAGIC) 
  {
    int ret;

    ret = __do_simple_load (fd, e);
    if (ret < 0) {
      fprintf (stderr, "Could not load EXOS_MAGIC executable\n");
      if (!(flags & _EXEC_USE_FD)) close(fd);
      return -ENOEXEC;
    }
   
    if ((r = setup_new_stack_simple(argv,envp,e->env_id,&e->env_tf.tf_esp)<0))
      return r;
    return 1;
  }

  return 0;
}
Exemplo n.º 3
0
/*
 * Make encoded (compressed) data.
 */
static void
mk_data(const struct iodesc * idi, const struct iodesc * ido,
	struct kgz_hdr * kh, size_t off)
{
    union {
	struct exec ex;
	Elf32_Ehdr ee;
    } hdr;
    struct stat sb;
    struct iodesc idp;
    int fd[2];
    pid_t pid;
    size_t n;
    int fmt, status, e;

    n = xread(idi, &hdr, sizeof(hdr), 0);
    fmt = 0;
    if (n >= sizeof(hdr.ee) && IS_ELF(hdr.ee))
	fmt = F_ELF;
    else if (n >= sizeof(hdr.ex) && N_GETMAGIC(hdr.ex) == ZMAGIC)
	fmt = F_AOUT;
    if (!fmt)
	errx(1, "%s: Format not supported", idi->fname);
    xseek(ido, off);
    if (pipe(fd))
	err(1, NULL);
    switch (pid = fork()) {
    case -1:
	err(1, NULL);
    case 0:
	close(fd[1]);
	dup2(fd[0], STDIN_FILENO);
	close(fd[0]);
	close(idi->fd);
	dup2(ido->fd, STDOUT_FILENO);
	close(ido->fd);
	execlp("gzip", "gzip", "-9n", (char *)NULL);
	warn(NULL);
	_exit(1);
    default:
	close(fd[0]);
	idp.fname = "(pipe)";
	idp.fd = fd[1];
	e = fmt == F_ELF  ? ld_elf(idi, &idp, kh, &hdr.ee) :
	    fmt == F_AOUT ? ld_aout(idi, &idp, kh, &hdr.ex) : -1;
	close(fd[1]);
	if ((pid = waitpid(pid, &status, 0)) == -1)
	    err(1, NULL);
	if (WIFSIGNALED(status) || WEXITSTATUS(status))
	    exit(1);
    }
    if (e)
	errx(1, "%s: Invalid format", idi->fname);
    if (fstat(ido->fd, &sb))
	err(1, "%s", ido->fname);
    kh->nsize = sb.st_size - off;
}
Exemplo n.º 4
0
/*
 * Link KGZ file and loader.
 */
void
kgzld(struct kgz_hdr * kh, const char *f1, const char *f2)
{
    char addr[16];
    struct iodesc idi;
    pid_t pid;
    size_t n;
    int status;

    if (strcmp(kh->ident, "KGZ")) {
	if ((idi.fd = open(idi.fname = f1, O_RDONLY)) == -1)
	    err(1, "%s", idi.fname);
	if (!format) {
	    union {
		struct exec ex;
		Elf32_Ehdr ee;
	    } hdr;
	    n = xread(&idi, &hdr, sizeof(hdr), 0);
	    if (n >= sizeof(hdr.ee) && IS_ELF(hdr.ee))
		format = F_ELF;
	    else if (n >= sizeof(hdr.ex) &&
		     N_GETMAGIC(hdr.ex) == OMAGIC)
		format = F_AOUT;
	    if (!format)
		errx(1, "%s: Format not supported", idi.fname);
	}
	n = xread(&idi, kh, sizeof(*kh),
		  format == F_AOUT ? sizeof(struct kgz_aouthdr0)
				   : sizeof(struct kgz_elfhdr));
	xclose(&idi);
	if (n != sizeof(*kh) || strcmp(kh->ident, "KGZ"))
	    errx(1, "%s: Invalid format", idi.fname);
    }
    sprintf(addr, "%#x", align(kh->dload + kh->dsize, 0x1000));
    switch (pid = fork()) {
    case -1:
	err(1, NULL);
    case 0:
	if (format == F_AOUT)
	    execlp("ld", "ld", "-aout", "-Z", "-T", addr, "-o", f2,
		   loader, f1, (char *)NULL);
	else
	    execlp("ld", "ld", "-Ttext", addr, "-o", f2, loader, f1,
		   (char *)NULL);
	warn(NULL);
	_exit(1);
    default:
	if ((pid = waitpid(pid, &status, 0)) == -1)
	    err(1, NULL);
	if (WIFSIGNALED(status) || WEXITSTATUS(status))
	    exit(1);
    }
}
Exemplo n.º 5
0
static int
is_exos_aout(int fd)
{
  struct exec hdr;
  u_int dynamic;

  if (lseek(fd, 0, SEEK_SET) == -1 ||
      read(fd, &hdr, sizeof(hdr)) != sizeof(hdr) ||
      lseek(fd, sizeof(hdr) + hdr.a_text, SEEK_SET) == -1 ||
      read(fd, &dynamic, sizeof(dynamic)) != sizeof(dynamic))
    return 0;

  if (N_GETMAGIC(hdr) != OMAGIC ||
      N_GETMID(hdr) != MID_I386 ||
      N_GETFLAG(hdr) != 0)
    return 0;

  return 1;
}
Exemplo n.º 6
0
void
run_header(struct exec *exhdr, int extended_info)
{
	char *id = NULL;

	assert(NULL != exhdr);

	/* print raw values */
	printf(
		"\ta_midmag 0x%08x (mid %d, magic 0%o, flag 0x%x)\n"
		"\ta_text   0x%08x\n"
		"\ta_data   0x%08x\n"
		"\ta_bss    0x%08x\n"
		"\ta_syms   0x%08x\n"
		"\ta_entry  0x%08x\n"
		"\ta_trsize 0x%08x\n"
		"\ta_drsize 0x%08x\n",
		exhdr->a_midmag,
		N_GETMID(*exhdr), N_GETMAGIC(*exhdr), N_GETFLAG(*exhdr),
		exhdr->a_text,
		exhdr->a_data,
		exhdr->a_bss,
		exhdr->a_syms,
		exhdr->a_entry,
		exhdr->a_trsize,
		exhdr->a_drsize
	);

	printf(
		"magic number %04o: %s\n", N_GETMAGIC(*exhdr),
		N_GETMAGIC(*exhdr) == OMAGIC ?  "old impure format" :
		N_GETMAGIC(*exhdr) == NMAGIC ?  "read-only text" :
		N_GETMAGIC(*exhdr) == ZMAGIC ?  "demand load format" :
		N_GETMAGIC(*exhdr) == QMAGIC ?  "deprecated format" :
		"totally funky"
	);

	switch (N_GETMID(*exhdr)) {
	case MID_ZERO:    id = "unknown - implementation dependent"; break;
	case MID_SUN010:  id = "sun 68010/68020 binary";             break;
	case MID_SUN020:  id = "sun 68020-only binary";              break;
	case MID_PC386:   id = "386 PC binary. (so quoth BFD)";      break;
	case MID_HP200:   id = "hp200 (68010) BSD binary";           break;
	case MID_I386:    id = "i386 BSD binary";                    break;
	case MID_M68K:    id = "m68k BSD binary with 8K page sizes"; break;
	case MID_M68K4K:  id = "m68k BSD binary with 4K page sizes"; break;
	case MID_NS32532: id = "ns32532";                            break;
	case MID_SPARC:   id = "sparc";                              break;
	case MID_PMAX:    id = "pmax";                               break;
	case MID_VAX:     id = "vax";                                break;
	case MID_ALPHA:   id = "Alpha BSD binary";                   break;
	case MID_MIPS:    id = "big-endian MIPS";                    break;
	case MID_ARM6:    id = "ARM6";                               break;
	case MID_HP300:   id = "hp300 (68020+68881) BSD binary";     break;
	case MID_HPUX:    id = "hp200/300 HP-UX binary";             break;
	case MID_HPUX800: id = "hp800 HP-UX binary";                 break;
	default:
		id = "don't know"; break;
	}

	printf("type %d, %s\n", N_GETMID(*exhdr), id);

	/* this left shift seems a bit bogus */

	switch((N_GETFLAG(*exhdr) & EX_DPMASK)>>4) {
	case 0:
		id = "traditional executable or object file"; break;
	case 1:
		id = "object file contains PIC code"; break;
	case 2:
		id = "dynamic executable"; break;
	case 3:
		id = "position independent executable image"; break;
	default:
		id = NULL;
	}

	if (NULL != id)
		printf("flags: 0x%x, %s\n", N_GETFLAG(*exhdr), id);
	else
		printf("flags: 0x%x\n", N_GETFLAG(*exhdr));

	if (extended_info) {
		unsigned long txt_addr;
		unsigned long dat_addr;
		unsigned long bss_addr;

		/* N_TXTADDR and N_DATADDR macros DON'T WORK */
		if (N_GETMAGIC(*exhdr) == ZMAGIC) {
			txt_addr = __LDPGSZ;
			dat_addr = ((txt_addr + exhdr->a_text + __LDPGSZ - 1) & ~(__LDPGSZ - 1));
		} else if (N_GETMAGIC(*exhdr) == OMAGIC) {
			txt_addr = 0;
			dat_addr = txt_addr + exhdr->a_text;
		} else {
			txt_addr = 0xdeadbeef;
			dat_addr = 0xcafebabe;
		}

		bss_addr = dat_addr + exhdr->a_data;

		printf("	text segment size  = 0x%lx, text segment file offset = %ld\n", exhdr->a_text, N_TXTOFF(*exhdr));
		printf("	data segment size  = 0x%lx, data segment file offset = %ld\n", exhdr->a_data, N_DATOFF(*exhdr));
		printf("	bss  segment size  = 0x%lx\n", exhdr->a_bss);
		printf("	text segment relocation size  = 0x%lx, file offset   = %ld, %d text relocations\n",
			exhdr->a_trsize, N_TRELOFF(*exhdr), exhdr->a_trsize/sizeof(struct relocation_info));
		printf("	data segment relocation size  = 0x%lx, file offset   = %ld, %d data relocations\n",
			exhdr->a_drsize, N_DRELOFF(*exhdr), exhdr->a_drsize/sizeof(struct relocation_info));
		printf("	symbol table size  = 0x%lx, symbol table file offset = %ld (%d symbols)\n",
			exhdr->a_syms, N_SYMOFF(*exhdr), exhdr->a_syms/sizeof(struct nlist));
		printf("	string table file offset = 0x%lx (%d)\n", N_STROFF(*exhdr), N_STROFF(*exhdr));
		printf("	entry point  = 0x%lx\n", exhdr->a_entry);
		printf("	text address = 0x%lx\n\tdata address = 0x%lx\n"
			"\tbss address = 0x%lx\n",
			txt_addr, dat_addr, bss_addr
			/* N_TXTADDR(*exhdr), N_DATADDR(*exhdr), N_BSSADDR(*exhdr) */
		);
	}
}
Exemplo n.º 7
0
/*
 * Get file size and read a.out or ELF header.
 */
static void
gethdr(int fd, struct hdr *hdr)
{
    struct stat sb;
    const struct exec *ex;
    const Elf32_Ehdr *ee;
    const Elf32_Phdr *ep;
    void *p;
    unsigned int fmt, x, n, i;

    memset(hdr, 0, sizeof(*hdr));
    if (fstat(fd, &sb))
	err(2, "%s", fname);
    if (sb.st_size > MAXU32)
	errx(1, "%s: Too big", fname);
    hdr->size = sb.st_size;
    if (!hdr->size)
	return;
    if ((p = mmap(NULL, hdr->size, PROT_READ, MAP_SHARED, fd,
		  0)) == MAP_FAILED)
	err(2, "%s", fname);
    for (fmt = F_CNT - 1; !hdr->fmt && fmt; fmt--)
	switch (fmt) {
	case F_AOUT:
	    ex = p;
	    if (hdr->size >= sizeof(struct exec) && !N_BADMAG(*ex)) {
		hdr->fmt = fmt;
		x = N_GETMAGIC(*ex);
		if (x == OMAGIC || x == NMAGIC) {
		    if (x == NMAGIC)
			Warn(fname, "Treating %s NMAGIC as OMAGIC",
			     fmtlist[fmt]);
		    hdr->flags |= IMPURE;
		}
		hdr->text = le32toh(ex->a_text);
		hdr->data = le32toh(ex->a_data);
		hdr->bss = le32toh(ex->a_bss);
		hdr->entry = le32toh(ex->a_entry);
		if (le32toh(ex->a_entry) >= BTX_PGSIZE)
		    hdr->org = BTX_PGSIZE;
	    }
	    break;
	case F_ELF:
	    ee = p;
	    if (hdr->size >= sizeof(Elf32_Ehdr) && IS_ELF(*ee)) {
		hdr->fmt = fmt;
		for (n = i = 0; i < le16toh(ee->e_phnum); i++) {
		    ep = (void *)((uint8_t *)p + le32toh(ee->e_phoff) +
				  le16toh(ee->e_phentsize) * i);
		    if (le32toh(ep->p_type) == PT_LOAD)
			switch (n++) {
			case 0:
			    hdr->text = le32toh(ep->p_filesz);
			    hdr->org = le32toh(ep->p_paddr);
			    if (le32toh(ep->p_flags) & PF_W)
				hdr->flags |= IMPURE;
			    break;
			case 1:
			    hdr->data = le32toh(ep->p_filesz);
			    hdr->bss = le32toh(ep->p_memsz) -
				le32toh(ep->p_filesz);
			    break;
			case 2:
			    Warn(fname,
				 "Ignoring extra %s PT_LOAD segments",
				 fmtlist[fmt]);
			}
		}
		hdr->entry = le32toh(ee->e_entry);
	    }
	}
    if (munmap(p, hdr->size))
	err(2, "%s", fname);
}
Exemplo n.º 8
0
/*
 * 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;
}
Exemplo n.º 9
0
static void
load(void)
{
    union {
	struct exec ex;
	Elf32_Ehdr eh;
    } hdr;
    Elf32_Phdr ep[2];
    Elf32_Shdr es[2];
    caddr_t p;
    ino_t ino;
    uint32_t addr, x;
    int fmt, i, j;

    if (!(ino = lookup(kname))) {
	if (!ls)
	    printf("No %s\n", kname);
	return;
    }
    if (xfsread(ino, &hdr, sizeof(hdr)))
	return;
    if (N_GETMAGIC(hdr.ex) == ZMAGIC)
	fmt = 0;
    else if (IS_ELF(hdr.eh))
	fmt = 1;
    else {
	printf("Invalid %s\n", "format");
	return;
    }
    if (fmt == 0) {
	addr = hdr.ex.a_entry & 0xffffff;
	p = PTOV(addr);
	fs_off = PAGE_SIZE;
	if (xfsread(ino, p, hdr.ex.a_text))
	    return;
	p += roundup2(hdr.ex.a_text, PAGE_SIZE);
	if (xfsread(ino, p, hdr.ex.a_data))
	    return;
	p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE);
	bootinfo.bi_symtab = VTOP(p);
	memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms));
	p += sizeof(hdr.ex.a_syms);
	if (hdr.ex.a_syms) {
	    if (xfsread(ino, p, hdr.ex.a_syms))
		return;
	    p += hdr.ex.a_syms;
	    if (xfsread(ino, p, sizeof(int)))
		return;
	    x = *(uint32_t *)p;
	    p += sizeof(int);
	    x -= sizeof(int);
	    if (xfsread(ino, p, x))
		return;
	    p += x;
	}
    } else {
	fs_off = hdr.eh.e_phoff;
	for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) {
	    if (xfsread(ino, ep + j, sizeof(ep[0])))
		return;
	    if (ep[j].p_type == PT_LOAD)
		j++;
	}
	for (i = 0; i < 2; i++) {
	    p = PTOV(ep[i].p_paddr & 0xffffff);
	    fs_off = ep[i].p_offset;
	    if (xfsread(ino, p, ep[i].p_filesz))
		return;
	}
	p += roundup2(ep[1].p_memsz, PAGE_SIZE);
	bootinfo.bi_symtab = VTOP(p);
	if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) {
	    fs_off = hdr.eh.e_shoff + sizeof(es[0]) *
		(hdr.eh.e_shstrndx + 1);
	    if (xfsread(ino, &es, sizeof(es)))
		return;
	    for (i = 0; i < 2; i++) {
		memcpy(p, &es[i].sh_size, sizeof(es[i].sh_size));
		p += sizeof(es[i].sh_size);
		fs_off = es[i].sh_offset;
		if (xfsread(ino, p, es[i].sh_size))
		    return;
		p += es[i].sh_size;
	    }
	}
	addr = hdr.eh.e_entry & 0xffffff;
    }
    bootinfo.bi_esymtab = VTOP(p);
    bootinfo.bi_kernelname = VTOP(kname);
    bootinfo.bi_bios_dev = dsk.drive;
    __exec((caddr_t)addr, opts & RBX_MASK,
	   MAKEBOOTDEV(dev_maj[dsk.type], 0, dsk.slice, dsk.unit, dsk.part),
	   0, 0, 0, VTOP(&bootinfo));
}
Exemplo n.º 10
0
/*
 * 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;
}
Exemplo n.º 11
0
static int
aout_exec(int fd, struct exec *aout, vaddr_t *entryp)
{
	caddr_t addr = (caddr_t)LOADADDR;
	int strtablen;
	char *strtab;
	vaddr_t entry = (vaddr_t)LOADADDR;
	int i;

	printf("%d", aout->a_text);
	if (N_GETMAGIC(*aout) == ZMAGIC) {
		entry = (vaddr_t)(addr+sizeof(struct exec));
		addr += sizeof(struct exec);
	}
	/* we can't lseek() here - we may be booting off tape */
	bcopy((char *)aout + sizeof(struct exec), addr,
	    sizeof(hdr) - sizeof(struct exec));
	if (read(fd, (char *)addr + sizeof(hdr) - sizeof(struct exec),
	    aout->a_text - (sizeof(hdr) - sizeof(struct exec))) !=
	    aout->a_text - (sizeof(hdr) - sizeof(struct exec)))
		goto shread;
	addr += aout->a_text;
	if (N_GETMAGIC(*aout) == ZMAGIC || N_GETMAGIC(*aout) == NMAGIC)
		while ((int)addr & __LDPGSZ)
			*addr++ = 0;
	printf("+%d", aout->a_data);
	if (read(fd, addr, aout->a_data) != aout->a_data)
		goto shread;
	addr += aout->a_data;
	printf("+%d", aout->a_bss);
	for (i = aout->a_bss; i ; --i)
		*addr++ = 0;
	if (aout->a_syms != 0) {
		bcopy(&aout->a_syms, addr, sizeof(aout->a_syms));
		addr += sizeof(aout->a_syms);
		printf("+[%d", aout->a_syms);
		if (read(fd, addr, aout->a_syms) != aout->a_syms)
			goto shread;
		addr += aout->a_syms;

		if (read(fd, &strtablen, sizeof(int)) != sizeof(int))
			goto shread;

		bcopy(&strtablen, addr, sizeof(int));
		if (i = strtablen) {
			i -= sizeof(int);
			addr += sizeof(int);
			if (read(fd, addr, i) != i)
			    goto shread;
			addr += i;
		}
		printf("+%d]", i);
		esym = ((u_int)aout->a_entry - (u_int)LOADADDR) +
			(((int)addr + sizeof(int) - 1) & ~(sizeof(int) - 1));
	}
	printf("=0x%x\n", addr);
	close(fd);

	*entryp = entry;
	return (0);

shread:
	printf("boot: short read\n");
	return (1);
}
Exemplo n.º 12
0
long AOutParser::Read(Stream* stream)
{
	m_pStream = stream;

	ULONG filesize = stream->GetSize();

	if (stream->Read(&exec_header, sizeof(exec)) != sizeof(exec))
	{
//		printf("AOut read error\n");
		return -1;
	}

	switch (N_GETMAGIC(&exec_header))
	{
	case A_MAGIC:
		//printf("68020");
		break;
	case I_MAGIC:
		//printf("intel 386");
		break;

	case J_MAGIC:// printf("intel 960"); break;
	case K_MAGIC:// printf("sparc"); break;
	case V_MAGIC:// printf("mips 3000"); break;
	case X_MAGIC:// printf("att dsp 3210"); break;
	case M_MAGIC:// printf("mips 4000"); break;
	case D_MAGIC:// printf("amd 29000"); break;
	case E_MAGIC:// printf("arm 7-something"); break;
	case Q_MAGIC:// printf("powerpc"); break;
	case N_MAGIC:// printf("mips 4000-le"); break;
	case L_MAGIC:// printf("dec alpha"); break;
		break;

	default:
//		printf("AOut: Unknown magic\n");
		return -2;
	}

	exec_header.a_text = BigEndian32(exec_header.a_text);
	exec_header.a_data = BigEndian32(exec_header.a_data);
	exec_header.a_bss = BigEndian32(exec_header.a_bss);
	exec_header.a_trsize = BigEndian32(exec_header.a_trsize);
	exec_header.a_drsize = BigEndian32(exec_header.a_drsize);
	exec_header.a_syms = BigEndian32(exec_header.a_syms);

	m_numberOfSections = 0;
	m_Sections[0] = -1;
	m_Sections[1] = -1;
	m_Sections[2] = -1;
	if (exec_header.a_text) m_Sections[m_numberOfSections++] = 0;
	if (exec_header.a_data) m_Sections[m_numberOfSections++] = 1;
	if (exec_header.a_bss) m_Sections[m_numberOfSections++] = 2;

	m_nsymbols = exec_header.a_syms / sizeof(nlist);

#if 0
	printf("text size: %d\n", exec_header.a_text);
	printf("data size: %d\n", exec_header.a_data);
	printf("bss size: %d\n", exec_header.a_bss);
	printf("text reloc size: %d\n", exec_header.a_trsize);
	printf("data reloc size: %d\n", exec_header.a_drsize);
	printf("symbol size: %d\n", exec_header.a_syms);
	printf("number of symbols: %d\n", nsymbols);
#endif

	m_TextOffset = sizeof(exec);
	m_DataOffset = sizeof(exec) + exec_header.a_text;
	m_TextRelocOffset = m_DataOffset + exec_header.a_data;
	m_DataRelocOffset = m_TextRelocOffset + exec_header.a_trsize;
	m_SymbolTableOffset = m_DataRelocOffset + exec_header.a_drsize;
	m_StringTableOffset = m_SymbolTableOffset + exec_header.a_syms;

	{
		int count = exec_header.a_trsize / sizeof(relocation_info);

	//	fprintf(stdout, "nrelocs: %d\n", count);

		if (count)
		{
			stream->Seek(m_TextRelocOffset, System::IO::STREAM_SEEK_SET);

			m_tr = new Relocation[count];

			for (int i = 0; i < count; i++)
			{
				relocation_info relocinfo;// = &m_tr[i];
				stream->Read(&relocinfo, sizeof(relocation_info));

				m_tr[i].r_address = BigEndian32(relocinfo.r_address);
			//	((DWORD*)&relocinfo)[1] = BigEndian32(((DWORD*)&relocinfo)[1]);

			//	fprintf(stdout, "r_address: %d, ", m_tr[i].r_address);

				uint8* bf = (uint8*)(((uint32*)&relocinfo)+1);

				bool r_pcrel = (bf[3] >> 7) & 0x1;
				int r_length = (bf[3] >> 5) & 0x3;
				bool r_extern = (bf[3] >> 4) & 0x1;
				bool r_baserel = (bf[3] >> 3) & 0x1;
				bool r_jmptable = (bf[3] >> 2) & 0x1;
				bool r_relative = (bf[3] >> 1) & 0x1;
				bool r_copy = (bf[3] >> 0) & 0x1;

				// TODO, support other values on these
				VERIFY(r_length == 2);
				VERIFY(r_baserel == 0);
				VERIFY(r_jmptable == 0);
				VERIFY(r_relative == 0);
				VERIFY(r_copy == 0);

				m_tr[i].r_extern = r_extern;
				m_tr[i].r_pcrel = r_pcrel;

	//TRACE("pcrel: %d, baserel: %d, relative: %d, copy: %d\n", r_pcrel, r_baserel, r_relative, r_copy);

				uint32 symbolnum = (bf[0]<<16) | (bf[1]<<8) | (bf[2]);

				//printf("symbolnum: %d, r_baserel: %d, r_extern: %d\n", symbolnum, r_baserel, r_extern);

			//	relocinfo->r_symbolnum = symbolnum;	// hm..
				m_tr[i].r_symbolnum = symbolnum;

			//	fprintf(stdout, "symbolnum: %d", m_tr[i].r_symbolnum);

			//	printf("Text Reloc(addr=%d, symbol=%d)\n", relocinfo->r_address - m_TextOffset, symbolnum);

			//	fprintf(stdout, "\n");
			}
		}
	}

	{
		int count = exec_header.a_drsize / sizeof(relocation_info);

	//	fprintf(stdout, "nrelocs: %d\n", count);

		if (count)
		{
			stream->Seek(m_DataRelocOffset, System::IO::STREAM_SEEK_SET);

			m_dr = new Relocation[count];

			for (int i = 0; i < count; i++)
			{
				relocation_info relocinfo;// = &m_tr[i];
				stream->Read(&relocinfo, sizeof(relocation_info));

				m_dr[i].r_address = BigEndian32(relocinfo.r_address);
			//	((DWORD*)&relocinfo)[1] = BigEndian32(((DWORD*)&relocinfo)[1]);

			//	fprintf(stdout, "r_address: %d, ", m_tr[i].r_address);

				uint8* bf = (uint8*)(((uint32*)&relocinfo)+1);

				bool r_pcrel = (bf[3] >> 7) & 0x1;
				int r_length = (bf[3] >> 5) & 0x3;
				bool r_extern = (bf[3] >> 4) & 0x1;;
				bool r_baserel = (bf[3] >> 3) & 0x1;
				bool r_jmptable = (bf[3] >> 2) & 0x1;
				bool r_relative = (bf[3] >> 1) & 0x1;
				bool r_copy = (bf[3] >> 0) & 0x1;
				
			//	ASSERT(r_pcrel == 0);
				ASSERT(r_length == 2);
				ASSERT(r_baserel == 0);
				ASSERT(r_jmptable == 0);
				ASSERT(r_relative == 0);
				ASSERT(r_copy == 0);

				m_dr[i].r_extern = r_extern;
				m_dr[i].r_pcrel = r_pcrel;

	//TRACE("pcrel: %d, baserel: %d, relative: %d, copy: %d\n", r_pcrel, r_baserel, r_relative, r_copy);

				uint32 symbolnum = (bf[0]<<16) | (bf[1]<<8) | (bf[2]);

				//printf("symbolnum: %d, r_baserel: %d, r_extern: %d\n", symbolnum, r_baserel, r_extern);

			//	relocinfo->r_symbolnum = symbolnum;	// hm..
				m_dr[i].r_symbolnum = symbolnum;

			//	fprintf(stdout, "symbolnum: %d", m_tr[i].r_symbolnum);

			//	printf("Text Reloc(addr=%d, symbol=%d)\n", relocinfo->r_address - m_TextOffset, symbolnum);

			//	fprintf(stdout, "\n");
			}
		}
	}

	// Symbols
	if (m_nsymbols)
	{
		m_nlistSymbols = new nlist[m_nsymbols];

		long StringTableLen = filesize - m_StringTableOffset;

		stream->position = m_StringTableOffset;
		m_StringData = new char[StringTableLen];
		int n = stream->Read(m_StringData, StringTableLen);
		ASSERT(n == StringTableLen);

		stream->position = m_SymbolTableOffset;
		for (int i = 0; i < m_nsymbols; i++)
		{
			nlist& symbol = m_nlistSymbols[i];

			stream->Read(&symbol, sizeof(nlist));
			symbol.n_un.n_strx = BigEndian32(symbol.n_un.n_strx);
			symbol.n_value = BigEndian32(symbol.n_value);
			symbol.n_desc = BigEndian16(symbol.n_desc);

			// Convert offset into string table to pointer
			symbol.n_un.n_name = m_StringData + symbol.n_un.n_strx;

			if ((symbol.n_type & N_TYPE) == N_DATA)
			{
				symbol.n_value -= exec_header.a_text;
			}

			/*

			printf("%d, %s, value=%d, type=%d", i+1, symbol.n_un.n_name, symbol.n_value, symbol.n_type);
			printf("\n");
			*/
		}
	}

#if 0
	{
		uint8* text = new uint8[exec_header.a_text];
		if (text == NULL)
		{
			printf("Out of memory");
			return -1;
		}

		fseek(fp, m_TextOffset, SEEK_SET);
		fread(text, 1, exec_header.a_text, fp);

		// Text Code
		if (N_GETMAGIC(&exec_header) == A_MAGIC)	// // 68020
		{
			pass2_CODE(text, exec_header.a_text, m_nsymbols, Symbols);
		}
		else if (N_GETMAGIC(&exec_header) == I_MAGIC)	// intel 386
		{
			ReadCode_x86(text, exec_header.a_text);
		}
		else if (N_GETMAGIC(&exec_header) == Q_MAGIC)	// powerpc
		{
			dasm_powerpc(text, exec_header.a_text);
		}
		else
		{
		}

		delete[] text;
	}
#endif

	return 0;
}
Exemplo n.º 13
0
static int
exec_exos_aout(int fd, const char *path, char *const argv[],
	       char *const envp[], struct Env *e, u_int flags)
{
  u_int envid = e->env_id;
  struct exec hdr;
  u_int dynamic;
  int r;
  struct _exos_exec_args eea;

  if (lseek(fd, 0, SEEK_SET) == -1 ||
      read(fd, &hdr, sizeof(hdr)) != sizeof(hdr) ||
      lseek(fd, sizeof(hdr) + hdr.a_text, SEEK_SET) == -1 ||
      read(fd, &dynamic, sizeof(dynamic)) != sizeof(dynamic))
    return 0;

  if (N_GETMAGIC(hdr) != OMAGIC ||
      N_GETMID(hdr) != MID_I386 ||
      N_GETFLAG(hdr) != 0)
    return 0;

  if (!(flags & _EXEC_USE_FD)) {
    close(fd);
    fd = -1;
  } else if (lseek(fd, 0, SEEK_SET) == -1)
    return 0;

  if (dynamic < SHARED_LIBRARY_START) dynamic = 0;
  if (dynamic == 0 && (flags & _EXEC_SHLIB_ONLY)) {
    r = -EINVAL;
    goto err;
  }

  /* if static, then read in entire program... */
  if (!dynamic) {
    u_int start_text_addr;

    if (flags & _EXEC_USE_FD)
      start_text_addr = __load_prog_fd(fd, 1, envid);
    else
      start_text_addr = __load_prog(path, argv[0], 1, envid);
    if (!start_text_addr) {
      r = -ENOEXEC;
      goto err;
    }
    /* set start address */
    e->env_tf.tf_eip = start_text_addr;
  }
  /* if dynamic, then make sure shared library is available */
  else if (dynamic) {
    struct stat sb;

    /* If flag so indicates, then require RO copy and use in mem version */
    if (!(flags & _EXEC_SHLIB_ONLY)) {
      /* if the shared library is not already in memory, or if it's old */
      /* then we need to (re)read it in */
      if (stat(PATH_LIBEXOS, &sb)) {
	r = -errno;
	kprintf("error stat'ing sl: %d\n", errno);
	goto err;
      }
      /* if we don't have a RO copy or it's out of date... */
      if (!isvamapped(SHARED_LIBRARY_START_RODATA) ||
	  memcmp(&sl_data->mod_time, &sb.st_mtimespec,
		 sizeof(sb.st_mtimespec))) {
	int slfd;

	/* if it's out of date, then unmap it */
	if (isvamapped(SHARED_LIBRARY_START_RODATA))
	  munmap((void*)SHARED_LIBRARY_START_RODATA,
		 (sl_data->text_pages + sl_data->data_pages) * NBPG);
	slfd = open (PATH_LIBEXOS, O_RDONLY);
	if (slfd < 0) {
	  r = -errno;
	  kprintf("could not open shared library " PATH_LIBEXOS "\n");
	  goto err;
	}
	if ((r = __load_sl_image (slfd)) < 0) {
	  kprintf("could not load library\n");
	  close(slfd);
	  goto err;
	}
	*((struct timespec*)&sl_data->mod_time) = sb.st_mtimespec;
	assert(sys_self_mod_pte_range(0, PG_RO, PG_W,
				      SHARED_LIBRARY_START_RODATA, 1) == 0);
	close (slfd);
      }
    } else {
      if (!isvamapped(SHARED_LIBRARY_START_RODATA)) {
	r = -EINVAL;
	goto err;
      }
    }

    /* share the text region read only/exec into child */
    if (__vm_share_region(SHARED_LIBRARY_START_RODATA,
			  sl_data->text_pages * NBPG, 0, 0,
			  envid, SHARED_LIBRARY_START)) {
      kprintf ("__vm_share_region failed for text region\n");
      r = -ENOEXEC;
      goto err;
    }

    /* share the read only data region into child cow */
    if (__vm_share_region(SHARED_LIBRARY_START_RODATA +
			  sl_data->text_pages * NBPG,
			  sl_data->data_pages * NBPG, 0, 0, envid,
			  SHARED_LIBRARY_START + sl_data->text_pages * NBPG)) {
      kprintf ("__vm_share_region failed for cow data region\n");
      r = -ENOEXEC;
      goto err;
    }
    if (sys_mod_pte_range(0, PG_COW, PG_RO | PG_SHARED, SHARED_LIBRARY_START +
			  sl_data->text_pages * NBPG, sl_data->data_pages, 0,
			  envid) < 0) {
      kprintf ("sys_mod_pte_range failed for cow data region\n");
      r = -ENOEXEC;
      goto err;
    }

    /* share the RO copy of the shared library */
    if (__vm_share_region(SHARED_LIBRARY_START_RODATA,
			  (sl_data->text_pages + sl_data->data_pages) * NBPG,
			  0, 0, envid, SHARED_LIBRARY_START_RODATA)) {
      kprintf ("__vm_share_region failed for read only text/data region\n");
      r = -ENOEXEC;
      goto err;
    }

    /* demand alloc bss for sl or no? */    
    if (getenv("NO_BSS_DEMAND_ALLOC")) {
      /* zero the bss */
      if (__zero_segment (envid, SHARED_LIBRARY_START +
			  (sl_data->text_pages + sl_data->data_pages) *
			  NBPG, sl_data->bss_pages * NBPG) < 0) {
	kprintf("could not create bss segment\n");
	r = -ENOEXEC;
	goto err;
      }
     } /* otherwise the fault handler will deal with it */
    
    /* set start address */
    e->env_tf.tf_eip = SHARED_LIBRARY_START + sizeof(struct exec);
  }

  /* take care of args, etc */
  if (flags & _EXEC_USE_FD)
    eea.eea_prog_fd = fd;
  else
    eea.eea_prog_fd = -1;
  if ((r = setup_new_stack(argv, envp, envid, &e->env_tf.tf_esp, &eea)) < 0)
    goto err;

  return 1;

 err:
  return r;
}
/*
 * It should be responsible for setting up everything that must be
 * in place when main is called.
 * This includes:
 *   Initializing the physical console so characters can be printed.
 *   Setting up page tables for the kernel.
 */
u_int
init_sa11x0(int argc, char **argv, struct bootinfo *bi)
{
	u_int kerneldatasize, symbolsize;
	u_int l1pagetable;
	vaddr_t freemempos;
	vsize_t pt_size;
	int loop;
#if NKSYMS || defined(DDB) || defined(MODULAR)
	Elf_Shdr *sh;
#endif

#ifdef DEBUG_BEFOREMMU
	/*
	 * At this point, we cannot call real consinit().
	 * Just call a faked up version of consinit(), which does the thing
	 * with MMU disabled.
	 */
	fakecninit();
#endif

	/*
	 * XXX for now, overwrite bootconfig to hardcoded values.
	 * XXX kill bootconfig and directly call uvm_physload
	 */
	bootconfig.dram[0].address = 0xc0000000;
	bootconfig.dram[0].pages = DRAM_PAGES;
	bootconfig.dramblocks = 1;

	kerneldatasize = (uint32_t)&end - (uint32_t)KERNEL_TEXT_BASE;
	symbolsize = 0;
#if NKSYMS || defined(DDB) || defined(MODULAR)
	if (!memcmp(&end, "\177ELF", 4)) {
		sh = (Elf_Shdr *)((char *)&end + ((Elf_Ehdr *)&end)->e_shoff);
		loop = ((Elf_Ehdr *)&end)->e_shnum;
		for (; loop; loop--, sh++)
			if (sh->sh_offset > 0 &&
			    (sh->sh_offset + sh->sh_size) > symbolsize)
				symbolsize = sh->sh_offset + sh->sh_size;
	}
#endif

	printf("kernsize=0x%x\n", kerneldatasize);
	kerneldatasize += symbolsize;
	kerneldatasize = ((kerneldatasize - 1) & ~(PAGE_SIZE * 4 - 1)) +
	    PAGE_SIZE * 8;

	/*
	 * hpcboot has loaded me with MMU disabled.
	 * So create kernel page tables and enable MMU.
	 */

	/*
	 * Set up the variables that define the availability of physcial
	 * memory.
	 */
	physical_start = bootconfig.dram[0].address;
	physical_freestart = physical_start
	    + (KERNEL_TEXT_BASE - KERNEL_BASE) + kerneldatasize;
	physical_end = bootconfig.dram[bootconfig.dramblocks - 1].address
	    + bootconfig.dram[bootconfig.dramblocks - 1].pages * PAGE_SIZE;
	physical_freeend = physical_end;
    
	for (loop = 0; loop < bootconfig.dramblocks; ++loop)
		physmem += bootconfig.dram[loop].pages;
    
	/* XXX handle UMA framebuffer memory */

	/* Use the first 256kB to allocate things */
	freemempos = KERNEL_BASE;
	memset((void *)KERNEL_BASE, 0, KERNEL_TEXT_BASE - KERNEL_BASE);

	/*
	 * Right. We have the bottom meg of memory mapped to 0x00000000
	 * so was can get at it. The kernel will occupy the start of it.
	 * After the kernel/args we allocate some of the fixed page tables
	 * we need to get the system going.
	 * We allocate one page directory and NUM_KERNEL_PTS page tables
	 * and store the physical addresses in the kernel_pt_table array.
	 * Must remember that neither the page L1 or L2 page tables are the
	 * same size as a page !
	 *
	 * Ok, the next bit of physical allocate may look complex but it is
	 * simple really. I have done it like this so that no memory gets
	 * wasted during the allocate of various pages and tables that are
	 * all different sizes.
	 * The start address will be page aligned.
	 * We allocate the kernel page directory on the first free 16KB
	 * boundary we find.
	 * We allocate the kernel page tables on the first 1KB boundary we
	 * find.  We allocate at least 9 PT's (12 currently).  This means
	 * that in the process we KNOW that we will encounter at least one
	 * 16KB boundary.
	 *
	 * Eventually if the top end of the memory gets used for process L1
	 * page tables the kernel L1 page table may be moved up there.
	 */

#ifdef VERBOSE_INIT_ARM
	printf("Allocating page tables\n");
#endif

	/* Define a macro to simplify memory allocation */
#define	valloc_pages(var, np)			\
	alloc_pages((var).pv_pa, (np));		\
	(var).pv_va = KERNEL_BASE + (var).pv_pa - physical_start;
#define	alloc_pages(var, np)			\
	(var) = freemempos;			\
	freemempos += (np) * PAGE_SIZE;

	valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE);
	for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) {
		alloc_pages(kernel_pt_table[loop].pv_pa,
		    L2_TABLE_SIZE / PAGE_SIZE);
		kernel_pt_table[loop].pv_va = kernel_pt_table[loop].pv_pa;
	}

	/* This should never be able to happen but better confirm that. */
	if (!kernel_l1pt.pv_pa || (kernel_l1pt.pv_pa & (L1_TABLE_SIZE-1)) != 0)
		panic("initarm: Failed to align the kernel page directory");

	/*
	 * Allocate a page for the system page mapped to V0x00000000
	 * This page will just contain the system vectors and can be
	 * shared by all processes.
	 */
	valloc_pages(systempage, 1);

	pt_size = round_page(freemempos) - physical_start;

	/* Allocate stacks for all modes */
	valloc_pages(irqstack, IRQ_STACK_SIZE);
	valloc_pages(abtstack, ABT_STACK_SIZE);
	valloc_pages(undstack, UND_STACK_SIZE);
	valloc_pages(kernelstack, UPAGES);

#ifdef VERBOSE_INIT_ARM
	printf("IRQ stack: p0x%08lx v0x%08lx\n", irqstack.pv_pa,
	    irqstack.pv_va); 
	printf("ABT stack: p0x%08lx v0x%08lx\n", abtstack.pv_pa,
	    abtstack.pv_va); 
	printf("UND stack: p0x%08lx v0x%08lx\n", undstack.pv_pa,
	    undstack.pv_va); 
	printf("SVC stack: p0x%08lx v0x%08lx\n", kernelstack.pv_pa,
	    kernelstack.pv_va); 
#endif

	alloc_pages(msgbufphys, round_page(MSGBUFSIZE) / PAGE_SIZE);

	/*
	 * XXX Actually, we only need virtual space and don't need
	 * XXX physical memory for sa110_cc_base and sa11x0_idle_mem.
	 */
	/*
	 * XXX totally stuffed hack to work round problems introduced
	 * in recent versions of the pmap code. Due to the calls used there
	 * we cannot allocate virtual memory during bootstrap.
	 */
	for (;;) {
		alloc_pages(sa1_cc_base, 1);
		if (!(sa1_cc_base & (CPU_SA110_CACHE_CLEAN_SIZE - 1)))
			break;
	}
	alloc_pages(sa1_cache_clean_addr, CPU_SA110_CACHE_CLEAN_SIZE / PAGE_SIZE - 1);

	sa1_cache_clean_addr = sa1_cc_base;
	sa1_cache_clean_size = CPU_SA110_CACHE_CLEAN_SIZE / 2;

	alloc_pages(sa11x0_idle_mem, 1);

	/*
	 * Ok, we have allocated physical pages for the primary kernel
	 * page tables.
	 */

#ifdef VERBOSE_INIT_ARM
	printf("Creating L1 page table\n");
#endif

	/*
	 * Now we start construction of the L1 page table.
	 * We start by mapping the L2 page tables into the L1.
	 * This means that we can replace L1 mappings later on if necessary.
	 */
	l1pagetable = kernel_l1pt.pv_pa;

	/* Map the L2 pages tables in the L1 page table */
	pmap_link_l2pt(l1pagetable, 0x00000000,
	    &kernel_pt_table[KERNEL_PT_SYS]);
#define SAIPIO_BASE		0xd0000000		/* XXX XXX */
	pmap_link_l2pt(l1pagetable, SAIPIO_BASE,
	    &kernel_pt_table[KERNEL_PT_IO]);
	for (loop = 0; loop < KERNEL_PT_KERNEL_NUM; ++loop)
		pmap_link_l2pt(l1pagetable, KERNEL_BASE + loop * 0x00400000,
		    &kernel_pt_table[KERNEL_PT_KERNEL + loop]);
	for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop)
		pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000,
		    &kernel_pt_table[KERNEL_PT_VMDATA + loop]);

	/* update the top of the kernel VM */
	pmap_curmaxkvaddr =
	    KERNEL_VM_BASE + (KERNEL_PT_VMDATA_NUM * 0x00400000);

#ifdef VERBOSE_INIT_ARM
	printf("Mapping kernel\n");
#endif

	/* Now we fill in the L2 pagetable for the kernel code/data */

	/*
	 * XXX there is no ELF header to find RO region.
	 * XXX What should we do?
	 */
#if 0
	if (N_GETMAGIC(kernexec[0]) == ZMAGIC) {
		logical = pmap_map_chunk(l1pagetable, KERNEL_TEXT_BASE,
		    physical_start, kernexec->a_text,
		    VM_PROT_READ, PTE_CACHE);
		logical += pmap_map_chunk(l1pagetable,
		    KERNEL_TEXT_BASE + logical, physical_start + logical,
		    kerneldatasize - kernexec->a_text,
		    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
	} else
#endif
		pmap_map_chunk(l1pagetable, KERNEL_TEXT_BASE,
		    KERNEL_TEXT_BASE - KERNEL_BASE + physical_start,
		    kerneldatasize, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);

#ifdef VERBOSE_INIT_ARM
	printf("Constructing L2 page tables\n");
#endif

	/* Map the stack pages */
	pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa,
	    IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
	pmap_map_chunk(l1pagetable, abtstack.pv_va, abtstack.pv_pa,
	    ABT_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
	pmap_map_chunk(l1pagetable, undstack.pv_va, undstack.pv_pa,
	    UND_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
	pmap_map_chunk(l1pagetable, kernelstack.pv_va, kernelstack.pv_pa,
	    UPAGES * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);

	pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa,
	    L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);

	/* Map page tables */
	pmap_map_chunk(l1pagetable, KERNEL_BASE, physical_start, pt_size,
	    VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);

	/* Map a page for entering idle mode */
	pmap_map_entry(l1pagetable, sa11x0_idle_mem, sa11x0_idle_mem,
	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);

	/* Map the vector page. */
	pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa,
	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);

	/* Map the statically mapped devices. */
	pmap_devmap_bootstrap(l1pagetable, sa11x0_devmap);

	pmap_map_chunk(l1pagetable, sa1_cache_clean_addr, 0xe0000000,
	    CPU_SA110_CACHE_CLEAN_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);

	/*
	 * Now we have the real page tables in place so we can switch to them.
	 * Once this is done we will be running with the REAL kernel page
	 * tables.
	 */

#ifdef VERBOSE_INIT_ARM
	printf("done.\n");
#endif

	/*
	 * Pages were allocated during the secondary bootstrap for the
	 * stacks for different CPU modes.
	 * We must now set the r13 registers in the different CPU modes to
	 * point to these stacks.
	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
	 * of the stack memory.
	 */
#ifdef VERBOSE_INIT_ARM
	printf("init subsystems: stacks ");
#endif

	set_stackptr(PSR_IRQ32_MODE,
	    irqstack.pv_va + IRQ_STACK_SIZE * PAGE_SIZE);
	set_stackptr(PSR_ABT32_MODE,
	    abtstack.pv_va + ABT_STACK_SIZE * PAGE_SIZE);
	set_stackptr(PSR_UND32_MODE,
	    undstack.pv_va + UND_STACK_SIZE * PAGE_SIZE);
#ifdef PMAP_DEBUG
	if (pmap_debug_level >= 0)
		printf("kstack V%08lx P%08lx\n", kernelstack.pv_va,
		    kernelstack.pv_pa);
#endif /* PMAP_DEBUG */

	/*
	 * Well we should set a data abort handler.
	 * Once things get going this will change as we will need a proper
	 * handler. Until then we will use a handler that just panics but
	 * tells us why.
	 * Initialization of the vectors will just panic on a data abort.
	 * This just fills in a slightly better one.
	 */
#ifdef VERBOSE_INIT_ARM
	printf("vectors ");
#endif
	data_abort_handler_address = (u_int)data_abort_handler;
	prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
	undefined_handler_address = (u_int)undefinedinstruction_bounce;
#ifdef DEBUG
	printf("%08x %08x %08x\n", data_abort_handler_address,
	    prefetch_abort_handler_address, undefined_handler_address); 
#endif

	/* Initialize the undefined instruction handlers */
#ifdef VERBOSE_INIT_ARM
	printf("undefined\n");
#endif
	undefined_init();

	/* Set the page table address. */
#ifdef VERBOSE_INIT_ARM
	printf("switching to new L1 page table  @%#lx...\n", kernel_l1pt.pv_pa);
#endif
	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
	cpu_setttb(kernel_l1pt.pv_pa, true);
	cpu_tlb_flushID();
	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2));

	/*
	 * Moved from cpu_startup() as data_abort_handler() references
	 * this during uvm init.
	 */
	uvm_lwp_setuarea(&lwp0, kernelstack.pv_va);

#ifdef BOOT_DUMP
	dumppages((char *)0xc0000000, 16 * PAGE_SIZE);
	dumppages((char *)0xb0100000, 64); /* XXX */
#endif
	/* Enable MMU, I-cache, D-cache, write buffer. */
	cpufunc_control(0x337f, 0x107d);

	arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL);

	consinit();

#ifdef VERBOSE_INIT_ARM
	printf("bootstrap done.\n");
#endif

#ifdef VERBOSE_INIT_ARM
	printf("freemempos=%08lx\n", freemempos);
	printf("MMU enabled. control=%08x\n", cpu_get_control());
#endif

	/* Load memory into UVM. */
	uvm_setpagesize();	/* initialize PAGE_SIZE-dependent variables */
	for (loop = 0; loop < bootconfig.dramblocks; loop++) {
		paddr_t dblk_start = (paddr_t)bootconfig.dram[loop].address;
		paddr_t dblk_end = dblk_start
			+ (bootconfig.dram[loop].pages * PAGE_SIZE);

		if (dblk_start < physical_freestart)
			dblk_start = physical_freestart;
		if (dblk_end > physical_freeend)
			dblk_end = physical_freeend;

		uvm_page_physload(atop(dblk_start), atop(dblk_end),
		    atop(dblk_start), atop(dblk_end), VM_FREELIST_DEFAULT);
	}

	/* Boot strap pmap telling it where the kernel page table is */
	pmap_bootstrap(KERNEL_VM_BASE, KERNEL_VM_BASE + KERNEL_VM_SIZE);

#ifdef BOOT_DUMP
	dumppages((char *)kernel_l1pt.pv_va, 16);
#endif

#ifdef DDB
	db_machine_init();
#endif
#if NKSYMS || defined(DDB) || defined(MODULAR)
	ksyms_addsyms_elf(symbolsize, ((int *)&end), ((char *)&end) + symbolsize);
#endif

	printf("kernsize=0x%x", kerneldatasize);
	printf(" (including 0x%x symbols)\n", symbolsize);

#ifdef DDB
	if (boothowto & RB_KDB)
		Debugger();
#endif /* DDB */

	/* We return the new stack pointer address */
	return (kernelstack.pv_va + USPACE_SVC_STACK_TOP);
}
Exemplo n.º 15
0
void
exec(char *path, void *loadaddr, int howto)
{
    int io;
#ifndef INSECURE
    struct stat sb;
#endif
    struct exec x;
    u_int i;
    ssize_t sz;
    char *addr;
#ifdef EXEC_DEBUG
    char *daddr, *etxt;
#endif

    io = open(path, 0);
    if (io < 0)
        return;

    (void) fstat(io, &sb);
    if (sb.st_mode & 2)
        printf("non-secure file, check permissions!\n");

    sz = read(io, (char *)&x, sizeof(x));
    if (sz != sizeof(x) || N_BADMAG(x)) {
        close(io);
        errno = EFTYPE;
        return;
    }

#ifdef EXEC_DEBUG
    printf("\nstruct exec {%x, %x, %x, %x, %x, %x, %x, %x}\n",
           x.a_midmag, x.a_text, x.a_data, x.a_bss, x.a_syms,
           x.a_entry, x.a_trsize, x.a_drsize);
#endif

    /* Text */
    printf("%u", x.a_text);
    addr = loadaddr;
    sz = x.a_text;
    if (N_GETMAGIC(x) == ZMAGIC) {
        bcopy((char *)&x, addr, sizeof x);
        addr += sizeof x;
        sz -= sizeof x;
    }
    if (read(io, (char *)addr, sz) != sz)
        goto shread;
    addr += sz;
#ifdef EXEC_DEBUG
    printf("\ntext {%x, %x, %x, %x}\n",
           addr[0], addr[1], addr[2], addr[3]);
    etxt = addr;
#endif
    if (N_GETMAGIC(x) == NMAGIC)
        while ((long)addr & (N_PAGSIZ(x) - 1))
            *addr++ = 0;

    /* Data */
#ifdef EXEC_DEBUG
    daddr = addr;
#endif
    printf("+%u", x.a_data);
    if (read(io, addr, x.a_data) != (ssize_t)x.a_data)
        goto shread;
    addr += x.a_data;

    /* Bss */
    printf("+%u", x.a_bss);
    for (i = 0; i < x.a_bss; i++)
        *addr++ = 0;

    /* Symbols */
    if (x.a_syms) {
        ssym = addr;
        bcopy(&x.a_syms, addr, sizeof(x.a_syms));
        addr += sizeof(x.a_syms);
        printf("+[%u", x.a_syms);
        if (read(io, addr, x.a_syms) != (ssize_t)x.a_syms)
            goto shread;
        addr += x.a_syms;

        if (read(io, &i, sizeof(u_int)) != sizeof(u_int))
            goto shread;

        bcopy(&i, addr, sizeof(u_int));
        if (i) {
            sz = i - sizeof(int);
            addr += sizeof(int);
            if (read(io, addr, sz) != sz)
                goto shread;
            addr += sz;
        }

        /* and that many bytes of string table */
        printf("+%d]", sz);
        esym = addr;
    } else {
        ssym = 0;
        esym = 0;
    }

    close(io);

    /* and note the end address of all this	*/
    printf(" total=0x%lx", (u_long)addr);

    /* XXX - Hack alert!
       This is no good, loadaddr is passed into
       machdep_start(), and it should do whatever
       is needed.

    	x.a_entry += (long)loadaddr;
    */
    printf(" start=0x%x\n", x.a_entry);

#ifdef EXEC_DEBUG
    printf("loadaddr=%p etxt=%p daddr=%p ssym=%p esym=%p\n",
           loadaddr, etxt, daddr, ssym, esym);
    printf("\n\nReturn to boot...\n");
    getchar();
#endif

    machdep_start((char *)((register_t)x.a_entry), howto, loadaddr, ssym,
                  esym);

    /* exec failed */
    errno = ENOEXEC;
    return;

shread:
    close(io);
    errno = EIO;
    return;
}
Exemplo n.º 16
0
static
#endif
void
dump_file(const char *fname)
{
    int fd;
    struct stat sb;
    caddr_t objbase;

    if (stat(fname, &sb) == -1) {
	warnx("cannot stat \"%s\"", fname);
	++error_count;
	return;
    }

    if ((sb.st_mode & S_IFMT) != S_IFREG) {
	warnx("\"%s\" is not a regular file", fname);
	++error_count;
	return;
    }

    if ((fd = open(fname, O_RDONLY, 0)) == -1) {
	warnx("cannot open \"%s\"", fname);
	++error_count;
	return;
    }

    objbase = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
    if (objbase == (caddr_t) -1) {
	warnx("cannot mmap \"%s\"", fname);
	++error_count;
	close(fd);
	return;
    }

    close(fd);

    file_base = (const char *) objbase;	/* Makes address arithmetic easier */

    if (IS_ELF(*(const Elf32_Ehdr*) align_struct(file_base))) {
	warnx("%s: this is an ELF program; use objdump to examine", fname);
	++error_count;
	munmap(objbase, sb.st_size);
	return;
    }

    ex = (const struct exec *) align_struct(file_base);

    printf("%s: a_midmag = 0x%lx\n", fname, (long)ex->a_midmag);
    printf("  magic = 0x%lx = 0%lo, netmagic = 0x%lx = 0%lo\n",
	(long)N_GETMAGIC(*ex), (long)N_GETMAGIC(*ex),
	(long)N_GETMAGIC_NET(*ex), (long)N_GETMAGIC_NET(*ex));

    if (N_BADMAG(*ex)) {
	warnx("%s: bad magic number", fname);
	++error_count;
	munmap(objbase, sb.st_size);
	return;
    }

    printf("  a_text   = 0x%lx\n", (long)ex->a_text);
    printf("  a_data   = 0x%lx\n", (long)ex->a_data);
    printf("  a_bss    = 0x%lx\n", (long)ex->a_bss);
    printf("  a_syms   = 0x%lx\n", (long)ex->a_syms);
    printf("  a_entry  = 0x%lx\n", (long)ex->a_entry);
    printf("  a_trsize = 0x%lx\n", (long)ex->a_trsize);
    printf("  a_drsize = 0x%lx\n", (long)ex->a_drsize);

    text_base = file_base + N_TXTOFF(*ex);
    data_base = file_base + N_DATOFF(*ex);
    rel_base = (const struct relocation_info *)
	align_struct(file_base + N_RELOFF(*ex));
    sym_base = (const struct nlist *) align_struct(file_base + N_SYMOFF(*ex));
    str_base = file_base + N_STROFF(*ex);

    rel_count = (ex->a_trsize + ex->a_drsize) / sizeof rel_base[0];
    assert(rel_count * sizeof rel_base[0] == ex->a_trsize + ex->a_drsize);
    sym_count = ex->a_syms / sizeof sym_base[0];
    assert(sym_count * sizeof sym_base[0] == ex->a_syms);

    if (sym_count != 0) {
	sym_used = (unsigned char *) calloc(sym_count, sizeof(unsigned char));
	assert(sym_used != NULL);
    }

    printf("  Entry = 0x%lx\n", (long)ex->a_entry);
    printf("  Text offset = %x, address = %lx\n", N_TXTOFF(*ex),
	(long)N_TXTADDR(*ex));
    printf("  Data offset = %lx, address = %lx\n", (long)N_DATOFF(*ex),
	(long)N_DATADDR(*ex));

    /*
     * In an executable program file, everything is relocated relative to
     * the assumed run-time load address, i.e., N_TXTADDR(*ex), i.e., 0x1000.
     *
     * In a shared library file, everything is relocated relative to the
     * start of the file, i.e., N_TXTOFF(*ex), i.e., 0.
     *
     * The way to tell the difference is by looking at ex->a_entry.   If it
     * is >= 0x1000, then we have an executable program.  Otherwise, we
     * have a shared library.
     *
     * When a program is executed, the entire file is mapped into memory,
     * including the a.out header and so forth.  But it is not mapped at
     * address 0; rather it is mapped at address 0x1000.  The first page
     * of the user's address space is left unmapped in order to catch null
     * pointer dereferences.
     *
     * In this program, when we map in an executable program, we have to
     * simulate the empty page by decrementing our assumed base address by
     * a pagesize.
     */

    text_addr = text_base;
    data_addr = data_base;
    origin = 0;

    if (ex->a_entry >= PAGE_SIZE) {	/* Executable, not a shared library */
	/*
	 * The fields in the object have already been relocated on the
	 * assumption that the object will be loaded at N_TXTADDR(*ex).
	 * We have to compensate for that.
	 */
	text_addr -= PAGE_SIZE;
	data_addr -= PAGE_SIZE;
	origin = PAGE_SIZE;
	printf("  Program, origin = %lx\n", origin);
    } else if (N_GETFLAG(*ex) & EX_DYNAMIC)
	printf("  Shared library, origin = %lx\n", origin);
    else
	printf("  Object file, origin = %lx\n", origin);

    if (N_GETFLAG(*ex) & EX_DYNAMIC) {
	dyn = (const struct _dynamic *) align_struct(data_base);
	printf("  Dynamic version = %d\n", dyn->d_version);

	sdt = (const struct section_dispatch_table *)
	    align_struct(text_addr + (unsigned long) dyn->d_un.d_sdt);

	rtrel_base = (const struct relocation_info *)
	    align_struct(text_addr + sdt->sdt_rel);
	rtrel_count = (sdt->sdt_hash - sdt->sdt_rel) / sizeof rtrel_base[0];
	assert(rtrel_count * sizeof rtrel_base[0] ==
	    (size_t)(sdt->sdt_hash - sdt->sdt_rel));

	rtsym_base = (const struct nzlist *)
	    align_struct(text_addr + sdt->sdt_nzlist);
	rtsym_count = (sdt->sdt_strings - sdt->sdt_nzlist) /
	    sizeof rtsym_base[0];
	assert(rtsym_count * sizeof rtsym_base[0] ==
	    (size_t)(sdt->sdt_strings - sdt->sdt_nzlist));

	if (rtsym_count != 0) {
	    rtsym_used = (unsigned char *) calloc(rtsym_count,
		sizeof(unsigned char));
	    assert(rtsym_used != NULL);
	}

	rtstr_base = text_addr + sdt->sdt_strings;
    }

    dump_segs();
    dump_sods();
    dump_rels("Relocations", rel_base, rel_count, sym_name, sym_used);
    dump_syms();

    dump_rels("Run-time relocations", rtrel_base, rtrel_count, rtsym_name,
	rtsym_used);
    dump_rtsyms();

    if (rtsym_used != NULL) {
	free(rtsym_used);
	rtsym_used = NULL;
    }
    if (sym_used != NULL) {
	free(sym_used);
	sym_used = NULL;
    }
    munmap(objbase, sb.st_size);
}
Exemplo n.º 17
0
int
GetAOutFileInfo(struct dllist *dl)
{
#ifdef NOAOUT
	return(-1);
#else
	struct exec ex, ex_swap;
	u_int32_t	mid = -1;
	u_int32_t	magic, clbytes, clofset;

	if (read(dl->ldfd, (char *)&ex, sizeof(ex)) != sizeof(ex))
		return(-1);

	(void)lseek(dl->ldfd, (off_t) 0, SEEK_SET);

	if (read(dl->ldfd, (char *)&ex_swap,
		 sizeof(ex_swap)) != sizeof(ex_swap))
		return(-1);

	mopFileSwapX((u_char *)&ex_swap, 0, 4);

	mid = getMID(mid, N_GETMID (ex));

	if (mid == (uint32_t)-1) {
		mid = getMID(mid, N_GETMID (ex_swap));
		if (mid != (uint32_t)-1) {
			mopFileSwapX((u_char *)&ex, 0, 4);
		}
	}

	if (mid == (uint32_t)-1) {
		return(-1);
	}

	if (N_BADMAG (ex)) {
		return(-1);
	}

	switch (mid) {
	case MID_I386:
#ifdef MID_NS32532
	case MID_NS32532:
#endif
#ifdef MID_PMAX
	case MID_PMAX:
#endif
#ifdef MID_VAX
	case MID_VAX:
#endif
#ifdef MID_ALPHA
	case MID_ALPHA:
#endif
#ifdef MID_ARM6
	case MID_ARM6:
#endif
		ex.a_text  = mopFileGetLX((u_char *)&ex_swap,  4, 4);
		ex.a_data  = mopFileGetLX((u_char *)&ex_swap,  8, 4);
		ex.a_bss   = mopFileGetLX((u_char *)&ex_swap, 12, 4);
		ex.a_syms  = mopFileGetLX((u_char *)&ex_swap, 16, 4);
		ex.a_entry = mopFileGetLX((u_char *)&ex_swap, 20, 4);
		ex.a_trsize= mopFileGetLX((u_char *)&ex_swap, 24, 4);
		ex.a_drsize= mopFileGetLX((u_char *)&ex_swap, 28, 4);
		break;
#ifdef MID_M68K
	case MID_M68K:
#endif
#ifdef MID_M68K4K
	case MID_M68K4K:
#endif
	case MID_SPARC:
#ifdef MID_MIPS
	case MID_MIPS:
#endif
		ex.a_text  = mopFileGetBX((u_char *)&ex_swap,  4, 4);
		ex.a_data  = mopFileGetBX((u_char *)&ex_swap,  8, 4);
		ex.a_bss   = mopFileGetBX((u_char *)&ex_swap, 12, 4);
		ex.a_syms  = mopFileGetBX((u_char *)&ex_swap, 16, 4);
		ex.a_entry = mopFileGetBX((u_char *)&ex_swap, 20, 4);
		ex.a_trsize= mopFileGetBX((u_char *)&ex_swap, 24, 4);
		ex.a_drsize= mopFileGetBX((u_char *)&ex_swap, 28, 4);
		break;
	default:
		break;
	}

	printf("a.out image (");
	switch (N_GETMID (ex)) {
	case MID_I386:
		printf("i386");
		break;
#ifdef MID_M68K
	case MID_M68K:
		printf("m68k");
		break;
#endif
#ifdef MID_M68K4K
	case MID_M68K4K:
		printf("m68k 4k");
		break;
#endif
#ifdef MID_NS32532
	case MID_NS32532:
		printf("pc532");
		break;
#endif
	case MID_SPARC:
		printf("sparc");
		break;
#ifdef MID_PMAX
	case MID_PMAX:
		printf("pmax");
		break;
#endif
#ifdef MID_VAX
	case MID_VAX:
		printf("vax");
		break;
#endif
#ifdef MID_ALPHA
	case MID_ALPHA:
		printf("alpha");
		break;
#endif
#ifdef MID_MIPS
	case MID_MIPS:
		printf("mips");
		break;
#endif
#ifdef MID_ARM6
	case MID_ARM6:
		printf("arm32");
		break;
#endif
	default:
		break;
	}
	printf(") Magic: ");
	switch (N_GETMAGIC (ex)) {
	case OMAGIC:
		printf("OMAGIC");
		break;
	case NMAGIC:
		printf("NMAGIC");
		break;
	case ZMAGIC:
		printf("ZMAGIC");
		break;
	case QMAGIC:
		printf("QMAGIC");
		break;
	default:
		printf("Unknown %ld", (long) N_GETMAGIC (ex));
	}
	printf("\n");
	printf("Size of text:       %08lx\n", (long)ex.a_text);
	printf("Size of data:       %08lx\n", (long)ex.a_data);
	printf("Size of bss:        %08lx\n", (long)ex.a_bss);
	printf("Size of symbol tab: %08lx\n", (long)ex.a_syms);
	printf("Transfer Address:   %08lx\n", (long)ex.a_entry);
	printf("Size of reloc text: %08lx\n", (long)ex.a_trsize);
	printf("Size of reloc data: %08lx\n", (long)ex.a_drsize);

	magic = N_GETMAGIC (ex);
	clbytes = getCLBYTES(mid);
	clofset = clbytes - 1;

	dl->image_type = IMAGE_TYPE_AOUT;
	dl->loadaddr = 0;
	dl->xferaddr = ex.a_entry;

	dl->a_text = ex.a_text;
	if (magic == ZMAGIC || magic == NMAGIC) {
		dl->a_text_fill = clbytes - (ex.a_text & clofset);
		if (dl->a_text_fill == clbytes)
			dl->a_text_fill = 0;
	} else
		dl->a_text_fill = 0;
	dl->a_data = ex.a_data;
	if (magic == ZMAGIC || magic == NMAGIC) {
		dl->a_data_fill = clbytes - (ex.a_data & clofset);
		if (dl->a_data_fill == clbytes)
			dl->a_data_fill = 0;
	} else
		dl->a_data_fill = 0;
	dl->a_bss = ex.a_bss;
	if (magic == ZMAGIC || magic == NMAGIC) {
		dl->a_bss_fill = clbytes - (ex.a_bss & clofset);
		if (dl->a_bss_fill == clbytes)
			dl->a_bss_fill = 0;
	} else {
		dl->a_bss_fill = clbytes -
		    ((ex.a_text+ex.a_data+ex.a_bss) & clofset);
		if (dl->a_bss_fill == clbytes)
			dl->a_bss_fill = 0;
	}
	dl->a_mid = mid;

	return(0);
#endif /* NOAOUT */
}
Exemplo n.º 18
0
/*ARGSUSED*/
void
exec_aout(char *file, const char *args, int bootdev, int bootunit, int bootpart)
{
	char *loadaddr;
	int io;
	struct exec x;
	int cc, magic;
	void (*entry)();
	char *cp;
	int *ip;

	io = open(file, 0);
	if (io < 0)
		return;

	/*
	 * Read in the exec header, and validate it.
	 */
	if (read(io, (char *)&x, sizeof(x)) != sizeof(x))
		goto shread;

	if (N_BADMAG(x)) {
		errno = EFTYPE;
		goto closeout;
	}

	/*
	 * note: on the mvme ports, the kernel is linked in such a way that 
	 * its entry point is the first item in .text, and thus a_entry can 
	 * be used to determine both the load address and the entry point.
	 * (also note that we make use of the fact that the kernel will live
	 *  in a VA == PA range of memory ... otherwise we would take 
	 *  loadaddr as a parameter and let the kernel relocate itself!)
	 *
	 * note that ZMAGIC files included the a.out header in the text area
	 * so we must mask that off (has no effect on the other formats)
	 */
	loadaddr = (void *)(x.a_entry & ~sizeof(x));

	cp = loadaddr;
	magic = N_GETMAGIC(x);
	if (magic == ZMAGIC)
		cp += sizeof(x);
	entry = (void (*)())cp;

	/*
	 * Read in the text segment.
	 */
	printf("%d", x.a_text);
	cc = x.a_text;
	if (magic == ZMAGIC)
		cc = cc - sizeof(x); /* a.out header part of text in zmagic */
	if (read(io, cp, cc) != cc)
		goto shread;
	cp += cc;

	/*
	 * NMAGIC may have a gap between text and data.
	 */
	if (magic == NMAGIC) {
		register int mask = N_PAGSIZ(x) - 1;
		while ((int)cp & mask)
			*cp++ = 0;
	}

	/*
	 * Read in the data segment.
	 */
	printf("+%d", x.a_data);
	if (read(io, cp, x.a_data) != x.a_data)
		goto shread;
	cp += x.a_data;

	/*
	 * Zero out the BSS section.
	 */
	printf("+%d", x.a_bss);
	cc = x.a_bss;
	while ((int)cp & 3) {
		*cp++ = 0;
		--cc;
	}
	ip = (int *)cp;
	cp += cc;
	while ((char *)ip < cp)
		*ip++ = 0;

	/*
	 * Read in the symbol table and strings.
	 * (Always set the symtab size word.)
	 */
	*ip++ = x.a_syms;
	cp = (char *) ip;

	if (x.a_syms > 0) {
		/* Symbol table and string table length word. */
		cc = x.a_syms;
		printf("+[%d", cc);
		cc += sizeof(int);	/* strtab length too */
		if (read(io, cp, cc) != cc)
			goto shread;
		cp += x.a_syms;
		ip = (int *)cp;		/* points to strtab length */
		cp += sizeof(int);

		/* String table.  Length word includes itself. */
		cc = *ip;
		printf("+%d]", cc);
		cc -= sizeof(int);
		if (cc <= 0)
			goto shread;
		if (read(io, cp, cc) != cc)
			goto shread;
		cp += cc;
	}
	printf("=0x%lx\n", cp - loadaddr);
	close(io);

	(*entry)(args, bootdev, bootunit, bootpart, SYM_MAGIC, cp);

	printf("exec: kernel returned!\n");
	return;

shread:
	printf("exec: short read\n");
	errno = EIO;
closeout:
	close(io);
	return;
}
Exemplo n.º 19
0
static int
aout_exec(int fd, struct exec *x, u_long *marks, int flags)
{
	u_long entry = x->a_entry;
	paddr_t aoutp = 0;
	paddr_t minp, maxp;
	int cc;
	paddr_t offset = marks[MARK_START];
	u_long magic = N_GETMAGIC(*x);
	int sub;

	/* In OMAGIC and NMAGIC, exec header isn't part of text segment */
	if (magic == OMAGIC || magic == NMAGIC)
		sub = 0;
	else
		sub = sizeof(*x);

	minp = maxp = ALIGNENTRY(entry);

	if (lseek(fd, sizeof(*x), SEEK_SET) == -1)  {
		WARN(("lseek text"));
		return 1;
	}

	/*
	 * Leave a copy of the exec header before the text.
	 * The kernel may use this to verify that the
	 * symbols were loaded by this boot program.
	 */
	if (magic == OMAGIC || magic == NMAGIC) {
		if (flags & LOAD_HDR && maxp >= sizeof(*x))
			BCOPY(x, maxp - sizeof(*x), sizeof(*x));
	}
	else {
		if (flags & LOAD_HDR)
			BCOPY(x, maxp, sizeof(*x));
		if (flags & (LOAD_HDR|COUNT_HDR))
			maxp += sizeof(*x);
	}

	/*
	 * Read in the text segment.
	 */
	if (flags & LOAD_TEXT) {
		PROGRESS(("%ld", x->a_text));

		if (READ(fd, maxp, x->a_text - sub) != x->a_text - sub) {
			WARN(("read text"));
			return 1;
		}
	} else {
		if (lseek(fd, x->a_text - sub, SEEK_CUR) == -1) {
			WARN(("seek text"));
			return 1;
		}
	}
	if (flags & (LOAD_TEXT|COUNT_TEXT))
		maxp += x->a_text - sub;

	/*
	 * Provide alignment if required
	 */
	if (magic == ZMAGIC || magic == NMAGIC) {
		int size = -(unsigned int)maxp & (__LDPGSZ - 1);

		if (flags & LOAD_TEXTA) {
			PROGRESS(("/%d", size));
			BZERO(maxp, size);
		}

		if (flags & (LOAD_TEXTA|COUNT_TEXTA))
			maxp += size;
	}

	/*
	 * Read in the data segment.
	 */
	if (flags & LOAD_DATA) {
		PROGRESS(("+%ld", x->a_data));

		if (READ(fd, maxp, x->a_data) != x->a_data) {
			WARN(("read data"));
			return 1;
		}
	}
	else {
		if (lseek(fd, x->a_data, SEEK_CUR) == -1) {
			WARN(("seek data"));
			return 1;
		}
	}
	if (flags & (LOAD_DATA|COUNT_DATA))
		maxp += x->a_data;

	/*
	 * Zero out the BSS section.
	 * (Kernel doesn't care, but do it anyway.)
	 */
	if (flags & LOAD_BSS) {
		PROGRESS(("+%ld", x->a_bss));

		BZERO(maxp, x->a_bss);
	}

	if (flags & (LOAD_BSS|COUNT_BSS))
		maxp += x->a_bss;

	/*
	 * Read in the symbol table and strings.
	 * (Always set the symtab size word.)
	 */
	if (flags & LOAD_SYM)
		BCOPY(&x->a_syms, maxp, sizeof(x->a_syms));

	if (flags & (LOAD_SYM|COUNT_SYM)) {
		maxp += sizeof(x->a_syms);
		aoutp = maxp;
	}

	if (x->a_syms > 0) {
		/* Symbol table and string table length word. */

		if (flags & LOAD_SYM) {
			PROGRESS(("+[%ld", x->a_syms));

			if (READ(fd, maxp, x->a_syms) != x->a_syms) {
				WARN(("read symbols"));
				return 1;
			}
		} else  {
			if (lseek(fd, x->a_syms, SEEK_CUR) == -1) {
				WARN(("seek symbols"));
				return 1;
			}
		}
		if (flags & (LOAD_SYM|COUNT_SYM))
			maxp += x->a_syms;

		if (read(fd, &cc, sizeof(cc)) != sizeof(cc)) {
			WARN(("read string table"));
			return 1;
		}

		if (flags & LOAD_SYM) {
			BCOPY(&cc, maxp, sizeof(cc));

			/* String table. Length word includes itself. */

			PROGRESS(("+%d]", cc));
		}
		if (flags & (LOAD_SYM|COUNT_SYM))
			maxp += sizeof(cc);

		cc -= sizeof(int);
		if (cc <= 0) {
			WARN(("symbol table too short"));
			return 1;
		}

		if (flags & LOAD_SYM) {
			if (READ(fd, maxp, cc) != cc) {
				WARN(("read strings"));
				return 1;
			}
		} else {
			if (lseek(fd, cc, SEEK_CUR) == -1) {
				WARN(("seek strings"));
				return 1;
			}
		}
		if (flags & (LOAD_SYM|COUNT_SYM))
			maxp += cc;
	}

	marks[MARK_START] = LOADADDR(minp);
	marks[MARK_ENTRY] = LOADADDR(entry);
	marks[MARK_NSYM] = x->a_syms;
	marks[MARK_SYM] = LOADADDR(aoutp);
	marks[MARK_END] = LOADADDR(maxp);
	return 0;
}
Exemplo n.º 20
0
/*
 * Load an a.out image.
 * Exit codes:
 *	-1      : Not an a.outfile
 *	 0      : OK
 *	 error# : Error during load (*errp might contain error string).
 */
int
aout_load(int fd, osdsc_t *od, char **errp, int loadsyms)
{
	long		textsz, stringsz;
	struct exec	ehdr;
	int		err;

	*errp = NULL;

	lseek(fd, (off_t)0, SEEK_SET);
	if (read(fd, (char *)&ehdr, sizeof(ehdr)) != sizeof(ehdr))
		return -1;

#ifdef TOSTOOLS
	if ((ehdr.a_magic & 0xffff) != NMAGIC)
		return -1;
#else
	if ((N_GETMAGIC(ehdr) != NMAGIC) && (N_GETMAGIC(ehdr) != OMAGIC))
		return -1;
#endif

	/*
	 * Extract various sizes from the kernel executable
	 */
	textsz     = (ehdr.a_text + AOUT_LDPGSZ - 1) & ~(AOUT_LDPGSZ - 1);
	od->k_esym = 0;
	od->ksize  = textsz + ehdr.a_data + ehdr.a_bss;
	od->kentry = ehdr.a_entry;

	if (loadsyms && ehdr.a_syms) {
		err = 1;
		if (lseek(fd, ehdr.a_text+ehdr.a_data+ehdr.a_syms+sizeof(ehdr),
			  0) <= 0)
			goto error;
		err = 2;
		if (read(fd, (char *)&stringsz, sizeof(long)) != sizeof(long))
			goto error;
		err = 3;
		if (lseek(fd, sizeof(ehdr), 0) <= 0)
			goto error;
		od->ksize += ehdr.a_syms + sizeof(long) + stringsz;
	}

	err = 4;
	if ((od->kstart = (u_char *)MALLOC(od->ksize)) == NULL)
		goto error;

	/*
	 * Read text & data, clear bss
	 */
	err = 5;
	if ((read(fd, (char *)(od->kstart), ehdr.a_text) != ehdr.a_text)
	    ||(read(fd,(char *)(od->kstart+textsz),ehdr.a_data) != ehdr.a_data))
		goto error;
	bzero(od->kstart + textsz + ehdr.a_data, ehdr.a_bss);

	/*
	 * Read symbol and string table
	 */
	if (loadsyms && ehdr.a_syms) {
		long	*p;

		p = (long *)((od->kstart) + textsz + ehdr.a_data + ehdr.a_bss);
		*p++ = ehdr.a_syms;
		err = 6;
		if (read(fd, (char *)p, ehdr.a_syms) != ehdr.a_syms)
			goto error;
		p = (long *)((char *)p + ehdr.a_syms);
		err = 7;
		if (read(fd, (char *)p, stringsz) != stringsz)
			goto error;
		od->k_esym = (long)((char *)p-(char *)od->kstart +stringsz);
	}
	return 0;

error:
#ifdef TOSTOOLS
	{
		static char *errs[] = {
			/* 1 */ "Cannot seek to string table",
			/* 2 */ "Cannot read string-table size",
			/* 3 */ "Cannot seek back to text start",
			/* 4 */ "Cannot malloc kernel image space",
			/* 5 */ "Unable to read kernel image",
			/* 6 */ "Cannot read symbol table",
			/* 7 */ "Cannot read string table"
		};
		*errp = errs[err];
	}
#endif /* TOSTOOLS */

	return err;
}
Exemplo n.º 21
0
int
putfile(char *from_file, int to)
{
	struct exec ex;
	char buf[2048];
	int n, total;
	int from, check_sum = 0;
	struct hppa_lifload load;
	Elf32_External_Ehdr elf_header;
	Elf32_External_Phdr *elf_segments;
	int i, header_count, memory_needed, elf_load_image_segment;

	if ((from = open(from_file, O_RDONLY)) < 0)
		err(1, "%s", from_file);

	n = read(from, &ex, sizeof(ex));
	if (n != sizeof(ex))
		err(1, "%s: reading file header", from_file);

	entry = ex.a_entry;
	if (N_GETMAGIC(ex) == OMAGIC || N_GETMAGIC(ex) == NMAGIC)
		entry += sizeof(ex);
	else if (IS_ELF(*(Elf32_External_Ehdr *)&ex)) {

		if (lseek(from, 0, SEEK_SET) < 0)
			err(1, "lseek");
		n = read(from, &elf_header, sizeof (elf_header));
		if (n != sizeof (elf_header))
			err(1, "%s: reading ELF header", from_file);
		header_count = ELFGET16(elf_header.e_phnum);
		memory_needed = header_count * sizeof (Elf32_External_Phdr);
		elf_segments = malloc(memory_needed);
		if (elf_segments == NULL)
			err(1, "malloc");
		if (lseek(from, ELFGET32(elf_header.e_phoff), SEEK_SET) < 0)
			err(1, "lseek");
		n = read(from, elf_segments, memory_needed);
		if (n != memory_needed)
			err(1, "%s: reading ELF segments", from_file);
		elf_load_image_segment = -1;
		for (i = 0; i < header_count; i++) {
			if (ELFGET32(elf_segments[i].p_filesz) &&
			    ELFGET32(elf_segments[i].p_flags) & PF_X) {
				if (elf_load_image_segment != -1)
					errx(1, "%s: more than one ELF program "
					     "segment", from_file);
				elf_load_image_segment = i;
			}
		}
		if (elf_load_image_segment == -1)
			errx(1, "%s: no suitable ELF program segment",
			     from_file);
		entry = ELFGET32(elf_header.e_entry) +
			ELFGET32(elf_segments[elf_load_image_segment].p_offset) -
			ELFGET32(elf_segments[elf_load_image_segment].p_vaddr);
	} else if (*(uint8_t *)&ex == 0x1f && ((uint8_t *)&ex)[1] == 0x8b) {
		entry = 0;
	} else
		errx(1, "%s: bad magic number", from_file);

	entry += sizeof(load);
	lseek(to, sizeof(load), SEEK_CUR);

	total = 0;
	n = sizeof(buf) - sizeof(load);
	/* copy the whole file */
	for (lseek(from, 0, SEEK_SET); ; n = sizeof(buf)) {
		memset(buf, 0, sizeof(buf));
		if ((n = read(from, buf, n)) < 0)
			err(1, "%s", from_file);
		else if (n == 0)
			break;

		if (write(to, buf, n) != n)
			err(1, "%s", to_file);

		total += n;
		check_sum = cksum(check_sum, (int *)buf, n);
	}

	/* load header */
	load.address = htobe32(loadpoint + sizeof(load));
	load.count = htobe32(4 + total);
	check_sum = cksum(check_sum, (int *)&load, sizeof(load));

	if (verbose)
		warnx("wrote %d bytes of file \'%s\'", total, from_file);

	total += sizeof(load);
	/* insert the header */
	lseek(to, -total, SEEK_CUR);
	if (write(to, &load, sizeof(load)) != sizeof(load))
		err(1, "%s", to_file);
	lseek(to, total - sizeof(load), SEEK_CUR);

	memset(buf, 0, sizeof(buf));
	/* pad to int */
	n = sizeof(int) - total % sizeof(int);
	if (total % sizeof(int)) {
		if (write(to, buf, n) != n)
			err(1, "%s", to_file);
		else
			total += n;
	}

	/* pad to the blocksize */
	n = sizeof(buf) - total % sizeof(buf);

	if (n < sizeof(int)) {
		n += sizeof(buf);
		total += sizeof(buf);
	} else
		total += n;

	/* TODO should pad here to the 65k boundary for tape boot */

	if (verbose)
		warnx("checksum is 0x%08x", -check_sum);

	check_sum = htobe32(-check_sum);
	if (write(to, &check_sum, sizeof(int)) != sizeof(int))
		err(1, "%s", to_file);

	n -= sizeof(int);

	if (write(to, buf, n) != n)
		err(1, "%s", to_file);

	if (close(from) < 0)
		err(1, "%s", from_file);

	return total;
}
Exemplo n.º 22
0
int
main(int argc, char *argv[])
{
	struct exec head;
	struct ecoff_exechdr ehead;
	struct ecoff_scnhdr escn[3];
	int infd, outfd;
	int n;

	if (argc != 3)
		usage();

	infd = open(argv[1], O_RDONLY);
	if (infd < 0)
		err(1, argv[1]);

	outfd = open(argv[2], O_WRONLY | O_TRUNC | O_CREAT, 0644);
	if (outfd < 0)
		err(1, argv[2]);

	n = read(infd, &head, sizeof(head));
	if (n < sizeof(head))
		err(1, "read");

	if (N_BADMAG(head)) {
		printf("%s: bad magic number\n", argv[1]);
		exit(1);
	}

	if (head.a_trsize || head.a_drsize) {
		printf("%s: has relocations\n", argv[1]);
		exit(1);
	}

	/*
	 * Header
	 */

	ehead.f.f_magic = 0x016d;		/* MC88OMAGIC */
	ehead.f.f_nscns = 3;
	ehead.f.f_timdat = 0;			/* ignored */
	ehead.f.f_symptr = 0;			/* ignored */
	ehead.f.f_nsyms = 0;			/* ignored */
	ehead.f.f_opthdr = sizeof ehead.a;
	ehead.f.f_flags = 0x020f;
		/* F_RELFLG | F_EXEC | F_LNNO | 8 | F_AR16WR */

	ehead.a.magic = N_GETMAGIC(head);
	ehead.a.vstamp = 0;			/* ignored */
	ehead.a.tsize = head.a_text;		/* ignored */
	ehead.a.dsize = head.a_data;		/* ignored */
	ehead.a.bsize = head.a_bss;		/* ignored */
	ehead.a.entry = head.a_entry;
	ehead.a.text_start = N_TXTADDR(head);	/* ignored */
	ehead.a.data_start = N_DATADDR(head);	/* ignored */

	n = write(outfd, &ehead, sizeof(ehead));
	if (n != sizeof(ehead))
		err(1, "write");

	/*
	 * Sections.
	 * Note that we merge .bss into .data since the PROM will not
	 * clear it and locore does not do this either.
	 */

	strncpy(escn[0].s_name, ".text", sizeof escn[0].s_name);
	escn[0].s_paddr = N_TXTADDR(head);	/* ignored, 1:1 mapping */
	escn[0].s_size = round(head.a_text, 8);
	escn[0].s_scnptr = round(sizeof(ehead) + sizeof(escn), 0x10);
	escn[0].s_relptr = 0;
	escn[0].s_lnnoptr = 0;
	escn[0].s_nlnno = 0;
	escn[0].s_flags = 0x20;	/* STYP_TEXT */

	strncpy(escn[1].s_name, ".data", sizeof escn[1].s_name);
	escn[1].s_paddr = N_DATADDR(head);		/* ignored, 1:1 mapping */
	escn[1].s_scnptr = escn[0].s_scnptr + escn[0].s_size;
	escn[1].s_size = round(head.a_data + head.a_bss, 8);
	escn[1].s_relptr = 0;
	escn[1].s_lnnoptr = 0;
	escn[1].s_nlnno = 0;
	escn[1].s_flags = 0x40;	/* STYP_DATA */

	strncpy(escn[2].s_name, ".bss", sizeof escn[2].s_name);
	escn[2].s_paddr = N_BSSADDR(head) + head.a_bss;	/* ignored, 1:1 mapping */
	escn[2].s_scnptr = 0;		/* nothing in the file */
	escn[2].s_size = 0;
	escn[2].s_relptr = 0;
	escn[2].s_lnnoptr = 0;
	escn[2].s_nlnno = 0;
	escn[2].s_flags = 0x80;	/* STYP_BSS */

	/* adjust load addresses */
	escn[0].s_paddr += (head.a_entry & ~(__LDPGSZ - 1)) - __LDPGSZ;
	escn[1].s_paddr += (head.a_entry & ~(__LDPGSZ - 1)) - __LDPGSZ;
	escn[2].s_paddr += (head.a_entry & ~(__LDPGSZ - 1)) - __LDPGSZ;
	escn[0].s_vaddr = escn[0].s_paddr;
	escn[1].s_vaddr = escn[1].s_paddr;
	escn[2].s_vaddr = escn[2].s_paddr;

	n = write(outfd, &escn, sizeof(escn));
	if (n != sizeof(escn))
		err(1, "write");

	/*
	 * Copy text section
	 */

#ifdef DEBUG
	printf("copying %s: source %lx dest %lx size %x\n",
	    escn[0].s_name, N_TXTOFF(head), escn[0].s_scnptr, head.a_text);
#endif
	lseek(outfd, escn[0].s_scnptr, SEEK_SET);
	lseek(infd, N_TXTOFF(head), SEEK_SET);
	copybits(infd, outfd, head.a_text);

	/*
	 * Copy data section
	 */

#ifdef DEBUG
	printf("copying %s: source %lx dest %lx size %x\n",
	    escn[1].s_name, N_DATOFF(head), escn[1].s_scnptr, head.a_data);
#endif
	lseek(outfd, escn[1].s_scnptr, SEEK_SET);
	lseek(infd, N_DATOFF(head), SEEK_SET);
	copybits(infd, outfd, head.a_data);

	/*
	 * ``Copy'' bss section
	 */

#ifdef DEBUG
	printf("copying %s: size %lx\n",
	    escn[2].s_name, round(head.a_data + head.a_bss, 8) - head.a_data);
#endif
	zerobits(outfd, round(head.a_data + head.a_bss, 8) - head.a_data);

	close(infd);
	close(outfd);
	exit(0);
}