Exemple #1
0
/*
 *	Write or sendto a socket. We don't yet handle message addresses
 *	sensible and that needs fixing
 */
arg_t net_write(struct socket * s, uint8_t flag)
{
	usize_t n = 0;
	uint8_t p = 0;
	struct sockdata *sd = s->s_priv;
	irqflags_t irq;
	uint8_t st;


	irq = di();
	while (1) {

		netstat = s->s_num;
		st = status(s);

		if (s->s_state == SS_CLOSED || (s->s_iflag & SI_SHUTW)) {
		        udata.u_error = EPIPE;
			break;
                }

		/* Error or EOF */
		if (st & 0xC0)
			break;

		/* Good status after a write means byte ok */
		n += p;
		if (n == udata.u_count) {
		        irqrestore(irq);
			return n;
                }
		/* Can we send more bytes ? */
		p = 0;

		if (st & 2) {
			/* Count bytes sent. The byte we just loaded isn't
			   sent until we check the status of it and it is
			   clean */
			p = 1;
			netdata = ugetc(udata.u_base++);
			continue;
		}
		s->s_iflag |= SI_THROTTLE;
		if (psleep_flags_io(&s->s_iflag, flag, &n)) {
                        irqrestore(irq);
			return n;
                }
                di();
	}
	/* It broke mummy ! */
        irqrestore(irq);
	if (n) {
	        s->s_error = udata.u_error;
	        udata.u_error = 0;
		return n;
        }
	err_xlate(s);
	if (udata.u_error == EPIPE)
		ssig(udata.u_ptab, SIGPIPE);
	return -1;
}
Exemple #2
0
int sock_write(inoptr ino, uint8_t flag)
{
	struct socket *s = &sockets[ino->c_node.i_nlink];
	int r;

	/* FIXME: IRQ protection */
	while(1) {
		if (s->s_state != SS_CONNECTED && s->s_state != SS_CLOSING) {
			/* FIXME: handle shutdown states properly */
			if (s->s_state >= SS_CLOSEWAIT) {
				ssig(udata.u_ptab, SIGPIPE);
				udata.u_error = EPIPE;
			} else
				udata.u_error = EINVAL;
			return -1;
		}
		switch(r = net_write(s, flag)) {
			case -2:
				s->s_iflag |= SI_THROTTLE;
				break;
			case -1:
				return -1;
			default:
				return r;
		}
		if (s->s_iflag == SI_THROTTLE &&
			psleep_flags(&s->s_iflag, flag) == -1)
				return -1;
	}
}
Exemple #3
0
void sgrpsig(uint16_t pgrp, uint16_t sig)
{
	ptptr p;
	for (p = ptab; p < ptab_end; ++p) {
		if (p->p_pgrp == pgrp)
			ssig(p, sig);
	}
}
Exemple #4
0
void timer_interrupt(void)
{
	/* Increment processes and global tick counters. We can't do this
	   mid swap because we might have half of the bits for one process
	   and half of another.. */
	if (!inswap && udata.u_ptab->p_status == P_RUNNING) {
		if (udata.u_insys)
			udata.u_stime++;
		else
			udata.u_utime++;
	}

	/* Do once-per-decisecond things - this doesn't work out well on
	   boxes with 64 ticks/second.. need a better approach */
	if (++ticks_this_dsecond == ticks_per_dsecond) {
		static ptptr p;

		/* Update global time counters */
		ticks_this_dsecond = 0;
		ticks.full++;

		/* Update process alarm clocks and timeouts */
		for (p = ptab; p < ptab_end; ++p) {
			if (p->p_alarm) {
				p->p_alarm--;
				if (!p->p_alarm)
					ssig(p, SIGALRM);
			}
			if (p->p_timeout > 1) {
				p->p_timeout--;
				if (p->p_timeout == 1)
					pwake(p);
			}
		}
		updatetod();
                load_average();
#ifdef CONFIG_AUDIO
		audio_tick();
#endif
	}
#ifndef CONFIG_SINGLETASK
	/* Check run time of current process. We don't charge time while
	   swapping as the last thing we want to do is to swap a process in
	   and decide it took time to swap in so needs to go away again! */
	/* FIXME: can we kill off inint ? */
	if (!inswap && (++runticks >= udata.u_ptab->p_priority)
	    && !udata.u_insys && inint && nready > 1) {
                 need_resched = 1;
#ifdef DEBUG_PREEMPT
		kprintf("[preempt %p %d]", udata.u_ptab,
		        udata.u_ptab->p_priority);
#endif
        }
#endif
}
Exemple #5
0
void timer_interrupt(void)
{
	/* Increment processes and global tick counters */
	if (udata.u_ptab->p_status == P_RUNNING) {
		if (udata.u_insys)
			udata.u_stime++;
		else
			udata.u_utime++;
	}

	/* Do once-per-decisecond things - this doesn't work out well on
	   boxes with 64 ticks/second.. need a better approach */
	if (++ticks_this_dsecond == ticks_per_dsecond) {
		static ptptr p;

		/* Update global time counters */
		ticks_this_dsecond = 0;
		ticks.full++;

		/* Update process alarm clocks and timeouts */
		for (p = ptab; p < ptab_end; ++p) {
			if (p->p_alarm) {
				p->p_alarm--;
				if (!p->p_alarm)
					ssig(p, SIGALRM);
			}
			if (p->p_timeout > 1) {
				p->p_timeout--;
				if (p->p_timeout == 1)
					pwake(p);
			}
		}
		updatetod();
                load_average();
#ifdef CONFIG_AUDIO
		audio_tick();
#endif
	}
#ifndef CONFIG_SINGLETASK
	/* Check run time of current process */
        /* Time to switch out? */
	if ((++runticks >= udata.u_ptab->p_priority)
	    && !udata.u_insys && inint && nready > 1) {
                 need_resched = 1;
#ifdef DEBUG_PREEMPT
		kprintf("[preempt %x %d %x]", udata.u_ptab,
		        udata.u_ptab->p_priority,
		        *((uint16_t *)0xEAFE));
#endif
        }
#endif
}
Exemple #6
0
/* Perform the terminal process signalling */
static int signal_parent(ptptr p)
{
        if (p->p_ignored & (1UL << SIGCHLD)) {
		/* POSIX.1 says that SIG_IGN for SIGCHLD means don't go
		   zombie, just clean up as we go */
		udata.u_ptab->p_status = P_EMPTY;
                return 0;
	}
	ssig(p, SIGCHLD);
	/* Wake up a waiting parent, if any. */
	wakeup((char *)p);
	udata.u_ptab->p_status = P_ZOMBIE;
	return 1;
}
static void
lmsr_adapt_i (LMSR lms)
{
  int i, j, k;
  REAL sum_sq, scl1, scl2;
  REAL accum, error;

  scl1 = (REAL) (1.0 - rate * leak);

  for (i = 0; i < ssiz; i++)
    {

      dlay (dptr) = ssig (i);
      accum = 0.0;
      sum_sq = 0.0;

      for (j = 0; j < asiz; j++)
		{
			k = wrap (j);
			sum_sq += sqr (dlay (k));
			accum += afil (j) * dlay (k);
		}

      error = ssig (i) - accum;
      ssig_i (i) = ssig (i) = error;

      scl2 = (REAL) (rate / (sum_sq + 1.19e-6));
      error *= scl2;
      for (j = 0; j < asiz; j++)
		{
			k = wrap (j);
			afil (j) = afil (j) * scl1 + error * dlay (k);
		}

      dptr = bump (dptr);
    }
}
Exemple #8
0
arg_t net_write(struct socket *s, uint8_t flag)
{
  uint16_t n = 0;

  used(s);
  used(flag);

  while(n < udata.u_count) {
    if (sockets[0].s_state == SS_CLOSED) {
      udata.u_error = EPIPE;
      ssig(udata.u_ptab, SIGPIPE);
      return -1;
    }
    /* FIXME - screen +++ handling ! */
    netat_outbyte(ugetc(udata.u_base++));
    n++;
  }
  return udata.u_count;
}
static void
lmsr_adapt_i (LMSR lms)
{
  int i, j, k;
  REAL sum_sq, scl1, scl2;
  COMPLEX accum, error;

  scl1 = (REAL) (1.0 - rate * leak);

  for (i = 0; i < ssiz; i++)
    {

      dlay (dptr) = CXBdata (lms->signal, i);
      accum = cxzero;
      sum_sq = 0;

      for (j = 0; j < asiz; j++)
		{
			k = wrap (j);
			sum_sq += Csqrmag (dlay (k));
			accum.re += afil (j).re * dlay (k).re;
			accum.im += afil (j).im * dlay (k).im;
		}

      error = Csub(cssig(i),accum);
      ssig_i (i) = error.im;
	  ssig (i) = error.re;

      scl2 = (REAL) (rate / (sum_sq + 1.19e-7));
      error = Cscl(error,scl2);
      for (j = 0; j < asiz; j++)
		{
			k = wrap (j);
			afil (j).re = afil (j).re * scl1 + error.re * dlay (k).re;
			afil (j).im = afil (j).im * scl1 + error.im * dlay (k).im;
		}

      dptr = bump (dptr);
    }
}
Exemple #10
0
arg_t _kill(void)
{
	ptptr p;
	int f = 0, s = 0;

	if (sig < 0 || sig >= NSIGS) {
		udata.u_error = EINVAL;
		return (-1);
	}

	if (pid == 0)
		udata.u_argn = -udata.u_ptab->p_pgrp;

	for (p = ptab; p < ptab_end; ++p) {
		/* No overlap here */
		if (-p->p_pgrp == pid || p->p_pid == pid) {
			f = 1;	/* Found */
			if (udata.u_ptab->p_uid == p->p_uid || super()) {
				if (sig)
					ssig(p, sig);
				s = 1;	/* Signalled */
				/* Only one match possible for a process */
				if (pid > 0)
					return 0;
			}
		}
	}
	if (s)
		return 0;
	/* Not found */
	udata.u_error = ESRCH;
	/* Found but none signalled */
	if (f)
		udata.u_error = EPERM;
	return (-1);
}
Exemple #11
0
/*FGROUP SSM_VME_Access ReadSSM
Analyze SSM memory - like AS python + check of serial versus TTC
*/
int analyze(){    
 int i,j,bit,word,ier;
 int first=1;
 /*         L0 L1s L2s AE  */
 char *SIGname[]={"ORB","PP ","L0 ","L1s","L1d","L2s","L2d","sBU","lBU","1FF","2FF","ChA","ChB","TBU","PPT","SST","STA","AER"};
 int NPR=6;
 char *PRINT[]={"PP ","L0 ","L1s","L2s","AER","LBH"};
 int COUNT[18]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  /* COUNT SSM signals */
 int COUNTe[18]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* COUNT errors */
 int COUNTl[18]={0,0,-DISTL0,-DISTL1,0,-DISTL2,0,0,0,0,0,0,0,0,0,0,0,0}; /* How close they can be ? */
 int COUNTa[18]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* Is signal active ? */
 int DIST[18]={0,0,DISTL0,DISTL1,0,DISTL2,0,0,0,0,0,0,0,0,0,0,1,0}; /* How close the signals can be ? */
 int L1DATA[NL1dat],L2DATA[NL2dat],TT[64];
 int iL1d=0,iL2d=0,ivmes=0,ichb=0,iorbi=0,ipp=0,ialls=0;
 int isdb=0,iltb=0,il1fi=0,il2fi=0,icha=0,ittcbusy=0,ippt=0;
 if(readFile()!=0) exit(9);
 dump=NULL;
 for(i=0;i<Mega;i++){
   word=SSMem[i];
   // start only after first L0
   //bit= ( (word & 4) == 4);
   //if(bit) first=0;
   //if(first) continue;
   for(j=0;j<18;j++){
    bit= ( (word & (1<<j)) == (1<<j));
    switch(j){
     case  0:    /* ORBIT   */
	   lsig(0,bit,i,COUNT,COUNTa,&iorbi,"ORBIT");  
           break;
     case  1:    /* PREPULSE    */
           lsig(1,bit,i,COUNT,COUNTa,&ipp," PP");
	   break;
     case  2:  /* L0 */
	   ssig(2,bit,i,COUNT,COUNTa,COUNTl,COUNTe,DIST,"L0");
           break;
     case  3:  /* L1s */  	   
	   asig(3,bit,i,COUNT,COUNTa,COUNTl,COUNTe,DIST,"L1S");
           break;
     case  4:   /* L1data */
	   ier=data(4,bit,i,COUNTa,L1DATA,NL1dat,&iL1d,"L1DATA");
           break;
     case  5:   /* L2 strobe */
           asig(5,bit,i,COUNT,COUNTa,COUNTl,COUNTe,DIST,"L2S");
	   break;
     case  6:   /* L2 data */
	   ier=data(6,bit,i,COUNTa,L2DATA,NL2dat,&iL2d,"L2DATA");
           break;
     case  7: /* Sub Detector Busy */
	   lsig(7,bit,i,COUNT,COUNTa,&isdb,"SBUSY");
           break;
     case  8: /* LTU BUSY */
	   lsig(8,bit,i,COUNT,COUNTa,&iltb,"ALLBUSY");
           break;
     case  9: /* L1 FIFO Nearly Full */
	   lsig(9,bit,i,COUNT,COUNTa,&il1fi,"L1NF");
           break;
     case 10: /* L2 FIFO Nearly Full */
	   lsig(10,bit,i,COUNT,COUNTa,&il2fi,"L2NF");
           break;
     case 11: /* Channel A (L0) */
	   lsig(11,bit,i,COUNT,COUNTa,&icha,"ChanA");
           break;
     case 12:    /*  Channel B */
           channelB(12,bit,i,COUNT,COUNTa,&ichb,TT,"ChanB");
           break;
     case 13:   /* TTC  BUSY */
           lsig(13,bit,i,COUNT,COUNTa,&ittcbusy,"TTCBUSY"); 
           break;
     case 14:          /* PP transmit */
           lsig(14,bit,i,COUNT,COUNTa,&ippt,"PPT"); 
           break;
     case 15:    /*  vme SLAVE strobe  */
	   lsig(15,bit,i,COUNT,COUNTa,&ivmes,"VMES");
           break;
     case 16:   /* START ALL - emulator */
	   lsig(16,bit,i,COUNT,COUNTa,&ialls,"ALLSTART");
	   break;
     case 17: /* ANY ERROR */
	   ssig(17,bit,i,COUNT,COUNTa,COUNTl,COUNTe,DIST,"ANYERR");
           break;
    }
   }
 }
 // to take into acount signals up in all memory
 lsig(1,0,Mega,COUNT,COUNTa,&ipp," PP");
 lsig(7,0,Mega,COUNT,COUNTa,&isdb,"SBUSY");
 lsig(8,0,Mega,COUNT,COUNTa,&iltb,"ALLBUSY");
 lsig(9,0,Mega,COUNT,COUNTa,&il1fi,"L1NF");
 lsig(10,0,Mega,COUNT,COUNTa,&il2fi,"L2NF");
 lsig(11,0,Mega,COUNT,COUNTa,&icha,"LBHALT");
 //lsig(12,0,Mega,COUNT,COUNTa,&ivmem,"VMEM");
 lsig(13,0,Mega,COUNT,COUNTa,&ittcbusy,"TTCBUSY"); 
 lsig(15,0,Mega,COUNT,COUNTa,&ivmes,"VMES");
 lsig(16,0,Mega,COUNT,COUNTa,&ialls,"ALLSTART");
 for(i=0;i<NPR;i++){
  for(j=0;j<18;j++)if(SIGname[j] == PRINT[i])
	  printf("<%s=%i> ",SIGname[j],COUNT[j]);
 }
 printf("\n");
 writeLog();
 return 0;
}
Exemple #12
0
arg_t _execve(void)
{
	/* We aren't re-entrant where this matters */
	uint8_t hdr[16];
	staticfast inoptr ino;
	char **nargv;		/* In user space */
	char **nenvp;		/* In user space */
	struct s_argblk *abuf, *ebuf;
	int argc;
	uint16_t progptr;
	uint16_t progload;
	staticfast uint16_t top;
	uint16_t bin_size;	/* Will need to be bigger on some cpus */
	uint16_t bss;

	top = ramtop;

	if (!(ino = n_open_lock(name, NULLINOPTR)))
		return (-1);

	if (!((getperm(ino) & OTH_EX) &&
	      (ino->c_node.i_mode & F_REG) &&
	      (ino->c_node.i_mode & (OWN_EX | OTH_EX | GRP_EX)))) {
		udata.u_error = EACCES;
		goto nogood;
	}

	setftime(ino, A_TIME);

	udata.u_offset = 0;
	udata.u_count = 16;
	udata.u_base = hdr;
	udata.u_sysio = true;

	readi(ino, 0);
	if (udata.u_done != 16) {
		udata.u_error = ENOEXEC;
		goto nogood;
	}

	if (!header_ok(hdr)) {
		udata.u_error = ENOEXEC;
		goto nogood2;
	}

	progload = hdr[7] << 8;
	if (progload == 0)
		progload = PROGLOAD;

	top = *(uint16_t *)(hdr + 8);
	if (top == 0)	/* Legacy 'all space' binary */
		top = ramtop;
	else	/* Requested an amount, so adjust for the base */
		top += progload;

	bss = *(uint16_t *)(hdr + 14);

	/* Binary doesn't fit */
	/* FIXME: review overflows */
	bin_size = ino->c_node.i_size;
	progptr = bin_size + 1024 + bss;
	if (progload < PROGLOAD || top - progload < progptr || progptr < bin_size) {
		udata.u_error = ENOMEM;
		goto nogood2;
	}

	udata.u_ptab->p_status = P_NOSLEEP;

	/* If we made pagemap_realloc keep hold of some defined area we
	   could in theory just move the arguments up or down as part of
	   the process - that would save us all this hassle but replace it
	   with new hassle */

	/* Gather the arguments, and put them in temporary buffers. */
	abuf = (struct s_argblk *) tmpbuf();
	/* Put environment in another buffer. */
	ebuf = (struct s_argblk *) tmpbuf();

	/* Read args and environment from process memory */
	if (rargs(argv, abuf) || rargs(envp, ebuf))
		goto nogood3;	/* SN */

	/* This must be the last test as it makes changes if it works */
	/* FIXME: once we sort out chmem we can make stack and data
	   two elements. We never allocate 'code' as there is no split I/D */
	/* This is only safe from deadlocks providing pagemap_realloc doesn't
	   sleep */
	if (pagemap_realloc(0, top - MAPBASE, 0))
		goto nogood3;

	/* From this point on we are commmited to the exec() completing */

	/* Core dump and ptrace permission logic */
#ifdef CONFIG_LEVEL_2
	/* Q: should uid == 0 mean we always allow core */
	if ((!(getperm(ino) & OTH_RD)) ||
		(ino->c_node.i_mode & (SET_UID | SET_GID)))
		udata.u_flags |= U_FLAG_NOCORE;
	else
		udata.u_flags &= ~U_FLAG_NOCORE;
#endif
	udata.u_top = top;
	udata.u_ptab->p_top = top;

	/* setuid, setgid if executable requires it */
	if (ino->c_node.i_mode & SET_UID)
		udata.u_euid = ino->c_node.i_uid;

	if (ino->c_node.i_mode & SET_GID)
		udata.u_egid = ino->c_node.i_gid;

	/* FIXME: In the execve case we may on some platforms have space
	   below PROGLOAD to clear... */

	/* We are definitely going to succeed with the exec,
	 * so we can start writing over the old program
	 */
	uput(hdr, (uint8_t *)progload, 16);
	/* At this point, we are committed to reading in and
	 * executing the program. This call must not block. */

	close_on_exec();

	/*
	 *  Read in the rest of the program, block by block. We rely upon
	 *  the optimization path in readi to spot this is a big move to user
	 *  space and move it directly.
	 */

	 progptr = progload + 16;
	 if (bin_size > 16) {
		bin_size -= 16;
		udata.u_base = (uint8_t *)progptr;		/* We copied the first block already */
		udata.u_count = bin_size;
		udata.u_sysio = false;
		readi(ino, 0);
		if (udata.u_done != bin_size)
			goto nogood4;
		progptr += bin_size;
	}
	/* Wipe the memory in the BSS. We don't wipe the memory above
	   that on 8bit boxes, but defer it to brk/sbrk() */
	uzero((uint8_t *)progptr, bss);

	/* Set initial break for program */
	udata.u_break = (int)ALIGNUP(progptr + bss);

	/* Turn off caught signals */
	memset(udata.u_sigvec, 0, sizeof(udata.u_sigvec));

	// place the arguments, environment and stack at the top of userspace memory,

	// Write back the arguments and the environment
	nargv = wargs(((char *) top - 2), abuf, &argc);
	nenvp = wargs((char *) (nargv), ebuf, NULL);

	// Fill in udata.u_name with program invocation name
	uget((void *) ugetw(nargv), udata.u_name, 8);
	memcpy(udata.u_ptab->p_name, udata.u_name, 8);

	tmpfree(abuf);
	tmpfree(ebuf);
	i_deref(ino);

	/* Shove argc and the address of argv just below envp
	   FIXME: should flip them in crt0.S of app for R2L setups
	   so we can get rid of the ifdefs */
#ifdef CONFIG_CALL_R2L	/* Arguments are stacked the 'wrong' way around */
	uputw((uint16_t) nargv, nenvp - 2);
	uputw((uint16_t) argc, nenvp - 1);
#else
	uputw((uint16_t) nargv, nenvp - 1);
	uputw((uint16_t) argc, nenvp - 2);
#endif

	/* Set stack pointer for the program */
	udata.u_isp = nenvp - 2;

	/* Start execution (never returns) */
	udata.u_ptab->p_status = P_RUNNING;
	doexec(progload);

	/* tidy up in various failure modes */
nogood4:
	/* Must not run userspace */
	ssig(udata.u_ptab, SIGKILL);
nogood3:
	udata.u_ptab->p_status = P_RUNNING;
	tmpfree(abuf);
	tmpfree(ebuf);
nogood2:
nogood:
	i_unlock_deref(ino);
	return (-1);
}
Exemple #13
0
void doexit(uint16_t val)
{
	int16_t j;
	ptptr p;
	irqflags_t irq;

#ifdef DEBUG
	kprintf("process %d exiting %d\n", udata.u_ptab->p_pid, val);

	kprintf
	    ("udata.u_page %u, udata.u_ptab %p, udata.u_ptab->p_page %u\n",
	     udata.u_page, udata.u_ptab, udata.u_ptab->p_page);
#endif
	if (udata.u_ptab->p_pid == 1)
		panic(PANIC_KILLED_INIT);

	sync();		/* Not necessary, but a good idea. */

	irq = di();

	/* We are exiting, hold all signals  (they will never be
	   delivered). If we don't do this we might take a signal
	   while exiting which would be ... unfortunate */
	udata.u_ptab->p_held = 0xFFFFFFFFUL;
	udata.u_cursig = 0;

	/* Discard our memory before we blow away and reuse the memory */
	pagemap_free(udata.u_ptab);

	for (j = 0; j < UFTSIZE; ++j) {
		if (udata.u_files[j] != NO_FILE)
			doclose(j);
	}


	udata.u_ptab->p_exitval = val;

	i_deref(udata.u_cwd);
	i_deref(udata.u_root);

	/* Stash away child's execution tick counts in process table,
	 * overlaying some no longer necessary stuff.
	 *
	 * Pedantically POSIX says we should do this at the point of wait()
	 */
	udata.u_utime += udata.u_cutime;
	udata.u_stime += udata.u_cstime;
	memcpy(&(udata.u_ptab->p_priority), &udata.u_utime,
	       2 * sizeof(clock_t));

	for (p = ptab; p < ptab_end; ++p) {
		if (p->p_status == P_EMPTY || p == udata.u_ptab)
			continue;
		/* Set any child's parents to init */
		if (p->p_pptr == udata.u_ptab) {
			p->p_pptr = ptab;	/* ptab is always init */
			/* Suppose our child is a zombie and init has
			   SIGCLD blocked */
		        if (ptab[0].p_ignored & (1UL << SIGCHLD)) {
				p->p_status = P_EMPTY;
			} else {
				ssig(&ptab[0], SIGCHLD);
				wakeup(&ptab[0]);
			}
		}
		/* Send SIGHUP to any pgrp members and remove
		   them from our pgrp */
                if (p->p_pgrp == udata.u_ptab->p_pid) {
			p->p_pgrp = 0;
			ssig(p, SIGHUP);
			ssig(p, SIGCONT);
		}
	}
	tty_exit();
	irqrestore(irq);
#ifdef DEBUG
	kprintf
	    ("udata.u_page %u, udata.u_ptab %p, udata.u_ptab->p_page %u\n",
	     udata.u_page, udata.u_ptab, udata.u_ptab->p_page);
#endif
#ifdef CONFIG_ACCT
	acctexit(p);
#endif
        udata.u_page = 0xFFFFU;
        udata.u_page2 = 0xFFFFU;
        signal_parent(udata.u_ptab->p_pptr);
	nready--;
	nproc--;

	switchin(getproc());
	panic(PANIC_DOEXIT);
}
Exemple #14
0
void doexit(int16_t val, int16_t val2)
{
	int16_t j;
	ptptr p;
	irqflags_t irq;

#ifdef DEBUG
	kprintf("process %d exiting\n", udata.u_ptab->p_pid);

	kprintf
	    ("udata.u_page %u, udata.u_ptab %x, udata.u_ptab->p_page %u\n",
	     udata.u_page, udata.u_ptab, udata.u_ptab->p_page);
#endif
	if (udata.u_ptab->p_pid == 1)
		panic("killed init");

	_sync();		/* Not necessary, but a good idea. */

	irq = di();

	/* Discard our memory before we blow away and reuse the memory */
	pagemap_free(udata.u_ptab);

	for (j = 0; j < UFTSIZE; ++j) {
		if (udata.u_files[j] != NO_FILE)
			doclose(j);
	}


	udata.u_ptab->p_exitval = (val << 8) | (val2 & 0xff);

	i_deref(udata.u_cwd);
	i_deref(udata.u_root);

	/* Stash away child's execution tick counts in process table,
	 * overlaying some no longer necessary stuff.
	 *
	 * Pedantically POSIX says we should do this at the point of wait()
	 */
	udata.u_utime += udata.u_cutime;
	udata.u_stime += udata.u_cstime;
	memcpy(&(udata.u_ptab->p_priority), &udata.u_utime,
	       2 * sizeof(clock_t));

	for (p = ptab; p < ptab_end; ++p) {
		if (p->p_status == P_EMPTY || p == udata.u_ptab)
			continue;
		/* Set any child's parents to our parent */
		if (p->p_pptr == udata.u_ptab)
			p->p_pptr = udata.u_ptab->p_pptr;
		/* Send SIGHUP to any pgrp members and remove
		   them from our pgrp */
                if (p->p_pgrp == udata.u_ptab->p_pid) {
			p->p_pgrp = 0;
			ssig(p, SIGHUP);
		}
	}
	tty_exit();
	irqrestore(irq);
#ifdef DEBUG
	kprintf
	    ("udata.u_page %u, udata.u_ptab %x, udata.u_ptab->p_page %u\n",
	     udata.u_page, udata.u_ptab, udata.u_ptab->p_page);
#endif
#ifdef CONFIG_ACCT
	acctexit(p);
#endif
        udata.u_page = 0xFFFFU;
        udata.u_page2 = 0xFFFFU;
	/* FIXME: send SIGCLD here */
	/* FIXME: POSIX.1 says that SIG_IGN for SIGCLD means don't go
	   zombie, just clean up as we go */
	/* Wake up a waiting parent, if any. */
	wakeup((char *) udata.u_ptab->p_pptr);

	udata.u_ptab->p_status = P_ZOMBIE;
	nready--;
	nproc--;

	switchin(getproc());
	panic("doexit: won't exit");
}
Exemple #15
0
arg_t _execve(void)
{
	/* Not ideal on stack */
	struct binfmt_flat binflat;
	inoptr ino;
	char **nargv;		/* In user space */
	char **nenvp;		/* In user space */
	struct s_argblk *abuf, *ebuf;
	int argc;
	uint32_t bin_size;	/* Will need to be bigger on some cpus */
	uaddr_t progbase, top;
	uaddr_t go;
	uint32_t true_brk;

	if (!(ino = n_open_lock(name, NULLINOPTR)))
		return (-1);

	if (!((getperm(ino) & OTH_EX) &&
	      (ino->c_node.i_mode & F_REG) &&
	      (ino->c_node.i_mode & (OWN_EX | OTH_EX | GRP_EX)))) {
		udata.u_error = EACCES;
		goto nogood;
	}

	setftime(ino, A_TIME);

	udata.u_offset = 0;
	udata.u_count = sizeof(struct binfmt_flat);
	udata.u_base = (void *)&binflat;
	udata.u_sysio = true;

	readi(ino, 0);
	if (udata.u_done != sizeof(struct binfmt_flat)) {
		udata.u_error = ENOEXEC;
		goto nogood;
	}

	/* FIXME: ugly - save this as valid_hdr modifies it */
	true_brk = binflat.bss_end;

	/* Hard coded for our 68K format. We don't quite use the ucLinux
	   names, we don't want to load a ucLinux binary in error! */
	if (memcmp(binflat.magic, "bFLT", 4) || !valid_hdr(ino, &binflat)) {
		udata.u_error = ENOEXEC;
		goto nogood2;
	}

	/* Memory needed */
	bin_size = binflat.bss_end + binflat.stack_size;

	/* Overflow ? */
	if (bin_size < binflat.bss_end) {
		udata.u_error = ENOEXEC;
		goto nogood2;
	}
	
	/* Gather the arguments, and put them in temporary buffers. */
	abuf = (struct s_argblk *) tmpbuf();
	/* Put environment in another buffer. */
	ebuf = (struct s_argblk *) tmpbuf();

	/* Read args and environment from process memory */
	if (rargs(argv, abuf) || rargs(envp, ebuf))
		goto nogood3;

	/* This must be the last test as it makes changes if it works */
	/* FIXME: need to update this to support split code/data and to fix
	   stack handling nicely */
	/* FIXME: ENOMEM fix needs to go to 16bit ? */
	if ((udata.u_error = pagemap_realloc(0, bin_size, 0)) != 0)
		goto nogood3;

	/* Core dump and ptrace permission logic */
#ifdef CONFIG_LEVEL_2
	/* Q: should uid == 0 mean we always allow core */
	if ((!(getperm(ino) & OTH_RD)) ||
		(ino->c_node.i_mode & (SET_UID | SET_GID)))
		udata.u_flags |= U_FLAG_NOCORE;
	else
		udata.u_flags &= ~U_FLAG_NOCORE;
#endif

	udata.u_codebase = progbase = pagemap_base();
	/* From this point on we are commmited to the exec() completing
	   so we can start writing over the old program */
	uput(&binflat, (uint8_t *)progbase, sizeof(struct binfmt_flat));

	/* setuid, setgid if executable requires it */
	if (ino->c_node.i_mode & SET_UID)
		udata.u_euid = ino->c_node.i_uid;

	if (ino->c_node.i_mode & SET_GID)
		udata.u_egid = ino->c_node.i_gid;

	top = progbase + bin_size;

	udata.u_top = top;
	udata.u_ptab->p_top = top;

//	kprintf("user space at %p\n", progbase);
//	kprintf("top at %p\n", progbase + bin_size);

	bin_size = binflat.reloc_start + 4 * binflat.reloc_count;
	go = (uint32_t)progbase + binflat.entry;

	close_on_exec();

	/*
	 *  Read in the rest of the program, block by block. We rely upon
	 *  the optimization path in readi to spot this is a big move to user
	 *  space and move it directly.
	 */

	 if (bin_size > sizeof(struct binfmt_flat)) {
		/* We copied the header already */
		bin_size -= sizeof(struct binfmt_flat);
		udata.u_base = (uint8_t *)progbase +
					sizeof(struct binfmt_flat);
		udata.u_count = bin_size;
		udata.u_sysio = false;
		readi(ino, 0);
		if (udata.u_done != bin_size)
			goto nogood4;
	}

	/* Header isn't counted in relocations */
	relocate(&binflat, progbase, bin_size);
	/* This may wipe the relocations */	
	uzero((uint8_t *)progbase + binflat.data_end,
		binflat.bss_end - binflat.data_end + binflat.stack_size);

	/* Use of brk eats into the stack allocation */

	/* Use the temporary we saved (hack) as we mangled bss_end */
	udata.u_break = udata.u_codebase + true_brk;

	/* Turn off caught signals */
	memset(udata.u_sigvec, 0, sizeof(udata.u_sigvec));

	/* place the arguments, environment and stack at the top of userspace memory. */

	/* Write back the arguments and the environment */
	nargv = wargs(((char *) top - 4), abuf, &argc);
	nenvp = wargs((char *) (nargv), ebuf, NULL);

	/* Fill in udata.u_name with Program invocation name */
	uget((void *) ugetl(nargv, NULL), udata.u_name, 8);
	memcpy(udata.u_ptab->p_name, udata.u_name, 8);

	tmpfree(abuf);
	tmpfree(ebuf);
	i_unlock_deref(ino);

	/* Shove argc and the address of argv just below envp */
	uputl((uint32_t) nargv, nenvp - 1);
	uputl((uint32_t) argc, nenvp - 2);

	// Set stack pointer for the program
	udata.u_isp = nenvp - 2;

	/*
	 * Sort of - it's a good way to deal with all the stupidity of
	 * random 68K platforms we will have to handle, and a nice place
	 * to stuff the signal trampoline 8)
	 */
	install_vdso();

//	kprintf("Go = %p ISP = %p\n", go, udata.u_isp);

	doexec(go);

nogood4:
	/* Must not run userspace */
	ssig(udata.u_ptab, SIGKILL);
nogood3:
	tmpfree(abuf);
	tmpfree(ebuf);
nogood2:
nogood:
	i_unlock_deref(ino);
	return (-1);
}
Exemple #16
0
void doexit(uint16_t val)
{
	int16_t j;
	ptptr p;
	irqflags_t irq;

#ifdef DEBUG
	kprintf("process %d exiting\n", udata.u_ptab->p_pid);

	kprintf
	    ("udata.u_page %u, udata.u_ptab %x, udata.u_ptab->p_page %u\n",
	     udata.u_page, udata.u_ptab, udata.u_ptab->p_page);
#endif
	if (udata.u_ptab->p_pid == 1)
		panic(PANIC_KILLED_INIT);

	sync();		/* Not necessary, but a good idea. */

	irq = di();

	/* Discard our memory before we blow away and reuse the memory */
	pagemap_free(udata.u_ptab);

	for (j = 0; j < UFTSIZE; ++j) {
		if (udata.u_files[j] != NO_FILE)
			doclose(j);
	}


	udata.u_ptab->p_exitval = val;

	i_deref(udata.u_cwd);
	i_deref(udata.u_root);

	/* Stash away child's execution tick counts in process table,
	 * overlaying some no longer necessary stuff.
	 *
	 * Pedantically POSIX says we should do this at the point of wait()
	 */
	udata.u_utime += udata.u_cutime;
	udata.u_stime += udata.u_cstime;
	memcpy(&(udata.u_ptab->p_priority), &udata.u_utime,
	       2 * sizeof(clock_t));

	for (p = ptab; p < ptab_end; ++p) {
		if (p->p_status == P_EMPTY || p == udata.u_ptab)
			continue;
		/* Set any child's parents to our parent */
		/* FIXME: do we need to wakeup the parent if we do this ? */
		if (p->p_pptr == udata.u_ptab)
			p->p_pptr = udata.u_ptab->p_pptr;
		/* Send SIGHUP to any pgrp members and remove
		   them from our pgrp */
                if (p->p_pgrp == udata.u_ptab->p_pid) {
			p->p_pgrp = 0;
			ssig(p, SIGHUP);
			ssig(p, SIGCONT);
		}
	}
	tty_exit();
	irqrestore(irq);
#ifdef DEBUG
	kprintf
	    ("udata.u_page %u, udata.u_ptab %x, udata.u_ptab->p_page %u\n",
	     udata.u_page, udata.u_ptab, udata.u_ptab->p_page);
#endif
#ifdef CONFIG_ACCT
	acctexit(p);
#endif
        udata.u_page = 0xFFFFU;
        udata.u_page2 = 0xFFFFU;
        signal_parent(udata.u_ptab->p_pptr);
	nready--;
	nproc--;

	switchin(getproc());
	panic(PANIC_DOEXIT);
}
Exemple #17
0
int exception(struct trapdata *framedata)
{
	ptptr proc;
	unsigned int frame, fsize;
	uint8_t trap = framedata->trap;
	unsigned int sig = 0;
	uint16_t m;
	uint16_t *sp = (uint16_t *)framedata;
	uint16_t *usp = get_usp();
	uint16_t *unwind, *context;
	uint8_t err = 0;
	int i;

	/* We translate debug to SIGIOT and A and F line to SIGILL
	   We will need to fix up 68000 v 68010 move to/from SR */
	static const uint8_t trap_to_sig[] = {
		0, 0, SIGSEGV, SIGBUS, SIGILL, SIGFPE,
		SIGABRT/*CHK*/, SIGTRAP/*TRAPV */,
		SIGILL, SIGIOT, SIGILL, SIGFPE };

	proc = udata.u_ptab;

	if (sysinfo.cpu[0] == 10) {
		/* Long or short frame: the CPU tells us the frame format */
		if (framedata->exception[3] & 0x8000) {
			fsize = 29;
			frame = FRAME_C;
		} else  {
			fsize = 4;
			frame = FRAME_D;
		}
	} else {
		frame = FRAME_B;
		fsize = 3;
	}
	if (trap == 0) {
		sig = udata.u_cursig;
		udata.u_cursig = 0;
	} else if (trap < 12) {
		if (trap < 4) {
			/* On a 68010 this frame is 29 words and the event is
			   restartable (although not always usefully). We need to
			   decide whether to set the restart flag case by case */
			if (sysinfo.cpu[0] == 0) {
				frame = FRAME_A;
				fsize = 7;
			}
		}
		sig = trap_to_sig[trap];
	} else if (trap >= 32 && trap < 48)
		sig = SIGTRAP;
	/* This processing only applies to synchronous hardware exceptions */
	if (trap) {
		/* Went boom in kernel space or without a user recovery */
		if (kernel_flag || sig == 0) {
			explode(framedata, frame);
			panic("trap");
		}

		/* Cheating here .. all our exceptions are low 16 signal */
		m = 1 << sig;
		/*
		 *	The caller is ignoring our signal. In some cases this is fine
		 *	but in others it's less clear (eg division by zero) and we
		 *	may need to take different action.
		 */
		if (proc->p_sig[0].s_ignored & m)
			return 0;
		/* Weird case - we took a sync signal and the caller wants us to
		   report it later. */
		if (proc->p_sig[0].s_held & m) {
			/* TODO: if it's not meaningfully restartable we should
			   probably treat this as a kill */
			ssig(proc, sig);
			return 0;
		}
		recalc_cursig();	/* Put any async signal back */
	}
	if (udata.u_sigvec[sig] == SIG_DFL) {
		/* Default action for our signal ? */
		doexit(dump_core(sig));
		/* This will never return. We will go schedule new work */
		panic("exret");
	}
	/* build signal frame

		Our unwinder code does
		move.l 8(sp),sp
		movem.l a0-a1/d0-d1,(sp)+
		move.w (sp)+,ccr
		rts */


	/* Now update the user stack */
	/* - Push the recovery PC */
	/* - Patch the kernel exception frame */
	if (sysinfo.cpu[0]) {
		/* FIXME */
		err |= pushw(&usp, sp[34]);
		err |= pushw(&usp, sp[33]);
		*(uint32_t *)(&sp[33]) = (uint32_t)udata.u_sigvec[sig];
	} else {
		err |= pushw(&usp, sp[31 + fsize]);
		err |= pushw(&usp, sp[30 + fsize]);
		*(uint32_t *)(&sp[30 + fsize]) = (uint32_t)udata.u_sigvec[sig];
	}

	/* FIXME: when we do ptrace we will need to support adding the T
	   flag back here as the exception cleared it */
	err |= pushw(&usp,  framedata->sr);
	/* Push A1 A0 D1 D0 to match MOVEM.L */
	err |= pushl(&usp, framedata->a[1]);
	err |= pushl(&usp, framedata->a[0]);
	err |= pushl(&usp, framedata->d[1]);
	err |= pushl(&usp, framedata->d[0]);

	/* Remember the target for undoing the frame */
	unwind = usp;

	/* Copy in the signal context itself. 30 words of registers, 2 of
	   trap code and then the hardware exception */
	for (i = 0; i < 30 + 2 + fsize; i++)
		err |= pushw(&usp, *sp++);
	context = usp;
	err |= pushl(&usp, (uint32_t)unwind);
	/* Signal context is a secret extra non portable argument */
	err |= pushl(&usp, (uint32_t)context);
	/* We end it with the call frame as seen from the signal handler, a
	   single argument and a return address */
	err |= pushl(&usp, sig);
	err |= pushl(&usp, udata.u_codebase + 0x04);

	set_usp(usp);

	if (err) {
		doexit(dump_core(SIGSTKFLT));
		panic("exret2");
	}
	/* Once built clear the restart state */
	udata.u_sigvec[sig] = SIG_DFL;
	/* Return, RTE and end up on the signal frame */
	return 1;
}