/************************************************************************** * * Copyright (c) 2013 Alcatel-Lucent * * Alcatel Lucent licenses this file to You under the Apache License, * Version 2.0 (the "License"); you may not use this file except in * compliance with the License. A copy of the License is contained the * file LICENSE at the top level of this repository. * You may also obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ************************************************************************** * * 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. * * * Original author: Ed Sutter (ed.sutter@alcatel-lucent.com) * */ #include "config.h" #include "tfs.h" #include "tfsprivate.h" #include #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; itype) { 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; itype,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