Extracted commonalities between SYM and STKSYM into SymbolCommon and

between SYMTAB and STKFRAME into SymbolTableCommon<STKSYM>
This commit is contained in:
Artur K 2012-03-13 01:22:13 +01:00
parent d3e62a99aa
commit 902a5ec3d8
15 changed files with 311 additions and 290 deletions

View File

@ -3,39 +3,22 @@
#include <cstring>
#include "types.h"
#include "Enums.h"
struct COND_EXPR;
/* STACK FRAME */
struct STKSYM
{
COND_EXPR *actual; /* Expression tree of actual parameter */
COND_EXPR *regs; /* For register arguments only */
int16_t off; /* Immediate off from BP (+:args, -:params) */
uint8_t regOff; /* Offset is a register (e.g. SI, DI) */
int size; /* Size */
hlType type; /* Probable type */
eDuVal duVal; /* DEF, USE, VAL */
boolT hasMacro; /* This type needs a macro */
char macro[10]; /* Macro name */
char name[10]; /* Name for this symbol/argument */
bool invalid; /* Boolean: invalid entry in formal arg list*/
STKSYM()
{
memset(this,0,sizeof(STKSYM));
}
};
#include "symtab.h"
struct STKFRAME
struct STKFRAME : public SymbolTableCommon<STKSYM>
{
std::vector<STKSYM> sym;
//std::vector<STKSYM> sym;
//STKSYM * sym; /* Symbols */
int16_t m_minOff; /* Initial offset in stack frame*/
int16_t maxOff; /* Maximum offset in stack frame*/
int cb; /* Number of bytes in arguments */
int numArgs; /* No. of arguments in the table*/
void adjustForArgType(int numArg_, hlType actType_);
STKFRAME() : sym(0),m_minOff(0),maxOff(0),cb(0),numArgs(0)
STKFRAME() : m_minOff(0),maxOff(0),cb(0),numArgs(0)
{
}
size_t getLocVar(int off);
public:
void updateFrameOff(int16_t off, int size, uint16_t duFlag);
};

View File

@ -21,27 +21,6 @@
#include "Procedure.h"
#include "BasicBlock.h"
typedef llvm::iplist<Function> FunctionListType;
typedef FunctionListType lFunction;
typedef lFunction::iterator ilFunction;
/* SYMBOL TABLE */
struct SYM
{
SYM() : label(0),size(0),flg(0),type(TYPE_UNKNOWN)
{
}
char name[10]; /* New name for this variable */
uint32_t label; /* physical address (20 bit) */
int size; /* maximum size */
uint32_t flg; /* SEG_IMMED, IMPURE, WORD_OFF */
hlType type; /* probable type */
eDuVal duVal; /* DEF, USE, VAL */
};
typedef std::vector<SYM> SYMTAB;
/* CALL GRAPH NODE */
struct CALL_GRAPH
{
@ -134,7 +113,6 @@ extern STATS stats; /* Icode statistics */
/**** Global function prototypes ****/
void FrontEnd(char *filename, CALL_GRAPH * *); /* frontend.c */
void *allocMem(int cb); /* frontend.c */
void udm(void); /* udm.c */
void freeCFG(BB * cfg); /* graph.c */
@ -167,7 +145,7 @@ hlType expType (const COND_EXPR *, Function *);
/* Exported functions from hlicode.c */
std::string writeCall (Function *, STKFRAME *, Function *, int *);
std::string writeCall (Function *, STKFRAME &, Function *, int *);
char *writeJcond (const HLTYPE &, Function *, int *);
char *writeJcondInv (HLTYPE, Function *, int *);

View File

@ -65,7 +65,7 @@ struct ID
frameType loc; /* Frame location */
bool hasMacro; /* Identifier requires a macro */
char macro[10]; /* Macro for this identifier */
char name[20]; /* Identifier's name */
std::string name; /* Identifier's name */
union { /* Different types of identifiers */
eReg regi; /* For TYPE_BYTE(uint16_t)_(UN)SIGN registers */
struct { /* For TYPE_BYTE(uint16_t)_(UN)SIGN on the stack */
@ -95,9 +95,9 @@ struct ID
}
void setLocalName(int i)
{
// char buf[32];
//sprintf (buf, "loc%ld", i);
//name=buf;
char buf[32];
sprintf (buf, "loc%ld", i);
name=buf;
}
};

View File

@ -12,6 +12,76 @@ struct TypeContainer;
/* * * * * * * * * * * * * * * * * */
/* Symbol table structs and protos */
/* * * * * * * * * * * * * * * * * */
struct SymbolCommon
{
std::string name; /* New name for this variable/symbol/argument */
int size; /* Size/maximum size */
hlType type; /* probable type */
eDuVal duVal; /* DEF, USE, VAL */
SymbolCommon() : size(0),type(TYPE_UNKNOWN)
{}
};
struct SYM : public SymbolCommon
{
SYM() : label(0),flg(0)
{
}
int32_t label; /* physical address (20 bit) */
uint32_t flg; /* SEG_IMMED, IMPURE, WORD_OFF */
};
/* STACK FRAME */
struct STKSYM : public SymbolCommon
{
COND_EXPR *actual; /* Expression tree of actual parameter */
COND_EXPR *regs; /* For register arguments only */
int16_t label; /* Immediate off from BP (+:args, -:params) */
uint8_t regOff; /* Offset is a register (e.g. SI, DI) */
bool hasMacro; /* This type needs a macro */
std::string macro; /* Macro name */
bool invalid; /* Boolean: invalid entry in formal arg list*/
STKSYM()
{
actual=regs=0;
label=0;
regOff=0;
invalid=hasMacro = false;
}
void setArgName(int i)
{
char buf[32];
sprintf (buf, "arg%ld", i);
name = buf;
}
};
template<class T>
class SymbolTableCommon : public std::vector<T>
{
public:
typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_iterator;
iterator findByLabel(int lab)
{
auto iter = std::find_if(this->begin(),this->end(),
[lab](T &s)->bool {return s.label==lab;});
return iter;
}
const_iterator findByLabel(int lab) const
{
auto iter = std::find_if(this->begin(),this->end(),
[lab](const T &s)->bool {return s.label==lab;});
return iter;
}
};
/* SYMBOL TABLE */
class SYMTAB : public SymbolTableCommon<SYM>
{
public:
void updateSymType(uint32_t symbol, const TypeContainer &tc);
SYM *updateGlobSym(uint32_t operand, int size, uint16_t duFlag, bool &inserted_new);
};
struct Function;
struct SYMTABLE
{

View File

@ -183,7 +183,7 @@ COND_EXPR *COND_EXPR::idLoc(int off, LOCAL_ID *localId)
if (i == localId->csym())
printf ("Error, cannot find local var\n");
newExp->expr.ident.idNode.localIdx = i;
sprintf (localId->id_arr[i].name, "loc%ld", i);
localId->id_arr[i].setLocalName(i);
return (newExp);
}
@ -192,15 +192,13 @@ COND_EXPR *COND_EXPR::idLoc(int off, LOCAL_ID *localId)
COND_EXPR *COND_EXPR::idParam(int off, const STKFRAME * argSymtab)
{
COND_EXPR *newExp;
size_t i;
newExp = new COND_EXPR(IDENTIFIER);
newExp->expr.ident.idType = PARAM;
for (i = 0; i < argSymtab->sym.size(); i++)
if (argSymtab->sym[i].off == off)
break;
if (i == argSymtab->sym.size()) printf ("Error, cannot find argument var\n");
newExp->expr.ident.idNode.localIdx = i;
auto iter=argSymtab->findByLabel(off);
if (iter == argSymtab->end())
printf ("Error, cannot find argument var\n");
newExp->expr.ident.idNode.localIdx = distance(argSymtab->begin(),iter);
return (newExp);
}
@ -489,7 +487,7 @@ int hlTypeSize (const COND_EXPR *expr, Function * pproc)
case LOCAL_VAR:
return (hlSize[pproc->localId.id_arr[expr->expr.ident.idNode.localIdx].type]);
case PARAM:
return (hlSize[pproc->args.sym[expr->expr.ident.idNode.paramIdx].type]);
return (hlSize[pproc->args[expr->expr.ident.idNode.paramIdx].type]);
case GLOB_VAR_IDX:
return (hlSize[pproc->localId.id_arr[expr->expr.ident.idNode.idxGlbIdx].type]);
case CONSTANT:
@ -552,7 +550,7 @@ hlType expType (const COND_EXPR *expr, Function * pproc)
case LOCAL_VAR:
return (pproc->localId.id_arr[expr->expr.ident.idNode.localIdx].type);
case PARAM:
return (pproc->args.sym[expr->expr.ident.idNode.paramIdx].type);
return (pproc->args[expr->expr.ident.idNode.paramIdx].type);
case GLOB_VAR_IDX:
return (pproc->localId.id_arr[expr->expr.ident.idNode.idxGlbIdx].type);
case CONSTANT:
@ -708,7 +706,7 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
id = &pProc->localId.id_arr[expr->expr.ident.idNode.regiIdx];
if (id->name[0] == '\0') /* no name */
{
sprintf (id->name, "loc%ld", ++(*numLoc));
id->setLocalName(++(*numLoc));
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
codeOut <<"/* "<<Machine_X86::regName(id->id.regi)<<" */\n";
}
@ -723,7 +721,7 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
break;
case PARAM:
psym = &pProc->args.sym[expr->expr.ident.idNode.paramIdx];
psym = &pProc->args[expr->expr.ident.idNode.paramIdx];
if (psym->hasMacro)
o << psym->macro<<"("<<psym->name<< ")";
else
@ -752,12 +750,12 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
o << id->name;
else if (id->loc == REG_FRAME)
{
sprintf (id->name, "loc%ld", ++(*numLoc));
id->setLocalName(++(*numLoc));
codeOut <<TypeContainer::typeName(id->type)<< " "<<id->name<<"; ";
codeOut <<"/* "<<Machine_X86::regName(id->id.longId.h) << ":" <<
Machine_X86::regName(id->id.longId.l) << " */\n";
o << id->name;
pProc->localId.propLongId (id->id.longId.l,id->id.longId.h, id->name);
pProc->localId.propLongId (id->id.longId.l,id->id.longId.h, id->name.c_str());
}
else /* GLB_FRAME */
{
@ -769,7 +767,7 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
break;
case FUNCTION:
o << writeCall (expr->expr.ident.idNode.call.proc,expr->expr.ident.idNode.call.args, pProc, numLoc);
o << writeCall (expr->expr.ident.idNode.call.proc,*expr->expr.ident.idNode.call.args, pProc, numLoc);
break;
case OTHER:
@ -786,7 +784,6 @@ string walkCondExpr (const COND_EXPR* expr, Function * pProc, int* numLoc)
break;
}
cCode.appendDecl(codeOut.str());
return outStr.str();
}

View File

@ -94,35 +94,39 @@ char *cChar (uint8_t c)
* Note: to get to the value of the variable:
* com file: prog.Image[operand]
* exe file: prog.Image[operand+0x100] */
static void printGlobVar (std::ostream &ostr,SYM * psym);
static void printGlobVar (SYM * psym)
{
std::ostringstream ostr;
printGlobVar(ostr,psym);
cCode.appendDecl(ostr.str());
}
static void printGlobVar (std::ostream &ostr,SYM * psym)
{
int j;
uint32_t relocOp = prog.fCOM ? psym->label : psym->label + 0x100;
switch (psym->size)
{
case 1: cCode.appendDecl( "uint8_t\t%s = %ld;\n",
psym->name, prog.Image[relocOp]);
case 1:
ostr << "uint8_t\t"<<psym->name<<" = "<<prog.Image[relocOp]<<";\n";
break;
case 2: cCode.appendDecl( "uint16_t\t%s = %ld;\n",
psym->name, LH(prog.Image+relocOp));
case 2:
ostr << "uint16_t\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n";
break;
case 4: if (psym->type == TYPE_PTR) /* pointer */
cCode.appendDecl( "uint16_t\t*%s = %ld;\n",
psym->name, LH(prog.Image+relocOp));
ostr << "uint16_t *\t"<<psym->name<<" = "<<LH(prog.Image+relocOp)<<";\n";
else /* char */
cCode.appendDecl(
"char\t%s[4] = \"%c%c%c%c\";\n",
psym->name, prog.Image[relocOp],
prog.Image[relocOp+1], prog.Image[relocOp+2],
prog.Image[relocOp+3]);
ostr << "char\t"<<psym->name<<"[4] = \""<<
prog.Image[relocOp]<<prog.Image[relocOp+1]<<
prog.Image[relocOp+2]<<prog.Image[relocOp+3]<<";\n";
break;
default:
{
ostringstream strContents;
for (j=0; j < psym->size; j++)
strContents << cChar(prog.Image[relocOp + j]);
cCode.appendDecl( "char\t*%s = \"%s\";\n", psym->name, strContents.str().c_str());
ostr << "char\t*"<<psym->name<<" = \""<<strContents.str()<<"\";\n";
}
}
}
@ -133,32 +137,31 @@ static void printGlobVar (SYM * psym)
* initialization. */
static void writeGlobSymTable()
{
char type[10];
std::ostringstream ostr;
if (not symtab.empty())
{
cCode.appendDecl( "/* Global variables */\n");
if (symtab.empty())
return;
ostr<<"/* Global variables */\n";
for (SYM &sym : symtab)
{
if (sym.duVal.isUSE_VAL()) /* first used */
printGlobVar (&sym);
printGlobVar (ostr,&sym);
else { /* first defined */
switch (sym.size) {
case 1: strcpy (type, "uint8_t\t"); break;
case 2: strcpy (type, "int\t"); break;
case 1: ostr<<"uint8_t\t"; break;
case 2: ostr<<"int\t"; break;
case 4: if (sym.type == TYPE_PTR)
strcpy (type, "int\t*");
ostr<<"int\t*";
else
strcpy (type, "char\t*");
ostr<<"char\t*";
break;
default: strcpy (type, "char\t*");
default: ostr<<"char\t*";
}
cCode.appendDecl( "%s%s;\t/* size = %ld */\n",
type, sym.name, sym.size);
ostr<<sym.name<<";\t/* size = "<<sym.size<<" */\n";
}
}
cCode.appendDecl( "\n");
}
ostr<< "\n";
cCode.appendDecl( ostr.str() );
}
@ -202,7 +205,7 @@ static void emitFwdGotoLabel (ICODE * pt, int indLevel)
void Function::codeGen (std::ostream &fs)
{
int numLoc;
ostringstream buf;
ostringstream ostr;
//STKFRAME * args; /* Procedure arguments */
//char buf[200], /* Procedure's definition */
// arg[30]; /* One argument */
@ -211,22 +214,21 @@ void Function::codeGen (std::ostream &fs)
/* Write procedure/function header */
newBundle (&cCode);
if (flg & PROC_IS_FUNC) /* Function */
cCode.appendDecl( "\n%s %s (", hlTypes[retVal.type],name.c_str());
ostr<< "\n"<<TypeContainer::typeName(retVal.type)<<" "<<name<<" (";
else /* Procedure */
cCode.appendDecl( "\nvoid %s (", name.c_str());
ostr<< "\nvoid "<<name<<" (";
/* Write arguments */
for (size_t i = 0; i < args.sym.size(); i++)
for (size_t i = 0; i < args.size(); i++)
{
if (args.sym[i].invalid == false)
{
buf<<hlTypes[args.sym[i].type]<<" "<<args.sym[i].name;
if (i < (args.sym.size() - 1))
buf<<", ";
}
if ( args[i].invalid )
continue;
ostr<<hlTypes[args[i].type]<<" "<<args[i].name;
if (i < (args.size() - 1))
ostr<<", ";
}
buf<<")\n";
cCode.appendDecl( buf.str() );
ostr<<")\n";
cCode.appendDecl( ostr.str() );
/* Write comments */
writeProcComments();
@ -238,27 +240,25 @@ void Function::codeGen (std::ostream &fs)
for (ID &refId : localId )
{
/* Output only non-invalidated entries */
if (refId.illegal == false)
if ( refId.illegal )
continue;
if (refId.loc == REG_FRAME)
{
if (refId.loc == REG_FRAME)
{
/* Register variables are assigned to a local variable */
if (((flg & SI_REGVAR) && (refId.id.regi == rSI)) ||
/* Register variables are assigned to a local variable */
if (((flg & SI_REGVAR) && (refId.id.regi == rSI)) ||
((flg & DI_REGVAR) && (refId.id.regi == rDI)))
{
sprintf (refId.name, "loc%ld", ++numLoc);
cCode.appendDecl( "int %s;\n", refId.name);
}
/* Other registers are named when they are first used in
* the output C code, and appended to the proc decl. */
}
else if (refId.loc == STK_FRAME)
{
/* Name local variables and output appropriate type */
sprintf (refId.name, "loc%ld", ++numLoc);
cCode.appendDecl( "%s %s;\n",hlTypes[refId.type], refId.name);
refId.setLocalName(++numLoc);
cCode.appendDecl( "int %s;\n", refId.name.c_str());
}
/* Other registers are named when they are first used in
* the output C code, and appended to the proc decl. */
}
else if (refId.loc == STK_FRAME)
{
/* Name local variables and output appropriate type */
refId.setLocalName(++numLoc);
cCode.appendDecl( "%s %s;\n",hlTypes[refId.type], refId.name.c_str());
}
}
}

View File

@ -480,10 +480,10 @@ bool LibCheck(Function & pProc)
the appropriate field */
arg = pFunc[i].firstArg;
pProc.args.numArgs = pFunc[i].numArg;
pProc.args.sym.resize(pFunc[i].numArg);
pProc.args.resize(pFunc[i].numArg);
for (j=0; j < pFunc[i].numArg; j++)
{
pProc.args.sym[j].type = pArg[arg++];
pProc.args[j].type = pArg[arg++];
}
if (pFunc[i].typ != TYPE_UNKNOWN)
{

View File

@ -204,7 +204,7 @@ void Function::writeProcComments(std::ostream &ostr)
ostr << "/* Uses register arguments:\n";
for (i = 0; i < this->args.numArgs; i++)
{
psym = &this->args.sym[i];
psym = &this->args[i];
ostr << " * "<<psym->name<<" = ";
if (psym->regs->expr.ident.idType == REGISTER)
{

View File

@ -75,12 +75,8 @@ ExpStack g_exp_stk;
* is in the stack frame provided. */
size_t STKFRAME::getLocVar(int off)
{
size_t i;
for (i = 0; i < sym.size(); i++)
if (sym[i].off == off)
break;
return (i);
auto iter=findByLabel(off);
return distance(begin(),iter);
}
@ -686,11 +682,11 @@ static int processCArg (Function * pp, Function * pProc, ICODE * picode, int num
if (pp->args.numArgs > 0)
if (pp->flg & PROC_VARARG)
{
if (numArgs < pp->args.sym.size())
adjustActArgType (_exp, pp->args.sym[numArgs].type, pProc);
if (numArgs < pp->args.size())
adjustActArgType (_exp, pp->args[numArgs].type, pProc);
}
else
adjustActArgType (_exp, pp->args.sym[numArgs].type, pProc);
adjustActArgType (_exp, pp->args[numArgs].type, pProc);
}
else /* user function */
{
@ -774,7 +770,7 @@ void Function::processHliCall(COND_EXPR *_exp, iICODE picode)
if (pp->flg & PROC_ISLIB) /* library function */
{
if (pp->args.numArgs > 0)
adjustActArgType(_exp, pp->args.sym[numArgs].type, this);
adjustActArgType(_exp, pp->args[numArgs].type, this);
res = picode->newStkArg (_exp, (llIcode)picode->ll()->getOpcode(), this);
}
else /* user function */

View File

@ -487,20 +487,20 @@ COND_EXPR *COND_EXPR::inverse () const
/* Returns the string that represents the procedure call of tproc (ie. with
* actual parameters) */
std::string writeCall (Function * tproc, STKFRAME * args, Function * pproc, int *numLoc)
std::string writeCall (Function * tproc, STKFRAME & args, Function * pproc, int *numLoc)
{
int i; /* counter of # arguments */
string condExp;
ostringstream s;
s<<tproc->name<<" (";
for (i = 0; i < args->sym.size(); i++)
ostringstream ostr;
ostr<<tproc->name<<" (";
for(const STKSYM &sym : args)
{
s << walkCondExpr (args->sym[i].actual, pproc, numLoc);
if (i < (args->sym.size() - 1))
s << ", ";
ostr << walkCondExpr (sym.actual, pproc, numLoc);
if((&sym)!=&(args.back()))
ostr << ", ";
}
s << ")";
return s.str();
ostr << ")";
return ostr.str();
}
@ -547,7 +547,7 @@ string AssignType::writeOut(Function *pProc, int *numLoc)
string CallType::writeOut(Function *pProc, int *numLoc)
{
ostringstream ostr;
ostr << writeCall (proc, args, pProc,numLoc);
ostr << writeCall (proc, *args, pProc,numLoc);
ostr << ";\n";
return ostr.str();
}

View File

@ -204,7 +204,7 @@ void Function::findIdioms()
}
/* Check if number of parameter bytes match their calling convention */
if ((flg & PROC_HLL) && (!args.sym.empty()))
if ((flg & PROC_HLL) && (!args.empty()))
{
args.m_minOff += (flg & PROC_FAR ? 4 : 2);
delta = args.maxOff - args.m_minOff;

View File

@ -420,28 +420,23 @@ eReg otherLongRegi (eReg regi, int idx, LOCAL_ID *locTbl)
* long register identifier. */
void LOCAL_ID::propLongId (uint8_t regL, uint8_t regH, const char *name)
{
int i;
ID *_id;
for (i = 0; i < id_arr.size(); i++)
for (ID &rid : id_arr)
{
_id = &id_arr[i];
if (_id->typeBitsize()==16)
if (rid.typeBitsize()!=16)
continue;
if ( (rid.id.regi != regL) and (rid.id.regi != regH) )
continue;
// otherwise at least 1 is ok
rid.name = name;
rid.hasMacro = true;
rid.illegal = true;
if (rid.id.regi == regL)
{
if (_id->id.regi == regL)
{
strcpy (_id->name, name);
strcpy (_id->macro, "LO");
_id->hasMacro = true;
_id->illegal = true;
strcpy (rid.macro, "LO");
}
else if (_id->id.regi == regH)
else // if (rid.id.regi == regH)
{
strcpy (_id->name, name);
strcpy (_id->macro, "HI");
_id->hasMacro = true;
_id->illegal = true;
}
strcpy (rid.macro, "HI");
}
}
}

View File

@ -14,7 +14,7 @@ using namespace std;
//static void FollowCtrl (Function * pProc, CALL_GRAPH * pcallGraph, STATE * pstate);
static boolT process_JMP (ICODE * pIcode, STATE * pstate, CALL_GRAPH * pcallGraph);
static void setBits(int16_t type, uint32_t start, uint32_t len);
static SYM * updateGlobSym(uint32_t operand, int size, uint16_t duFlag);
//static SYM * updateGlobSym(uint32_t operand, int size, uint16_t duFlag,bool &created);
static void process_MOV(LLInst &ll, STATE * pstate);
static SYM * lookupAddr (LLOperand *pm, STATE * pstate, int size, uint16_t duFlag);
void interactDis(Function * initProc, int ic);
@ -718,77 +718,32 @@ static void process_MOV(LLInst & ll, STATE * pstate)
}
/* Type of the symbol according to the number of bytes it uses */
static hlType cbType[] = {TYPE_UNKNOWN, TYPE_BYTE_UNSIGN, TYPE_WORD_SIGN,
TYPE_UNKNOWN, TYPE_LONG_SIGN};
/* Creates an entry in the global symbol table (symtab) if the variable
* is not there yet. If it is part of the symtab, the size of the variable
* is checked and updated if the old size was less than the new size (ie.
* the maximum size is always saved). */
static SYM * updateGlobSym (uint32_t operand, int size, uint16_t duFlag)
{
int i;
/* Check for symbol in symbol table */
for (i = 0; i < symtab.size(); i++)
if (symtab[i].label == operand)
{
if (symtab[i].size < size)
symtab[i].size = size;
break;
}
/* New symbol, not in symbol table */
if (i == symtab.size())
{
SYM v;
sprintf (v.name, "var%05lX", operand);
v.label = operand;
v.size = size;
v.type = cbType[size];
if (duFlag == eDuVal::USE) /* must already have init value */
{
v.duVal.use =1; // USEVAL;
v.duVal.val =1;
}
else
{
v.duVal.setFlags(duFlag);
}
symtab.push_back(v);
}
return (&symtab[i]);
}
/* Updates the offset entry to the stack frame table (arguments),
* and returns a pointer to such entry. */
static void updateFrameOff (STKFRAME * ps, int16_t off, int size, uint16_t duFlag)
void STKFRAME::updateFrameOff ( int16_t off, int _size, uint16_t duFlag)
{
int i;
/* Check for symbol in stack frame table */
for (i = 0; i < ps->sym.size(); i++)
auto iter=findByLabel(off);
if(iter!=end())
{
if (ps->sym[i].off == off)
if (iter->size < _size)
{
if (ps->sym[i].size < size)
{
ps->sym[i].size = size;
iter->size = _size;
}
break;
}
}
/* New symbol, not in table */
if (i == ps->sym.size())
else
{
char nm[16];
STKSYM new_sym;
sprintf (new_sym.name, "arg%ld", i);
new_sym.off = off;
new_sym.size = size;
new_sym.type = cbType[size];
sprintf (nm, "arg%ld", size());
new_sym.name = nm;
new_sym.label= off;
new_sym.size = _size;
new_sym.type = TypeContainer::defaultTypeForSize(_size);
if (duFlag == eDuVal::USE) /* must already have init value */
{
new_sym.duVal.use=1;
@ -798,13 +753,13 @@ static void updateFrameOff (STKFRAME * ps, int16_t off, int size, uint16_t duFla
{
new_sym.duVal.setFlags(duFlag);
}
ps->sym.push_back(new_sym);
ps->numArgs++;
push_back(new_sym);
this->numArgs++;
}
/* Save maximum argument offset */
if ((uint32_t)ps->maxOff < (off + (uint32_t)size))
ps->maxOff = off + (int16_t)size;
if ((uint32_t)this->maxOff < (off + (uint32_t)_size))
this->maxOff = off + (int16_t)_size;
}
@ -815,29 +770,26 @@ static void updateFrameOff (STKFRAME * ps, int16_t off, int size, uint16_t duFla
static SYM * lookupAddr (LLOperand *pm, STATE *pstate, int size, uint16_t duFlag)
{
int i;
SYM * psym;
SYM * psym=nullptr;
uint32_t operand;
bool created_new=false;
if (pm->regi != rUNDEF)
return nullptr; // register or indexed
if (pm->regi == 0)
{
/* Global var */
if (pm->segValue) { /* there is a value in the seg field */
if (pm->segValue) /* there is a value in the seg field */
{
operand = opAdr (pm->segValue, pm->off);
psym = updateGlobSym (operand, size, duFlag);
/* Check for out of bounds */
if (psym->label >= (uint32_t)prog.cbImage)
return (NULL);
return (psym);
psym = symtab.updateGlobSym (operand, size, duFlag,created_new);
}
else if (pstate->f[pm->seg]) { /* new value */
else if (pstate->f[pm->seg]) /* new value */
{
pm->segValue = pstate->r[pm->seg];
operand = opAdr(pm->segValue, pm->off);
i = symtab.size();
psym = updateGlobSym (operand, size, duFlag);
psym = symtab.updateGlobSym (operand, size, duFlag,created_new);
/* Flag new memory locations that are segment values */
if (symtab.size() > i)
if (created_new)
{
if (size == 4)
operand += 2; /* High uint16_t */
@ -847,14 +799,11 @@ static SYM * lookupAddr (LLOperand *pm, STATE *pstate, int size, uint16_t duFlag
break;
}
}
/* Check for out of bounds */
if (psym->label >= (uint32_t)prog.cbImage)
return (NULL);
return (psym);
}
}
return (NULL);
/* Check for out of bounds */
if (psym && (psym->label>=0) and (psym->label < (uint32_t)prog.cbImage))
return psym;
return nullptr;
}
@ -944,7 +893,7 @@ static void use (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
if (pm->regi == INDEX_BP) /* indexed on bp */
{
if (pm->off >= 2)
updateFrameOff (&pProc->args, pm->off, size, eDuVal::USE);
pProc->args.updateFrameOff ( pm->off, size, eDuVal::USE);
else if (pm->off < 0)
pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, 0);
}
@ -991,7 +940,7 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
if (pm->regi == INDEX_BP) /* indexed on bp */
{
if (pm->off >= 2)
updateFrameOff (&pProc->args, pm->off, size, eDEF);
pProc->args.updateFrameOff ( pm->off, size, eDEF);
else if (pm->off < 0)
pProc->localId.newByteWordStk (TYPE_WORD_SIGN, pm->off, 0);
}
@ -1016,7 +965,7 @@ static void def (opLoc d, ICODE & pIcode, Function * pProc, STATE * pstate, int
{
setBits(BM_DATA, psym->label, (uint32_t)size);
pIcode.ll()->setFlags(SYM_DEF);
pIcode.ll()->caseTbl.numEntries = psym - &symtab[0];
pIcode.ll()->caseTbl.numEntries = distance(&symtab[0],psym);
}
}

View File

@ -132,7 +132,7 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
/* Check if register argument already on the formal argument list */
regExist = false;
for(STKSYM &tgt_sym : target_stackframe->sym)
for(STKSYM &tgt_sym : *target_stackframe)
{
if (type == REGISTER)
{
@ -158,7 +158,9 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
if (regExist == false)
{
STKSYM newsym;
sprintf (newsym.name, "arg%ld", target_stackframe->sym.size());
newsym.setArgName(target_stackframe->size());
if (type == REGISTER)
{
if (regL < rAL)
@ -171,23 +173,22 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
newsym.type = TYPE_BYTE_SIGN;
newsym.regs = COND_EXPR::idRegIdx(tidx, BYTE_REG);
}
sprintf (tproc->localId.id_arr[tidx].name, "arg%ld", target_stackframe->sym.size());
tproc->localId.id_arr[tidx].name = newsym.name;
}
else if (type == LONG_VAR)
{
newsym.regs = COND_EXPR::idLongIdx (tidx);
newsym.type = TYPE_LONG_SIGN;
sprintf (tproc->localId.id_arr[tidx].name, "arg%ld", target_stackframe->sym.size());
tproc->localId.propLongId (regL, regH,
tproc->localId.id_arr[tidx].name);
tproc->localId.id_arr[tidx].name = newsym.name;
tproc->localId.propLongId (regL, regH, tproc->localId.id_arr[tidx].name.c_str());
}
target_stackframe->sym.push_back(newsym);
target_stackframe->push_back(newsym);
target_stackframe->numArgs++;
}
/* Do ps (actual arguments) */
STKSYM newsym;
sprintf (newsym.name, "arg%ld", call_args_stackframe->sym.size());
newsym.setArgName(call_args_stackframe->size());
newsym.actual = picode->hl()->asgn.rhs;
newsym.regs = lhs;
/* Mask off high and low register(s) in picode */
@ -207,15 +208,15 @@ void Function::newRegArg(iICODE picode, iICODE ticode)
newsym.type = TYPE_LONG_SIGN;
break;
}
call_args_stackframe->sym.push_back(newsym);
call_args_stackframe->push_back(newsym);
call_args_stackframe->numArgs++;
}
/** Inserts the new expression (ie. the actual parameter) on the argument
* list.
* @return TRUE if it was a near call that made use of a segment register.
* FALSE elsewhere
* @return true if it was a near call that made use of a segment register.
* false elsewhere
*/
bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
{
@ -239,7 +240,7 @@ bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
/* Place register argument on the argument list */
STKSYM newsym;
newsym.actual = exp;
args->sym.push_back(newsym);
args->push_back(newsym);
args->numArgs++;
return false;
}
@ -249,8 +250,8 @@ bool CallType::newStkArg(COND_EXPR *exp, llIcode opcode, Function * pproc)
* argument list of picode. */
void CallType::placeStkArg (COND_EXPR *exp, int pos)
{
args->sym[pos].actual = exp;
sprintf (args->sym[pos].name, "arg%ld", pos);
(*args)[pos].actual = exp;
(*args)[pos].setArgName(pos);
}
@ -317,35 +318,32 @@ void STKFRAME::adjustForArgType(int numArg_, hlType actType_)
hlType forType;
STKSYM * psym, * nsym;
int off, i;
/* Find stack offset for this argument */
off = m_minOff;
for (i = 0; i < numArg_; i++)
{
if(i>=sym.size())
{
break; //TODO: verify
}
off += sym[i].size;
}
/* Find formal argument */
if (numArg_ < sym.size())
{
psym = &sym[numArg_];
i = numArg_;
//auto iter=std::find_if(sym.begin(),sym.end(),[off](STKSYM &s)->bool {s.off==off;});
auto iter=std::find_if(sym.begin()+numArg_,sym.end(),[off](STKSYM &s)->bool {s.off==off;});
if(iter==sym.end()) // symbol not found
return;
psym = &(*iter);
}
/* If formal argument does not exist, do not create new ones, just
* ignore actual argument
*/
else
if(numArg_>size())
return;
/* Find stack offset for this argument */
off = m_minOff;
i=0;
for(STKSYM &s : *this) // walk formal arguments upto numArg_
{
if(i>=numArg_)
break;
off+=s.size;
i++;
}
/* Find formal argument */
//psym = &at(numArg_);
//i = numArg_;
//auto iter=std::find_if(sym.begin(),sym.end(),[off](STKSYM &s)->bool {s.off==off;});
auto iter=std::find_if(begin()+numArg_,end(),[off](STKSYM &s)->bool {s.label==off;});
if(iter==end()) // symbol not found
return;
psym = &(*iter);
forType = psym->type;
if (forType != actType_)
{
@ -364,11 +362,11 @@ void STKFRAME::adjustForArgType(int numArg_, hlType actType_)
psym->type = actType_;
psym->size = 4;
nsym = psym + 1;
sprintf (nsym->macro, "HI");
sprintf (psym->macro, "LO");
nsym->macro = "HI";
psym->macro = "LO";
nsym->hasMacro = true;
psym->hasMacro = true;
sprintf (nsym->name, "%s", psym->name);
nsym->name = psym->name;
nsym->invalid = true;
numArgs--;
}

View File

@ -137,3 +137,58 @@ boolT readVal(std::ostringstream &symName, uint32_t symOff, Function * symProc)
{
return false; // no symbolic names for now
}
/* Updates the type of the symbol in the symbol table. The size is updated
* if necessary (0 means no update necessary). */
void SYMTAB::updateSymType (uint32_t symbol,const TypeContainer &tc)
{
int i;
auto iter=findByLabel(symbol);
if(iter==end())
return;
iter->type = tc.m_type;
if (tc.m_size != 0)
iter->size = tc.m_size;
}
/* Creates an entry in the global symbol table (symtab) if the variable
* is not there yet. If it is part of the symtab, the size of the variable
* is checked and updated if the old size was less than the new size (ie.
* the maximum size is always saved). */
//TODO: SYMTAB::updateGlobSym should be renamed to insertOrUpdateSym
SYM * SYMTAB::updateGlobSym (uint32_t operand, int size, uint16_t duFlag,bool &inserted_new)
{
/* Check for symbol in symbol table */
auto iter = findByLabel(operand);
if(iter!=end())
{
if(iter->size<size)
iter->size = size;
inserted_new=false;
return &(*iter);
}
/* New symbol, not in symbol table */
SYM v;
char buf[32]={};
sprintf (buf, "var%05X", operand);
v.name = buf;
v.label = operand;
v.size = size;
v.type = TypeContainer::defaultTypeForSize(size);
if (duFlag == eDuVal::USE) /* must already have init value */
{
v.duVal.use =1; // USEVAL;
v.duVal.val =1;
}
else
{
v.duVal.setFlags(duFlag);
}
push_back(v);
inserted_new=true;
return (&back());
}
//template<> class SymbolTableCommon<SYM>;
//template<> class SymbolTableCommon<STKSYM>;