Esempio n. 1
0
// Reload info from EEPROM
static void eeprom_reload(struct dm9000 *p)
{
    putreg(p, DM_EPCR, EPCR_REEP);
    while (getreg(p, DM_EPCR) & EPCR_ERRE)
	;
    CYGACC_CALL_IF_DELAY_US(200);
    putreg(p, DM_EPCR, 0);
}
Esempio n. 2
0
// Read a word from PHY
static cyg_uint16 phy_read(struct dm9000 *p, int offset)
{
    putreg(p, DM_EPAR, 0x40 + offset);
    putreg(p, DM_EPCR, EPCR_EPOS | EPCR_ERPRR);
    CYGACC_CALL_IF_DELAY_US(200);
    putreg(p, DM_EPCR, 0);
    return getreg(p, DM_EPDRL) | (getreg(p, DM_EPDRH) << 8);
}
Esempio n. 3
0
// Write a word to PHY
static void phy_write(struct dm9000 *p, int offset, cyg_uint16 val)
{
    putreg(p, DM_EPAR, 0x40 + offset);
    putreg(p, DM_EPDRL, val);
    putreg(p, DM_EPDRH, val >> 8);
    putreg(p, DM_EPCR, EPCR_EPOS | EPCR_ERPRW);
    CYGACC_CALL_IF_DELAY_US(500);
    putreg(p, DM_EPCR, 0);
}
Esempio n. 4
0
static void init_phy(struct dm9000 *p)
{
    phy_write(p, 4, 0x1e1); // Advertise 10/100 half/full duplex w/CSMA
    phy_write(p, 0, 0x1200); // enable autoneg

    // release reset
    putreg(p, DM_GPCR, 1);
    putreg(p, DM_GPR, 0);  
}
Esempio n. 5
0
// Read a word from EEPROM
static cyg_uint16 eeprom_read(struct dm9000 *p, int offset)
{
    putreg(p, DM_EPAR, offset);
    putreg(p, DM_EPCR, EPCR_ERPRR);
    while (getreg(p, DM_EPCR) & EPCR_ERRE)
	;
    CYGACC_CALL_IF_DELAY_US(200);
    putreg(p, DM_EPCR, 0);
    return getreg(p, DM_EPDRL) | (getreg(p, DM_EPDRH) << 8);
}
Esempio n. 6
0
// Write a word to EEPROM
static void eeprom_write(struct dm9000 *p, int offset, cyg_uint16 val)
{
    putreg(p, DM_EPAR, offset);
    putreg(p, DM_EPDRH, val >> 8);
    putreg(p, DM_EPDRL, val);
    putreg(p, DM_EPCR, EPCR_WEP | EPCR_ERPRW);
    while (getreg(p, DM_EPCR) & EPCR_ERRE)
	;
    CYGACC_CALL_IF_DELAY_US(200);
    putreg(p, DM_EPCR, 0);
}
Esempio n. 7
0
// ------------------------------------------------------------------------
//
//  API Function : dm9000_start
//
// ------------------------------------------------------------------------
static void 
dm9000_start( struct eth_drv_sc *sc, unsigned char *enaddr, int flags )
{
    struct dm9000 *priv = (struct dm9000 *)sc->driver_private;

    // turn on receiver
    putreg(priv, DM_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);

    // unmask interrupt
    putreg(priv, DM_IMR, IMR_PAR | IMR_PTM | IMR_PRM);

    priv->active = 1;
}
Esempio n. 8
0
// ------------------------------------------------------------------------
//
//  API Function : dm9000_stop
//
// ------------------------------------------------------------------------
static void
dm9000_stop( struct eth_drv_sc *sc )
{
    struct dm9000 *priv = (struct dm9000 *)sc->driver_private;

    // turn on receiver
    putreg(priv, DM_RCR, 0);

    // mask interrupts
    putreg(priv, DM_IMR, IMR_PAR);

    priv->active = 0;
}
Esempio n. 9
0
void scc8530_t::write_reg(int offset, UINT8 data)
{
    //offset & 3;

//  printf(" mode %d data %x offset %d  \n", mode, data, offset);

    //Chan *pChan;
    switch(offset)
    {
    case 0: /* Channel B (Printer Port) Control */
    case 1: /* Channel A (Modem Port) Control */
    {
        int chan = ((offset == 0) ? 1 : 0);
        if (mode == 0)
        {
            if((data & 0xf0) == 0)  // not a reset command
            {
                mode = 1;
                reg = data & 0x0f;
//                  putbreg(data & 0xf0);
            }
            else if (data == 0x10)
            {
                // clear ext. interrupts
                channel[chan].extIRQPending = 0;
                channel[chan].baudIRQPending = 0;
                updateirqs();
            }
        }
        else
        {
            mode = 0;
            putreg(chan, data);
        }
        break;
    }

    case 2: /* Channel B (Printer Port) Data */
    case 3: /* Channel A (Modem Port) Data */
    {
        int chan = ((offset == 2) ? 1 : 0);
        if (channel[chan].txEnable)
        {
            channel[chan].txData = data;
            // local loopback?
            if (channel[chan].reg_val[14] & 0x10)
            {
                channel[chan].rxData = data;
                channel[chan].reg_val[0] |= 0x01;  // Rx character available
            }
            channel[chan].reg_val[1] |= 0x01;  // All sent
            channel[chan].reg_val[0] |= 0x04;  // Tx empty
            channel[chan].txUnderrun = 1;
            channel[chan].txIRQPending = 1;
            updateirqs();
        }
        break;
    }
    }
}
Esempio n. 10
0
static void ralloc(Node p) {
	int i;
	unsigned mask[2];

	mask[0] = tmask[0];
	mask[1] = tmask[1];
	assert(p);
	debug(fprint(stderr, "(rallocing %x)\n", p));
	for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) {
		Node kid = p->x.kids[i];
		Symbol r = kid->syms[RX];
		assert(r && kid->x.registered);
		if (r->sclass != REGISTER && r->x.lastuse == kid)
			putreg(r);
	}
	if (!p->x.registered && NeedsReg[opindex(p->op)]
	&& (*IR->x.rmap)(opkind(p->op))) {
		Symbol sym = p->syms[RX], set = sym;
		assert(sym);
		if (sym->temporary)
			set = (*IR->x.rmap)(opkind(p->op));
		assert(set);
		if (set->sclass != REGISTER) {
			Symbol r;
			if (*IR->x._templates[getrule(p, p->x.inst)] == '?')
				for (i = 1; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) {
					Symbol r = p->x.kids[i]->syms[RX];
					assert(p->x.kids[i]->x.registered);
					assert(r && r->x.regnode);
					assert(sym->x.wildcard || sym != r);
					mask[r->x.regnode->set] &= ~r->x.regnode->mask;
				}
			r = getreg(set, mask, p);
			if (sym->temporary) {
				Node q;
				r->x.lastuse = sym->x.lastuse;
				for (q = sym->x.lastuse; q; q = q->x.prevuse) {
					q->syms[RX] = r;
					q->x.registered = 1;
					if (sym->u.t.cse && q->x.copy)
						q->x.equatable = 1;
				}
			} else {
				p->syms[RX] = r;
				r->x.lastuse = p;
			}
			debug(dumpregs("(allocating %s to node %x)\n", r->x.name, (char *) p));
		}
	}
	p->x.registered = 1;
	(*IR->x.clobber)(p);
}
Esempio n. 11
0
static __asm __inline ULONG SWMethod(METHODFNPROTO)
{
   SW_IDATA *idata = INST_DATA(cl, o);

   putreg(REG_A6, (long)cl->cl_UserData);
   geta4();

   switch (msg->MethodID) {
      SW_DO_MF(SWM_RegCheck);
      SW_DO_MF(SWM_RegisterUI);
      SW_DO_MF(SWM_Reg_Banner);
   }

   return (ULONG)DoSuperMethodA(cl, o, msg);
}
Esempio n. 12
0
int
Reg(int argc,char *argv[])
{
    ulong   reg;
    int     opt, i, forscript;
    char    *varname, buf[32];

    forscript = 0;
    varname = (char *)0;
    while((opt=getopt(argc,argv,"sv:")) != -1) {
        switch(opt) {
        case 's':
            forscript = 1;
            break;
        case 'v':
            varname = optarg;
            break;
        default:
            return(CMD_PARAM_ERROR);
        }
    }

    if(argc == optind) {
        if(forscript) {
            for(i=0; i<REGTOT; i++) {
                printf("reg %s 0x%lx\n",regnames[i],regtbl[i]);
            }
        } else {
            showregs();
        }
        return(CMD_SUCCESS);
    } else if(argc == optind + 1) {
        if(getreg(argv[optind],&reg) != -1) {
            sprintf(buf,"0x%lx",reg);
            if(varname) {
                setenv(varname,buf);
            } else {
                printf("%s = %s\n",argv[optind],buf);
            }
        }
    } else if(argc == optind + 2) {
        putreg(argv[1],strtol(argv[optind+1],(char **)0,0));
    } else {
        return(CMD_PARAM_ERROR);
    }
    return(CMD_SUCCESS);
}
Esempio n. 13
0
Node gen(Node forest) {
	int i;
	struct node sentinel;
	Node dummy, p;

	head = forest;
	for (p = forest; p; p = p->link) {
		assert(p->count == 0);
		if (generic(p->op) == CALL)
			docall(p);
		else if (   generic(p->op) == ASGN
		&& generic(p->kids[1]->op) == CALL)
			docall(p->kids[1]);
		else if (generic(p->op) == ARG)
			(*IR->x.doarg)(p);
		rewrite(p);
		p->x.listed = 1;
	}
	for (p = forest; p; p = p->link)
		prune(p, &dummy);
	relink(&sentinel, &sentinel);
	for (p = forest; p; p = p->link)
		linearize(p, &sentinel);
	forest = sentinel.x.next;
	assert(forest);
	sentinel.x.next->x.prev = NULL;
	sentinel.x.prev->x.next = NULL;
	for (p = forest; p; p = p->x.next)
		for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) {
			assert(p->x.kids[i]->syms[RX]);
			if (p->x.kids[i]->syms[RX]->temporary) {
				p->x.kids[i]->x.prevuse =
					p->x.kids[i]->syms[RX]->x.lastuse;
				p->x.kids[i]->syms[RX]->x.lastuse = p->x.kids[i];
			}
		}
	for (p = forest; p; p = p->x.next) {
		ralloc(p);
		if (p->x.listed && NeedsReg[opindex(p->op)]
		&& (*IR->x.rmap)(opkind(p->op))) {
			assert(generic(p->op) == CALL || generic(p->op) == LOAD);
			putreg(p->syms[RX]);
		}
	}
	return forest;
}
Esempio n. 14
0
static void spillr(Symbol r, Node here) {
	int i;
	Symbol tmp;
	Node p = r->x.lastuse;
	assert(p);
	while (p->x.prevuse)
		assert(r == p->syms[RX]),
		p = p->x.prevuse;
	assert(p->x.registered && !readsreg(p));
	tmp = newtemp(AUTO, optype(p->op), opsize(p->op));
	genspill(r, p, tmp);
	for (p = here->x.next; p; p = p->x.next)
		for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) {
			Node k = p->x.kids[i];
			if (k->x.registered && k->syms[RX] == r)
				genreload(p, tmp, i);
		}
	putreg(r);
}
Esempio n. 15
0
/* gdb_P():
 * Store to a register.
 */
int
gdb_P(char *line)
{
	char *lp;
	int rnum;
	ulong rval;

	line++;
	rnum = strtol(line,&lp,16);
	if (rnum >= REGTBL_SIZE) {
		gdb_err(GDBERR_RNUMOOR);	
		return(-1);
	}
	lp++;
	rval = strtol(lp,0,16);
	self_ecl(rval);
	putreg(gdb_regtbl[rnum],rval);

	gdb_ok();
	return(0);
}
Esempio n. 16
0
// ------------------------------------------------------------------------
//
//  API Function : dm9000_send
//
// ------------------------------------------------------------------------
static void 
dm9000_send(struct eth_drv_sc *sc,
	    struct eth_drv_sg *sg_list, int sg_len,
	    int total_len, unsigned long key)
{
    struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
    struct eth_drv_sg *sg = sg_list;
    cyg_uint8 tmpbuf[4];
    int i, len, extra, n, save_len;
    char *p;

    if (0) {
	diag_printf("dm9000_send: NCR[%02x] NSR[%02x] TPL[%02x]\n",
		    getreg(priv, DM_NCR), getreg(priv, DM_NSR),
		    getreg(priv, DM_TRPAL) | (getreg(priv, DM_TRPAH) << 8)
	    );
    }

    priv->txbusy = 1;

    save_len = total_len;
    extra = 0;

    HAL_WRITE_UINT8(priv->io_addr, DM_MWCMD);

    while (total_len > 0) {
	len = sg->len;
	if (len > total_len)
	    len = total_len;
	p = (char *)sg->buf;

	if (extra) {
	    n = sizeof(tmpbuf) - extra;
	    memcpy(tmpbuf + extra, p, n);
	    p += n;
	    len -= n;
	    for (i = 0; i < sizeof(tmpbuf) && total_len > 0; i += n) {
		n = priv->write_data(priv, tmpbuf + i);
		total_len -= n;
	    }
	    extra = 0;
	}
	
	while (len >= sizeof(tmpbuf) && total_len > 0) {
	    n = priv->write_data(priv, p);
	    len -= n;
	    total_len -= n;
	    p += n;
	}

	if (len > 0 && total_len > 0) {
	    extra = len;
	    memcpy(tmpbuf, p, extra);

	    if ((total_len - extra) <= 0) {
		// go ahead and write it now
		for (i = 0; total_len > 0; i += n, total_len -= n) {
		    n = priv->write_data(priv, tmpbuf + i);
		    total_len = 0;
		}
		break;
	    }
	}
	sg++;
    }

    priv->txkey = key;

    putreg(priv, DM_TXPLL, save_len);
    putreg(priv, DM_TXPLH, save_len >> 8);

    putreg(priv, DM_TCR, TCR_TXREQ);

    return;
}
Esempio n. 17
0
// Progress window task
void __saveds progress_task(void)
{
	IPCData *ipc;
	ProgressWindow *prog;
	IPCMessage *msg;

	// Do startup
	if (!(ipc=L_IPC_ProcStartup((ULONG *)&prog,0)))
		return;

	// Fix A4 pointer
	putreg(REG_A4,prog->pw_A4);

/*
	// Debug?
	if (prog->pw_Flags&PWF_DEBUG)
		KPrintF("progress task : code entry %lx\n",(ULONG)progress_task);
*/

	// Open invisibly?
	if (prog->pw_Flags&PWF_INVISIBLE) prog->pw_Flags&=~PWF_INVISIBLE;

	// Open progress window
	else progress_open(prog);

	// Loop for messages
	FOREVER
	{
		BOOL quit=0;

		// Window open?
		if (prog->pw_Window)
		{
			struct IntuiMessage *msg;

			// Look for messages
			while (msg=(struct IntuiMessage *)GetMsg(prog->pw_Window->UserPort))
			{
				// Look at message
				switch (msg->Class)
				{
					// Key press
					case IDCMP_RAWKEY:

						// If not escape, break
						if (msg->Code!=0x45) break;

					// Abort
					case IDCMP_CLOSEWINDOW:
					case IDCMP_GADGETUP:

						// Task to signal?
						if (prog->pw_SigTask) Signal(prog->pw_SigTask,1<<prog->pw_SigBit);

						// Set flag
						prog->pw_Flags|=PWF_ABORTED;
						break;


					// Refresh
					case IDCMP_REFRESHWINDOW:

						// Refresh window
						BeginRefresh(prog->pw_Window);
						progress_draw(prog,PWF_ALL);
						EndRefresh(prog->pw_Window,TRUE);
						break;
				}

				// Reply the message
				ReplyMsg((struct Message *)msg);
			}
		}

		// Any messages?
		while (msg=(IPCMessage *)GetMsg(ipc->command_port))
		{
			// Look at message
			switch (msg->command)
			{
				// Hide
				case IPC_HIDE:
					progress_close(prog);
					break;


				// Show
				case IPC_SHOW:
					progress_open(prog);
					break;


				// Quit
				case IPC_QUIT:
					quit=1;
					break;


				// Set parameters
				case PROGRESS_SET:
					progress_set(prog,(struct TagItem *)msg->data);
					break;


				// Get parameters
				case PROGRESS_GET:
					progress_get(prog,(struct TagItem *)msg->data);
					break;
			}

			// Reply to the message
			IPC_Reply(msg);
		}

		// Quit?
		if (quit) break;

		// Wait for messages
		Wait(	1<<ipc->command_port->mp_SigBit|
				((prog->pw_Window)?1<<prog->pw_Window->UserPort->mp_SigBit:0));
	}

	// Close window
	progress_close(prog);

	// Free IPC data
	IPC_Free(ipc);

	// Free control structure
	FreeVec(prog);
}
Esempio n. 18
0
static int initialize_nic(struct dm9000 *priv)
{
    int i;

    dm9000_reset(priv);

    switch (getreg(priv, DM_ISR) >> 6) {
    case 0:
	priv->read_data = read_data_16;
	priv->write_data = write_data_16;
	priv->buswidth = 2;
	break;
    case 1:
	priv->read_data = read_data_32;
	priv->write_data = write_data_32;
	priv->buswidth = 4;
	break;
    case 2:
	priv->read_data = read_data_8;
	priv->write_data = write_data_8;
	priv->buswidth = 1;
	break;
    default:
	diag_printf("Unknown DM9000 bus i/f.\n");
	return 0;
    }

    init_phy(priv);

    putreg(priv, DM_TCR, 0);
    putreg(priv, DM_BPTR, 0x3f);
    putreg(priv, DM_FCTR, 0x38);
    putreg(priv, DM_FCR, 0xff);
    putreg(priv, DM_SMCR, 0);
    putreg(priv, DM_NSR, NSR_WAKEST | NSR_TX1END | NSR_TX2END);
    putreg(priv, DM_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);
    
    // set MAC address
    for (i = 0; i < 6; i++)
	putreg(priv, DM_PAR + i, priv->mac_address[i]);

    // clear multicast table except for broadcast address
    for (i = 0; i < 6; i++)
	putreg(priv, DM_MAR + i, 0x00);
    putreg(priv, DM_MAR + 6, 0x00);
    putreg(priv, DM_MAR + 7, 0x80);

    return 1;
}
Esempio n. 19
0
static inline void dm9000_reset(struct dm9000 *p)
{
    putreg(p, DM_NCR, NCR_RST);
    CYGACC_CALL_IF_DELAY_US(100);
}
Esempio n. 20
0
ULONG __asm string_edit_hook(
	register __a0 HookData *hook,
	register __a1 ULONG *msg,
	register __a2 struct SGWork *work)
{
	ULONG ret=1;
	short buffer_pos;
	BOOL signal=0;

	// Cache buffer position
	buffer_pos=work->StringInfo->BufferPos;

	// Fix registers
	putreg(REG_A4,hook->a4);
	putreg(REG_A6,hook->a6);

	// Key press?
	while (*msg==SGH_KEY)
	{
		// If this is a hotkey field, we grab stuff UNLESS capslock is down or return pressed
		if (hook->flags&OBJECTF_HOTKEY &&
			!(work->IEvent->ie_Qualifier&IEQUALIFIER_CAPSLOCK) &&
			work->IEvent->ie_Code!=0x44)
		{
			// Ignore key up and repeats
			if (!(work->IEvent->ie_Code&IECODE_UP_PREFIX) &&
				!(work->IEvent->ie_Qualifier&IEQUALIFIER_REPEAT))
			{
				// Ignore qualifier keys
				if (work->IEvent->ie_Code!=0x63 &&
					work->IEvent->ie_Code!=0x60 &&
					work->IEvent->ie_Code!=0x64 &&
					work->IEvent->ie_Code!=0x66 &&
					work->IEvent->ie_Code!=0x67 &&
					work->IEvent->ie_Code!=0x65 &&
					work->IEvent->ie_Code!=0x61)
				{
					// Convert string
					L_IPC_Command(
						launcher_ipc,
						STRING_CONVERT_KEY,
						(work->IEvent->ie_Code<<16)|work->IEvent->ie_Qualifier,
						work->WorkBuffer,
						0,
						REPLY_NO_PORT_IPC);

					// Same as last time?
					if (strcmp(work->WorkBuffer,work->PrevBuffer)==0)
					{
						// Was this backspace or delete?
						if (work->IEvent->ie_Code==0x41 ||
							work->IEvent->ie_Code==0x46)
						{
							// Clear buffer
							*work->WorkBuffer=0;
						}
					}

					// Fix settings
					work->NumChars=strlen(work->WorkBuffer);
					work->BufferPos=strlen(work->WorkBuffer);
					work->Actions|=SGA_REDISPLAY;

					// Set flag to signal
					signal=1;
					break;
				}
			}

			// Don't use
			work->Actions&=~SGA_USE;
			break;
		}

		// Hotkey field with capslock?
		if (hook->flags&OBJECTF_HOTKEY)
		{
			char *ptr;

			// Old character position
			ptr=work->WorkBuffer+work->StringInfo->BufferPos;

			// Change to lowercase
			if (*ptr>='A' && *ptr<='Z')
				*ptr+=('a'-'A');
		}

		// Uppercase string
		else
		if (hook->flags&OBJECTF_UPPERCASE)
		{
			char *ptr;

			// Old character position
			ptr=work->WorkBuffer+work->StringInfo->BufferPos;

			// Change to uppercase
			if (*ptr>='a' && *ptr<='z')
				*ptr-=('a'-'A');
		}

		// What happened?
		switch (work->EditOp)
		{
			// Return pressed?
			case EO_ENTER:

				// Shift pressed?
				if (work->IEvent->ie_Qualifier&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
				{
					// Activate previous gadget
					work->Actions&=~SGA_USE;
					work->Actions|=SGA_END|SGA_PREVACTIVE;
				}

				// Otherwise
				else
				{
					// Deactivate
					work->Actions&=~SGA_USE;
					work->Actions|=SGA_END;

					// Not read only?
					if (!(hook->flags&OBJECTF_READ_ONLY))
					{
						// Want next gadget?
						if (!(hook->flags&OBJECTF_NO_SELECT_NEXT))
						{
							struct Gadget *gadget;

							// Don't want to wrap around, so see if there are any others
							for (gadget=work->Gadget->NextGadget;gadget;gadget=gadget->NextGadget)
							{
								// Not disabled?
								if (!(gadget->Flags&GFLG_DISABLED))
								{
									// Tab cycle set?
									if (gadget->Flags&GFLG_TABCYCLE)
									{
										// Activate next gadget
										work->Actions|=SGA_NEXTACTIVE;
										break;
									}
								}
							}
						}
					}
				}
				break;


			// Clear/undo
			case EO_CLEAR:
			case EO_UNDO:

				// Read-only?
				if (hook->flags&OBJECTF_READ_ONLY)
					work->Actions&=~SGA_USE;

				// Set flag for signal
				else signal=1;
				break;


			// Real character typed
			case EO_INSERTCHAR:
			case EO_REPLACECHAR:

				// Right-Amiga held down?
				if (work->IEvent->ie_Qualifier&IEQUALIFIER_RCOMMAND)
				{
					// What key was pressed?
					switch (work->Code)
					{
						// Copy to clipboard
						case 'c':
						case 'C':
							{
								ClipData data;

								// Secure field?
								if (hook->flags&OBJECTF_SECURE)
								{
									short len;

									// Get maximum length of string, and string pointer
									len=work->StringInfo->MaxChars>>1;
									data.string=work->PrevBuffer+len;
								}

								// Normal field
								else data.string=work->PrevBuffer;

								// Get length
								data.length=work->StringInfo->NumChars;

								// Clip string
								L_IPC_Command(launcher_ipc,CLIP_PUTSTRING,0,&data,0,REPLY_NO_PORT_IPC);

								// Don't use
								work->Actions&=~SGA_USE;
							}
							break;


						// Paste from clipboard
						case 'v':
						case 'V':

							// Not read only?
							if (!(hook->flags&OBJECTF_READ_ONLY))
							{
								ClipData data;
								char *buffer=0;

								// Fill out packet
								data.string=work->WorkBuffer;
								data.length=work->StringInfo->MaxChars;

								// Try to allocate buffer for insert
								if (work->Code=='V' &&
									(buffer=AllocVec((work->StringInfo->MaxChars+1)*2,MEMF_CLEAR)))
								{
									// Fill out packet
									data.string=buffer;
								}

								// Paste string
								L_IPC_Command(launcher_ipc,CLIP_GETSTRING,0,&data,0,REPLY_NO_PORT_IPC);

								// Got a valid string?
								if (data.result)
								{
									char *ptr;

									// Integer?
									if (hook->flags&OBJECTF_INTEGER)
									{
										// Go through string, strip after a non-digit
										for (ptr=data.string;*ptr;ptr++)
										{
											// Not a digit?
											if ((*ptr<'0' || *ptr>'9') &&
												*ptr!='-' &&
												*ptr!='+')
											{
												// Strip from here
												*ptr=0;
												break;
											}
										}
									}

									// Path filter?
									if (hook->flags&OBJECTF_PATH_FILTER)
									{
										// Go through string, strip after a path character
										for (ptr=data.string;*ptr;ptr++)
										{
											// Path character?
											if (*ptr=='/' || *ptr==':')
											{
												// Strip from here
												*ptr=0;
												break;
											}
										}
									}

									// Insert?
									if (buffer)
									{
										char *temp;
										short a,len;

										// Get temp buffer pointer
										temp=buffer+work->StringInfo->MaxChars+1;

										// Copy head of old string
										stccpy(temp,work->StringInfo->Buffer,work->StringInfo->BufferPos+1);

										// Tack on insertion string
										a=work->StringInfo->MaxChars-work->StringInfo->NumChars;
										if ((len=strlen(buffer))>a) len=a;
										if (len>0) stccpy(temp+strlen(temp),buffer,len+1);

										// Tack on end of old string
										strcat(temp,work->StringInfo->Buffer+work->StringInfo->BufferPos);

										// Copy new string to work buffer
										strcpy(work->WorkBuffer,temp);
									}

									// Fix length
									work->NumChars=strlen(work->WorkBuffer);
									work->BufferPos=(buffer)?work->StringInfo->BufferPos+strlen(buffer):work->NumChars;
									work->Actions|=SGA_REDISPLAY;

									// Set flag to signal
									signal=1;

									// Secure field?
									if (hook->flags&OBJECTF_SECURE)
									{
										short len;

										// Get maximum length of string, and string pointer
										len=work->StringInfo->MaxChars>>1;
										ptr=work->PrevBuffer+len;

										// Copy string to real buffer
										strcpy(ptr,work->WorkBuffer);

										// Replace work buffer with asterisks
										for (len=work->NumChars-1;len>=0;len--)
											work->WorkBuffer[len]='*';
									}
								}
								else
								{
Esempio n. 21
0
/*
 * Main loop for command mode command decoding.
 * A few commands are executed here, but main function
 * is to strip command addresses, do a little address oriented
 * processing and call command routines to do the real work.
 */
void
commands(bool noprompt, bool exitoneof)
{
	register line *addr;
	register int c;
	register int lchng;
	int given;
	int seensemi;
	int cnt;
	bool hadpr;

	resetflav();
	nochng();
	for (;;) {
		/*
		 * If dot at last command
		 * ended up at zero, advance to one if there is a such.
		 */
		if (dot <= zero) {
			dot = zero;
			if (dol > zero)
				dot = one;
		}
		shudclob = 0;

		/*
		 * If autoprint or trailing print flags,
		 * print the line at the specified offset
		 * before the next command.
		 */
		if (pflag ||
		    (lchng != chng && value(AUTOPRINT) && !inglobal && !inopen && endline)) {
			pflag = 0;
			nochng();
			if (dol != zero) {
				addr1 = addr2 = dot + poffset;
				if (addr1 < one || addr1 > dol)
error("Offset out-of-bounds|Offset after command too large");
				setdot1();
				goto print;
			}
		}
		nochng();

		/*
		 * Print prompt if appropriate.
		 * If not in global flush output first to prevent
		 * going into pfast mode unreasonably.
		 */
		if (inglobal == 0) {
			flush();
			if (!hush && value(PROMPT) && !globp && !noprompt && endline) {
				ex_putchar(':');
				hadpr = 1;
			}
			TSYNC();
		}

		/*
		 * Gobble up the address.
		 * Degenerate addresses yield ".".
		 */
		addr2 = 0;
		given = seensemi = 0;
		do {
			addr1 = addr2;
			addr = address(0);
			c = getcd();
			if (addr == 0) {
				if (c == ',')
					addr = dot;
				else if (addr1 != 0) {
					addr2 = dot;
					break;
				} else
					break;
			}
			addr2 = addr;
			given++;
			if (c == ';') {
				c = ',';
				dot = addr;
				seensemi = 1;
			}
		} while (c == ',');
		if (c == '%') {
			/* %: same as 1,$ */
			addr1 = one;
			addr2 = dol;
			given = 2;
			c = ex_getchar();
		}
		if (addr1 == 0)
			addr1 = addr2;
		if (c == ':')
			c = ex_getchar();

		/*
		 * Set command name for special character commands.
		 */
		tailspec(c);

		/*
		 * If called via : escape from open or visual, limit
		 * the set of available commands here to save work below.
		 */
		if (inopen) {
			if (c=='\n' || c=='\r' || c==CTRL('d') || c==EOF) {
				if (addr2)
					dot = addr2;
				if (c == EOF)
					return;
				continue;
			}
			if (any(c, "o"))
notinvis:
				tailprim(Command, 1, 1);
		}
		switch (c) {

		case 'a':

			switch(peekchar()) {
			case 'b':
/* abbreviate */
				tail("abbreviate");
				setnoaddr();
				mapcmd(0, 1);
				anyabbrs = 1;
				continue;
			case 'r':
/* args */
				tail("args");
				setnoaddr();
				eol();
				pargs();
				continue;
			}

/* append */
			if (inopen)
				goto notinvis;
			tail("append");
			setdot();
			aiflag = exclam();
			ex_newline();
			vmacchng(0);
			deletenone();
			setin(addr2);
			inappend = 1;
			ignore(append(gettty, addr2));
			inappend = 0;
			nochng();
			continue;

		case 'c':
			switch (peekchar()) {

/* copy */
			case 'o':
				tail("copy");
				vmacchng(0);
				move();
				continue;

#ifdef CHDIR
/* cd */
			case 'd':
				tail("cd");
				goto changdir;

/* chdir */
			case 'h':
				ignchar();
				if (peekchar() == 'd') {
					register char *p;
					tail2of("chdir");
changdir:
					if (savedfile[0] == '/' || !value(WARN))
						ignore(exclam());
					else
						ignore(quickly());
					if (skipend()) {
						p = getenv("HOME");
						if (p == NULL)
							error("Home directory unknown");
					} else
						getone(), p = file;
					eol();
					if (chdir(p) < 0)
						filioerr(p);
					if (savedfile[0] != '/')
						edited = 0;
					continue;
				}
				if (inopen)
					tailprim("change", 2, 1);
				tail2of("change");
				break;

#endif
			default:
				if (inopen)
					goto notinvis;
				tail("change");
				break;
			}
/* change */
			aiflag = exclam();
			setCNL();
			vmacchng(0);
			setin(addr1);
			delete(0);
			inappend = 1;
			ignore(append(gettty, addr1 - 1));
			inappend = 0;
			nochng();
			continue;

/* delete */
		case 'd':
			/*
			 * Caution: dp and dl have special meaning already.
			 */
			tail("delete");
			c = cmdreg();
			setCNL();
			vmacchng(0);
			if (c)
				YANKreg(c);
			delete(0);
			appendnone();
			continue;

/* edit */
/* ex */
		case 'e':
			tail(peekchar() == 'x' ? "ex" : "edit");
editcmd:
			if (!exclam() && chng)
				c = 'E';
			filename(c);
			if (c == 'E') {
				ungetchar(lastchar());
				ignore(quickly());
			}
			setnoaddr();
doecmd:
			init();
			addr2 = zero;
			laste++;
			ex_sync();
			rop(c);
			nochng();
			continue;

/* file */
		case 'f':
			tail("file");
			setnoaddr();
			filename(c);
			noonl();
/*
			synctmp();
*/
			continue;

/* global */
		case 'g':
			tail("global");
			global(!exclam());
			nochng();
			continue;

/* insert */
		case 'i':
			if (inopen)
				goto notinvis;
			tail("insert");
			setdot();
			nonzero();
			aiflag = exclam();
			ex_newline();
			vmacchng(0);
			deletenone();
			setin(addr2);
			inappend = 1;
			ignore(append(gettty, addr2 - 1));
			inappend = 0;
			if (dot == zero && dol > zero)
				dot = one;
			nochng();
			continue;

/* join */
		case 'j':
			tail("join");
			c = exclam();
			setcount();
			nonzero();
			ex_newline();
			vmacchng(0);
			if (given < 2 && addr2 != dol)
				addr2++;
			join(c);
			continue;

/* k */
		case 'k':
casek:
			pastwh();
			c = ex_getchar();
			if (endcmd(c))
				serror("Mark what?|%s requires following letter", Command);
			ex_newline();
			if (!islower(c))
				error("Bad mark|Mark must specify a letter");
			setdot();
			nonzero();
			names[c - 'a'] = *addr2 &~ 01;
			anymarks = 1;
			continue;

/* list */
		case 'l':
			tail("list");
			setCNL();
			ignorf(setlist(1));
			pflag = 0;
			goto print;

		case 'm':
			if (peekchar() == 'a') {
				ignchar();
				if (peekchar() == 'p') {
/* map */
					tail2of("map");
					setnoaddr();
					mapcmd(0, 0);
					continue;
				}
/* mark */
				tail2of("mark");
				goto casek;
			}
/* move */
			tail("move");
			vmacchng(0);
			move();
			continue;

		case 'n':
			if (peekchar() == 'u') {
				tail("number");
				goto numberit;
			}
/* next */
			tail("next");
			setnoaddr();
			ckaw();
			ignore(quickly());
			if (getargs())
				makargs();
			next();
			c = 'e';
			filename(c);
			goto doecmd;

/* open */
		case 'o':
			tail("open");
			oop();
			pflag = 0;
			nochng();
			continue;

		case 'p':
		case 'P':
			switch (peekchar()) {

/* put */
			case 'u':
				tail("put");
				setdot();
				c = cmdreg();
				eol();
				vmacchng(0);
				if (c)
					putreg(c);
				else
					put();
				continue;

			case 'r':
				ignchar();
				if (peekchar() == 'e') {
/* preserve */
					tail2of("preserve");
					eol();
					if (preserve() == 0)
						error("Preserve failed!");
					else
						error("File preserved.");
				}
				tail2of("print");
				break;

			default:
				tail("print");
				break;
			}
/* print */
			setCNL();
			pflag = 0;
print:
			nonzero();
			if (CL && span() > EX_LINES) {
				flush1();
				vclear();
			}
			plines(addr1, addr2, 1);
			continue;

/* quit */
		case 'q':
			tail("quit");
			setnoaddr();
			c = quickly();
			eol();
			if (!c)
quit:
				nomore();
			if (inopen) {
				vgoto(WECHO, 0);
				if (!ateopr())
					vnfl();
				else {
					tostop();
				}
				flush();
				setty(normf);
			}
			cleanup(1);
			ex_exit(0);

		case 'r':
			if (peekchar() == 'e') {
				ignchar();
				switch (peekchar()) {

/* rewind */
				case 'w':
					tail2of("rewind");
					setnoaddr();
					if (!exclam()) {
						ckaw();
						if (chng && dol > zero)
							error("No write@since last chage (:rewind! overrides)");
					}
					eol();
					erewind();
					next();
					c = 'e';
					ungetchar(lastchar());
					filename(c);
					goto doecmd;

/* recover */
				case 'c':
					tail2of("recover");
					setnoaddr();
					c = 'e';
					if (!exclam() && chng)
						c = 'E';
					filename(c);
					if (c == 'E') {
						ungetchar(lastchar());
						ignore(quickly());
					}
					init();
					addr2 = zero;
					laste++;
					ex_sync();
					recover();
					rop2();
					revocer();
					if (status == 0)
						rop3(c);
					if (dol != zero)
						change();
					nochng();
					continue;
				}
				tail2of("read");
			} else
				tail("read");
/* read */
			if (savedfile[0] == 0 && dol == zero)
				c = 'e';
			pastwh();
			vmacchng(0);
			if (peekchar() == '!') {
				setdot();
				ignchar();
				unix0(0);
				filter(0);
				continue;
			}
			filename(c);
			rop(c);
			nochng();
			if (inopen && endline && addr1 > zero && addr1 < dol)
				dot = addr1 + 1;
			continue;

		case 's':
			switch (peekchar()) {
			/*
			 * Caution: 2nd char cannot be c, g, or r
			 * because these have meaning to substitute.
			 */

/* set */
			case 'e':
				tail("set");
				setnoaddr();
				set();
				continue;

/* shell */
			case 'h':
				tail("shell");
				setNAEOL();
				vnfl();
				putpad(TE);
				flush();
				unixwt(1, unixex("-i", (char *) 0, 0, 0));
				vcontin(0);
				continue;

/* source */
			case 'o':
#ifdef notdef
				if (inopen)
					goto notinvis;
#endif
				tail("source");
				setnoaddr();
				getone();
				eol();
				source(file, 0);
				continue;
#ifdef SIGTSTP
/* stop, suspend */
			case 't':
				tail("stop");
				goto suspend;
			case 'u':
				tail("suspend");
suspend:
				if (!dosusp)
					error("Old tty driver|Not using new tty driver/shell");
				c = exclam();
				eol();
				if (!c)
					ckaw();
				onsusp(0);
				continue;
#endif

			}
			/* fall into ... */

/* & */
/* ~ */
/* substitute */
		case '&':
		case '~':
			Command = "substitute";
			if (c == 's')
				tail(Command);
			vmacchng(0);
			if (!substitute(c))
				pflag = 0;
			continue;

/* t */
		case 't':
			if (peekchar() == 'a') {
				tail("tag");
				tagfind(exclam());
				if (!inopen)
					lchng = chng - 1;
				else
					nochng();
				continue;
			}
			tail("t");
			vmacchng(0);
			move();
			continue;

		case 'u':
			if (peekchar() == 'n') {
				ignchar();
				switch(peekchar()) {
/* unmap */
				case 'm':
					tail2of("unmap");
					setnoaddr();
					mapcmd(1, 0);
					continue;
/* unabbreviate */
				case 'a':
					tail2of("unabbreviate");
					setnoaddr();
					mapcmd(1, 1);
					anyabbrs = 1;
					continue;
				}
/* undo */
				tail2of("undo");
			} else
				tail("undo");
			setnoaddr();
			markDOT();
			c = exclam();
			ex_newline();
			undo(c);
			continue;

		case 'v':
			switch (peekchar()) {

			case 'e':
/* version */
				tail("version");
				setNAEOL();
				ex_printf("@(#) Version 3.6, 11/3/80"
				    " (4.0BSD).  git "
				    "160803 14:24"
				    +5);
				noonl();
				continue;

/* visual */
			case 'i':
				tail("visual");
				if (inopen) {
					c = 'e';
					goto editcmd;
				}
				vop();
				pflag = 0;
				nochng();
				continue;
			}
/* v */
			tail("v");
			global(0);
			nochng();
			continue;

/* write */
		case 'w':
			c = peekchar();
			tail(c == 'q' ? "wq" : "write");
wq:
			if (skipwh() && peekchar() == '!') {
				pofix();
				ignchar();
				setall();
				unix0(0);
				filter(1);
			} else {
				setall();
				wop(1);
				nochng();
			}
			if (c == 'q')
				goto quit;
			continue;

/* xit */
		case 'x':
			tail("xit");
			if (!chng)
				goto quit;
			c = 'q';
			goto wq;

/* yank */
		case 'y':
			tail("yank");
			c = cmdreg();
			setcount();
			eol();
			vmacchng(0);
			if (c)
				YANKreg(c);
			else
				yank();
			continue;

/* z */
		case 'z':
			zop(0);
			pflag = 0;
			continue;

/* * */
/* @ */
		case '*':
		case '@':
			c = ex_getchar();
			if (c=='\n' || c=='\r')
				ungetchar(c);
			if (any(c, "@*\n\r"))
				c = lastmac;
			if (isupper(c))
				c = tolower(c);
			if (!islower(c))
				error("Bad register");
			ex_newline();
			setdot();
			cmdmac(c);
			continue;

/* | */
		case '|':
			endline = 0;
			goto caseline;

/* \n */
		case '\n':
			endline = 1;
caseline:
			notempty();
			if (addr2 == 0) {
				if (UP != NOSTR && c == '\n' && !inglobal)
					c = CTRL('k');
				if (inglobal)
					addr1 = addr2 = dot;
				else {
					if (dot == dol)
						error("At EOF|At end-of-file");
					addr1 = addr2 = dot + 1;
				}
			}
			setdot();
			nonzero();
			if (seensemi)
				addr1 = addr2;
			ex_getline(*addr1);
			if (c == CTRL('k')) {
				flush1();
				destline--;
				if (hadpr)
					shudclob = 1;
			}
			plines(addr1, addr2, 1);
			continue;

/* " */
		case '"':
			comment();
			continue;

/* # */
		case '#':
numberit:
			setCNL();
			ignorf(setnumb(1));
			pflag = 0;
			goto print;

/* = */
		case '=':
			ex_newline();
			setall();
			if (inglobal == 2)
				pofix();
			ex_printf("%d", lineno(addr2));
			noonl();
			continue;

/* ! */
		case '!':
			if (addr2 != 0) {
				vmacchng(0);
				unix0(0);
				setdot();
				filter(2);
			} else {
				unix0(1);
				pofix();
				putpad(TE);
				flush();
				unixwt(1, unixex("-c", uxb, 0, 0));
				vclrech(1);	/* vcontin(0); */
				nochng();
			}
			continue;

/* < */
/* > */
		case '<':
		case '>':
			for (cnt = 1; peekchar() == c; cnt++)
				ignchar();
			setCNL();
			vmacchng(0);
			shift(c, cnt);
			continue;

/* ^D */
/* EOF */
		case CTRL('d'):
		case EOF:
			if (exitoneof) {
				if (addr2 != 0)
					dot = addr2;
				return;
			}
			if (!isatty(0)) {
				if (intty)
					/*
					 * Chtty sys call at UCB may cause a
					 * input which was a tty to suddenly be
					 * turned into /dev/null.
					 */
					onhup(0);
				return;
			}
			if (addr2 != 0) {
				setlastchar('\n');
				putnl();
			}
			if (dol == zero) {
				if (addr2 == 0)
					putnl();
				notempty();
			}
			ungetchar(EOF);
			zop(hadpr);
			continue;

		default:
			if (!isalpha(c))
				break;
			ungetchar(c);
			tailprim("", 0, 0);
		}
		ierror("What?|Unknown command character '%c'", c);
	}
}
Esempio n. 22
0
long arch_ptrace(struct task_struct *child, long request,
		 unsigned long addr, unsigned long data)
{
	int i, ret;
	unsigned long __user *p = (void __user *)data;
	void __user *vp = p;

	switch (request) {
	/* read the word at location addr in the USER area. */
	case PTRACE_PEEKUSR:
		ret = peek_user(child, addr, data);
		break;

	/* write the word at location addr in the USER area */
	case PTRACE_POKEUSR:
		ret = poke_user(child, addr, data);
		break;

	case PTRACE_SYSEMU:
	case PTRACE_SYSEMU_SINGLESTEP:
		ret = -EIO;
		break;

#ifdef PTRACE_GETREGS
	case PTRACE_GETREGS: { /* Get all gp regs from the child. */
		if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) {
			ret = -EIO;
			break;
		}
		for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
			__put_user(getreg(child, i), p);
			p++;
		}
		ret = 0;
		break;
	}
#endif
#ifdef PTRACE_SETREGS
	case PTRACE_SETREGS: { /* Set all gp regs in the child. */
		unsigned long tmp = 0;
		if (!access_ok(VERIFY_READ, p, MAX_REG_OFFSET)) {
			ret = -EIO;
			break;
		}
		for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
			__get_user(tmp, p);
			putreg(child, i, tmp);
			p++;
		}
		ret = 0;
		break;
	}
#endif
	case PTRACE_GET_THREAD_AREA:
		ret = ptrace_get_thread_area(child, addr, vp);
		break;

	case PTRACE_SET_THREAD_AREA:
		ret = ptrace_set_thread_area(child, addr, vp);
		break;

	default:
		ret = ptrace_request(child, request, addr, data);
		if (ret == -EIO)
			ret = subarch_ptrace(child, request, addr, data);
		break;
	}

	return ret;
}
Esempio n. 23
0
__asm ULONG ObjStringDispatcher(a0 struct IClass *cl, a2 Object *o, a1 Msg msg)
{
    TagItem    *ti;
    struct ObjStringData *idata = INST_DATA(cl, o);

    putreg(REG_A6, (long)cl->cl_UserData);
    geta4();

    switch (msg->MethodID) {
    case OM_NEW: {
        Object *obj = (Object*)DoSuperMethodA(cl, o, msg);
        if (obj) {
            idata = INST_DATA(cl, obj);
            if (ti = FindTagItem(SWA_ObjString_StrAttr, ((opSet *)msg)->ops_AttrList))
                idata->StrAttr = ti->ti_Data;
            SetAttrs(obj, MUIA_Draggable,          TRUE,
                     MUIA_CycleChain,         1,
                     MUIA_String_AdvanceOnCR, TRUE, TAG_DONE);
        }
        return (ULONG)obj;
    }

    case OM_GET: {
        if (((struct opGet *)msg)->opg_AttrID == SWA_ObjString_NumVal) {
            ULONG *Store = ((struct opGet *)msg)->opg_Storage;

            if (Store) *Store = SWGetUL(o, MUIA_String_Integer);

            return 1;
        }

        break;
    }

    case OM_SET:
    case OM_UPDATE: {
        ULONG rc;

        if (ti=FindTagItem(MUIA_String_Contents,((opSet *)msg)->ops_AttrList)) {
            rc = DoSuperMethodA(cl, o, msg);
            set(o, SWA_ObjString_NumVal, SWGetUL(o, MUIA_String_Integer));
            return rc;
        }


        if (ti=FindTagItem(SWA_ObjString_NumVal,((opSet *)msg)->ops_AttrList)) {
            if (idata->LastVal == ti->ti_Data) {
                ti->ti_Tag = TAG_IGNORE;
                rc = DoSuperMethodA(cl, o, msg);
                ti->ti_Tag = SWA_ObjString_NumVal;
                return rc;
            }

            SetSuperAttrs(cl, o,
                          MUIA_NoNotify,       TRUE,
                          MUIA_String_Integer, idata->LastVal = ti->ti_Data,
                          TAG_DONE);
        }
    }

    break;

    case MUIM_DragQuery: {
        Object *drag_o = ((struct MUIP_DragQuery *)msg)->obj;
        if (drag_o == o)                        return MUIV_DragQuery_Refuse;
        if (OCLASS(drag_o) == OCLASS(o)) {
            UBYTE *s1, *s2;
            get(drag_o, MUIA_String_Accept, &s1);
            get(o,      MUIA_String_Accept, &s2);
            if (!s1 && !s2) return MUIV_DragQuery_Accept;
            if (!s1 || !s2) return MUIV_DragQuery_Refuse;
            return (ULONG)(!strcmp(s1, s2) ? MUIV_DragQuery_Accept
                           : MUIV_DragQuery_Refuse);
        }

        if (OCLASS(drag_o) == SWObjListClass()) SWDB_RET(MUIV_DragQuery_Accept);

        if (!idata->StrAttr)                    return MUIV_DragQuery_Refuse;

        if (!(drag_o = (Object *)DoMethod(drag_o, SWM_Root_GetDragObj)))
            return MUIV_DragQuery_Refuse;

        return (ULONG)(get(drag_o, idata->StrAttr, NULL)
                       ? MUIV_DragQuery_Accept : MUIV_DragQuery_Refuse);
    }

    case MUIM_DragDrop: {
        Object *drag_o = ((struct MUIP_DragQuery *)msg)->obj;
        if (OCLASS(drag_o) == OCLASS(o)) {
            set(o, MUIA_String_Contents, SWGetUL(drag_o, MUIA_String_Contents));
            set(o, SWA_ObjString_NumVal, SWGetUL(o,      MUIA_String_Integer));
            return 0;
        }

        // -- if objlist, append its primary attribute -----------------------

        if (OCLASS(drag_o) == SWObjListClass()) {
            UBYTE *c, *val;
            get(o, MUIA_String_Contents, &c);

            val = (UBYTE *)DoMethod((Object *)muiUserData(drag_o),
                                    SWM_E_Listmgr_StrCopy, c);

            if (val && c) {
                set(o,  MUIA_String_Contents, val);
                FreeVec(val);
                return 0;
            }
        }

        if (!(drag_o = (Object *)DoMethod(drag_o, SWM_Root_GetDragObj)))
            return MUIV_DragQuery_Refuse;

        set(o, MUIA_String_Contents, SWGetStr(drag_o, idata->StrAttr));
        return 0;
    }

    case SWM_ObjString_AppMsg: {
        UBYTE FSpec[FMSIZE];
        struct AppMessage *AMsg = ((struct SWP_AppMsg *)msg)->AMsg;

        if (AMsg->am_NumArgs > 0) {
            NameFromLock(AMsg->am_ArgList[0].wa_Lock, FSpec, FMSIZE);
            AddPart(FSpec, AMsg->am_ArgList[0].wa_Name, FMSIZE);
            set(o, MUIA_String_Contents, FSpec);
        }
        return 0;
    }

    }

    return DoSuperMethodA(cl, o, msg);
}
Esempio n. 24
0
docommand() {
	register char	*p;
	register int	i;
	register ADDR	addr, bkaddr;
	struct proct 	*procp;
	char s[4];
	
	cntval = 1;
	adrflg = 0;
	errflg = 0;

	if (scallf) {
		doscall();
		setcur(1);
		lastcom = NOCOM;
		return;
	}
	
	if (reflag) {  /* search for regular expression */
		dore();
		lastcom = PRCOM;
		return;
	}
	
	if (cmd == '\0') {
		if (integ != 0 && var[0] != '\0') {
			error("Invalid command (1)");
			return;
		}
		if (integ != 0) { /* print line number */
			ffind(integ);
			fprint();
			lastcom = PRCOM;
			return;
		}
		if (var[0] != 0) {
			printf("Unexpected null command\n");
			return;
		}
	}
		
	switch (cmd) {
	
	case 'Y':
		debug = !debug;
		break;

	case 'V':
		version();
		break;

	case 'M':
		if (args[0]) {
			setmap(args);
		} else {
			printmap("? map", &txtmap);
			printmap("/ map", &datmap);
		}
		break;

	case 'x':
		printregs();
		break;

	case 'X':
		printpc();
		break;

	case 'a':
		if (integ) {
			cpstr(args, "l\n");
		} else if (proc[0]) {
			cpall(args, "T\n");
		} else {
			error("Bad arguments");
			break;
		}
		goto setbrk;
		break;	

	case 'l':
		setcur(1);
		lastcom = NOCOM;
		break;
		
	case 'T':
		prfrx(1);
		lastcom = NOCOM;
		break;
		
	case 't':
		prframe();
		lastcom = NOCOM;
		break;
		
	case 'e':
		p = args;
		if (*p == '\0') {
#ifndef FLEXNAMES
			printf("%.16s() in \"%s\"\n",
				curproc()->pname, curfile);
#else
			printf("%s() in \"%s\"\n",
				curproc()->pname, curfile);
#endif
			break;
		}

		while (*p != '\0')
			if (*p++ == '.') goto l1;
		/* argument is procedure name */
		procp = findproc(args);
		if ((procp->pname[0] != '\0') && (procp->sfptr != badfile)) {
			finit(adrtofilep(procp->paddr)->sfilename);
			ffind(procp->lineno);
		}
		else printf("Can't find %s\n", args);
#ifndef FLEXNAMES
		printf("%.16s() in \"%s\"\n", curproc()->pname, curfile);
#else
		printf("%s() in \"%s\"\n", curproc()->pname, curfile);
#endif
		lastcom = PRCOM;
		break;
		
	l1:	/* argument is filename */
		finit(args);
		printf("\"%s\"\n", curfile);
		lastcom = PRCOM;
		break;
		
	case 'p':
		if (integ) ffind(integ);
		fprint();
		lastcom = PRCOM;
		break;
		
	case 'q':
		exit(0);
		
	case 'w':
		if (integ) ffind(integ);
		i = fline;
		fback(WINDOW/2);
		fprintn(WINDOW);
		ffind(i);
		lastcom = PRCOM;
		break;
		
	case 'Q':
		prdebug();
		break;

	case 'z':
		if (integ) ffind(integ);
		fprintn(WINDOW);
		lastcom = PRCOM;
		break;

	case '-':
		fback(integ ? integ : 1);
		fpargs();
		lastcom = PRCOM;
		break;

	case '+':
		fforward(integ ? integ : 1);
		fpargs();
		lastcom = PRCOM;
		break;

	case '\n':
		switch (lastcom) {
		case PRCOM:
			fforward(1);
			fprint();
			break;
		case DSCOM:
			oaddr += oincr ? oincr : typetosize(otype, WORDSIZE);
			printf("0x%x/ ", oaddr);
			dispf((ADDR) oaddr, odesc,
			    oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP);
			break;
		case DSICOM:
			dot += oincr;
			prisploc();
			dispi(dot, odesc, N_GSYM, 0, 0);
			break;
		}
		break;

	case '\004':
		if (!isatty(0))
			exit(0);
		switch (lastcom) {
		case PRCOM:
			fforward(1);
			printf("\b");
			fprintn(WINDOW);
			lastcom = PRCOM;
			break;
		case DSICOM:
			printf("\b");
			for (i=0; i<WINDOW; i++) {
				dot += oincr;
				prisploc();
				if (dispi(dot, odesc, N_GSYM, 0, 0) == -1)
					break;
			}
			break;
		case DSCOM:
			printf("\b");
			for (i=0; i<WINDOW; i++) {
				oaddr += oincr ?
					oincr : typetosize(otype, WORDSIZE);
				printf("0x%x/ ", oaddr);
				if (dispf((ADDR) oaddr, odesc,
					oclass == N_RSYM ? oclass :
					N_GSYM, otype, 0, 0, DSP) == -1)
					break;
			}
			break;
		default:
			printf("\n");
		}
		break;

	case 'r':
		if (args[0] == '\0') getargs();
	case 'R':
		signo = 0;
		cpstr(oldargs, args);
		if (debug) error("calling dopcs");
		if (integ) cntval = integ;
		if (!executing) {
			executing = TRUE;
			if (integ) cntval = integ;
			dopcs('r');
			executing = FALSE;
		}
		if (debug) error("exiting dopcs");
		bkaddr = -1;
		goto f1;

	case 'c':
		signo = 0;
	case 'C':
		if (proc[0] != '\0' || integ != 0) {
			setdot();
			if (dot == -1) {
				error("Cannot set temporary breakpoint");
				break;
			}
			dopcs('b');
			bkaddr = dot;
		} else
			bkaddr = -1;
		integ = atoi(args);

f1:		if (debug) error("calling dopcs");
		if (integ) cntval = integ;
		dopcs('c');
		if (debug) error("exiting dopcs");
		if (bkaddr != -1) {
			ADDR dotsave;
			dotsave = dot;
			dot = bkaddr;
			dopcs('d');
			dot = dotsave;
		}
		if (!signo) printf("Breakpoint");
		printf(" at\n");
		setcur(1);
		lastcom = NOCOM;
		break;
		
	case 'S':
	case 's':
		signo = 0;
		integ = atoi(args);
		singstep(integ ? integ : 1, cmd);
		if (signo) printf("\n");
		setcur(1);
		lastcom = NOCOM;
		break;
		
	case 'g':
		if (pid == 0  ||  signo) {
			error("Not stopped at breakpoint");
			break;
		}
		setdot();
		if (dot == -1) {
			error("Bad address");
			break;
		}
		adrflg = 1;
		integ = atoi(args);
		if (integ) cntval = integ;
		dopcs('c');
		if (!signo) printf("Breakpoint");
		printf(" at\n");
		setcur(1);
		lastcom = NOCOM;
		break;

	case 'k':
		if (scallx) {
	 		userpc = dot = *(ADDR *)(((ADDR)&u)+PC) = pcs;
	 		*(ADDR *)(((ADDR)&u)+FP) = fps;
	 		*(ADDR *)(((ADDR)&u)+AP) = aps;
			if (bkpts)
				bkpts->flag = flagss;
			scallx = 0;
			error("Procedure killed");
			longjmp(env, 0);
		} else {
			dopcs('k');
			printf("\n");
			lastcom = NOCOM;
			break;
		}

	case 'B':
		prbkpt();
		break;

	case 'b':
	setbrk:
		if (proc[0] == '\0' && integ == 0) {
			integ = fline;
		}
		setdot();
		if (dot == -1 || dot == 0) {
			error("Cannot set breakpoint");
			break;
		}
		dopcs('b');
		s[0] = ' ';
		s[1] = cmd;
		s[2] = '\n';
		s[3] = 0;
		s[1] = cmd;
		printbkpt(s, adrtoprocp(dot), dot);
		break;
		
	case 'd':
		if (proc[0] == '\0' && integ == 0) {
			idbkpt();
			break;
		}
		setdot();
		if (dot == -1) {
			error("Non existent breakpoint");
			break;
		}
		dopcs('d');
		break;
		
	case 'D':
		dabkpt();
		error("All breakpoints deleted");
		break;

	case 'm':
		addr = varaddr(proc[0] ? proc : curproc()->pname, var);
		printf("stopped with value %d\n", monex(addr, 'd'));
		setcur(1);
		lastcom = NOCOM;
		break;
		
	case '?':
		if (!(var[0] == '.' && var[1] == '\0'))
			setdot();
		if (errflg) {
			error(errflg);
			break;
		}
		prisploc();
		dispi(dot, args[0] ? args : "i", N_GSYM, 0, 0);
		lastcom = DSICOM;
		break;

	case '/':
		if (var[0] == '.' && var[1] == '\0') {
			if (integ == 0) integ = oaddr;
			dispf((ADDR) integ, args[0] ? args : odesc,
			    oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP);
			oaddr = integ;
		} else
		if (integ && (var[0] == '\0')) {
			dispf((ADDR) integ, args, N_GSYM, 0, 0, 0, DSP);
			oaddr = integ;
			cpstr(odesc, args);
			oclass = N_GSYM;
			otype = 0;
		} else
			dispvar(proc, var, args);
		lastcom = DSCOM;
		break;
		
	case '=':
		if (var[0] == '\0') {
			if (proc[0]) {
				addr = getaddr(proc, integ);
				if (addr == -1) {
					error("Unknown address");
					break;
				}
			}
			else
				addr = integ;
			dispf(addr, args[0] ? args : "x", 0, -1, 0, 0, DSP);
		} else 
			findvar(proc, var, args[0] ? args : "x", 2);
		break;

	case '!':
		if (var[0] == '\0')
			addr = getaddr(proc, integ);
		else
			addr = varaddr(proc, var);
		if (addr == -1) 
			error("Unknown variable");
		else {
			if (number(args[0]) || eqany(args[0], ".-")) {
				char *p;
				double atof();
				union {
					struct{
						int w1, w2;
					} ww;
					double d;
				} dbl;

				p = (args[0] == '-') ? args+1 : args;
				for (; *p != '.' && *p != 'e'; p++) {
					if (!number(*p)) goto l2;
				}
				dbl.d = atof(args);
				putval(addr, 'd', dbl.ww.w1);
				if (typetodesc(sl_type,0)[0] == 'g')
					putval(addr+WORDSIZE, 'd', dbl.ww.w2);
				break;
			}
l2:			if (percentflag)
				*(ADDR *)(((ADDR)&u)+addr) = argvalue(args);
			else if (sl_class == N_RSYM && addr < 16)
				putreg(addr,typetodesc(sl_type,subflag)[0],
						argvalue(args));
			else
				putval(addr,typetodesc(sl_type,subflag)[0],
						argvalue(args));
		}
		lastcom = NOCOM;
		break;

	case '"':
		printf(args);
		break;
	}
}
Esempio n. 25
0
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
    int i, ret;
    unsigned long __user *p = (void __user *)(unsigned long)data;

    switch (request) {
    /* when I and D space are separate, these will need to be fixed. */
    case PTRACE_PEEKTEXT: /* read word at location addr. */
    case PTRACE_PEEKDATA: {
        unsigned long tmp;
        int copied;

        ret = -EIO;
        copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
        if (copied != sizeof(tmp))
            break;
        ret = put_user(tmp, p);
        break;
    }

    /* read the word at location addr in the USER area. */
    case PTRACE_PEEKUSR:
        ret = peek_user(child, addr, data);
        break;

    /* when I and D space are separate, this will have to be fixed. */
    case PTRACE_POKETEXT: /* write the word at location addr. */
    case PTRACE_POKEDATA:
        ret = -EIO;
        if (access_process_vm(child, addr, &data, sizeof(data),
                              1) != sizeof(data))
            break;
        ret = 0;
        break;

    case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
        ret = poke_user(child, addr, data);
        break;

    case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
    case PTRACE_CONT: { /* restart after signal. */
        ret = -EIO;
        if (!valid_signal(data))
            break;

        set_singlestepping(child, 0);
        if (request == PTRACE_SYSCALL) {
            set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
        }
        else {
            clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
        }
        child->exit_code = data;
        wake_up_process(child);
        ret = 0;
        break;
    }

    /*
     * make the child exit.  Best I can do is send it a sigkill.
     * perhaps it should be put in the status that it wants to
     * exit.
     */
    case PTRACE_KILL: {
        ret = 0;
        if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
            break;

        set_singlestepping(child, 0);
        child->exit_code = SIGKILL;
        wake_up_process(child);
        break;
    }

    case PTRACE_SINGLESTEP: {  /* set the trap flag. */
        ret = -EIO;
        if (!valid_signal(data))
            break;
        clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
        set_singlestepping(child, 1);
        child->exit_code = data;
        /* give it a chance to run. */
        wake_up_process(child);
        ret = 0;
        break;
    }

    case PTRACE_DETACH:
        /* detach a process that was attached. */
        ret = ptrace_detach(child, data);
        break;

#ifdef PTRACE_GETREGS
    case PTRACE_GETREGS: { /* Get all gp regs from the child. */
        if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) {
            ret = -EIO;
            break;
        }
        for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
            __put_user(getreg(child, i), p);
            p++;
        }
        ret = 0;
        break;
    }
#endif
#ifdef PTRACE_SETREGS
    case PTRACE_SETREGS: { /* Set all gp regs in the child. */
        unsigned long tmp = 0;
        if (!access_ok(VERIFY_READ, p, MAX_REG_OFFSET)) {
            ret = -EIO;
            break;
        }
        for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
            __get_user(tmp, p);
            putreg(child, i, tmp);
            p++;
        }
        ret = 0;
        break;
    }
#endif
#ifdef PTRACE_GETFPREGS
    case PTRACE_GETFPREGS: /* Get the child FPU state. */
        ret = get_fpregs(data, child);
        break;
#endif
#ifdef PTRACE_SETFPREGS
    case PTRACE_SETFPREGS: /* Set the child FPU state. */
        ret = set_fpregs(data, child);
        break;
#endif
#ifdef PTRACE_GETFPXREGS
    case PTRACE_GETFPXREGS: /* Get the child FPU state. */
        ret = get_fpxregs(data, child);
        break;
#endif
#ifdef PTRACE_SETFPXREGS
    case PTRACE_SETFPXREGS: /* Set the child FPU state. */
        ret = set_fpxregs(data, child);
        break;
#endif
    case PTRACE_GET_THREAD_AREA:
        ret = ptrace_get_thread_area(child, addr,
                                     (struct user_desc __user *) data);
        break;

    case PTRACE_SET_THREAD_AREA:
        ret = ptrace_set_thread_area(child, addr,
                                     (struct user_desc __user *) data);
        break;

    case PTRACE_FAULTINFO: {
        /* Take the info from thread->arch->faultinfo,
         * but transfer max. sizeof(struct ptrace_faultinfo).
         * On i386, ptrace_faultinfo is smaller!
         */
        ret = copy_to_user(p, &child->thread.arch.faultinfo,
                           sizeof(struct ptrace_faultinfo));
        if(ret)
            break;
        break;
    }

#ifdef PTRACE_LDT
    case PTRACE_LDT: {
        struct ptrace_ldt ldt;

        if(copy_from_user(&ldt, p, sizeof(ldt))) {
            ret = -EIO;
            break;
        }

        /* This one is confusing, so just punt and return -EIO for
         * now
         */
        ret = -EIO;
        break;
    }
#endif
#ifdef CONFIG_PROC_MM
    case PTRACE_SWITCH_MM: {
        struct mm_struct *old = child->mm;
        struct mm_struct *new = proc_mm_get_mm(data);

        if(IS_ERR(new)) {
            ret = PTR_ERR(new);
            break;
        }

        atomic_inc(&new->mm_users);
        child->mm = new;
        child->active_mm = new;
        mmput(old);
        ret = 0;
        break;
    }
#endif
    default:
        ret = ptrace_request(child, request, addr, data);
        break;
    }

    return ret;
}
Esempio n. 26
0
// ------------------------------------------------------------------------
//
//  API Function : dm9000_poll
//
// ------------------------------------------------------------------------
static void
dm9000_poll(struct eth_drv_sc *sc)
{
    struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
    cyg_uint8 status, rxstat, rx1;
    cyg_uint16 pkt_stat, pkt_len;
    int i;

    // mask interrupts
    putreg(priv, DM_IMR, IMR_PAR);

    // get and clear staus
    status = getreg(priv, DM_ISR);
    putreg(priv, DM_ISR, status);

    // check for rx done
    if (1 /*status & ISR_PRS*/) {

	rx1 = getreg(priv, DM_MRCMDX);
	HAL_READ_UINT8(priv->io_data, rxstat);

	// check for packet ready
	if (rxstat == 1) {
	    cyg_uint16 u16[2];
	    cyg_uint8 *cp;

	    HAL_WRITE_UINT8(priv->io_addr, DM_MRCMD);
	    for (i = 0, cp = (cyg_uint8 *)u16; i < 4; )
		i += priv->read_data(priv, cp + i);

	    u16[0] = CYG_LE16_TO_CPU(u16[0]);
	    u16[1] = CYG_LE16_TO_CPU(u16[1]);

#if (CYG_BYTEORDER == CYG_MSBFIRST)
	    pkt_stat = u16[0];
	    pkt_len = u16[1];
#else
	    pkt_stat = u16[1];
	    pkt_len = u16[0];
#endif

#ifdef DEBUG
	    diag_printf("pkt_stat=%04x pkt_len=%04x\n", pkt_stat, pkt_len);
#endif

	    if (pkt_len < 0x40) {
		diag_printf("packet too short: %d (0x%04x)\n", pkt_len, pkt_len);
		i = 0;
		while (i < pkt_len)
		    i += priv->read_data(priv, cp);
	    } else if (pkt_len > 1536) {
		priv->reset_pending = 1;
		diag_printf("packet too long: %d (0x%04x)\n", pkt_len, pkt_len);
	    } else if (pkt_stat & 0xbf00) {
		diag_printf("bad packet status: 0x%04x\n", pkt_stat);
		i = 0;
		while (i < pkt_len)
		    i += priv->read_data(priv, cp);
	    } else {
		// receive packet
		priv->rxlen = pkt_len;
		(sc->funs->eth_drv->recv)(sc, pkt_len);
	    }

	} else if (rxstat > 1) {
	    // this should never happen.
	    diag_printf("unknown rxstat byte: %d\n", rxstat);
	    priv->reset_pending = 1;
	}
    }


    // check transmit status
    if (status & ISR_PTS) {
	cyg_uint8 txstat;

	txstat = getreg(priv, DM_NSR);

	if (txstat & (NSR_TX1END | NSR_TX2END)) {
	    if (txstat & NSR_TX1END)
		txstat = getreg(priv, DM_TSRI);
	    else
		txstat = getreg(priv, DM_TSRII);

	    if (txstat & TSR_COL) {
		// collision
	    }

	    if (getreg(priv, DM_TRPAL) & 3) {
		// NIC bug detected. Need to reset.
		priv->reset_pending = 1;
		diag_printf("NIC collision bug detected!\n");
	    }

	    (sc->funs->eth_drv->tx_done)(sc, priv->txkey, 0);
	    priv->txbusy = 0;
	}
    }

    if (priv->reset_pending && !priv->txbusy) {
	initialize_nic(priv);

	// turn on receiver
	putreg(priv, DM_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);

	priv->reset_pending = 0;
    }

    // unmask interrupts
    putreg(priv, DM_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
}
Esempio n. 27
0
long arch_ptrace(struct task_struct *child, long request,
		 unsigned long addr, unsigned long data)
{
	int i, ret;
	unsigned long __user *p = (void __user *)data;
	void __user *vp = p;

	switch (request) {
	/* read word at location addr. */
	case PTRACE_PEEKTEXT:
	case PTRACE_PEEKDATA:
		ret = generic_ptrace_peekdata(child, addr, data);
		break;

	/* read the word at location addr in the USER area. */
	case PTRACE_PEEKUSR:
		ret = peek_user(child, addr, data);
		break;

	/* write the word at location addr. */
	case PTRACE_POKETEXT:
	case PTRACE_POKEDATA:
		ret = generic_ptrace_pokedata(child, addr, data);
		break;

	/* write the word at location addr in the USER area */
	case PTRACE_POKEUSR:
		ret = poke_user(child, addr, data);
		break;

	case PTRACE_SYSEMU:
	case PTRACE_SYSEMU_SINGLESTEP:
		ret = -EIO;
		break;

#ifdef PTRACE_GETREGS
	case PTRACE_GETREGS: { /* Get all gp regs from the child. */
		if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) {
			ret = -EIO;
			break;
		}
		for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
			__put_user(getreg(child, i), p);
			p++;
		}
		ret = 0;
		break;
	}
#endif
#ifdef PTRACE_SETREGS
	case PTRACE_SETREGS: { /* Set all gp regs in the child. */
		unsigned long tmp = 0;
		if (!access_ok(VERIFY_READ, p, MAX_REG_OFFSET)) {
			ret = -EIO;
			break;
		}
		for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
			__get_user(tmp, p);
			putreg(child, i, tmp);
			p++;
		}
		ret = 0;
		break;
	}
#endif
#ifdef PTRACE_GETFPREGS
	case PTRACE_GETFPREGS: /* Get the child FPU state. */
		ret = get_fpregs(vp, child);
		break;
#endif
#ifdef PTRACE_SETFPREGS
	case PTRACE_SETFPREGS: /* Set the child FPU state. */
		ret = set_fpregs(vp, child);
		break;
#endif
	case PTRACE_GET_THREAD_AREA:
		ret = ptrace_get_thread_area(child, addr, vp);
		break;

	case PTRACE_SET_THREAD_AREA:
		ret = ptrace_set_thread_area(child, addr, vp);
		break;

	case PTRACE_FAULTINFO: {
		/*
		 * Take the info from thread->arch->faultinfo,
		 * but transfer max. sizeof(struct ptrace_faultinfo).
		 * On i386, ptrace_faultinfo is smaller!
		 */
		ret = copy_to_user(p, &child->thread.arch.faultinfo,
				   sizeof(struct ptrace_faultinfo)) ?
			-EIO : 0;
		break;
	}

#ifdef PTRACE_LDT
	case PTRACE_LDT: {
		struct ptrace_ldt ldt;

		if (copy_from_user(&ldt, p, sizeof(ldt))) {
			ret = -EIO;
			break;
		}

		/*
		 * This one is confusing, so just punt and return -EIO for
		 * now
		 */
		ret = -EIO;
		break;
	}
#endif
#ifdef PTRACE_ARCH_PRCTL
	case PTRACE_ARCH_PRCTL:
		/* XXX Calls ptrace on the host - needs some SMP thinking */
		ret = arch_prctl(child, data, (void __user *) addr);
		break;
#endif
	default:
		ret = ptrace_request(child, request, addr, data);
		if (ret == -EIO)
			ret = subarch_ptrace(child, request, addr, data);
		break;
	}

	return ret;
}
Esempio n. 28
0
long sys_ptrace(long request, long pid, long addr, long data)
{
    struct task_struct *child;
    int i, ret;

    lock_kernel();
    ret = -EPERM;
    if (request == PTRACE_TRACEME) {
        /* are we already being traced? */
        if (current->ptrace & PT_PTRACED)
            goto out;

        ret = security_ptrace(current->parent, current);
        if (ret)
            goto out;

        /* set the ptrace bit in the process flags. */
        current->ptrace |= PT_PTRACED;
        ret = 0;
        goto out;
    }
    ret = -ESRCH;
    read_lock(&tasklist_lock);
    child = find_task_by_pid(pid);
    if (child)
        get_task_struct(child);
    read_unlock(&tasklist_lock);
    if (!child)
        goto out;

    ret = -EPERM;
    if (pid == 1)		/* you may not mess with init */
        goto out_tsk;

    if (request == PTRACE_ATTACH) {
        ret = ptrace_attach(child);
        goto out_tsk;
    }

#ifdef SUBACH_PTRACE_SPECIAL
    SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
#endif

    ret = ptrace_check_attach(child, request == PTRACE_KILL);
    if (ret < 0)
        goto out_tsk;

    switch (request) {
    /* when I and D space are separate, these will need to be fixed. */
    case PTRACE_PEEKTEXT: /* read word at location addr. */
    case PTRACE_PEEKDATA: {
        unsigned long tmp;
        int copied;

        ret = -EIO;
        copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
        if (copied != sizeof(tmp))
            break;
        ret = put_user(tmp, (unsigned long __user *) data);
        break;
    }

    /* read the word at location addr in the USER area. */
    case PTRACE_PEEKUSR:
        ret = peek_user(child, addr, data);
        break;

    /* when I and D space are separate, this will have to be fixed. */
    case PTRACE_POKETEXT: /* write the word at location addr. */
    case PTRACE_POKEDATA:
        ret = -EIO;
        if (access_process_vm(child, addr, &data, sizeof(data),
                              1) != sizeof(data))
            break;
        ret = 0;
        break;

    case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
        ret = poke_user(child, addr, data);
        break;

    case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
    case PTRACE_CONT: { /* restart after signal. */
        ret = -EIO;
        if (!valid_signal(data))
            break;

        set_singlestepping(child, 0);
        if (request == PTRACE_SYSCALL) {
            set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
        }
        else {
            clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
        }
        child->exit_code = data;
        wake_up_process(child);
        ret = 0;
        break;
    }

    /*
     * make the child exit.  Best I can do is send it a sigkill.
     * perhaps it should be put in the status that it wants to
     * exit.
     */
    case PTRACE_KILL: {
        ret = 0;
        if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
            break;

        set_singlestepping(child, 0);
        child->exit_code = SIGKILL;
        wake_up_process(child);
        break;
    }

    case PTRACE_SINGLESTEP: {  /* set the trap flag. */
        ret = -EIO;
        if (!valid_signal(data))
            break;
        clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
        set_singlestepping(child, 1);
        child->exit_code = data;
        /* give it a chance to run. */
        wake_up_process(child);
        ret = 0;
        break;
    }

    case PTRACE_DETACH:
        /* detach a process that was attached. */
        ret = ptrace_detach(child, data);
        break;

#ifdef PTRACE_GETREGS
    case PTRACE_GETREGS: { /* Get all gp regs from the child. */
        if (!access_ok(VERIFY_WRITE, (unsigned long *)data,
                       MAX_REG_OFFSET)) {
            ret = -EIO;
            break;
        }
        for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
            __put_user(getreg(child, i),
                       (unsigned long __user *) data);
            data += sizeof(long);
        }
        ret = 0;
        break;
    }
#endif
#ifdef PTRACE_SETREGS
    case PTRACE_SETREGS: { /* Set all gp regs in the child. */
        unsigned long tmp = 0;
        if (!access_ok(VERIFY_READ, (unsigned *)data,
                       MAX_REG_OFFSET)) {
            ret = -EIO;
            break;
        }
        for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
            __get_user(tmp, (unsigned long __user *) data);
            putreg(child, i, tmp);
            data += sizeof(long);
        }
        ret = 0;
        break;
    }
#endif
#ifdef PTRACE_GETFPREGS
    case PTRACE_GETFPREGS: /* Get the child FPU state. */
        ret = get_fpregs(data, child);
        break;
#endif
#ifdef PTRACE_SETFPREGS
    case PTRACE_SETFPREGS: /* Set the child FPU state. */
        ret = set_fpregs(data, child);
        break;
#endif
#ifdef PTRACE_GETFPXREGS
    case PTRACE_GETFPXREGS: /* Get the child FPU state. */
        ret = get_fpxregs(data, child);
        break;
#endif
#ifdef PTRACE_SETFPXREGS
    case PTRACE_SETFPXREGS: /* Set the child FPU state. */
        ret = set_fpxregs(data, child);
        break;
#endif
    case PTRACE_FAULTINFO: {
        /* Take the info from thread->arch->faultinfo,
         * but transfer max. sizeof(struct ptrace_faultinfo).
         * On i386, ptrace_faultinfo is smaller!
         */
        ret = copy_to_user((unsigned long __user *) data,
                           &child->thread.arch.faultinfo,
                           sizeof(struct ptrace_faultinfo));
        if(ret)
            break;
        break;
    }

#ifdef PTRACE_LDT
    case PTRACE_LDT: {
        struct ptrace_ldt ldt;

        if(copy_from_user(&ldt, (unsigned long __user *) data,
                          sizeof(ldt))) {
            ret = -EIO;
            break;
        }

        /* This one is confusing, so just punt and return -EIO for
         * now
         */
        ret = -EIO;
        break;
    }
#endif
#ifdef CONFIG_PROC_MM
    case PTRACE_SWITCH_MM: {
        struct mm_struct *old = child->mm;
        struct mm_struct *new = proc_mm_get_mm(data);

        if(IS_ERR(new)) {
            ret = PTR_ERR(new);
            break;
        }

        atomic_inc(&new->mm_users);
        child->mm = new;
        child->active_mm = new;
        mmput(old);
        ret = 0;
        break;
    }
#endif
    default:
        ret = ptrace_request(child, request, addr, data);
        break;
    }
out_tsk:
    put_task_struct(child);
out:
    unlock_kernel();
    return ret;
}