Ejemplo n.º 1
0
static long
load_text_data(int fd, struct exec *hdrp, int bss, long disp)
{
    int size;
    unsigned char* addr;

    lseek(fd, disp + N_TXTOFF(*hdrp), 0);
    size = hdrp->a_text + hdrp->a_data;

    if (bss == -1) size += hdrp->a_bss;
    else if (bss > 1) size += bss;

    addr = (unsigned char*)xmalloc(size);
    if (addr == NULL) {
	dln_errno = errno;
	return 0;
    }

    if (read(fd, addr, size) !=  size) {
	dln_errno = errno;
	free(addr);
	return 0;
    }

    if (bss == -1) {
	memset(addr +  hdrp->a_text + hdrp->a_data, 0, hdrp->a_bss);
    }
    else if (bss > 0) {
	memset(addr +  hdrp->a_text + hdrp->a_data, 0, bss);
    }

    return (long)addr;
}
BOOL
CoffLoader::load()
{
	size_t filesz;
	size_t memsz;
	vaddr_t kv;
	off_t fileofs;

	/* start tag chain */
	_load_segment_start();

	/* text */
	filesz = memsz = _ah->a_tsize;
	kv = _ah->a_tstart;
	fileofs = COFF_ROUND(N_TXTOFF(_fh, _ah), 16);
	DPRINTF((TEXT("[text]")));
	_load_segment(kv, memsz, fileofs, filesz);
	/* data */
	fileofs += filesz;
	filesz = memsz = _ah->a_dsize;
	kv = _ah->a_dstart;
	DPRINTF((TEXT("[data]")));
	_load_segment(kv, memsz, fileofs, filesz);
	/* bss */
	filesz = 0;
	memsz = _ah->a_bsize;
	kv = _ah->a_dstart + _ah->a_dsize;
	fileofs = 0;
	DPRINTF((TEXT("[bss ]")));
	_load_segment(kv, memsz, fileofs, filesz);

	/* tag chain still opening */
	return _load_success();
}
Ejemplo n.º 3
0
static bfd_boolean
aout_adobe_set_section_contents (bfd *abfd,
				 asection *section,
				 const void * location,
				 file_ptr offset,
				 bfd_size_type count)
{
  file_ptr section_start;
  sec_ptr sect;

  /* Set by bfd.c handler.  */
  if (! abfd->output_has_begun)
    {
      /* Assign file offsets to sections.  Text sections are first, and
	 are contiguous.  Then data sections.  Everything else at the end.  */
      section_start = N_TXTOFF (0);

      for (sect = abfd->sections; sect; sect = sect->next)
	{
	  if (sect->flags & SEC_CODE)
	    {
	      sect->filepos = section_start;
	      /* FIXME:  Round to alignment.  */
	      section_start += sect->size;
	    }
	}

      for (sect = abfd->sections; sect; sect = sect->next)
	{
	  if (sect->flags & SEC_DATA)
	    {
	      sect->filepos = section_start;
	      /* FIXME:  Round to alignment.  */
	      section_start += sect->size;
	    }
	}

      for (sect = abfd->sections; sect; sect = sect->next)
	{
	  if (sect->flags & SEC_HAS_CONTENTS &&
	      !(sect->flags & (SEC_CODE | SEC_DATA)))
	    {
	      sect->filepos = section_start;
	      /* FIXME:  Round to alignment.  */
	      section_start += sect->size;
	    }
	}
    }

  /* Regardless, once we know what we're doing, we might as well get
     going.  */
  if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0)
    return FALSE;

  if (count == 0)
    return TRUE;

  return bfd_bwrite (location, count, abfd) == count;
}
Ejemplo n.º 4
0
Archivo: loader.c Proyecto: anhkgg/temu
int load_aout(const char *filename, uint8_t *addr)
{
    int fd, size, ret;
    struct exec e;
    uint32_t magic;

    fd = open(filename, O_RDONLY | O_BINARY);
    if (fd < 0)
        return -1;

    size = read(fd, &e, sizeof(e));
    if (size < 0)
        goto fail;

    bswap_ahdr(&e);

    magic = N_MAGIC(e);
    switch (magic) {
    case ZMAGIC:
    case QMAGIC:
    case OMAGIC:
	lseek(fd, N_TXTOFF(e), SEEK_SET);
	size = read(fd, addr, e.a_text + e.a_data);
	if (size < 0)
	    goto fail;
	break;
    case NMAGIC:
	lseek(fd, N_TXTOFF(e), SEEK_SET);
	size = read(fd, addr, e.a_text);
	if (size < 0)
	    goto fail;
	ret = read(fd, addr + N_DATADDR(e), e.a_data);
	if (ret < 0)
	    goto fail;
	size += ret;
	break;
    default:
	goto fail;
    }
    close(fd);
    return size;
 fail:
    close(fd);
    return -1;
}
Ejemplo n.º 5
0
/* Set parameters about this a.out file that are machine-dependent.
   This routine is called from some_aout_object_p just before it returns.  */
static const bfd_target *
MY (callback) (bfd *abfd)
{
  struct internal_exec *execp = exec_hdr (abfd);

  /* Calculate the file positions of the parts of a newly read aout header */
  obj_textsec (abfd)->size = N_TXTSIZE (*execp);

  /* The virtual memory addresses of the sections */
  obj_textsec (abfd)->vma = N_TXTADDR (*execp);
  obj_datasec (abfd)->vma = N_DATADDR (*execp);
  obj_bsssec (abfd)->vma = N_BSSADDR (*execp);

  obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
  obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
  obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;

  /* The file offsets of the sections */
  obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
  obj_datasec (abfd)->filepos = N_DATOFF (*execp);

  /* The file offsets of the relocation info */
  obj_textsec (abfd)->rel_filepos = N_TRELOFF (*execp);
  obj_datasec (abfd)->rel_filepos = N_DRELOFF (*execp);

  /* The file offsets of the string table and symbol table.  */
  obj_sym_filepos (abfd) = N_SYMOFF (*execp);
  obj_str_filepos (abfd) = N_STROFF (*execp);

  /* Determine the architecture and machine type of the object file.  */
#ifdef SET_ARCH_MACH
  SET_ARCH_MACH (abfd, *execp);
#else
  bfd_default_set_arch_mach (abfd, DEFAULT_ARCH, 0);
#endif

  if (obj_aout_subformat (abfd) == gnu_encap_format)
    {
      /* The file offsets of the relocation info */
      obj_textsec (abfd)->rel_filepos = N_GNU_TRELOFF (*execp);
      obj_datasec (abfd)->rel_filepos = N_GNU_DRELOFF (*execp);

      /* The file offsets of the string table and symbol table.  */
      obj_sym_filepos (abfd) = N_GNU_SYMOFF (*execp);
      obj_str_filepos (abfd) = (obj_sym_filepos (abfd) + execp->a_syms);

      abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
      bfd_get_symcount (abfd) = execp->a_syms / 12;
      obj_symbol_entry_size (abfd) = 12;
      obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
    }

  return abfd->xvec;
}
Ejemplo n.º 6
0
/* deref a pointer to kernel text */
u_int
kv_dref_t(struct kernel *kp, u_int adr){
  u_int tadr;
  if(!kp->incore){
    struct exec *ep;
    ep=(struct exec *)kp->core;
    tadr=*(u_int*)((adr - ep->a_entry) + N_TXTOFF(*ep) + (u_int)kp->core);
  } else {
    lseek(kp->fd, adr, SEEK_SET);
    read(kp->fd, &tadr, sizeof(tadr));
  }
  return(tadr);
}
Ejemplo n.º 7
0
static unsigned long load_aout_interp(struct exec * interp_ex,
                                      int interpreter_fd)
{
  unsigned long text_data, offset, elf_entry = ~0UL;
  char * addr;
  int retval;
  
  printf("WARNING: load_aout_interp() has not been tested at all!\n");

  current->end_code = interp_ex->a_text;
  text_data = interp_ex->a_text + interp_ex->a_data;
  current->end_data = text_data;
  current->brk = interp_ex->a_bss + text_data;

  switch (N_MAGIC(*interp_ex)) {
  case OMAGIC:
    offset = 32;
    addr = (char *) 0;
    break;
  case ZMAGIC:
  case QMAGIC:
    offset = N_TXTOFF(*interp_ex);
    addr = (char *) N_TXTADDR(*interp_ex);
    break;
  default:
    goto out;
  }

  if ((unsigned long)addr + text_data < text_data)
    goto out;

  do_mmap(-1, 0, text_data, PROT_READ|PROT_WRITE|PROT_EXEC, 
          MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0);
          
  retval = read_exec(interpreter_fd, offset, addr, text_data, 0);
  if (retval < 0)
    goto out;
    
#if 0    
  flush_icache_range((unsigned long)addr,
                     (unsigned long)addr + text_data);
#endif

  do_mmap(-1, ELF_PAGESTART(text_data + ELF_EXEC_PAGESIZE - 1),
          interp_ex->a_bss,  PROT_READ|PROT_WRITE|PROT_EXEC, 
          MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0);
  elf_entry = interp_ex->a_entry;

out:
  return elf_entry;
}
Ejemplo n.º 8
0
//--------------------------------------------------------------------------
int get_aout_file_format_index(linput_t *li)
{
  exec ex;
  register int i = 0;
  if(qlread(li, &ex, sizeof(ex)) != sizeof(ex)) return false;

  if(N_BADMAG(ex)) {
    ex.a_info = swap32(ex.a_info);
    switch(N_MACHTYPE(ex)) {
      case M_386_NETBSD:
      case M_68K_NETBSD:
      case M_68K4K_NETBSD:
      case M_532_NETBSD:
      case M_SPARC_NETBSD:
      case M_PMAX_NETBSD:
      case M_VAX_NETBSD:
      case M_ALPHA_NETBSD:
      case M_ARM6_NETBSD:
        break;

      default:
        return false;
    }
  }

  switch(N_MAGIC(ex)) {
    case NMAGIC:
      ++i;
    case CMAGIC:
      ++i;
    case ZMAGIC:
      ++i;
    case OMAGIC:
      ++i;
    case QMAGIC:
//      msg("text=%d data=%d symsize=%d txtoff=%d sum=%d\n", ex.a_text, ex.a_data,
//                N_SYMSIZE(ex), N_TXTOFF(ex), ex.a_text + ex.a_data + N_SYMSIZE(ex) + N_TXTOFF(ex));
      if ( qlsize(li) >= ex.a_text + ex.a_data + N_SYMSIZE(ex) + N_TXTOFF(ex) )
        break;
      if ( N_MAGIC(ex) == ZMAGIC
        && qlsize(li) >= ex.a_text + ex.a_data + N_SYMSIZE(ex) )
      {
        i = 5; // OpenBSD demand-paged
        break;
      }
    default:
      return false;
  }

  return i+1;
}
Ejemplo n.º 9
0
// Обработчик #PF для A.OUT-процессов
// Аргумент - адрес, по которому программа попыталась обратиться
// Результат - адрес загруженной страницы + флаги, или 0, если процесс "ошибся адресом"
ulong aout_pf(uint address)
{
   TaskStruct *task = Task[Current];

   // Наибольшая страница, которая будет загружаться из файла
   // (я все время предполагаю, что размеры секций кратны странице)
   uint filepages = task->header.a_text + task->header.a_data;

   // Объем АП процесса
   uint maxpage = filepages + PAGE_ADDR(task->header.a_bss + 0xfff)
      + USER_STACK_PAGES * PAGE_SIZE;

   bool ok = 0;

   // Преобразуем адрес в адрес страницы
   ulong pageaddr = PAGE_ADDR(address);
   ulong *tmppage = 0;

   // Если это страница должна грузиться из файла
   if (address < filepages)
   {
      // Выделяем страницу...
      tmppage = (ulong*)alloc_first_page();

      // ... и загружаем ее. Пользуемся тем, что LoadPart остановится
      // на конце файла.
      LoadPart(&task->file, tmppage, pageaddr+N_TXTOFF(task->header), PAGE_SIZE);

      ok = 1;
   }

   // Если это страница bss или стека
   if (address >= filepages && address < maxpage)
   {
      // Выделяем страницу...
      tmppage = (ulong*)alloc_first_page();
      // ... и обнуляем ее
      memset(tmppage, 0, PAGE_SIZE);

      ok = 1;
   }

   if (ok)
      return (ulong)tmppage + PAGE_ATTR;
   else
      return 0;
}
Ejemplo n.º 10
0
static unsigned long load_aout_interp(struct exec * interp_ex,
			     struct file * interpreter)
{
	unsigned long text_data, elf_entry = ~0UL;
	char * addr;
	loff_t offset;

	current->mm->end_code = interp_ex->a_text;
	text_data = interp_ex->a_text + interp_ex->a_data;
	current->mm->end_data = text_data;
	current->mm->brk = interp_ex->a_bss + text_data;

	switch (N_MAGIC(*interp_ex)) {
	case OMAGIC:
		offset = 32;
		addr = (char *) 0;
		break;
	case ZMAGIC:
	case QMAGIC:
		offset = N_TXTOFF(*interp_ex);
		addr = (char *) N_TXTADDR(*interp_ex);
		break;
	default:
		goto out;
	}

	down_write(&current->mm->mmap_sem);
	do_brk(0, text_data);
	up_write(&current->mm->mmap_sem);

	if (!interpreter->f_op || !interpreter->f_op->read)
		goto out;
	if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0)
		goto out;
	flush_icache_range((unsigned long)addr,
	                   (unsigned long)addr + text_data);

	down_write(&current->mm->mmap_sem);
	do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
		interp_ex->a_bss);
	up_write(&current->mm->mmap_sem);

	elf_entry = interp_ex->a_entry;

out:
	return elf_entry;
}
Ejemplo n.º 11
0
    /*
     *	read in the text space of an a.out file
     */
static void
gettextspace(FILE *nfile)
{

    textspace = (u_char *) malloc( xbuf.a_text );
    if ( textspace == 0 ) {
	warnx("no room for %lu bytes of text space: can't do -c" ,
		  xbuf.a_text );
	return;
    }
    (void) fseek( nfile , N_TXTOFF( xbuf ) , 0 );
    if ( fread( textspace , 1 , xbuf.a_text , nfile ) != xbuf.a_text ) {
	warnx("couldn't read text space: can't do -c");
	free( textspace );
	textspace = 0;
	return;
    }
}
Ejemplo n.º 12
0
/*
 * "Load" an a.out-format executable.
 */
static int
ld_aout(const struct iodesc * idi, const struct iodesc * ido,
	struct kgz_hdr * kh, const struct exec * a)
{
    size_t load, addr;

    load = addr = N_TXTADDR(*a);
    xcopy(idi, ido, le32toh(a->a_text), N_TXTOFF(*a));
    addr += le32toh(a->a_text);
    if (N_DATADDR(*a) != addr)
	return -1;
    xcopy(idi, ido, le32toh(a->a_data), N_DATOFF(*a));
    addr += le32toh(a->a_data);
    kh->dload = load;
    kh->dsize = addr - load;
    kh->isize = kh->dsize + le32toh(a->a_bss);
    kh->entry = le32toh(a->a_entry);
    return 0;
}
Ejemplo n.º 13
0
static unsigned long load_aout_interp(struct exec * interp_ex,
			     struct dentry * interpreter_dentry)
{
	unsigned long text_data, offset, elf_entry = ~0UL;
	char * addr;
	int retval;

	current->mm->end_code = interp_ex->a_text;
	text_data = interp_ex->a_text + interp_ex->a_data;
	current->mm->end_data = text_data;
	current->mm->brk = interp_ex->a_bss + text_data;

	switch (N_MAGIC(*interp_ex)) {
	case OMAGIC:
		offset = 32;
		addr = (char *) 0;
		break;
	case ZMAGIC:
	case QMAGIC:
		offset = N_TXTOFF(*interp_ex);
		addr = (char *) N_TXTADDR(*interp_ex);
		break;
	default:
		goto out;
	}

	do_mmap(NULL, 0, text_data,
		PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0);
	retval = read_exec(interpreter_dentry, offset, addr, text_data, 0);
	if (retval < 0)
		goto out;
	flush_icache_range((unsigned long)addr,
	                   (unsigned long)addr + text_data);

	do_mmap(NULL, ELF_PAGESTART(text_data + ELF_EXEC_PAGESIZE - 1),
		interp_ex->a_bss,
		PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, 0);
	elf_entry = interp_ex->a_entry;

out:
	return elf_entry;
}
Ejemplo n.º 14
0
static void
dump_segs(void)
{
    printf("  Text segment starts at address %lx\n", origin + N_TXTOFF(*ex));
    if (N_GETFLAG(*ex) & EX_DYNAMIC) {
	printf("    rel starts at %lx\n", sdt->sdt_rel);
	printf("    hash starts at %lx\n", sdt->sdt_hash);
	printf("    nzlist starts at %lx\n", sdt->sdt_nzlist);
	printf("    strings starts at %lx\n", sdt->sdt_strings);
    }

    printf("  Data segment starts at address %lx\n", origin + N_DATOFF(*ex));
    if (N_GETFLAG(*ex) & EX_DYNAMIC) {
	printf("    _dynamic starts at %lx\n", origin + N_DATOFF(*ex));
	printf("    so_debug starts at %lx\n", (unsigned long) dyn->d_debug);
	printf("    sdt starts at %lx\n", (unsigned long) dyn->d_un.d_sdt);
	printf("    got starts at %lx\n", sdt->sdt_got);
	printf("    plt starts at %lx\n", sdt->sdt_plt);
	printf("    rest of stuff starts at %lx\n",
	    sdt->sdt_plt + sdt->sdt_plt_sz);
    }
}
Ejemplo n.º 15
0
static struct relocation_info *
load_reloc(int fd, struct exec *hdrp, long disp)
{
    struct relocation_info *reloc;
    int size;

    lseek(fd, disp + N_TXTOFF(*hdrp) + hdrp->a_text + hdrp->a_data, 0);
    size = hdrp->a_trsize + hdrp->a_drsize;
    reloc = (struct relocation_info*)xmalloc(size);
    if (reloc == NULL) {
	dln_errno = errno;
	return NULL;
    }

    if (read(fd, reloc, size) !=  size) {
	dln_errno = errno;
	free(reloc);
	return NULL;
    }

    return reloc;
}
Ejemplo n.º 16
0
void *
a_out_mod_load(int fd)
{
	struct exec info_buf;
	size_t b;
	ssize_t n;
	char buf[10 * BUFSIZ];

	/*
	 * Get the load module post load size... do this by reading the
	 * header and doing page counts.
	 */
	if (a_out_read_header(fd, &info_buf) < 0)
		return NULL;

	/*
	 * Seek to the text offset to start loading...
	 */
	if (lseek(fd, N_TXTOFF(info_buf), 0) == -1)
		err(12, "lseek");

	/*
	 * Transfer the relinked module to kernel memory in chunks of
	 * MODIOBUF size at a time.
	 */
	b = info_buf.a_text + info_buf.a_data;
	while (b) {
		n = read(fd, buf, MIN(b, sizeof(buf)));
		if (n < 0)
			err(1, "while reading from prelinked module");
		if (n == 0)
			errx(1, "EOF while reading from prelinked module");

		loadbuf(buf, n);
		b -= n;
	}
	return (void *)info_buf.a_entry;
}
Ejemplo n.º 17
0
static unsigned int load_aout_interp(struct exec * interp_ex,
			     struct inode * interpreter_inode)
{
  int retval;
  unsigned int elf_entry;
  
  current->mm->brk = interp_ex->a_bss +
    (current->mm->end_data = interp_ex->a_data +
     (current->mm->end_code = interp_ex->a_text));
  elf_entry = interp_ex->a_entry;
  
  
  if (N_MAGIC(*interp_ex) == OMAGIC) {
    do_mmap(NULL, 0, interp_ex->a_text+interp_ex->a_data,
	    PROT_READ|PROT_WRITE|PROT_EXEC,
	    MAP_FIXED|MAP_PRIVATE, 0);
    retval = read_exec(interpreter_inode, 32, (char *) 0, 
		       interp_ex->a_text+interp_ex->a_data);
  } else if (N_MAGIC(*interp_ex) == ZMAGIC || N_MAGIC(*interp_ex) == QMAGIC) {
    do_mmap(NULL, 0, interp_ex->a_text+interp_ex->a_data,
	    PROT_READ|PROT_WRITE|PROT_EXEC,
	    MAP_FIXED|MAP_PRIVATE, 0);
    retval = read_exec(interpreter_inode,
		       N_TXTOFF(*interp_ex) ,
		       (char *) N_TXTADDR(*interp_ex),
		       interp_ex->a_text+interp_ex->a_data);
  } else
    retval = -1;
  
  if(retval >= 0)
    do_mmap(NULL, (interp_ex->a_text + interp_ex->a_data + 0xfff) & 
	    0xfffff000, interp_ex->a_bss,
	    PROT_READ|PROT_WRITE|PROT_EXEC,
	    MAP_FIXED|MAP_PRIVATE, 0);
  if(retval < 0) return 0xffffffff;
  return elf_entry;
}
Ejemplo n.º 18
0
setsym()
{
	off_t loc;
	struct exec hdr;
	register struct nlist *sp;
	int ssiz;
	char *strtab;

	fsym = getfile(symfil, 1);
	txtmap.ufd = fsym;
	if (read(fsym, (char *)&hdr, sizeof hdr) != sizeof hdr ||
	    N_BADMAG(hdr)) {
		txtmap.e1 = MAXFILE;
		return;
	}
	filhdr = hdr;
	loc = filhdr.a_text+filhdr.a_data;
	txtmap.f1 = txtmap.f2 = N_TXTOFF(filhdr);
	txtmap.b1 = 0;
	switch (filhdr.a_magic) {

	case OMAGIC:
		txtmap.b1 = txtmap.e1 = 0;
		txtmap.b2 = datbas = 0;
		txtmap.e2 = loc;
		break;

	case ZMAGIC:
	case NMAGIC:
		txtmap.e1 = filhdr.a_text;
		txtmap.b2 = datbas = round(filhdr.a_text, PAGSIZ);
		txtmap.e2 = datbas + filhdr.a_data;
		txtmap.f2 += txtmap.e1;
	}
	loc = N_SYMOFF(filhdr);
	symtab = (struct nlist *) malloc(filhdr.a_syms);
	esymtab = &symtab[filhdr.a_syms / sizeof (struct nlist)];
	if (symtab == NULL)
		goto nospac;
	lseek(fsym, loc, L_SET);
	if (filhdr.a_syms == 0)
		goto nosymt;
	/* SHOULD SQUISH OUT STABS HERE!!! */
	if (read(fsym, symtab, filhdr.a_syms) != filhdr.a_syms)
		goto readerr;
	if (read(fsym, &ssiz, sizeof (ssiz)) != sizeof (ssiz))
		goto oldfmt;
	strtab = (char *) malloc(ssiz);
	if (strtab == 0)
		goto nospac;
	*(int *)strtab = ssiz;
	ssiz -= sizeof (ssiz);
	if (read(fsym, strtab + sizeof (ssiz), ssiz) != ssiz)
		goto readerr;
	for (sp = symtab; sp < esymtab; sp++)
		if (sp->n_strx)
			/* SHOULD PERFORM RANGE CHECK HERE */
			sp->n_un.n_name = strtab + sp->n_un.n_strx;
nosymt:
	if (INKERNEL(filhdr.a_entry)) {
		txtmap.b1 += KERNOFF;
		txtmap.e1 += KERNOFF;
		txtmap.b2 += KERNOFF;
		txtmap.e2 += KERNOFF;
	}
	return;
readerr:
	printf("Error reading symbol|string table\n");
	exit(1);
nospac:
	printf("Not enough space for symbol|string table\n");
	exit(1);
oldfmt:
	printf("Old format a.out - no string table\n");
	exit(1);
}
Ejemplo n.º 19
0
int 
aout_load(struct sys_info *info, ihandle_t dev)
{
    int retval = -1;
    struct exec ehdr;
    unsigned long start, size;
    unsigned int offset;

    image_name = image_version = NULL;

    /* Mark the saved-program-state as invalid */
    feval("0 state-valid !");
    
    fd = open_ih(dev);
    if (fd == -1) {
	goto out;
    }

    for (offset = 0; offset < 16 * 512; offset += 512) {
        seek_io(fd, offset);
        if (read_io(fd, &ehdr, sizeof ehdr) != sizeof ehdr) {
            debug("Can't read a.out header\n");
            retval = LOADER_NOT_SUPPORT;
            goto out;
        }
        if (is_aout(&ehdr))
            break;
    }

    if (!is_aout(&ehdr)) {
	debug("Not a bootable a.out image\n");
	retval = LOADER_NOT_SUPPORT;
	goto out;
    }

    if (ehdr.a_text == 0x30800007)
	ehdr.a_text=64*1024;

    if (N_MAGIC(ehdr) == NMAGIC) {
        size = addr_fixup(N_DATADDR(ehdr)) + addr_fixup(ehdr.a_data);
    } else {
        size = addr_fixup(ehdr.a_text) + addr_fixup(ehdr.a_data);
    }

    if (size < 7680)
        size = 7680;

    fword("load-base");
    start = POP(); // N_TXTADDR(ehdr);

    memcpy((void *)start, &ehdr, sizeof(ehdr));
    
    if (!check_mem_ranges(info, start, size))
	goto out;

    printf("Loading a.out %s...\n", image_name ? image_name : "image");
    seek_io(fd, offset + N_TXTOFF(ehdr));

    if (N_MAGIC(ehdr) == NMAGIC) {
        if ((size_t)read_io(fd, (void *)(start + N_TXTOFF(ehdr)), ehdr.a_text) != ehdr.a_text) {
            printf("Can't read program text segment (size 0x" FMT_aout_ehdr ")\n", ehdr.a_text);
            goto out;
        }
        if ((size_t)read_io(fd, (void *)(start + N_DATADDR(ehdr)), ehdr.a_data) != ehdr.a_data) {
            printf("Can't read program data segment (size 0x" FMT_aout_ehdr ")\n", ehdr.a_data);
            goto out;
        }
    } else {
        if ((size_t)read_io(fd, (void *)(start + N_TXTOFF(ehdr)), size) != size) {
            printf("Can't read program (size 0x" FMT_sizet ")\n", size);
            goto out;
        }
    }

    debug("Loaded %lu bytes\n", size);
    debug("entry point is %#lx\n", start);

    // Initialise saved-program-state
    PUSH(size);
    feval("load-state >ls.file-size !");
    feval("aout load-state >ls.file-type !");

out:
    close_io(fd);
    return retval;
}
Ejemplo n.º 20
0
/* N.B. Move to .h file and use code in fs/binfmt_aout.c? */
static int load_aout32_library(struct file *file)
{
	struct inode * inode;
	unsigned long bss, start_addr, len;
	unsigned long error;
	int retval;
	struct exec ex;

	inode = file->f_path.dentry->d_inode;

	retval = -ENOEXEC;
	error = kernel_read(file, 0, (char *) &ex, sizeof(ex));
	if (error != sizeof(ex))
		goto out;

	/* We come in here for the regular a.out style of shared libraries */
	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) ||
	    N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
	    inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
		goto out;
	}

	if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) &&
	    (N_TXTOFF(ex) < inode->i_sb->s_blocksize)) {
		printk("N_TXTOFF < BLOCK_SIZE. Please convert library\n");
		goto out;
	}

	if (N_FLAGS(ex))
		goto out;

	/* For  QMAGIC, the starting address is 0x20 into the page.  We mask
	   this off to get the starting address for the page */

	start_addr =  ex.a_entry & 0xfffff000;

	/* Now use mmap to map the library into memory. */
	down_write(&current->mm->mmap_sem);
	error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
			PROT_READ | PROT_WRITE | PROT_EXEC,
			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
			N_TXTOFF(ex));
	up_write(&current->mm->mmap_sem);
	retval = error;
	if (error != start_addr)
		goto out;

	len = PAGE_ALIGN(ex.a_text + ex.a_data);
	bss = ex.a_text + ex.a_data + ex.a_bss;
	if (bss > len) {
		down_write(&current->mm->mmap_sem);
		error = do_brk(start_addr + len, bss - len);
		up_write(&current->mm->mmap_sem);
		retval = error;
		if (error != start_addr + len)
			goto out;
	}
	retval = 0;
out:
	return retval;
}
Ejemplo n.º 21
0
static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{
	struct exec ex;
	unsigned long error;
	unsigned long fd_offset;
	unsigned long rlim;
	unsigned long orig_thr_flags;
	int retval;

	ex = *((struct exec *) bprm->buf);		/* exec-header */
	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
	     N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) ||
	    N_TRSIZE(ex) || N_DRSIZE(ex) ||
	    bprm->file->f_path.dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
		return -ENOEXEC;
	}

	fd_offset = N_TXTOFF(ex);

	/* Check initial limits. This avoids letting people circumvent
	 * size limits imposed on them by creating programs with large
	 * arrays in the data or bss.
	 */
	rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
	if (rlim >= RLIM_INFINITY)
		rlim = ~0;
	if (ex.a_data + ex.a_bss > rlim)
		return -ENOMEM;

	/* Flush all traces of the currently running executable */
	retval = flush_old_exec(bprm);
	if (retval)
		return retval;

	/* OK, This is the point of no return */
	set_personality(PER_SUNOS);

	current->mm->end_code = ex.a_text +
		(current->mm->start_code = N_TXTADDR(ex));
	current->mm->end_data = ex.a_data +
		(current->mm->start_data = N_DATADDR(ex));
	current->mm->brk = ex.a_bss +
		(current->mm->start_brk = N_BSSADDR(ex));
	current->mm->free_area_cache = current->mm->mmap_base;
	current->mm->cached_hole_size = 0;

	current->mm->mmap = NULL;
	compute_creds(bprm);
 	current->flags &= ~PF_FORKNOEXEC;
	if (N_MAGIC(ex) == NMAGIC) {
		loff_t pos = fd_offset;
		/* F**k me plenty... */
		down_write(&current->mm->mmap_sem);	
		error = do_brk(N_TXTADDR(ex), ex.a_text);
		up_write(&current->mm->mmap_sem);
		bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
			  ex.a_text, &pos);
		down_write(&current->mm->mmap_sem);
		error = do_brk(N_DATADDR(ex), ex.a_data);
		up_write(&current->mm->mmap_sem);
		bprm->file->f_op->read(bprm->file, (char __user *)N_DATADDR(ex),
			  ex.a_data, &pos);
		goto beyond_if;
	}

	if (N_MAGIC(ex) == OMAGIC) {
		loff_t pos = fd_offset;
		down_write(&current->mm->mmap_sem);
		do_brk(N_TXTADDR(ex) & PAGE_MASK,
			ex.a_text+ex.a_data + PAGE_SIZE - 1);
		up_write(&current->mm->mmap_sem);
		bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
			  ex.a_text+ex.a_data, &pos);
	} else {
		static unsigned long error_time;
		if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
		    (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time) > 5*HZ)
		{
			printk(KERN_NOTICE "executable not page aligned\n");
			error_time = jiffies;
		}

		if (!bprm->file->f_op->mmap) {
			loff_t pos = fd_offset;
			down_write(&current->mm->mmap_sem);
			do_brk(0, ex.a_text+ex.a_data);
			up_write(&current->mm->mmap_sem);
			bprm->file->f_op->read(bprm->file,
				  (char __user *)N_TXTADDR(ex),
				  ex.a_text+ex.a_data, &pos);
			goto beyond_if;
		}

	        down_write(&current->mm->mmap_sem);
		error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
			PROT_READ | PROT_EXEC,
			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
			fd_offset);
	        up_write(&current->mm->mmap_sem);

		if (error != N_TXTADDR(ex)) {
			send_sig(SIGKILL, current, 0);
			return error;
		}

	        down_write(&current->mm->mmap_sem);
 		error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
				PROT_READ | PROT_WRITE | PROT_EXEC,
				MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
				fd_offset + ex.a_text);
	        up_write(&current->mm->mmap_sem);
		if (error != N_DATADDR(ex)) {
			send_sig(SIGKILL, current, 0);
			return error;
		}
	}
beyond_if:
	set_binfmt(&aout32_format);

	set_brk(current->mm->start_brk, current->mm->brk);

	/* Make sure STACK_TOP returns the right thing.  */
	orig_thr_flags = current_thread_info()->flags;
	current_thread_info()->flags |= _TIF_32BIT;

	retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
	if (retval < 0) { 
		current_thread_info()->flags = orig_thr_flags;

		/* Someone check-me: is this error path enough? */ 
		send_sig(SIGKILL, current, 0); 
		return retval;
	}

	current->mm->start_stack =
		(unsigned long) create_aout32_tables((char __user *)bprm->p, bprm);
	tsb_context_switch(current->mm);

	start_thread32(regs, ex.a_entry, current->mm->start_stack);
	if (current->ptrace & PT_PTRACED)
		send_sig(SIGTRAP, current, 0);
	return 0;
}
Ejemplo n.º 22
0
/* End of test binpatch variables */
int
main(int argc, char *argv[])
{
  struct exec e;
  int c;
  u_long addr = 0, offset = 0;
  u_long index = 0;/* Related to offset */
  u_long replace = 0, do_replace = 0;
  char *symbol = 0;
  char size = 4;  /* default to long */
  char size_opt = 0; /* Flag to say size option was set, used with index */
  char *fname;
  char *pgname = argv[0]; /* Program name */
  int fd;
  int type, off;
  u_long  lval;
  u_short sval;
  u_char  cval;


  while ((c = getopt (argc, argv, "H:a:bwlr:s:o:")) != -1)
    switch (c)
      {
      case 'H':
        Usage(argv[0]);
        break;
      case 'a':
	if (addr || symbol)
	  error ("only one address/symbol allowed");
	if (! strncmp (optarg, "0x", 2))
	  sscanf (optarg, "%x", &addr);
	else
	  addr = atoi (optarg);
	if (! addr)
	  error ("invalid address");
	break;

      case 'b':
	size = 1;
        size_opt = 1;
	break;

      case 'w':
	size = 2;
        size_opt = 1;
	break;

      case 'l':
	size = 4;
        size_opt = 1;
	break;

      case 'r':
	do_replace = 1;
	if (! strncmp (optarg, "0x", 2))
	  sscanf (optarg, "%x", &replace);
	else
	  replace = atoi (optarg);
	break;

      case 's':
	if (addr || symbol)
	  error ("only one address/symbol allowed");
	symbol = optarg;
	break;

      case 'o':
	if (offset)
	  error ("only one offset allowed");
	if (! strncmp (optarg, "0x", 2))
	  sscanf (optarg, "%x", &offset);
	else
          offset = atoi (optarg);
        break;
      }/* while switch() */

  if (argc > 1)
  {
    if (addr || symbol)
    {
      argv += optind;
      argc -= optind;

      if (argc < 1)
        error ("No file to patch.");

      fname = argv[0];
      if ((fd = open (fname, 0)) < 0)
        error ("Can't open file");

      if (read (fd, &e, sizeof (e)) != sizeof (e)
        || N_BADMAG (e))
        error ("Not a valid executable.");

      /* fake mid, so the N_ macros work on the amiga.. */
      e.a_midmag |= 127 << 16;

      if (symbol)
      {
        struct nlist nl[2];
        if (offset == 0)
	{
            u_long new_do_replace = 0;
            new_do_replace = FindAssign(symbol,&replace);
            if (new_do_replace && do_replace)
              error("Cannot use both '=' and '-r' option!");
            FindOffset(symbol,&index);
            if (size_opt)
               offset = index*size; /* Treat like an index */
            else
               offset = index; /* Treat index like an offset */
	    if (new_do_replace)
	       do_replace = new_do_replace;
	}
        nl[0].n_un.n_name = symbol;
        nl[1].n_un.n_name = 0;
        if (nlist (fname, nl) != 0)
	{
          fprintf(stderr,"Symbol is %s ",symbol);
	  error ("Symbol not found.");
        }
        addr = nl[0].n_value;
        type = nl[0].n_type & N_TYPE;
      }
      else
      {
        type = N_UNDF;
        if (addr >= N_TXTADDR(e) && addr < N_DATADDR(e))
	  type = N_TEXT;
        else if (addr >= N_DATADDR(e) && addr < N_DATADDR(e) + e.a_data)
	  type = N_DATA;
      }
      addr += offset;

      /* if replace-mode, have to reopen the file for writing.
         Can't do that from the beginning, or nlist() will not
         work (at least not under AmigaDOS) */
      if (do_replace)
      {
        close (fd);
        if ((fd = open (fname, 2)) == -1)
	  error ("Can't reopen file for writing.");
      }

      if (type != N_TEXT && type != N_DATA)
        error ("address/symbol is not in text or data section.");

      if (type == N_TEXT)
        off = addr - N_TXTADDR(e) + N_TXTOFF(e);
      else
        off = addr - N_DATADDR(e) + N_DATOFF(e);

      if (lseek (fd, off, 0) == -1)
        error ("lseek");

      /* not beautiful, but works on big and little endian machines */
      switch (size)
        {
        case 1:
          if (read (fd, &cval, 1) != 1)
	    error ("cread");
          lval = cval;
          break;

        case 2:
          if (read (fd, &sval, 2) != 2)
	    error ("sread");
          lval = sval;
          break;

        case 4:
          if (read (fd, &lval, 4) != 4)
	    error ("lread");
          break;
        }/* switch size */


      if (symbol)
        printf ("%s(0x%x): %d (0x%x)\n", symbol, addr, lval, lval);
      else
        printf ("0x%x: %d (0x%x)\n", addr, lval, lval);

      if (do_replace)
      {
        if (lseek (fd, off, 0) == -1)
	  error ("write-lseek");
        switch (size)
	  {
	  case 1:
	    cval = replace;
	    if (cval != replace)
	      error ("byte-value overflow.");
	    if (write (fd, &cval, 1) != 1)
	      error ("cwrite");
	    break;

	  case 2:
	    sval = replace;
	    if (sval != replace)
	      error ("word-value overflow.");
	    if (write (fd, &sval, 2) != 2)
	      error ("swrite");
	    break;

	  case 4:
	    if (write (fd, &replace, 4) != 4)
	      error ("lwrite");
	    break;
	  }/* switch(size) */
      }/* if (do_replace) */

      close (fd);
    }/* if(addr || symbol ) */
    else
    {
      error("Must specify either address or symbol.");
    }
  }/* if argc < 1 */
  else
  {
    Synopsis(pgname);
  }
  return(0);
}/* main () */
Ejemplo n.º 23
0
static int load_aout_library(struct file *file)
{
	struct inode * inode;
	unsigned long bss, start_addr, len;
	unsigned long error;
	int retval;
	struct exec ex;

	inode = file->f_dentry->d_inode;

	retval = -ENOEXEC;
	error = kernel_read(file, 0, (char *) &ex, sizeof(ex));
	if (error != sizeof(ex))
		goto out;

	/* We come in here for the regular a.out style of shared libraries */
	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) ||
	    N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
	    inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
		goto out;
	}

	if (N_FLAGS(ex))
		goto out;

	/* For  QMAGIC, the starting address is 0x20 into the page.  We mask
	   this off to get the starting address for the page */
#ifndef __arm__
	start_addr =  ex.a_entry & 0xfffff000;
#else
	start_addr = ex.a_entry & 0xffff8000;
#endif

	if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) {
		static unsigned long error_time;
		loff_t pos = N_TXTOFF(ex);

		if ((jiffies-error_time) > 5*HZ)
		{
			printk(KERN_WARNING 
			       "N_TXTOFF is not page aligned. Please convert library: %s\n",
			       file->f_dentry->d_name.name);
			error_time = jiffies;
		}

		do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
		
		file->f_op->read(file, (char *)start_addr,
			ex.a_text + ex.a_data, &pos);
		flush_icache_range((unsigned long) start_addr,
				   (unsigned long) start_addr + ex.a_text + ex.a_data);

		retval = 0;
		goto out;
	}
	/* Now use mmap to map the library into memory. */
	down_write(&current->mm->mmap_sem);
	error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
			PROT_READ | PROT_WRITE | PROT_EXEC,
			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
			N_TXTOFF(ex));
	up_write(&current->mm->mmap_sem);
	retval = error;
	if (error != start_addr)
		goto out;

	len = PAGE_ALIGN(ex.a_text + ex.a_data);
	bss = ex.a_text + ex.a_data + ex.a_bss;
	if (bss > len) {
		error = do_brk(start_addr + len, bss - len);
		retval = error;
		if (error != start_addr + len)
			goto out;
	}
	retval = 0;
out:
	return retval;
}
Ejemplo n.º 24
0
static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
{
	struct exec ex;
	unsigned long error;
	unsigned long fd_offset;
	unsigned long rlim;
	int retval;

	ex = *((struct exec *) bprm->buf);		/* exec-header */
	if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
	     N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) ||
	    N_TRSIZE(ex) || N_DRSIZE(ex) ||
	    bprm->file->f_dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
		return -ENOEXEC;
	}

	fd_offset = N_TXTOFF(ex);

	/* Check initial limits. This avoids letting people circumvent
	 * size limits imposed on them by creating programs with large
	 * arrays in the data or bss.
	 */
	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
	if (rlim >= RLIM_INFINITY)
		rlim = ~0;
	if (ex.a_data + ex.a_bss > rlim)
		return -ENOMEM;

	/* Flush all traces of the currently running executable */
	retval = flush_old_exec(bprm);
	if (retval)
		return retval;

	/* OK, This is the point of no return */
#if defined(__alpha__)
	SET_AOUT_PERSONALITY(bprm, ex);
#elif defined(__sparc__)
	set_personality(PER_SUNOS);
#if !defined(__sparc_v9__)
	memcpy(&current->thread.core_exec, &ex, sizeof(struct exec));
#endif
#else
	set_personality(PER_LINUX);
#endif

	current->mm->end_code = ex.a_text +
		(current->mm->start_code = N_TXTADDR(ex));
	current->mm->end_data = ex.a_data +
		(current->mm->start_data = N_DATADDR(ex));
	current->mm->brk = ex.a_bss +
		(current->mm->start_brk = N_BSSADDR(ex));

	current->mm->rss = 0;
	current->mm->mmap = NULL;

#ifdef CONFIG_ARM_FASS
	arch_new_mm(current, current->mm);
#endif

	compute_creds(bprm);
 	current->flags &= ~PF_FORKNOEXEC;
#ifdef __sparc__
	if (N_MAGIC(ex) == NMAGIC) {
		loff_t pos = fd_offset;
		/* F**k me plenty... */
		/* <AOL></AOL> */
		error = do_brk(N_TXTADDR(ex), ex.a_text);
		bprm->file->f_op->read(bprm->file, (char *) N_TXTADDR(ex),
			  ex.a_text, &pos);
		error = do_brk(N_DATADDR(ex), ex.a_data);
		bprm->file->f_op->read(bprm->file, (char *) N_DATADDR(ex),
			  ex.a_data, &pos);
		goto beyond_if;
	}
#endif

	if (N_MAGIC(ex) == OMAGIC) {
		unsigned long text_addr, map_size;
		loff_t pos;

		text_addr = N_TXTADDR(ex);

#if defined(__alpha__) || defined(__sparc__)
		pos = fd_offset;
		map_size = ex.a_text+ex.a_data + PAGE_SIZE - 1;
#else
		pos = 32;
		map_size = ex.a_text+ex.a_data;
#endif

		error = do_brk(text_addr & PAGE_MASK, map_size);
		if (error != (text_addr & PAGE_MASK)) {
			send_sig(SIGKILL, current, 0);
			return error;
		}

		error = bprm->file->f_op->read(bprm->file, (char *)text_addr,
			  ex.a_text+ex.a_data, &pos);
		if ((signed long)error < 0) {
			send_sig(SIGKILL, current, 0);
			return error;
		}
			 
		flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data);
	} else {
		static unsigned long error_time, error_time2;
		if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
		    (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time2) > 5*HZ)
		{
			printk(KERN_NOTICE "executable not page aligned\n");
			error_time2 = jiffies;
		}

		if ((fd_offset & ~PAGE_MASK) != 0 &&
		    (jiffies-error_time) > 5*HZ)
		{
			printk(KERN_WARNING 
			       "fd_offset is not page aligned. Please convert program: %s\n",
			       bprm->file->f_dentry->d_name.name);
			error_time = jiffies;
		}

		if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
			loff_t pos = fd_offset;
			do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
			bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex),
					ex.a_text+ex.a_data, &pos);
			flush_icache_range((unsigned long) N_TXTADDR(ex),
					   (unsigned long) N_TXTADDR(ex) +
					   ex.a_text+ex.a_data);
			goto beyond_if;
		}

		down_write(&current->mm->mmap_sem);
		error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
			PROT_READ | PROT_EXEC,
			MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
			fd_offset);
		up_write(&current->mm->mmap_sem);

		if (error != N_TXTADDR(ex)) {
			send_sig(SIGKILL, current, 0);
			return error;
		}

		down_write(&current->mm->mmap_sem);
 		error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
				PROT_READ | PROT_WRITE | PROT_EXEC,
				MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
				fd_offset + ex.a_text);
		up_write(&current->mm->mmap_sem);
		if (error != N_DATADDR(ex)) {
			send_sig(SIGKILL, current, 0);
			return error;
		}
	}
beyond_if:
	set_binfmt(&aout_format);

	set_brk(current->mm->start_brk, current->mm->brk);

	retval = setup_arg_pages(bprm); 
	if (retval < 0) { 
		/* Someone check-me: is this error path enough? */ 
		send_sig(SIGKILL, current, 0); 
		return retval;
	}

	current->mm->start_stack =
		(unsigned long) create_aout_tables((char *) bprm->p, bprm);
#ifdef __alpha__
	regs->gp = ex.a_gpvalue;
#endif
	start_thread(regs, ex.a_entry, current->mm->start_stack);
	if (current->ptrace & PT_PTRACED)
		send_sig(SIGTRAP, current, 0);
#ifndef __arm__
	return 0;
#else
	return regs->ARM_r0;
#endif
}
Ejemplo n.º 25
0
int
main (int argc, char** argv)
{
  struct exec my_exec;
  int page_size;
  char * target;
  char * arch = "unknown";
  FILE * file;

  target = argv[1];
  if (target == NULL)
    {
      fprintf (stderr, "Usage: gen-aout target_name\n");
      exit (1);
    }

  file = fopen ("gen-aout", "r");
  if (file == NULL)
    {
      fprintf (stderr, "Cannot open gen-aout!\n");
      return -1;
    }

  if (fread (&my_exec, sizeof (struct exec), 1, file) != 1)
    {
      fprintf(stderr, "Cannot read gen-aout!\n");
      return -1;
    }

  fclose (file);

#ifdef N_TXTOFF
  page_size = N_TXTOFF(my_exec);
  if (page_size == 0)
    printf ("#define N_HEADER_IN_TEXT(x) 1\n");
  else
    printf ("#define N_HEADER_IN_TEXT(x) 0\n");
#endif

  printf("#define BYTES_IN_WORD %d\n", sizeof (int));
  if (my_exec.a_entry == 0)
    {
      printf ("#define ENTRY_CAN_BE_ZERO\n");
      printf ("#define N_SHARED_LIB(x) 0 /* Avoids warning */\n");
    }
  else
    {
      printf ("/*#define ENTRY_CAN_BE_ZERO*/\n");
      printf ("/*#define N_SHARED_LIB(x) 0*/\n");
    }

  printf ("#define TEXT_START_ADDR %d\n", my_exec.a_entry);

#ifdef PAGSIZ
  if (page_size == 0)
    page_size = PAGSIZ;
#endif

  if (page_size != 0)
    printf ("#define TARGET_PAGE_SIZE %d\n", page_size);
  else
    printf ("/* #define TARGET_PAGE_SIZE ??? */\n");

  printf ("#define SEGMENT_SIZE TARGET_PAGE_SIZE\n");

#ifdef vax
  arch = "vax";
#endif
#ifdef m68k
  arch = "m68k";
#endif
  if (arch[0] == '1')
    {
      fprintf (stderr, _("warning: preprocessor substituted architecture name inside string;"));
      fprintf (stderr, _("         fix DEFAULT_ARCH in the output file yourself\n"));
      arch = "unknown";
    }
  printf ("#define DEFAULT_ARCH bfd_arch_%s\n\n", arch);

  printf ("/* Do not \"beautify\" the CONCAT* macro args.  Traditional C will not");
  printf ("   remove whitespace added here, and thus will fail to concatenate");
  printf ("   the tokens.  */");
  printf ("\n#define MY(OP) CONCAT2 (%s_,OP)\n\n", target);
  printf ("#define TARGETNAME \"a.out-%s\"\n\n", target);

  printf ("#include \"sysdep.h\"\n");
  printf ("#include \"bfd.h\"\n");
  printf ("#include \"libbfd.h\"\n");
  printf ("#include \"libaout.h\"\n");
  printf ("\n#include \"aout-target.h\"\n");

  return 0;
}
Ejemplo n.º 26
0
static long loadprog(long *hsize)
{
	long addr;	/* physical address.. not directly useable */
	long hmaddress;
	unsigned long pad;
	long i;
	static int (*x_entry)() = 0;

	ufs_read(&head, (long) sizeof(head));
	if (N_BADMAG(head)) {
		printf("Invalid format!\n");
		exit(0);
	}

	startaddr = (long)head.a_entry;
	addr = (startaddr & 0x00ffffffl); /* some MEG boundary */
	printf("Booting @ 0x%lx\n", addr);
	if(addr < 0x100000l)
	{
		printf("Start address too low!\n");
		exit(0);
	}

	poff = N_TXTOFF(head)+head.a_text+head.a_data+head.a_syms;
	ufs_read((void *)&i, sizeof(long));
	*hsize = head.a_text+head.a_data+head.a_bss;
	*hsize = (*hsize+NBPG-1)&~(NBPG-1);
	*hsize += i+4+head.a_syms;
	addr=hmaddress=get_high_memory(*hsize);
	if (!hmaddress) {
		printf("Sorry, can't allocate enough memory!\n");
		exit(0);
	}

	poff = N_TXTOFF(head);

	/********************************************************/
	/* LOAD THE TEXT SEGMENT                                */
	/********************************************************/
	printf("text=0x%lx ", head.a_text);
	xread(addr, head.a_text);
	addr += head.a_text;

	/********************************************************/
	/* Load the Initialised data after the text		*/
	/********************************************************/
	while (addr & CLOFSET)
		pm_copy("\0", addr++, 1);

	printf("data=0x%lx ", head.a_data);
	xread(addr, head.a_data);
	addr += head.a_data;

	/********************************************************/
	/* Skip over the uninitialised data			*/
	/* (but clear it)					*/
	/********************************************************/
	printf("bss=0x%lx ", head.a_bss);
	pbzero(addr, head.a_bss);
	addr += head.a_bss;

	/* Pad to a page boundary. */
	pad = (unsigned long)(addr-hmaddress+(startaddr & 0x00ffffffl)) % NBPG;
	if (pad != 0) {
		pad = NBPG - pad;
		addr += pad;
	}
	bootinfo.bi_symtab = addr-hmaddress+(startaddr & 0x00ffffffl);

	/********************************************************/
	/* Copy the symbol table size				*/
	/********************************************************/
	pm_copy((char *)&head.a_syms, addr, sizeof(head.a_syms));
	addr += sizeof(head.a_syms);

	/********************************************************/
	/* Load the symbol table				*/
	/********************************************************/
	printf("symbols=[+0x%lx+0x%lx+0x%lx", pad, (long) sizeof(head.a_syms),
	       (long) head.a_syms);
	xread(addr, head.a_syms);
	addr += head.a_syms;

	/********************************************************/
	/* Load the string table size				*/
	/********************************************************/
	ufs_read((void *)&i, sizeof(long));
	pm_copy((char *)&i, addr, sizeof(long));
	i -= sizeof(long);
	addr += sizeof(long);

	/********************************************************/
	/* Load the string table				*/
	/********************************************************/
	printf("+0x%x+0x%lx] ", sizeof(long), i);
	xread(addr, i);
	addr += i;

	bootinfo.bi_esymtab = addr-hmaddress+(startaddr & 0x00ffffffl);

	/*
	 * For backwards compatibility, use the previously-unused adaptor
	 * and controller bitfields to hold the slice number.
	 */
	printf("total=0x%lx entry point=0x%lx\n",
		addr-hmaddress+(startaddr & 0x00ffffffl),
		startaddr & 0x00ffffffl);

	return hmaddress;
}
Ejemplo n.º 27
0
/*
 * LoadForeign(ofiles,libs,proc_name,init_proc) dynamically loads foreign
 * code files and libraries and locates an initialization routine
*/
static Int
LoadForeign(StringList ofiles,
	    StringList libs,
	    char *proc_name,
	    YapInitProc *init_proc)
{
  char		  command[2*MAXPATHLEN];
  char            o_files[1024];    /* list of objects we want to load
				       */
  char            l_files[1024];    /* list of libraries we want to
				       load */ 
  char            tmp_buff[32] = "/tmp/YAP_TMP_XXXXXX";    /* used for
							 mktemp */
  char           *tfile;	    /* name of temporary file */
  int             fildes;	    /* temp file descriptor */
  struct aouthdr  sysHeader;
  struct filehdr  fileHeader;
  struct scnhdr   sectionHeader[MAXSECTIONS];
  struct exec     header;	    /* header for loaded file */
  unsigned long   loadImageSize, firstloadImSz;  /* size of image we will load */
  char           *FCodeBase;  /* where we load foreign code */

  /*
   * put in a string the names of the files you want to load and of any
   * libraries you want to use 
   */
  /* files first */
  *o_files = '\0';
  {
    StringList tmp = ofiles;

    while(tmp != NULL) {
      strcat(o_files," ");
      strcat(o_files,tmp->s);
      tmp = tmp->next;
    }
  }
  /* same_trick for libraries */
  *l_files = '\0';
  {
    StringList tmp = libs;

    while(tmp != NULL) {
      strcat(l_files," ");
      strcat(l_files,tmp->s);
      tmp = tmp->next;
    }
  }
  /* next, create a temp file to serve as loader output */
  tfile = mktemp(tmp_buff);

  /* prepare the magic */
  if (strlen(o_files) + strlen(l_files) + strlen(proc_name) +
	    strlen(YapExecutable) > 2*MAXPATHLEN) {
    strcpy(Yap_ErrorSay, " too many parameters in load_foreign/3 ");
    return LOAD_FAILLED;
  }
  sprintf(command, "/usr/bin/ld -N -A %s -o %s %s %s -lc",
	  YapExecutable,
	  tfile, o_files, l_files);
  /* now, do the magic */
  if (system(command) != 0) {
    unlink(tfile);
    strcpy(Yap_ErrorSay," ld returned error status in load_foreign_files ");
    return LOAD_FAILLED;
  }
  /* now check the music has played */
  if ((fildes = open(tfile, O_RDONLY)) < 0) {
    strcpy(Yap_ErrorSay," unable to open temp file in load_foreign_files ");
    return LOAD_FAILLED;
  }
  /* it did, get the mice */
  /* first, get the header */
  read(fildes, (char *) &fileHeader, sizeof(fileHeader));
  read(fildes, (char *) &sysHeader, sizeof(sysHeader));
  { int i;
    for (i = 0; i < fileHeader.f_nscns; i++)
      read(fildes, (char *) &sectionHeader[i],
	   sizeof(*sectionHeader));
  }
  close(fildes);
  /* get the full size of what we need to load */
  loadImageSize = sysHeader.tsize + sysHeader.dsize + sysHeader.bsize;
#ifdef mips
  /* add an extra page in mips machines */
  loadImageSize += 4095 + 16;
#else
  /* add 16 just to play it safe */
  loadImageSize += 16;
#endif
  /* keep this copy */
  firstloadImSz = loadImageSize;
  /* now fetch the space we need */
  if (!(FCodeBase = Yap_AllocCodeSpace((int) loadImageSize))
#ifdef pyr
      || activate_code(ForeignCodeBase, u1)
#endif				/* pyr */
      ) {
    strcpy(Yap_ErrorSay," unable to allocate space for external code ");
    return LOAD_FAILLED;
  }
#ifdef mips
  FCodeBase = (char *) (Unsigned(FCodeBase + PAGESIZE - 1) & ~(PAGESIZE - 1));
#endif

  /* now, a new incantation to load the new foreign code */
#ifdef convex
  /* No -N flag in the Convex loader */
  /* -T option does not want MallocBase bit set */
  sprintf(command, "ld -x -A %s -T %lx -o %s -u %s %s %s -lc",
	  ostabf,
	  ((unsigned long) (((unsigned long) (ForeignCodeBase)) &
			    ((unsigned long) (~Yap_HeapBase))
			    )
	   ), tfile, entry_point, o_files, l_files);
#else
#ifdef mips
  sprintf(command, "ld -systype bsd43 -N -A %s -T %lx -o %s -u %s %s %s -lc",
	  ostabf,
	  (unsigned long) ForeignCodeBase,
	  tfile, entry_point, o_files, l_files);
#else
  sprintf(command, "ld -N -A %s -T %lx -o %s -e %s -u _%s %s -lc",
	  ostabf,
	  (unsigned long) ForeignCodeBase,
	  tfile, entry_point, o_files, l_files);
#endif				/* mips */
#endif				/* convex */
  /* and do it */ 
  if (system(command) != 0) {
    unlink(tfile);
    strcpy(Yap_ErrorSay," ld returned error status in load_foreign_files ");
    return LOAD_FAILLED;
  }
  if ((fildes = open(tfile, O_RDONLY)) < 0) {
    strcpy(Yap_ErrorSay," unable to open temp file in load_foreign_files ");
    return LOAD_FAILLED;
  }
  read(fildes, (char *) &fileHeader, sizeof(fileHeader));
  read(fildes, (char *) &sysHeader, sizeof(sysHeader));
  {
    int i;
    for (i = 0; i < fileHeader.f_nscns; i++)
      read(fildes, (char *) &sectionHeader[i], sizeof(*sectionHeader));
  }
  loadImageSize = sysHeader.tsize + sysHeader.dsize + sysHeader.bsize;
  if (firstloadImSz < loadImageSize) {
    strcpy(Yap_ErrorSay," miscalculation in load_foreign/3 ");
    return LOAD_FAILLED;
  }
  /* now search for our init function */
  {
    char entry_fun[256];
    struct nlist    func_info[2];
#if defined(mips) || defined(I386)
    char            NAME1[128], NAME2[128];
    func_info[0].n_name = NAME1;
    func_info[1].n_name = NAME2;
#endif				/* COFF */
    sprintf(entry_fun, "_%s", proc_name);
    func_info[0].n_name = entry_fun;
    func_info[1].n_name = NULL;
    if (nlist(tfile, func_info) == -1) {
      strcpy(Yap_ErrorSay," in nlist(3) ");
      return LOAD_FAILLED;
    }
    if (func_info[0].n_type == 0) {
      strcpy(Yap_ErrorSay," in nlist(3) ");
      return LOAD_FAILLED;
    }
    *init_proc = (YapInitProc)(func_info[0].n_value);
  }
  /* ok, we got our init point */
  /* now read our text */
  lseek(fildes, (long)(N_TXTOFF(header)), 0);
  {
    unsigned int u1 = header.a_text + header.a_data;
    read(fildes, (char *) FCodeBase, u1);
    /* zero the BSS segment */
    while (u1 < loadImageSize)
      FCodeBase[u1++] = 0;
  }
  close(fildes);
  unlink(tfile);
  return LOAD_SUCCEEDED;
}
Ejemplo n.º 28
0
int
main (int argc, char *argv[])
{
    size_t nwritten, tocopy, n, mem_size, fil_size, pad = 0;
    int fd, ofd, i, j, verbose = 0, primary = 0;
    char buf[8192], *inname;
    struct exec * aout;		/* includes file & aout header */
    long offset;
#ifdef __ELF__
    struct elfhdr *elf;
    struct elf_phdr *elf_phdr;	/* program header */
    unsigned long long e_entry;
#endif

    prog_name = argv[0];

    for (i = 1; i < argc && argv[i][0] == '-'; ++i) {
	for (j = 1; argv[i][j]; ++j) {
	    switch (argv[i][j]) {
	      case 'v':
		  verbose = ~verbose;
		  break;

	      case 'b':
		  pad = BLOCK_SIZE;
		  break;

	      case 'p':
		  primary = 1;		/* make primary bootblock */
		  break;
	    }
	}
    }

    if (i >= argc) {
	usage();
    }
    inname = argv[i++];

    fd = open(inname, O_RDONLY);
    if (fd == -1) {
	perror("open");
	exit(1);
    }

    ofd = 1;
    if (i < argc) {
	ofd = open(argv[i++], O_WRONLY | O_CREAT | O_TRUNC, 0666);
	if (ofd == -1) {
	    perror("open");
	    exit(1);
	}
    }

    if (primary) {
	/* generate bootblock for primary loader */
	
	unsigned long bb[64], sum = 0;
	struct stat st;
	off_t size;
	int i;

	if (ofd == 1) {
	    usage();
	}

	if (fstat(fd, &st) == -1) {
	    perror("fstat");
	    exit(1);
	}

	size = (st.st_size + BLOCK_SIZE - 1) & ~(BLOCK_SIZE - 1);
	memset(bb, 0, sizeof(bb));
	strcpy((char *) bb, "Linux SRM bootblock");
	bb[60] = size / BLOCK_SIZE;	/* count */
	bb[61] = 1;			/* starting sector # */
	bb[62] = 0;			/* flags---must be 0 */
	for (i = 0; i < 63; ++i) {
	    sum += bb[i];
	}
	bb[63] = sum;
	if (write(ofd, bb, sizeof(bb)) != sizeof(bb)) {
	    perror("boot-block write");
	    exit(1);
	}
	printf("%lu\n", size);
	return 0;
    }

    /* read and inspect exec header: */

    if (read(fd, buf, sizeof(buf)) < 0) {
	perror("read");
	exit(1);
    }

#ifdef __ELF__
    elf = (struct elfhdr *) buf;

    if (elf->e_ident[0] == 0x7f && strncmp((char *)elf->e_ident + 1, "ELF", 3) == 0) {
	if (elf->e_type != ET_EXEC) {
	    fprintf(stderr, "%s: %s is not an ELF executable\n",
		    prog_name, inname);
	    exit(1);
	}
	if (!elf_check_arch(elf)) {
	    fprintf(stderr, "%s: is not for this processor (e_machine=%d)\n",
		    prog_name, elf->e_machine);
	    exit(1);
	}
	if (elf->e_phnum != 1) {
	    fprintf(stderr,
		    "%s: %d program headers (forgot to link with -N?)\n",
		    prog_name, elf->e_phnum);
	}

	e_entry = elf->e_entry;

	lseek(fd, elf->e_phoff, SEEK_SET);
	if (read(fd, buf, sizeof(*elf_phdr)) != sizeof(*elf_phdr)) {
	    perror("read");
	    exit(1);
	}

	elf_phdr = (struct elf_phdr *) buf;
	offset	 = elf_phdr->p_offset;
	mem_size = elf_phdr->p_memsz;
	fil_size = elf_phdr->p_filesz;

	/* work around ELF bug: */
	if (elf_phdr->p_vaddr < e_entry) {
	    unsigned long delta = e_entry - elf_phdr->p_vaddr;
	    offset   += delta;
	    mem_size -= delta;
	    fil_size -= delta;
	    elf_phdr->p_vaddr += delta;
	}

	if (verbose) {
	    fprintf(stderr, "%s: extracting %#016lx-%#016lx (at %lx)\n",
		    prog_name, (long) elf_phdr->p_vaddr,
		    elf_phdr->p_vaddr + fil_size, offset);
	}
    } else
#endif
    {
	aout = (struct exec *) buf;

	if (!(aout->fh.f_flags & COFF_F_EXEC)) {
	    fprintf(stderr, "%s: %s is not in executable format\n",
		    prog_name, inname);
	    exit(1);
	}

	if (aout->fh.f_opthdr != sizeof(aout->ah)) {
	    fprintf(stderr, "%s: %s has unexpected optional header size\n",
		    prog_name, inname);
	    exit(1);
	}

	if (N_MAGIC(*aout) != OMAGIC) {
	    fprintf(stderr, "%s: %s is not an OMAGIC file\n",
		    prog_name, inname);
	    exit(1);
	}
	offset = N_TXTOFF(*aout);
	fil_size = aout->ah.tsize + aout->ah.dsize;
	mem_size = fil_size + aout->ah.bsize;

	if (verbose) {
	    fprintf(stderr, "%s: extracting %#016lx-%#016lx (at %lx)\n",
		    prog_name, aout->ah.text_start,
		    aout->ah.text_start + fil_size, offset);
	}
    }

    if (lseek(fd, offset, SEEK_SET) != offset) {
	perror("lseek");
	exit(1);
    }

    if (verbose) {
	fprintf(stderr, "%s: copying %lu byte from %s\n",
		prog_name, (unsigned long) fil_size, inname);
    }

    tocopy = fil_size;
    while (tocopy > 0) {
	n = tocopy;
	if (n > sizeof(buf)) {
	    n = sizeof(buf);
	}
	tocopy -= n;
	if ((size_t) read(fd, buf, n) != n) {
	    perror("read");
	    exit(1);
	}
	do {
	    nwritten = write(ofd, buf, n);
	    if ((ssize_t) nwritten == -1) {
		perror("write");
		exit(1);
	    }
	    n -= nwritten;
	} while (n > 0);
    }

    if (pad) {
	mem_size = ((mem_size + pad - 1) / pad) * pad;
    }

    tocopy = mem_size - fil_size;
    if (tocopy > 0) {
	fprintf(stderr,
		"%s: zero-filling bss and aligning to %lu with %lu bytes\n",
		prog_name, pad, (unsigned long) tocopy);

	memset(buf, 0x00, sizeof(buf));
	do {
	    n = tocopy;
	    if (n > sizeof(buf)) {
		n = sizeof(buf);
	    }
	    nwritten = write(ofd, buf, n);
	    if ((ssize_t) nwritten == -1) {
		perror("write");
		exit(1);
	    }
	    tocopy -= nwritten;
	} while (tocopy > 0);
    }
    return 0;
}
Ejemplo n.º 29
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);
}
Ejemplo n.º 30
0
/* os_strings: List the strings of a binary and
 * check if the regex given is there.
 */
int os_string(char *file, char *regex)
{
    int ch, cnt;
    
    unsigned char *C;
    unsigned char *bfr;
 
    char line[OS_SIZE_1024 +1];
    char *buf;
    
    EXEC *head;

    os_strings oss;
   
    /* Return didn't match */
    if(!file || !regex)
    {
        return(0);
    }
    
    
    /* Allocating for the buffer */ 
    bfr = calloc(STR_MINLEN + 2, sizeof(char *));
    if (!bfr)
    {
        merror(MEM_ERROR, ARGV0);
        return(0);
    }

    /* Opening the file */
    oss.fp = fopen(file, "r");
    if(!oss.fp)
    {
        free(bfr);
        return(0);
    }

    /* cleaning the line */
    memset(line, '\0', OS_SIZE_1024 +1);
    
    /* starting .. (from old strings.c) */
    oss.foff = 0;
    oss.head_len = 0;
    
    oss.read_len = -1;
    head = (EXEC *)oss.hbfr;

    
    if ((oss.head_len = read(fileno(oss.fp), head, sizeof(EXEC))) == -1)
    {
        oss.head_len = 0;
        oss.read_len = -1;
    }
    else if (oss.head_len == sizeof(EXEC) && !N_BADMAG(*head)) 
    {
        oss.foff = N_TXTOFF(*head);
        if (fseek(stdin, oss.foff, SEEK_SET) == -1)
        {
            oss.read_len = -1;
        }
        else
        {
            #ifdef AIX
            oss.read_len = head->tsize + head->dsize;
            #else
            oss.read_len = head->a_text + head->a_data;
            #endif
        }

        oss.head_len = 0;
    }
    else
    {
        oss.hcnt = 0;
    }

    /* Read the file and perform the regex comparison */
    for (cnt = 0; (ch = os_getch(&oss)) != EOF;) 
    {
        if (ISSTR(ch)) 
        {
            if (!cnt)
                C = bfr;
            *C++ = ch;
            if (++cnt < STR_MINLEN)
                continue;
            
            strncpy(line, (char *)bfr, STR_MINLEN +1);
            buf = line;
            buf+=strlen(line);
            

            while ((ch = os_getch(&oss)) != EOF && ISSTR(ch))
            {
                if(cnt < OS_SIZE_1024)
                {
                    *buf = (char)ch;
                    buf++;
                }
                else
                {
                    *buf = '\0';
                    break;
                }
		cnt++;
            }

            *buf = '\0';

            if(OS_PRegex(line, regex))
            {
                if(oss.fp)
                    fclose(oss.fp);
                free(bfr);
                return(1);
            }
        }

        cnt = 0;
    }

    if(oss.fp)
        fclose(oss.fp);
    free(bfr);
    return(0);
}