Exemple #1
0
Bool
aout_is_exec(Environ *e, uByte *load, uInt loadlen)
{
	struct exec *ex = (struct exec*)load;
	int m;

	DPRINTF(("aout_is_exec: midmag=%#x badmagic=%d mid=%#x\n",
			ex->a_midmag, N_BADMAG(*ex), N_GETMID(*ex)));

	if (N_BADMAG(*ex))
		return FALSE;

	m = N_GETMID(*ex);

	if (m == AOUT_MAGIC_0)
		return TRUE;

	#ifdef AOUT_MAGIC_1
		if (m == AOUT_MAGIC_1)
			return TRUE;
	#endif

	#ifdef AOUT_MAGIC_2
		if (m == AOUT_MAGIC_2)
			return TRUE;
	#endif

	#ifdef AOUT_MAGIC_3
		if (m == AOUT_MAGIC_3)
			return TRUE;
	#endif

	return FALSE;
}
Exemple #2
0
int
CheckAOutFile(int fd)
{
#ifdef NOAOUT
	return(-1);
#else
	struct exec ex, ex_swap;
	int	mid = -1;

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

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

	(void)lseek(fd, (off_t) 0, SEEK_SET);
	
	mid = getMID(mid, N_GETMID (ex));

	if (mid == -1) {
		mid = getMID(mid, N_GETMID (ex_swap));
	}

	if (mid != -1) {
		return(0);
	} else {
		return(-1);
	}
#endif /* NOAOUT */
}
Exemple #3
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;
}
Exemple #4
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;
}
Exemple #5
0
/*
 * read_exec
 *	Read the exec structure; ignore any files that don't look
 *	exactly right. Return MID.
 *	return -1 for files that don't look right.
 *	XXX it's hard to be sure when to ignore files, and when to error
 *	out.
 */
int
read_exec(FILE *rfp, FILE *wfp, long *symcnt, long *tsymlen)
{
	union {
		struct exec exec;
		Elf32_Ehdr elf32;
		Elf64_Ehdr elf64;
	} eh;
	struct nlist nl;
	off_t r_off, w_off;
	char *strtab = NULL;
	long strsize, nsyms;
	int i;

	/* Get current offsets for original and tmp files. */
	r_off = ftello(rfp);
	w_off = ftello(wfp);

	/* Read in exec structure. */
	if (fread(&eh, sizeof(eh), 1, rfp) != 1)
		err(1, "fread: %s", archive);

	if (!elf32_chk_header(&eh.elf32)) {
		Elf32_Sym sbuf;
		char *shstr;
		Elf32_Shdr *shdr;
		size_t stabsize;

		elf32_fix_header(&eh.elf32);
		if (eh.elf32.e_ehsize < sizeof eh.elf32) {
			warnx("%s: ELF header is too short", archive);
			goto bad;
		}

		if (!(shdr = elf32_load_shdrs(archive, rfp, r_off, &eh.elf32)))
			goto bad;
		elf32_fix_shdrs(&eh.elf32, shdr);

		if (!(shstr = elf32_shstrload(archive, rfp, r_off, &eh.elf32,
		    shdr))) {
			free(shdr);
			goto bad;
		}

		if (!(strtab = elf32_strload(archive, rfp, r_off, &eh.elf32,
		    shdr, shstr, ELF_STRTAB, &stabsize))) {
			free(shstr);
			free(shdr);
			goto bad;
		}

		/* find the symtab section */
		for (i = 0; i < eh.elf32.e_shnum; i++)
			if (!strcmp(shstr + shdr[i].sh_name, ELF_SYMTAB)) {
				nsyms = shdr[i].sh_size / sizeof(Elf32_Sym);
				break;
			}

		if (i == eh.elf32.e_shnum) {
			free(shstr);
			free(shdr);
			goto bad;
		}

		if (fseeko(rfp, r_off + shdr[i].sh_offset, SEEK_SET))
			err(1, "fseeko: %s", archive);

		for (i = 0; i < nsyms; i++) {
			if (fread(&sbuf, sizeof(sbuf), 1, rfp) != 1)
				err(1, "fread: %s", archive);

			elf32_fix_sym(&eh.elf32, &sbuf);
			if (!sbuf.st_name || sbuf.st_name > stabsize)
				continue;

			if (elf32_2nlist(&sbuf, &eh.elf32, shdr, shstr, &nl))
				continue;

			addsym(&nl, strtab, r_off - r_fuzz -
			    sizeof(struct ar_hdr), symcnt, tsymlen, archive);
		}

		free(strtab);
		free(shstr);
		free(shdr);
		(void)fseeko(rfp, r_off, SEEK_SET);
		return MID_ELFFL | eh.elf32.e_machine;

	} else if (!elf64_chk_header(&eh.elf64)) {
		Elf64_Sym sbuf;
		char *shstr;
		Elf64_Shdr *shdr;
		size_t stabsize;

		elf64_fix_header(&eh.elf64);
		if (eh.elf64.e_ehsize < sizeof eh.elf64) {
			warnx("%s: ELF header is too short", archive);
			goto bad;
		}

		if (!(shdr = elf64_load_shdrs(archive, rfp, r_off, &eh.elf64)))
			goto bad;
		elf64_fix_shdrs(&eh.elf64, shdr);

		if (!(shstr = elf64_shstrload(archive, rfp, r_off, &eh.elf64,
		    shdr))) {
			free(shdr);
			goto bad;
		}

		if (!(strtab = elf64_strload(archive, rfp, r_off, &eh.elf64,
		    shdr, shstr, ELF_STRTAB, &stabsize))) {
			free(shstr);
			free(shdr);
			goto bad;
		}

		/* find the symtab section */
		for (i = 0; i < eh.elf64.e_shnum; i++)
			if (!strcmp(shstr + shdr[i].sh_name, ELF_SYMTAB)) {
				nsyms = shdr[i].sh_size / sizeof(Elf64_Sym);
				break;
			}

		if (i == eh.elf64.e_shnum) {
			free(shstr);
			free(shdr);
			goto bad;
		}

		if (fseeko(rfp, r_off + shdr[i].sh_offset, SEEK_SET))
			err(1, "fseeko: %s", archive);

		for (i = 0; i < nsyms; i++) {
			if (fread(&sbuf, sizeof(sbuf), 1, rfp) != 1)
				err(1, "fread: %s", archive);

			elf64_fix_sym(&eh.elf64, &sbuf);
			if (!sbuf.st_name || sbuf.st_name > stabsize)
				continue;

			if (elf64_2nlist(&sbuf, &eh.elf64, shdr, shstr, &nl))
				continue;

			addsym(&nl, strtab, r_off - r_fuzz -
			    sizeof(struct ar_hdr), symcnt, tsymlen, archive);
		}

		free(strtab);
		free(shstr);
		free(shdr);
		(void)fseeko(rfp, r_off, SEEK_SET);
		return MID_ELFFL | eh.elf64.e_machine;

	} else if (BAD_OBJECT(eh.exec) || eh.exec.a_syms == 0)
		goto bad;

	fix_header_order(&eh.exec);

	/* Seek to string table. */
	if (fseeko(rfp, N_STROFF(eh.exec) + r_off, SEEK_SET) == -1) {
		if (errno == EINVAL)
			goto bad;
		else
			err(1, "lseek: %s", archive);
	}

	/* Read in size of the string table. */
	if (fread((char *)&strsize, sizeof(strsize), 1, rfp) != 1)
		err(1, "fread: %s", archive);

	strsize = fix_32_order(strsize, N_GETMID(eh.exec));

	/* Read in the string table. */
	strsize -= sizeof(strsize);
	strtab = malloc(strsize);
	if (!strtab)
		err(1, "malloc: %s", archive);
	if (fread(strtab, strsize, 1, rfp) != 1)
		err(1, "fread: %s", archive);

	/* Seek to symbol table. */
	if (fseek(rfp, N_SYMOFF(eh.exec) + r_off, SEEK_SET) == (off_t)-1)
		err(1, "fseeko: %s", archive);

	/* For each symbol read the nlist entry and save it as necessary. */
	nsyms = eh.exec.a_syms / sizeof(struct nlist);
	while (nsyms--) {
		if (!fread((char *)&nl, sizeof(struct nlist), 1, rfp)) {
			if (feof(rfp))
				badfmt();
			err(1, "fread: %s", archive);
		}
		fix_nlist_order(&nl, N_GETMID(eh.exec));

		addsym(&nl, strtab - sizeof(long), r_off - r_fuzz -
		    sizeof(struct ar_hdr), symcnt, tsymlen, archive);
	}

bad:
	free(strtab);
	(void)fseeko(rfp, r_off, SEEK_SET);
	return N_GETMID(eh.exec);
}
Exemple #6
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 */
}
Exemple #7
0
/*
 * rexec
 *	Read the exec structure; ignore any files that don't look
 *	exactly right. Return MID.
 * 	return -1 for files that don't look right.
 *	XXX it's hard to be sure when to ignore files, and when to error
 *	out.
 */
static int
rexec(int rfd, int wfd)
{
	RLIB *rp;
	long nsyms;
	int nr, symlen;
	char *strtab = 0;
	char *sym;
	struct exec ebuf;
	struct nlist nl;
	off_t r_off, w_off;
	long strsize;
	int result = -1;

	/* Get current offsets for original and tmp files. */
	r_off = lseek(rfd, (off_t)0, SEEK_CUR);
	w_off = lseek(wfd, (off_t)0, SEEK_CUR);

	/* Read in exec structure. */
	nr = read(rfd, (char *)&ebuf, sizeof(struct exec));
	if (nr != sizeof(struct exec))
		goto bad;

	/* Check magic number and symbol count. */
	if (BAD_OBJECT(ebuf) || ebuf.a_syms == 0)
		goto bad;
	fix_header_order(&ebuf);

	/* Seek to string table. */
	if (lseek(rfd, N_STROFF(ebuf) + r_off, SEEK_SET) == (off_t)-1) {
		if (errno == EINVAL)
			goto bad;
		else
			error(archive);
	}

	/* Read in size of the string table. */
	nr = read(rfd, (char *)&strsize, sizeof(strsize));
	if (nr != sizeof(strsize))
		goto bad;

	strsize = fix_32_order(strsize, N_GETMID(ebuf));

	/* Read in the string table. */
	strsize -= sizeof(strsize);
	strtab = (char *)emalloc(strsize);
	nr = read(rfd, strtab, strsize);
	if (nr != strsize) 
		goto bad;

	/* Seek to symbol table. */
	if (fseek(fp, N_SYMOFF(ebuf) + r_off, SEEK_SET) == (off_t)-1)
		goto bad;

	result = N_GETMID(ebuf);
	/* For each symbol read the nlist entry and save it as necessary. */
	nsyms = ebuf.a_syms / sizeof(struct nlist);
	while (nsyms--) {
		if (!fread((char *)&nl, sizeof(struct nlist), 1, fp)) {
			if (feof(fp))
				badfmt();
			error(archive);
		}
		fix_nlist_order(&nl, N_GETMID(ebuf));

		/* Ignore if no name or local. */
		if (!nl.n_un.n_strx || !(nl.n_type & N_EXT))
			continue;

		/*
		 * If the symbol is an undefined external and the n_value
		 * field is non-zero, keep it.
		 */
		if ((nl.n_type & N_TYPE) == N_UNDF && !nl.n_value)
			continue;

		/* First four bytes are the table size. */
		sym = strtab + nl.n_un.n_strx - sizeof(long);
		symlen = strlen(sym) + 1;

		rp = (RLIB *)emalloc(sizeof(RLIB));
		rp->sym = (char *)emalloc(symlen);
		bcopy(sym, rp->sym, symlen);
		rp->symlen = symlen;
		rp->pos = w_off;

		/* Build in forward order for "ar -m" command. */
		*pnext = rp;
		pnext = &rp->next;

		++symcnt;
		tsymlen += symlen;
	}

bad: 	if (nr < 0)
		error(archive);
	free(strtab);
	(void)lseek(rfd, (off_t)r_off, SEEK_SET);
	return result;
}
Exemple #8
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) */
		);
	}
}
Exemple #9
0
int main (int argc, char *argv[]) {
  register struct nlist *s;
  register caddr_t strtab;
  register off_t stroff, symoff;
  register u_long symsize;
  register int cc;
  size_t strsize;
  struct nlist nbuf[1024];
  struct exec exec;
  struct stat st;
  int fd;
  int pageOffset;

  if ((fd = open (argv[1], O_RDONLY)) < 0) {
    fprintf (stderr, "could not open %s\n", argv[1]);
    return -1;
  }
  if (lseek(fd, (off_t)0, SEEK_SET) == -1 ||
      read(fd, &exec, sizeof(exec)) != sizeof(exec) ||
      fstat(fd, &st) < 0) {
    fprintf (stderr, "Invalid binary file\n");
    return -1;
  }
  if (N_BADMAG (exec) || N_GETMID (exec) != MID_I386) {
    fprintf (stderr, "invalid executable file N_BADMAG(exec) %d N_GETMID (exec) %d MID_I386 %d\n", N_BADMAG(exec), N_GETMID(exec), MID_I386);
    exit (1);
  }
  if (N_GETFLAG (exec) & EX_DYNAMIC) {
    fprintf (stderr, "are you giving me a dynamically linked executable??\n");
    return -1;
  }
  symoff = N_SYMOFF(exec);
  symsize = exec.a_syms;
  stroff = symoff + symsize;

#ifndef __linux__
  /* Check for files too large to mmap. */
  if (st.st_size - stroff > SIZE_T_MAX) {
    fprintf (stderr, "file too large\n");
    return -1;
  }
#endif

  /*
   * Map string table into our address space.  This gives us
   * an easy way to randomly access all the strings, without
   * making the memory allocation permanent as with malloc/free
   * (i.e., munmap will return it to the system).
   */
  strsize = st.st_size - stroff;
  pageOffset = stroff % 4096;
  stroff -= pageOffset;
  strsize += pageOffset;

  strtab = mmap(NULL, (size_t)strsize, PROT_READ, MAP_SHARED, fd, stroff);
  if (strtab == (char *)-1) {
    warn ("could not mmap string table");
    return -1;
  }
  strtab += pageOffset;
  strsize -= pageOffset;

  if (lseek(fd, symoff, SEEK_SET) == -1) {
    fprintf (stderr, "could not lseek to symbol table\n");
    return -1;
  }

  while (symsize > 0) {
    int i;
    cc = my_min(symsize, sizeof(nbuf));
    if (read(fd, nbuf, cc) != cc)
      break;
    symsize -= cc;
    for (s = nbuf; cc > 0; ++s, cc -= sizeof(*s)) {
      register int soff = s->n_un.n_strx;

      if (soff == 0 || (s->n_type & N_STAB) != 0)
        continue;
      for (i = 0; exclude[i]; i++) {
        if (!strcmp (&strtab[soff], exclude[i]))
          goto skip;
      }
      /* hack to avoid symbol with name equal to tmp filename used
         to build us */
      if (strchr (&strtab[soff], '.') || strchr (&strtab[soff], '/'))
        goto skip;
      if (s->n_type & N_EXT) {
        printf ("\t.globl\t%s\n\t.set\t%s,0x%lx\n\t.weak\t%s\n\n",
                &strtab[soff], &strtab[soff], s->n_value, &strtab[soff]);
      }
    skip:
      ;
    }
  }
  munmap(strtab, strsize);
  return 0;
}
Exemple #10
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;
}
Exemple #11
0
/*
 * show_file()
 *	show symbols from the object file pointed to by fp.  The current
 *	file pointer for fp is expected to be at the beginning of an object
 *	file header.
 */
int
show_file(int count, int warn_fmt, const char *name, FILE *fp, off_t foff, union hdr *head)
{
	u_long text, data, bss, total;
	struct nlist *np, *names, **snames;
	char *stab;
	int i, aout, nnames;
	size_t stabsize;
	off_t staboff;

	aout = 0;
	if (!elf32_chk_header(&head->elf32)) {
		struct elf_symtab es;

		es.name = name;
		es.ehdr = &head->elf32;
		if (head->elf32.e_ehsize < sizeof head->elf32) {
			warnx("%s: ELF header is too short", name);
			return 1;
		}

		if (!(es.shdr = elf32_load_shdrs(name, fp, foff, es.ehdr)))
			return (1);
		elf32_fix_shdrs(es.ehdr, es.shdr);
		es.shstr = NULL;

		if (issize)
			i = elf32_size(es.ehdr, es.shdr, &text, &data, &bss);
		else {
			nrawnames = 0;
			names = NULL;
			i = elf32_symload(&es, fp, foff, elf_symadd, &names);
			stab = es.stab;
			stabsize = es.stabsz;
		}
		free(es.shstr);
		free(es.shdr);
		if (i)
			return (i);

	} else if (!elf64_chk_header(&head->elf64)) {
		struct elf_symtab es;

		es.name = name;
		es.ehdr = &head->elf64;
		if (head->elf64.e_ehsize < sizeof head->elf64) {
			warnx("%s: ELF header is too short", name);
			return 1;
		}
		if (!(es.shdr = elf64_load_shdrs(name, fp, foff, es.ehdr)))
			return (1);
		elf64_fix_shdrs(es.ehdr, es.shdr);
		es.shstr = NULL;

		if (issize)
			i = elf64_size(es.ehdr, es.shdr, &text, &data, &bss);
		else {
			nrawnames = 0;
			names = NULL;
			i = elf64_symload(&es, fp, foff, elf_symadd, &names);
			stab = es.stab;
			stabsize = es.stabsz;
		}
		free(es.shstr);
		free(es.shdr);
		if (i)
			return (i);

	} else if (BAD_OBJECT(head->aout)) {
		if (warn_fmt)
			warnx("%s: bad format", name);
		return (1);
	} else do {
		u_int32_t w;

		aout++;

		fix_header_order(&head->aout);

		if (issize) {
			text = head->aout.a_text;
			data = head->aout.a_data;
			bss = head->aout.a_bss;
			break;
		}

		/* stop if the object file contains no symbol table */
		if (!head->aout.a_syms) {
			warnx("%s: no name list", name);
			return(1);
		}

		if (fseeko(fp, foff + N_SYMOFF(head->aout), SEEK_SET)) {
			warn("%s", name);
			return(1);
		}

#ifdef __LP64__
		nrawnames = head->aout.a_syms / sizeof(struct nlist32);
#else
		nrawnames = head->aout.a_syms / sizeof(*names);
#endif
		/* get memory for the symbol table */
		if ((names = calloc(nrawnames, sizeof(struct nlist))) == NULL) {
			warn("%s: malloc names", name);
			return (1);
		}

#ifdef __LP64__
		for (np = names, i = nrawnames; i--; np++) {
			struct nlist32 nl32;

			if (fread(&nl32, sizeof(nl32), 1, fp) != 1) {
				warnx("%s: cannot read symbol table", name);
				free(names);
				return (1);
			}
			np->n_type = nl32.type;
			np->n_other = nl32.other;
			if (byte_sex(N_GETMID(head->aout)) != BYTE_ORDER) {
				np->n_un.n_strx = swap32(nl32.strx);
				np->n_desc = swap16(nl32.desc);
				np->n_value = swap32(nl32.value);
			} else {
				np->n_un.n_strx = nl32.strx;
				np->n_desc = nl32.desc;
				np->n_value = nl32.value;
			}
		}
#else
		if (fread(names, head->aout.a_syms, 1, fp) != 1) {
			warnx("%s: cannot read symbol table", name);
			free(names);
			return (1);
		}
		fix_nlists_order(names, nrawnames, N_GETMID(head->aout));
#endif

		staboff = ftello(fp);
		/*
		 * Following the symbol table comes the string table.
		 * The first 4-byte-integer gives the total size of the
		 * string table _including_ the size specification itself.
		 */
		if (fread(&w, sizeof(w), (size_t)1, fp) != 1) {
			warnx("%s: cannot read stab size", name);
			free(names);
			return(1);
		}

		stabsize = fix_32_order(w, N_GETMID(head->aout));
		if ((stab = malloc(stabsize)) == NULL) {
			warn("%s: malloc", name);
			return 1;
		}

		if (pread(fileno(fp), stab, stabsize, staboff) != stabsize) {
			free(stab);
			warn("%s: pread", name);
			return 1;
		}

		stabsize -= 4;		/* we already have the size */
		for (np = names, i = nnames = 0; i < nrawnames; np++, i++) {
			/*
			 * make n_un.n_name a character pointer by adding
			 * the string table's base to n_un.n_strx
			 *
			 * don't mess with zero offsets
			 */
			if (np->n_un.n_strx)
				np->n_un.n_name = stab + np->n_un.n_strx;
			else
				np->n_un.n_name = "";
		}
	} while (0);

	if (issize) {
		static int first = 1;

		if (first) {
			first = 0;
			printf("text\tdata\tbss\tdec\thex\n");
		}

		total = text + data + bss;
		printf("%lu\t%lu\t%lu\t%lu\t%lx",
		    text, data, bss, total, total);
		if (count > 1)
			(void)printf("\t%s", name);

		total_text += text;
		total_data += data;
		total_bss += bss;
		total_total += total;

		printf("\n");
		return (0);
	}
	/* else we are nm */

	/*
	 * it seems that string table is sequential
	 * relative to the symbol table order
	 */
	if ((snames = calloc(nrawnames, sizeof *snames)) == NULL) {
		warn("%s: malloc snames", name);
		free(names);
		return (1);
	}

	/*
	 * fix up the symbol table and filter out unwanted entries
	 *
	 * common symbols are characterized by a n_type of N_UNDF and a
	 * non-zero n_value -- change n_type to N_COMM for all such
	 * symbols to make life easier later.
	 *
	 * filter out all entries which we don't want to print anyway
	 */
	for (np = names, i = nnames = 0; i < nrawnames; np++, i++) {
		if (aout && SYMBOL_TYPE(np->n_type) == N_UNDF && np->n_value)
			np->n_type = N_COMM | (np->n_type & N_EXT);
		if (!print_all_symbols && IS_DEBUGGER_SYMBOL(np->n_type))
			continue;
		if (print_only_external_symbols && !IS_EXTERNAL(np->n_type))
			continue;
		if (print_only_undefined_symbols &&
		    SYMBOL_TYPE(np->n_type) != N_UNDF)
			continue;

		snames[nnames++] = np;
	}

	/* sort the symbol table if applicable */
	if (sfunc)
		qsort(snames, (size_t)nnames, sizeof(*snames), sfunc);

	if (count > 1)
		(void)printf("\n%s:\n", name);

	/* print out symbols */
	for (i = 0; i < nnames; i++) {
		if (show_extensions && snames[i] != names &&
		    SYMBOL_TYPE((snames[i] -1)->n_type) == N_INDR)
			continue;
		print_symbol(name, snames[i], aout);
	}

	free(snames);
	free(names);
	free(stab);
	return(0);
}
Exemple #12
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;
}