⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wdbgopherlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* wdbGopherLib.c - info gathering interpreter for the agent *//* Copyright 1994-2001 Wind River Systems, Inc. *//*modification history--------------------01l,14sep01,jhw Fixed warnings from compiling with gnu -pedantic flag01k,09sep97,elp added global variable to prevent taskLock() calls (SPR# 7653)		+ replaced hardcoded value by macro.01j,10dec96,elp gopherWriteString() cleanup.01i,09dec96,elp fixed null length string error (gopher type was not written).01h,30apr96,elp	Merged with the host version written by bss (SPR# 6497).		+ enabled transfer of larger strings (SPR #6277)		+ fix SPR #6403.01g,20mar96,s_w modify the gopherWriteString to cope with strings near memory		boundaries (SPR 6218).01f,31oct95,ms  changed a couple of strtol's to strtoul's.01e,14sep95,c_s added more syntax checking, bug fixes, and memory protection.		(SPRs 4659, 4462).01d,23jun95,tpr replaced memcpy() by bcopy()01c,20jun95,ms	added static buffer back in to make DSA easier01b,01jun95,ms	added interlocking in task mode, removed static buffer.01a,01nov94,c_s written.*//*DESCRIPTION*/#ifdef HOST#include <limits.h>#include <string.h>#include <ctype.h>#include <stdlib.h>#if 0   /* omitted because host.h redefines memset () and memchr () */#include <memory.h>#else   /* which breaks the declaration of memcpy () ... */extern "C" void * memcpy (void * s1, const void * s2, size_t n);#endif#include "host.h"#include "wdb.h"#include "backend.h"#else /* #ifdef HOST */#include "wdb/wdb.h"#include "wdb/wdbRtIfLib.h"#include "wdb/wdbLibP.h"#include "wdb/wdbSvcLib.h"#include "limits.h"#include "string.h"#include "ctype.h"#include "stdlib.h"#endif  /* #ifdef HOST */typedef struct    {    char *		program;	/* where to start executing */    UINT32		p;		/* initial value of pointer */    char *		pTape;		/* tape array */    int			tapeIx;		/* index in tape to write next cell */    int			tapeLen;	/* total length of tape */    int			execute;	/* whether to execute, or just parse */    unsigned int	status;		/* error code */    } wdbGopherCtx_t;/* The Gopher Byte Stream Format *  * The first byte of an item is the type code, one of GOPHER_UINT32,  * GOPHER_UINT16, GOPHER_FLOAT64, etc.  This code determines the number * of bytes that immediately follow and represent the tape cell value. * These data bytes will be in the target byte order.  If the type code * is GOPHER_STRING, all following bytes are part of the string up to  * a trailing NUL character. */#define MAX_TAPE_LEN	1400#ifdef HOST/** XXX - because some emulator back ends only provide low-bandwidth* memory read capabilities, the host implementation assumes that* the maximum size of a string in target memory is 32 bytes.* This is necessary for performance.  However, gopherWriteString()* should be modified to make several small reads until it finds* the end of a string.*/const int       MaxTgtStrLen    = 32;   /* XXX - Maximum length of a string */#else#define ADD_TAPE_NB	10BOOL		wdbGopherLock = TRUE;	  /* lock during gopher evaluation */static char *	pAddTape [ADD_TAPE_NB];	  /* additional tape pointers */static int	pAddTapeIx [ADD_TAPE_NB]; /* additional tape fill indexes */static int	tapeIndex;		  /* current tape number */#endif /* #ifdef HOST */static char 	tape [MAX_TAPE_LEN];	/* XXX should be passed to					 * wdbGopherLib(), but that would					 * make the host based DSA harder					 * to implement */static int	tapeLen = MAX_TAPE_LEN;#define WDB_REPLY_HDR_SZ	24#define WDB_WRAPPER_HDR_SZ	12#define WDB_MEM_XFER_HDR_SZ	8#define WDB_OPAQUE_HDR_SZ	4/* it is required to reserve space for headers (WDB + XDR + IP) */#define WDB_GOPHER_MTU_OFFSET  (WDB_REPLY_HDR_SZ + WDB_WRAPPER_HDR_SZ + \				WDB_MEM_XFER_HDR_SZ + WDB_OPAQUE_HDR_SZ + 8)/* forward declarations */#ifdef HOST/* * Note:  although this is a '.c' file, it must be * compiled with the '-x c++' option. */extern "C" UINT32 wdbEvaluateGopher (WDB_STRING_T *program,                                     WDB_MEM_XFER *pTape);static STATUS gopherWriteP (wdbGopherCtx_t *gc);#elsestatic UINT32 wdbEvaluateGopher (WDB_STRING_T *program, WDB_MEM_XFER *pTape);static STATUS wdbTransferGopher (WDB_MEM_XFER *pTape);static STATUS gopherNewTapeAllocate (wdbGopherCtx_t *gc);#endif /* #ifdef HOST */static STATUS gopher		(wdbGopherCtx_t *gc);static STATUS gopherWriteScalar	(wdbGopherCtx_t *gc, UINT8 *src, int type);static STATUS gopherWriteString (wdbGopherCtx_t *gc, char *string);/******************************************************************************** gopher -*/static STATUS gopher     (    wdbGopherCtx_t *	gc		/* gopher execution context */    )    {    while (*gc->program)	{	/* skip whitespace */	while (*gc->program && isspace ((int) *gc->program))	    ++gc->program;	if (isxdigit ((int) *gc->program)) /* unsigned constants replace p */	    {	    char *newPc;#ifdef HOST            /* XXX - this is a work around for the bug in GNU's strtoul (). */            unsigned int newP = (unsigned int) strtol (gc->program, &newPc, 0);#else	    unsigned int newP = (unsigned int) strtoul (gc->program, &newPc, 0);#endif /* #ifdef HOST */	    	    if (gc->program == newPc)		{		gc->status = WDB_ERR_GOPHER_SYNTAX;		return ERROR;		}			    if (gc->execute)		{		gc->p = newP;		}	    	    gc->program = newPc;	    }	else if (*gc->program == '+'	/* signed constants increment p */		 || *gc->program == '-')	    {	    char *newPc;	    int minus = *gc->program == '-';	    int delta = strtol (++gc->program, &newPc, 0);	    if (gc->program == newPc)		{		gc->status = WDB_ERR_GOPHER_SYNTAX;		return ERROR;		}			    if (gc->execute)		{		gc->p += minus ? -delta : delta;		}	    gc->program = newPc;	    }	else if (*gc->program == '*')	/* * replaces p with *p */	    {	    if (gc->execute)		{		UINT32 newP;#ifdef HOST                if (Backend_T::memProbe_s ((TGT_ADDR_T) gc->p, VX_READ,                                        sizeof (UINT32), (char *) &newP) != OK)#else		if ((*pWdbRtIf->memProbe) ((INT8 *) gc->p, VX_READ,					sizeof (UINT32), (char *) &newP) != OK)#endif /* #ifdef HOST */		    {			    gc->status = WDB_ERR_GOPHER_FAULT;		    return ERROR;		    }		gc->p = newP;		}	    ++gc->program;	    }	else if (*gc->program == '!')	/* ! writes p on the tape */	    {	    if (gc->execute)		{#ifdef HOST                if (gopherWriteP (gc) != OK)                    return ERROR;#else		if (gopherWriteScalar (gc, (UINT8 *) &gc->p, GOPHER_UINT32)		    != OK)		    return ERROR;#endif /* #ifdef HOST */		}	    ++gc->program;	    }	else if (*gc->program == '@')	/* @ writes *p on the tape, advance p */	    {	    int		size = 4;	    int		type = GOPHER_UINT32;	    /* If the next character is in [bwlfdx] then modify	     * the size of the transfer. Otherwise pick up 32 bits.	     */	    	    switch (gc->program [1])		{		case 'b':		    size = 1; 		    type = GOPHER_UINT8;		    ++gc->program;		    break;		case 'w':		    size = 2; 		    type = GOPHER_UINT16;		    ++gc->program;		    break;		case 'f':		    size = 4; 		    type = GOPHER_FLOAT32;		    ++gc->program;		    break;		case 'd':		    size = 8; 		    type = GOPHER_FLOAT64;		    ++gc->program;		    break;		case 'x':		    size = 10; 		    type = GOPHER_FLOAT80;		    ++gc->program;		    break;		case 'l':		    size = 4; 		    type = GOPHER_UINT32;		    ++gc->program;		    break;		}		    	    if (gc->execute)		{		if (gopherWriteScalar (gc, (UINT8 *) gc->p, type) != OK)		    return ERROR;		gc->p += size;		}	    ++gc->program;	    }	else if (*gc->program == '$')	/* $ writes string at p on tape */	    {	    if (gc->execute)		{		if (gopherWriteString (gc, (char *) gc->p) != OK)		    return ERROR;		}	    ++gc->program;	    }	else if (*gc->program == '{')	/* { saves p and repeats contents */	    {				/* while p is not NULL.           */	    wdbGopherCtx_t subGc;	    char *progStart = gc->program+1;	    UINT32 oldP = gc->p;	    int oldX = gc->execute;	    int result = OK;	    subGc = *gc;		/* set up initial context */	    ++subGc.program;		/* skip the initial left-brace */	    /* We set the execute flag to zero if the pointer value 	       is currently zero in our context.  This is because if	       p == 0 upon encountering an open-brace, we should not execute 	       the contents of the brace construct, but we still need	       to know where to resume execution, so we must parse	       in a subcontext. */	    if (gc->p == 0)		{		subGc.execute = 0;		result = gopher (&subGc);		}	    else		{		while (result == OK && subGc.p != 0)		    {		    subGc.program = progStart;		    result = gopher (&subGc);		    }		}	    /* Now set our program pointer to the character after the 	       execution of the subprogram. */	    *gc = subGc;	    if (result != OK)		{			return result;		}	    	    /* restore p, execute. */	    gc->p = oldP;	    gc->execute = oldX;	    }	else if (*gc->program == '}')	/* } ends the loop opened by {. */	    {	    ++gc->program;	    return OK;	    }	else if (*gc->program == '<')	/* < saves p and executes body once. */	    {	    wdbGopherCtx_t subGc;	    UINT32 oldP = gc->p;	    int result;	    subGc = *gc;		/* set up initial context */	    ++subGc.program;		/* skip the initial left-bracket */	    result = gopher (&subGc);	    if (result != OK)  		{		*gc = subGc;		return result;		}	    /* Now set our program pointer to the character after the 	       execution of the subprogram. */	    *gc = subGc;	    gc->p = oldP;	    }	else if (*gc->program == '>')	/* > closes the block opened by <. */	    {	    ++gc->program;	    return OK;	    }	else if (*gc->program == '(')	/* perform "n" times, where n follows */	    {	    char *newPc;	    UINT32 oldP = gc->p;	    wdbGopherCtx_t subGc;#ifdef HOST            /* XXX - fix for GNU's bug in strtoul (). */            unsigned int count = (unsigned int) strtol (gc->program + 1,                                                        &newPc, 0);#else	    unsigned int count = (unsigned int) strtoul (gc->program + 1,							&newPc, 0);#endif /* #ifdef HOST */	    int ix;	    	    if (gc->program+1 == newPc || count <= 0)		{		gc->status = WDB_ERR_GOPHER_SYNTAX;		return ERROR;		}	    /* if we're not executing, just execute the loop once, so we 	       can find the end of the nesting. */	    if (! gc->execute) count = 1;	    gc->program = newPc;	    subGc = *gc;	    for (ix = 0; ix < count; ++ix)		{		/* start the program at the beginning: after the (# part. */		subGc.program = newPc;		if (gopher (&subGc) != OK)		    {		    *gc = subGc;		    return ERROR;		    }		}	    	    *gc = subGc;	    gc->p = oldP;	    }	else if (*gc->program == ')')	    {	    ++gc->program;	    return OK;	    }	else if (*gc->program == '_')	    {	    /* _ is ignored.  It can be used to separate two numbers	       in a generated gopher program. */	    ++gc->program;	    }	else if (*gc->program)	    {	    /* unknown character: syntax error. */	    gc->status = WDB_ERR_GOPHER_SYNTAX;	    return ERROR;	    }	}        return OK;    }#ifdef HOST/******************************************************************************** wdbEvaluateGopher -*/UINT32 wdbEvaluateGopher    (    WDB_STRING_T *      pProgram,    WDB_MEM_XFER *      pValueTape    )    {    wdbGopherCtx_t      gc;    gc.program  = *pProgram;    gc.p        = 0;    gc.pTape    = tape;    gc.tapeIx   = 0;    gc.tapeLen  = tapeLen;    gc.execute  = 1;    gc.status   = OK;    gopher (&gc);    pValueTape->source          = gc.pTape;    pValueTape->numBytes        = gc.tapeIx;    return (gc.status);    }/******************************************************************************** gopherWriteScalar -*/static STATUS gopherWriteScalar    (    wdbGopherCtx_t *    gc,                     /* gopher context */    UINT8 *             src,                    /* source address */    int                 type                    /* GOPHER_UINT32, etc. */    )    {    int                 nbytes = 4;             /* UINT32 is most common */    int			status;    if (type == GOPHER_UINT16)   nbytes = 2;    /* fix nbytes if size != 4 */    if (type == GOPHER_UINT8)    nbytes = 1;    if (type == GOPHER_FLOAT64)  nbytes = 8;    if (type == GOPHER_FLOAT80)  nbytes = 10;    /* We must have at least nbytes+1 bytes left: one for type marker,       nbytes for the scalar itself. */    if (gc->tapeLen - gc->tapeIx < nbytes+1)        {        gc->status = WDB_ERR_GOPHER_TRUNCATED;        return ERROR;        }    /* Write the scalar type. */    gc->pTape [gc->tapeIx++] = type;    status = Backend_T::tgtRead_s ((TGT_ADDR_T) src,				   (void *) (gc->pTape + gc->tapeIx),				   nbytes);    if (status != OK)	{	gc->status = WDB_ERR_MEM_ACCES;	return ERROR;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -