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

📄 cast.c

📁 umon bootloader source code, support mips cpu.
💻 C
字号:
/* cast.c:
 *  The cast command is used in the monitor to cast or overlay a structure
 *  onto a block of memory to display that memory in the format specified 
 *  by the structure.  The structure definition is found in the file
 *  "structfile" in TFS.  Valid types within structfile are
 *	char, char.c, char.x, short, short.x, long, long.x and struct name.
 *  Default format is decimal.  The '.x' extension tells cast to print
 *  in hex and the '.c' extension tells cast to print the actual character.
 *
 *	General notice:
 *	This code is part of a boot-monitor package developed as a generic base
 *	platform for embedded system designs.  As such, it is likely to be
 *	distributed to various projects beyond the control of the original
 *	author.  Please notify the author of any enhancements made or bugs found
 *	so that all may benefit from the changes.  In addition, notification back
 *	to the author will allow the new user to pick up changes that may have
 *	been made by other users after this version of the code was distributed.
 *
 *	Note1: the majority of this code was edited with 4-space tabs.
 *	Note2: as more and more contributions are accepted, the term "author"
 *		   is becoming a mis-representation of credit.
 *
 *	Original author:	Ed Sutter
 *	Email:				esutter@lucent.com
 *	Phone:				908-582-2351
 */
#include "config.h"
#include "tfs.h"
#include "tfsprivate.h"
#include "ctype.h"
#include "genlib.h"
#include "stddefs.h"
#include "cli.h"

#if INCLUDE_CAST

static	ulong memAddr;
static	int castDepth;

#define OPEN_BRACE	'{'
#define CLOSE_BRACE	'}'

#define STRUCT_SEARCH	1
#define STRUCT_DISPLAY	2
#define STRUCT_ALLDONE	3
#define STRUCT_ERROR	4

#define STRUCT_SHOWPAD	(1<<0)
#define STRUCT_SHOWADD	(1<<1)
#define STRUCT_VERBOSE	(1<<2)


#define STRUCTFILE "structfile"

struct mbrinfo {
	char *type;
	char *format;
	int	size;
	int mode;
};

struct mbrinfo mbrinfotbl[] = {
	{ "char",		"%d",		1 },		/* decimal */
	{ "char.x",		"0x%02x",	1 },		/* hex */
	{ "char.c",		"%c",		1 },		/* character */
	{ "short",		"%d",		2 },		/* decimal */
	{ "short.x",	"0x%04x",	2 },		/* hex */
	{ "long",		"%ld",		4 },		/* decimal */
	{ "long.x",		"0x%08lx",	4 },		/* hex */
	{ 0,0,0 }
};

/* castIndent():
 *	Used to insert initial whitespace based on the depth of the
 *	structure nesting.
 */
void
castIndent(void)
{
	int	i;

	for(i=0;i<castDepth;i++)
		printf("  ");
}

/* strAddr():
 *	Called by showStruct().  It will populate the incoming buffer pointer
 *	with either NULL or the ascii-hex representation of the current address
 *	pointer.
 */
char *
strAddr(long flags, char *buf)
{
	if (flags & STRUCT_SHOWADD)
		sprintf(buf,"0x%08lx: ",memAddr);
	else
		buf[0] = 0;
	return(buf);
}

/* showStruct():
 *	The workhorse of cast.  This function parses the structfile looking for
 *	the structure type; then it attempts to display the memory block that
 *	begins at memAddr as if it was the structure.  Note that there is no
 *	pre-processing done to verify valid syntax of the structure definition.
 */
int
showStruct(int tfd,long flags,char *structtype,char *structname,char *linkname)
{
	struct mbrinfo *mptr;
	ulong curpos, nextlink;
	int	i, state, snl, retval, tblsize;
	char line[96], addrstr[16], format[64];
	char *cp, *eol, *type, *eotype, *name, *bracket, *eoname, tmp;

	type = (char *)0;
	retval = nextlink = 0;
	curpos = tfsctrl(TFS_TELL,tfd,0);
	tfsseek(tfd,0,TFS_BEGIN);
	castIndent();
	if (structname)
		printf("struct %s %s:\n",structtype,structname);
	else
		printf("struct %s @0x%lx:\n",structtype,memAddr);
	castDepth++;

	state = STRUCT_SEARCH;
	snl = strlen(structtype);

	while(1) {
		if (tfsgetline(tfd,line,sizeof(line)-1) == 0) {
			printf("Structure definition '%s' not found\n",structtype);
			break;
		}
		if ((line[0] == '\r') || (line[0] == '\n'))	/* empty line? */
			continue;

		eol = strpbrk(line,";#\r\n");
		if (eol)
			*eol = 0;

		if (state == STRUCT_SEARCH) {
			if (!strncmp(line,"struct",6)) {
				cp = line+6;
				while(isspace(*cp))
					cp++;
				if (!strncmp(cp,structtype,snl)) {
					cp += snl;
					while(isspace(*cp))
						cp++;
					if (*cp == OPEN_BRACE) 
						state = STRUCT_DISPLAY;
					else {
						retval = -1;
						break;
					}
				}
			}
		}
		else if (state == STRUCT_DISPLAY) {
			type = line;
			while(isspace(*type))
				type++;

			if (*type == CLOSE_BRACE) {
				state = STRUCT_ALLDONE;
				break;
			}

			eotype = type;
			while(!isspace(*eotype))
				eotype++;
			*eotype = 0;
			name = eotype+1;
			while(isspace(*name))
				name++;
			bracket = strchr(name,'[');
			if (bracket)
				tblsize = atoi(bracket+1);						
			else
				tblsize = 1;

			if (*name == '*') {
				castIndent();
				printf("%s%-8s %s: ",strAddr(flags,addrstr),type,name);
				if (!strcmp(type,"char.c"))
					printf("\"%s\"\n",*(char **)memAddr);
				else
					printf("0x%lx\n",*(ulong *)memAddr);
				memAddr += 4;
				continue;
			}
			mptr = mbrinfotbl;			
			while(mptr->type) {
				if (!strcmp(type,mptr->type)) {
					castIndent();
					eoname = name;
					while(!isspace(*eoname))
						eoname++;
					tmp = *eoname;
					*eoname = 0;

					if (bracket) {
						if (!strcmp(type,"char.c")) {
							printf("%s%-8s %s: ",
								strAddr(flags,addrstr),mptr->type,name);
							cp = (char *)memAddr;
							for(i=0;i<tblsize && isprint(*cp);i++)
								printf("%c",*cp++);
							printf("\n");
						}
						else
							printf("%s%-8s %s\n",
								strAddr(flags,addrstr),mptr->type,name);
						memAddr += mptr->size * tblsize;
					}
					else {
						sprintf(format,"%s%-8s %%s: %s\n",
							strAddr(flags,addrstr),mptr->type,mptr->format);
						switch(mptr->size) {
							case 1:
								printf(format,name,*(uchar *)memAddr);
								break;
							case 2:
								printf(format,name,*(ushort *)memAddr);
								break;
							case 4:
								printf(format,name,*(ulong *)memAddr);
								break;
						}
						memAddr += mptr->size;
					}
					*eoname = tmp;
					break;
				}
				mptr++;
			}
			if (!(mptr->type)) {
				int	padsize;
				char *subtype, *subname, *eossn;

				if (!strcmp(type,"struct")) {
					subtype = eotype+1;
					while(isspace(*subtype))
						subtype++;
					subname = subtype;
					while(!isspace(*subname))
						subname++;
					*subname = 0;
					
					subname++;
					while(isspace(*subname))
						subname++;
					eossn = subname;
					while(!isspace(*eossn))
						eossn++;
					*eossn = 0;
					if (*subname == '*') {
						castIndent();
						printf("%s%s %s %s: 0x%08lx\n",strAddr(flags,addrstr),
							type,subtype,subname,*(ulong *)memAddr);
						if (linkname) {
							if (!strcmp(linkname,subname+1))
								nextlink = *(ulong *)memAddr;
						}
						memAddr += 4;
					}
					else {
						for (i=0;i<tblsize;i++) {
							if (bracket)
								sprintf(bracket+1,"%d]",i);
							if (showStruct(tfd,flags,subtype,subname,0) < 0) {
								state = STRUCT_ALLDONE;
								goto done;
							}
						}
					}
				}
				else if (!strncmp(type,"pad[",4)) {
					padsize = atoi(type+4);
					if (flags & STRUCT_SHOWPAD) {
						castIndent();
						printf("%spad[%d]\n",strAddr(flags,addrstr),padsize);
					}
					memAddr += padsize;
				}
				else  {
					retval = -1;
					break;
				}
			}
		}
		else {
			state = STRUCT_ERROR;
			break;
		}
	}
done:

	switch(state) {
		case STRUCT_SEARCH:
			printf("struct %s not found\n",structtype);
			retval = -1;
			break;
		case STRUCT_DISPLAY:
			printf("invalid member type: %s\n",type);
			retval = -1;
			break;
		case STRUCT_ERROR:
			printf("unknown error\n");
			retval = -1;
			break;
	}
	tfsseek(tfd,curpos,TFS_BEGIN);
	if (linkname)
		memAddr = nextlink;
	castDepth--;
	return(retval);
}

char *CastHelp[] = {
	"Cast a structure definition across data in memory.",
	"-[al:n:pt:] {struct type} {address}",
#if INCLUDE_VERBOSEHELP
	"Options:",
	" -a   show addresses",
	" -l{linkname}",
	" -n{structname}",
	" -p   show padding",
	" -t{tablename}",
#endif
	0,
};

int
Cast(int argc,char *argv[])
{
	long	flags;
	int		opt, tfd, index;
	char	*structtype, *structfile, *tablename, *linkname, *name;

	flags = 0;
	name = (char *)0;
	linkname = (char *)0;
	tablename = (char *)0;
	while((opt=getopt(argc,argv,"apl:n:t:")) != -1) {
		switch(opt) {
		case 'a':
			flags |= STRUCT_SHOWADD;
			break;
		case 'l':
			linkname = optarg;
			break;
		case 'n':
			name = optarg;
			break;
		case 'p':
			flags |= STRUCT_SHOWPAD;
			break;
		case 't':
			tablename = optarg;
			break;
		default:
			return(CMD_PARAM_ERROR);
		}
	}
	if (argc != optind + 2)
		return(CMD_PARAM_ERROR);

	structtype = argv[optind];
	memAddr = strtoul(argv[optind+1],0,0);

	/* Start by detecting the presence of a structure definition file... */
	structfile = getenv("STRUCTFILE");
	if (!structfile)
		structfile = STRUCTFILE;

	tfd = tfsopen(structfile,TFS_RDONLY,0);
	if (tfd < 0) {
		printf("Structure definition file '%s' not found\n",structfile);
		return(CMD_FAILURE);
	}

	index = 0;
	do {
		castDepth = 0;
		showStruct(tfd,flags,structtype,name,linkname);
		index++;
		if (linkname)
			printf("Link #%d = 0x%lx\n",index,memAddr);
		if (tablename || linkname) {
			if (askuser("next?"))  {
				if (tablename)
					printf("%s[%d]:\n",tablename,index);
			}
			else
				tablename = linkname = (char *)0;
		}
	} while(tablename || linkname);

	tfsclose(tfd,0);
	return(CMD_SUCCESS);
}
#endif

⌨️ 快捷键说明

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