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

📄 symexpr.c

📁 一个用在mips体系结构中的操作系统
💻 C
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * */#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <string.h>#include "cpu_interface.h"#include "symbols.h"#include "symfile.h"#include "symexpr.h"#include "sim_error.h"/*  CFL: * *     top   = exec:src:expr | exec:src:int *     expr  = *expr | &expr | (typecast) int | term *     term  = term.string | term->string | term[ int ] | term < int > | atom *     atom  = (expr) | string */#define MAX_STR_LEN 256#define BUFFER_SIZE 64int SymParseExpr(ParseInfo *pip);int SymParseTerm(ParseInfo *pip);int SymParseAtom(ParseInfo *pip);int SymParseField(ParseInfo *pip);int SymDeref(ParseInfo *pip);int SymParseTypeCast(ParseInfo *pip);char *SymParseString(ParseInfo *pip);int SymParseInt(char **str, Reg *val);static char ename[MAX_STR_LEN];static char fname[MAX_STR_LEN];int SymParse(char *symexpr, ParseInfo *pip){   int offset;   char *str = symexpr;   int line;      if (sscanf(str, "%[^:]%n", ename, &offset) != 1) {      ename[0] = '\0';   } else {      str += offset;   }   if (*str++ != ':') {      SymReportError("syntax error parsing execname", NULL);      return SYM_ERROR;   }   if (sscanf(str, "%[^:]%n", fname, &offset) != 1) {      fname[0] = '\0';   } else {      str += offset;   }   if (*str++ != ':') {      SymReportError("syntax error parsing source file name", NULL);      return SYM_ERROR;   }   if (isdigit(*str)) {      /* must be a line number */      if (sscanf(str, "%i%n", &line, &offset) != 1) {         SymReportError("expected a line number, got \"", str, "\"", NULL);         return SYM_ERROR;      }      if ((str[0] == '0') && (str[1] == '\0')) {         ASSERT(line == 0);         ASSERT(offset == 2);         /* WAR bug in scanf */         offset = 1;      }      str += offset;            if (SymLine2Addr(ename, fname, line, &(pip->sym)) != SYM_OK) {         return SYM_ERROR;      }      pip->value = SymValue(&(pip->sym));      pip->constant = 1;         } else {      pip->execname = ename;      pip->srcfile = fname;      pip->str = str;      pip->internal = (!strcmp(ename, "SIMOS"));#ifdef __alpha      if (pip->internal) {          return SYM_ERROR;      }#endif      if (SymParseExpr(pip) != SYM_OK) {         return SYM_ERROR;      }      str = pip->str;   }   if (*str != '\0') {      SymReportError("extra characters at end of expression\"", str, "\"", NULL);      return SYM_ERROR;   }      return SYM_OK;}int SymParseExpr(ParseInfo *pip){   int code;      if (pip->str[0] == '*') {      pip->str++;      if ((code = SymParseExpr(pip)) != SYM_OK) {         return code;      }      if ((code = SymDeref(pip)) != SYM_OK) {         return code;      }   } else if (pip->str[0] == '&') {      pip->str++;      if ((code = SymParseExpr(pip)) != SYM_OK) {         return code;      }      if (pip->constant) {         SymReportError("cannot take address of address", NULL);         return SYM_ERROR;      }      SymMakeAddr(&pip->sym);      pip->constant = 1;   } else if (pip->str[0] == '(') {      /*       *  OK here is the problem. This could be either a type cast or a        *  sub-expression. The way to figure this out is to read to the       *  matching end paren and see if the next token is anything but a       *  ".", "->", or a "[". We will just let SymParseTypeCast figure       *  it all out.       */      return SymParseTypeCast(pip);         } else {      return SymParseTerm(pip);   }   return SYM_OK;}int SymParseTerm(ParseInfo *pip){   int code;   if ((code = SymParseAtom(pip)) != SYM_OK) {      return code;   }      while (1) {      if (pip->str[0] == '.') {         pip->str++;                  if ((code = SymParseField(pip)) != SYM_OK) {            return code;         }               } else if ((pip->str[0] == '-') && (pip->str[1] == '>')) {         pip->str += 2;         if ((code = SymDeref(pip)) != SYM_OK) {            return code;         }         if ((code = SymParseField(pip)) != SYM_OK) {            return code;         }               } else if ((pip->str[0] == '[') || (pip->str[0] == '<')) {         Reg val;                  pip->str++;         if ((code = SymDeref(pip)) != SYM_OK) {            return code;         }         if ((code = SymParseInt(&(pip->str), &val)) != SYM_OK) {            return code;         }         if ((pip->str[0] != ']') && (pip->str[0] != '>')) {            SymReportError("\"]\" or \">\" expected", NULL);            return SYM_ERROR;         }         pip->str++;         pip->value += val * SymSize(&(pip->sym));      } else if (pip->str[0] == ':') {         char *symb;                  pip->str++;         if (SymType(&(pip->sym), SYM_RESOLVE) != tProc) {            SymReportError("can't use \":\" operator on non-procedure", NULL);            return SYM_ERROR;         }         if (!(symb = SymParseString(pip))) {            return SYM_ERROR;         }         if (!strcmp(symb, "START")) {                     } else if (!strcmp(symb, "STARTOPT")) {            pip->value += 12;         } else if (!strcmp(symb, "END")) {            pip->value += SymSize(&(pip->sym)) - 4;         } else if (SymFind(&(pip->sym), symb, 0) == SYM_OK) {            if (SymType(&(pip->sym), SYM_RESOLVE) != tLabel) {               SymReportError("symbol is not a label", NULL);               return SYM_ERROR;            }            pip->value = SymValue(&(pip->sym));         } else {            SymReportError("No such label in procedure", NULL);            return SYM_ERROR;         }         return SYM_OK;               } else {         return SYM_OK;      }   }   return SYM_OK;}int SymParseAtom(ParseInfo *pip){   int code;   int st;      if (pip->str[0] == '(') {      pip->str++;      if ((code = SymParseExpr(pip)) != SYM_OK) {         return code;      }      if (pip->str[0] != ')') {         SymReportError("\")\" expected", NULL);         return SYM_ERROR;      }      pip->str++;   } else if (isalpha(pip->str[0]) || (pip->str[0] == '_')) {      char *symb;      if (!(symb = SymParseString(pip))) {         return SYM_ERROR;      }      #ifdef DWARF2      if (Dwarf_SymLookup(pip->execname, pip->srcfile, symb, 0, &(pip->sym)) != SYM_OK) {         return SYM_ERROR;      }#else      if (SymLookup(pip->execname, pip->srcfile, symb, 0, &(pip->sym)) != SYM_OK) {         return SYM_ERROR;      }#endif      st = SymType(&(pip->sym), SYM_RESOLVE);            if ((st == tProc) || (st == tArray) || (st == tLabel)) {         pip->constant = 1;      } else {         pip->constant = 0;      }            pip->value = SymValue(&(pip->sym));   } else {      SymReportError("syntax error, expected \".\" or \"->\"", NULL);      return SYM_ERROR;   }   return SYM_OK;}int SymParseField(ParseInfo *pip){   char *symb;   int st;   st = SymType(&(pip->sym), SYM_RESOLVE);      if ((st != tStruct) && (st != tUnion)) {      SymReportError("expected a structure", NULL);      return SYM_ERROR;   }   ASSERT(!pip->constant);      if (SymSubtype(&(pip->sym), SYM_RESOLVE) != SYM_OK) {      return SYM_ERROR;   }   st = SymType(&(pip->sym), SYM_RESOLVE);      if ((st != tStructDef) && (st != tUnionDef)) {      ASSERT(0);      return SYM_ERROR;   }   if (!(symb = SymParseString(pip))) {      return SYM_ERROR;   }   if (SymFind(&(pip->sym), symb, 0) != SYM_OK) {      return SYM_ERROR;   }   st = SymType(&(pip->sym), SYM_RESOLVE);      if (st == tArray) {      pip->constant = 1;   } else {      ASSERT(st != tProc);   }    /* it seems all fields are in bit width */   ASSERT(!(SymValue(&(pip->sym)) % 8));      pip->value += SymValue(&(pip->sym)) / 8;   return SYM_OK;}int SymDeref(ParseInfo *pip){   Reg_s value = 0;   int st;   st = SymType(&(pip->sym), SYM_RESOLVE);      if (st == tPtr) {      if (pip->constant) {         pip->constant = 0;      } else if (pip->internal) {         /*          * XXX chances are that this is broken          * XXX for some configurations          */#ifdef __alpha         ASSERT (0);#else         pip->value = *(Reg_s*)pip->value;#endif               } else {         if (CPUVec.GetMemory(CPUVec.CurrentCpuNum(), pip->value,                              sizeof(value), (char *)&value) != SUCCESS) {            SymReportError("addr not mapped", NULL);            return SYM_ERROR;         }         pip->value = BE2HO_4(value);      }         } else if ((st == tAddr) || (st == tArray)) {      ASSERT(pip->constant);      pip->constant = 0;         } else {      SymReportError("array or pointer expected", NULL);      return SYM_ERROR;   }   ASSERT(!pip->constant);      if (SymSubtype(&(pip->sym), SYM_RESOLVE) != SYM_OK) {      return SYM_ERROR;   }   st = SymType(&(pip->sym), SYM_RESOLVE);   if (st == tArray) {      pip->constant = 1;   } else {      ASSERT(st != tProc);   }       return SYM_OK;}/* *   Type cast */static char *btNames[] = {   "char",   "uchar",   "short",   "ushort",    "int",   "uint",   "long",   "ulong",    "float",   "double",    "struct",   "union",   "enum"};static int btTypes[] = {   tChar,   tUChar,   tShort,   tUShort,   tInt,   tUInt,   tLong,   tULong,   tFloat,   tDouble,   tStruct,   tUnion,   tEnum};#define NUM_BTS      (sizeof(btNames)/sizeof(char*))int SymParseTypeCast(ParseInfo *pip){   char *str;   char *name = "";   char *scan;   int level, i;   int types[6];   int nextt;   int bt;      ASSERT(pip->str[0] == '(');   /* check if it is a typecast */   for (level=1, scan=pip->str+1; level && *scan; scan++) {      if (*scan == '(') {         level++;      } else if (*scan == ')') {         level--;      }   }   if ((*scan == '.') || (*scan == '[')       || (*scan == '<') || (*scan == ')') || (*scan == '\0')       || ((*scan == '-') && (*(scan+1) == '>'))) {      /* not a typecast - oh well just parse it as a term */      return SymParseTerm(pip);         }      /* its a type cast */   pip->str++;   nextt = 0;      str = SymParseString(pip);   bt = -1;    for (i=0; i<NUM_BTS; i++) {      if (!strcmp(str, btNames[i])) {         bt = btTypes[i];         break;      }   }   if (i == NUM_BTS) {      name = str;      bt = tTypedef;   } else if ((bt == tStruct)       || (bt == tUnion)       || (bt == tEnum)) {      while (*pip->str == ' ') {         pip->str++;      }      name = SymParseString(pip);         } else {      name = "";   }   while (1) {      while (*pip->str == ' ') {         pip->str++;      }            if (pip->str[0] == '*') {         types[nextt++] = tPtr;         pip->str++;      } else {         break;      }   }   types[nextt++] = bt;   types[nextt++] = tNil;   if ((types[0] != tPtr) && !((types[0] >= tChar) && (types[0] <= tDouble))) {      SymReportError("Can only cast to pointer or basic type", NULL);      return SYM_ERROR;         }      if (pip->str[0] != ')') {      SymReportError("Syntax error in type cast", NULL);      return SYM_ERROR;   }   pip->str++;      if (SymParseInt(&(pip->str), &(pip->value)) == SYM_OK) {      pip->constant = 1;   } else {      SymReportError("Only type casting hard coded constants suported so far. Sorry.",                     NULL);      return SYM_ERROR;#ifdef notdef      /* XXX fix */      if ((code = SymParseExpr(pip)) != SYM_OK) {         return code;      }      pip->constant = 0;#endif   }#ifdef DWARF2_not   if (Dwarf_SymTypeCast(pip->execname, pip->srcfile, types, name, &(pip->sym)) != SYM_OK) {      return SYM_ERROR;   }#else   if (SymTypeCast(pip->execname, pip->srcfile, types, name, &(pip->sym)) != SYM_OK) {      return SYM_ERROR;   }#endif   return SYM_OK;}int SymParseInt(char **str, Reg *val){   int offset;   while (**str == ' ') {      (*str)++;   }   if (isdigit(**str)) {      int i;      uint64 val64=0;#ifdef __alpha      i = sscanf(*str, "%li%n", &val64, &offset);#else      i = sscanf(*str, "%lli%n", &val64, &offset);#endif      *val = val64;      if (i != 1) {         return SYM_ERROR;      }      *str += offset;      while (**str == ' ') {         (*str)++;      }         } else {      SymReportError("expected an int, got \"", str, "\"", NULL);      return SYM_ERROR;   }   return SYM_OK;}char *SymParseString(ParseInfo *pip){   static char buf[BUFFER_SIZE];   char *dst = buf;   while (isalnum(*(pip->str)) || (*(pip->str) == '_')) {      if ((dst - buf) == (BUFFER_SIZE-1)) {         SymReportError("symbol overflowed internal buffers (internal error)", NULL);         return NULL;      }      *dst++ = *(pip->str)++;   }   *dst = '\0';   if (!buf[0]) {      SymReportError("expected a string", NULL);   }      return buf;}

⌨️ 快捷键说明

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