This commit is contained in:
Artur K 2011-12-12 21:50:30 +01:00
parent 900438c453
commit cd040363e6
15 changed files with 125 additions and 1698 deletions

View File

@ -7,7 +7,7 @@ if(CMAKE_BUILD_TOOL MATCHES "(msdev|devenv|nmake)")
add_definitions(/W4)
else()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall --std=c++0x")
SET(CMAKE_CXX_FLAGS_DEBUG "-D_GLIBCXX_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}" )
SET(CMAKE_CXX_FLAGS_DEBUG "-D_GLIBCXX_DEBUG --coverage ${CMAKE_CXX_FLAGS_DEBUG}" )
endif()
FIND_PACKAGE(LLVM)

View File

@ -112,6 +112,11 @@ public:
void controlFlowAnalysis();
void newRegArg(ICODE *picode, ICODE *ticode);
protected:
// TODO: replace those with friend visitor ?
void propLongReg(Int i, ID *pLocId);
void propLongStk(Int i, ID *pLocId);
void propLongGlb(Int i, ID *pLocId);
void structCases();
void findExps();
void genDU1();

View File

@ -11,23 +11,32 @@
#define word unsigned short
/* Prototypes */
void hashParams(int NumEntry, int EntryLen, int SetSize, char SetMin,
int NumVert); /* Set the parameters for the hash table */
void hashCleanup(void); /* Frees memory allocated by hashParams() */
void map(void); /* Part 1 of creating the tables */
void assign(void); /* Part 2 of creating the tables */
int hash(byte *s); /* Hash the string to an int 0 .. NUMENTRY-1 */
word *readT1(void); /* Returns a pointer to the T1 table */
word *readT2(void); /* Returns a pointer to the T2 table */
word *readG(void); /* Returns a pointer to the g table */
/* The application must provide these functions: */
void getKey(int i, byte **pKeys);/* Set *keys to point to the i+1th key */
void dispKey(int i); /* Display the key */
class PatternHasher
{
word *T1base, *T2base; /* Pointers to start of T1, T2 */
int NumEntry; /* Number of entries in the hash table (# keys) */
int EntryLen; /* Size (bytes) of each entry (size of keys) */
int SetSize; /* Size of the char set */
char SetMin; /* First char in the set */
int NumVert; /* c times NumEntry */
int *graphNode; /* The array of edges */
int *graphNext; /* Linked list of edges */
int *graphFirst;/* First edge at a vertex */
public:
word *readT1(void); /* Returns a pointer to the T1 table */
word *readT2(void); /* Returns a pointer to the T2 table */
word *readG(void); /* Returns a pointer to the g table */
void init(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,int _NumVert); /* Set the parameters for the hash table */
void cleanup();
int hash(unsigned char *string); //!< Hash the string to an int 0 .. NUMENTRY-1
};
extern PatternHasher g_pattern_hasher;
/* Macro reads a LH word from the image regardless of host convention */
#ifndef LH
#define LH(p) ((int)((byte *)(p))[0] + ((int)((byte *)(p))[1] << 8))

View File

@ -36,15 +36,6 @@ enum tableType /* The table types */
void createSymTables(void);
void destroySymTables(void);
void enterSym(char *symName, dword symOff, Function *symProc, boolT bSymToo);
boolT readSym (char *symName, dword *pSymOff, Function **pSymProc);
boolT readVal (char *symName, dword symOff, Function *symProc);
void deleteSym(char *symName);
void deleteVal(dword symOff, Function * symProc, boolT bSymToo);
std::string findVal(dword symOff, Function * symProc, word *pIndex);
word symHash(char *name, word *pre);
word valHash(dword off, Function * proc, word *pre);
void selectTable(tableType); /* Select a particular table */
char *addStrTbl(char *pStr); /* Add string to string table */

View File

@ -153,7 +153,7 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode,
if (numHlIcodes > 1)
{
/* Write the code for this basic block */
writeBB(pProc->Icode.GetFirstIcode(), indLevel, pProc, numLoc);
writeBB(&pProc->Icode.front(), indLevel, pProc, numLoc);
repCond = TRUE;
}
@ -183,7 +183,7 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode,
/* Write the code for this basic block */
if (repCond == FALSE)
writeBB (pProc->Icode.GetFirstIcode(), indLevel, pProc, numLoc);
writeBB (&pProc->Icode.front(), indLevel, pProc, numLoc);
/* Check for end of path */
_nodeType = nodeType;
@ -218,7 +218,7 @@ void BB::writeCode (Int indLevel, Function * pProc , Int *numLoc,Int latchNode,
/* Check if there is need to repeat other statements involved
* in while condition, then, emit the loop trailer */
if (repCond)
writeBB (pProc->Icode.GetFirstIcode(), indLevel+1, pProc, numLoc);
writeBB (&pProc->Icode.front(), indLevel+1, pProc, numLoc);
cCode.appendCode( "%s} /* end of while */\n",indent(indLevel));
}
else if (_loopType == ENDLESS_TYPE)
@ -365,6 +365,11 @@ ICODE &BB::back()
return Parent->Icode[rbegin()];
}
size_t BB::size()
{
return length;
}
ICODE &BB::front()
{
return Parent->Icode[start];

View File

@ -329,17 +329,17 @@ void SetupLibCheck(void)
}
/* Initialise the perfhlib stuff. Also allocates T1, T2, g, etc */
hashParams( /* Set the parameters for the hash table */
/* Set the parameters for the hash table */
g_pattern_hasher.init(
numKeys, /* The number of symbols */
PatLen, /* The length of the pattern to be hashed */
256, /* The character set of the pattern (0-FF) */
0, /* Minimum pattern character value */
numVert); /* Specifies c, the sparseness of the graph.
See Czech, Havas and Majewski for details */
T1base = readT1();
T2base = readT2();
g = readG();
T1base = g_pattern_hasher.readT1();
T2base = g_pattern_hasher.readT2();
g = g_pattern_hasher.readG();
/* Read T1 and T2 tables */
grab(2, f);
@ -461,7 +461,7 @@ boolT LibCheck(Function & pProc)
memmove(pat, &prog.Image[fileOffset], PATLEN);
fixWildCards(pat); /* Fix wild cards in the copy */
h = hash(pat); /* Hash the found proc */
h = g_pattern_hasher.hash(pat); /* Hash the found proc */
/* We always have to compare keys, because the hash function will
always return a valid index */
if (memcmp(ht[h].htPat, pat, PATLEN) == 0)

View File

@ -125,7 +125,7 @@ static const char *szWreg[12] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di"
static const char *szPtr[2] = { " word ptr ", " byte ptr " };
static void dis1Line (Int i, boolT fWin, char attr, Int pass);
static void dis1Line (Int i, Int pass);
void dis1LineOp(Int i, boolT fWin, char attr, word *len, Function * pProc);
static void formatRM(char *p, flags32 flg, ICODEMEM* pm);
static char *strDst(flags32 flg, ICODEMEM *pm);
@ -160,93 +160,6 @@ static char cbuf[256]; /* Has to be 256 for wgetstr() to work */
// These are "curses equivalent" functions. (Used to use curses for all this,
// but it was too much of a distribution hassle
#if _CONSOLE
HANDLE hConsole; /* All 32 bit console style routines need this handle */
#endif
void attrSet(char attrib)
{
#ifdef _CONSOLE
switch (attrib)
{
case A_NORMAL:
SetConsoleTextAttribute(hConsole,FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
break;
case A_REVERSE:
SetConsoleTextAttribute(hConsole,BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED);
break;
case A_BOLD:
SetConsoleTextAttribute(hConsole,FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED |FOREGROUND_INTENSITY);
break;
}
#else
/* Set the attribute, using VT100 codes */
switch (attrib)
{
case A_NORMAL:
printf("\033[0m");
break;
case A_REVERSE:
printf("\033[7m");
break;
case A_BOLD:
printf("\033[1m");
break;
}
#endif
}
#ifdef _CONSOLE
void initConsole()
{
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
}
#endif
void erase(void)
{
#ifdef _CONSOLE
COORD coordScreen = { 0, 0 }; /* here's where we'll home the
cursor */
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
DWORD dwConSize; /* number of character cells in
the current buffer */
/* get the number of character cells in the current buffer */
GetConsoleScreenBufferInfo( hConsole, &csbi );
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
/* fill the entire screen with blanks */
FillConsoleOutputCharacter( hConsole, (TCHAR) ' ',dwConSize, coordScreen, &cCharsWritten );
/* get the current text attribute */
// GetConsoleScreenBufferInfo( hConsole, &csbi );
/* now set the buffer's attributes accordingly */
FillConsoleOutputAttribute( hConsole, csbi.wAttributes,dwConSize, coordScreen, &cCharsWritten );
/* put the cursor at (0, 0) */
SetConsoleCursorPosition( hConsole, coordScreen );
#else
// Assume that ANSI is supported
printf("\033[2J");
#endif
}
void move(int r, int c)
{
#ifdef _CONSOLE
COORD pos;
pos.X = c;
pos.Y = r;
SetConsoleCursorPosition( hConsole, pos );
#else
printf("\033[%d;%dH", r+1, c+1);
#endif
}
#define printfd(x) printf(x)
#define dis_newline() printf("\n")
#define dis_show() // Nothing to do unless using Curses
@ -270,7 +183,8 @@ void disassem(Int pass, Function * ppProc)
}
createSymTables();
allocIcode = numIcode = pProc->Icode.GetNumIcodes();
if ((cb = allocIcode * sizeof(ICODE)) == 0)
cb = allocIcode * sizeof(ICODE);
if (numIcode == 0)
{
return; /* No Icode */
}
@ -325,7 +239,7 @@ void disassem(Int pass, Function * ppProc)
/* Loop over array printing each record */
for (i = nextInst = 0; i < numIcode; i++)
{
dis1Line(i, FALSE, 0, pass);
dis1Line(i, pass);
}
/* Write procedure epilogue */
@ -344,8 +258,7 @@ void disassem(Int pass, Function * ppProc)
* i is index into Icode for this proc *
* It is assumed that icode i is already scanned *
****************************************************************************/
static void
dis1Line(Int i, boolT fWindow, char attr, Int pass)
static void dis1Line(Int i, Int pass)
{
ICODE * pIcode = &pc[i];
@ -368,10 +281,8 @@ dis1Line(Int i, boolT fWindow, char attr, Int pass)
if (pIcode->ic.ll.flg & (TARGET | CASE))
{
if (fWindow) /* Printing to disassem window? */
dis_newline(); /* Yes */
else if (pass == 3)
cCode.appendCode("\n"); /* No, print to c code buffer */
if (pass == 3)
cCode.appendCode("\n"); /* Print to c code buffer */
else
fprintf(fp, "\n"); /* No, print to the stream */
}
@ -670,21 +581,7 @@ dis1Line(Int i, boolT fWindow, char attr, Int pass)
/* Display output line */
if (! (pIcode->ic.ll.flg & SYNTHETIC))
{
if (fWindow)
{
word off;
char szOffset[6];
off = (word)(pIcode->ic.ll.label - ((dword)pProc->state.r[rCS] << 4));
attrSet(attr);
sprintf(szOffset, "%04X ", off);
printfd(szOffset);
printfd(buf);
dis_newline();
attrSet(A_NORMAL);
}
else if (pass == 3) /* output to .b code buffer */
if (pass == 3) /* output to .b code buffer */
cCode.appendCode("%s\n", buf);
else /* output to .a1 or .a2 file */
fprintf (fp, "%03ld %06lX %s\n", i, pIcode->ic.ll.label, buf);
@ -692,13 +589,7 @@ dis1Line(Int i, boolT fWindow, char attr, Int pass)
else /* SYNTHETIC instruction */
{
strcat (buf, ";Synthetic inst");
if (fWindow)
{
printfd(" ");
printfd(buf);
dis_newline();
}
else if (pass == 3) /* output to .b code buffer */
if (pass == 3) /* output to .b code buffer */
{
cCode.appendCode("%s\n", buf);
}
@ -806,706 +697,13 @@ static char *strHex(dword d)
return (buf + (buf[1] <= '9'));
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
| Interactive Disassembler and Associated Routines |
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
dword pcTop; /* Image offset of top line */
Int icTop; /* Icode index of top line */
dword pcCur; /* Image offset of cursor */
static dword oldPcCur; /* As above, before latest command */
Int icCur; /* Icode index of cursor */
dword pcBot; /* Image offset of bottom line */
Int icBot; /* Icode index of bottom line */
dword pcLast; /* Image offset of last instr in proc */
int NSCROLL; /* Number of limes to scroll. Pseudo constant */
/* Paint the title line */
void dispTitle(void)
{
char buf[80];
move(0, 0); /* Must move before setting attributes */
attrSet(A_BOLD);
sprintf(buf, "Proc %s at %06lX (%04X:%04X): %d bytes of parameters ",pProc->name, pProc->Icode.GetFirstIcode()->ic.ll.label,
pProc->state.r[rCS],(word)(pProc->Icode.GetFirstIcode()->ic.ll.label - ((dword)(pProc->state.r[rCS]) << 4)),
pProc->cbParam);
printfd(buf);
if (pProc->flg & PROC_ISLIB) printfd(" LIBRARY");
attrSet(A_NORMAL);
}
/****************************************************************************
* updateScr - update the screen *
****************************************************************************/
/* bNew is true if must recalculate the top line */
void updateScr(boolT bNew)
{
int y, x;
Int i, ic;
bNew |= (pcCur > pcBot) || (pcCur < pcTop);
if (bNew)
{
/* We need to redo the screen completely */
erase();
dispTitle();
icTop = icCur;
for (x=0; x < NSCROLL; x++)
{
if (icTop && pc[icTop-1].ic.ll.label +
(dword)pc[icTop-1].ic.ll.numBytes == pc[icTop].ic.ll.label)
{
/* Then this instruction is contiguous with the current */
icTop--;
}
else break;
}
pcTop = pc[icTop].ic.ll.label;
}
else
{
dispTitle();
}
move(1, 0);
nextInst = pcTop;
for (y=1, ic=icTop; y < LINES-1; ic++, y++)
{
if ((ic >= numIcode) || (nextInst != pc[ic].ic.ll.label))
{
if (labelSrch(pc,numIcode, nextInst, &i))
{
ic = i;
}
else
{
pcLast = pc[ic-1].ic.ll.label; /* Remember end of proc */
break; /* Must be past last */
}
}
/* Save pc of current line. Last assignment will be pc of bott line */
pcBot = nextInst;
icBot = ic;
// Only have to repaint if screen is new, or repainting formerly highlighted
// line, or newly highlighted line
if (bNew || (pcCur == nextInst) || (oldPcCur == nextInst))
dis1Line(ic, TRUE, (char)((pcCur == nextInst) ? A_REVERSE : A_NORMAL), 0);
if (ic == numIcode-1)
{
switch (pc[ic].ic.ll.opcode)
{
case iJMP: case iJMPF:
case iRET: case iRETF:
case iIRET:
break;
default:
/* We have other than a break of control flow instruction
at the end of the proc. Parse more instructions to
complete the basic block
*/
if ((ic = checkScanned(nextInst)) == -1)
{
/* Some error. */
pcLast = pcCur; /* Remember end of proc */
break; /* Must be past last */
}
}
}
}
dis_show(); /* Make it happen */
}
#if 0
/* An opcode based version of updateScr() */
/****************************************************************************
* updateScrOp - update the screen *
****************************************************************************/
/* bNew is true if must recalculate the top line */
void
updateScrOp(boolT bNew)
{
int y, x;
dword pc;
word len;
dispTitle();
if (bNew || (pcCur > pcBot) || (pcCur < pcTop))
{
/* We need to redo the screen completely */
pcTop = pcCur;
}
move(1, 0);
for (y=1, pc = pcTop; y < LINES-1;)
{
/* Save pc of current line. Last assignment will be pc of bott line */
pcBot = pc;
dis1LineOp(pc, TRUE, (pcCur == pc) ? A_REVERSE : A_NORMAL, &len,pProc);
pc += len;
getyx(stdscr, y, x);
}
refresh();
}
#endif
void pushPosStack(void)
{
/* Push the current position on the position stack */
posStack[iPS].ic = icCur;
posStack[iPS++].pProc = pProc;
}
static void popPosStack(void)
{
/* Push the current position on the position stack */
/* Note: relies on the byte wraparound. Beware! */
// if ((Int)(posStack[--iPS].pProc) != -1)
if ((intptr_t)(posStack[--iPS].pProc) != intptr_t(-1))
{
if (posStack[iPS].pProc != pProc)
{
setProc(posStack[iPS].pProc);
}
icCur = posStack[iPS].ic;
pcCur = pc[icCur].ic.ll.label;
}
else iPS++; /* Stack empty.. don't pop */
}
/* Check to see if there is an icode for given image offset.
Scan it if necessary, adjusting the allocation of pc[] and pl[]
if necessary. Returns -1 if an error, otherwise the icode offset
*/
static Int checkScanned(dword pcCur)
{
Int i;
/* First we check if the current icode is in range */
/* A sanity check first */
if (pcCur >= (dword)prog.cbImage)
{
/* Couldn't be! */
return -1;
}
if (!labelSrch(pc,numIcode, pcCur, &i))
{
/* This icode does not exist yet. Tack it on the end of the existing */
if (numIcode >= allocIcode)
{
allocIcode = numIcode + DELTA_ICODE; /* Make space for this one, and a few more */
pc = (ICODE *)reallocVar(pc, allocIcode * sizeof(ICODE));
/* It is important to clear the new icodes, to ensure that the type
is set to NOT_SCANNED */
memset(&pc[numIcode], 0, (size_t)(allocIcode-numIcode)*sizeof(ICODE));
pl.resize(allocIcode);
memset(&pl[numIcode], 0, (size_t)(allocIcode-numIcode)*sizeof(Int));
}
i = numIcode++;
}
if (pc[i].type == NOT_SCANNED)
{
/* This is a new icode not even scanned yet. Scan it now */
/* Ignore most errors... at this stage */
if (scan(pcCur, &pc[i]) == IP_OUT_OF_RANGE)
{
/* Something went wrong... just forget it */
return -1;
}
}
return i;
}
/* Set up to use the procedure proc */
/* This includes some important initialisations, allocations, etc that are
normally done in disassem() */
static void setProc(Function * proc)
{
Int i;
pProc = proc; /* Keep in a static */
/* Free old arrays, if any */
if (pc) free(pc);
pl.clear();
/* Create temporary code array */
numIcode = pProc->Icode.GetNumIcodes();
cb = numIcode * sizeof(ICODE);
// Mike: needs objectising
pc = (ICODE *)memcpy(allocMem(cb), pProc->Icode.GetFirstIcode(), (size_t)cb);
/* Create label array to keep track of location => label name */
pl.clear();
pl.resize(numIcode,0);
/* Bind jump offsets to labels */
for (i = 0; i < numIcode; i++)
{
if ((pc[i].ic.ll.flg & I) && !(pc[i].ic.ll.flg & JMP_ICODE) &&
JmpInst(pc[i].ic.ll.opcode))
{
/* Immediate jump instructions. Make dest an icode index */
if (labelSrch(pc,numIcode, pc[i].ic.ll.immed.op, (Int *)&pc[i].ic.ll.immed.op))
{
/* This icode is the target of a jump */
pc[pc[i].ic.ll.immed.op].ic.ll.flg |= TARGET;
pc[i].ic.ll.flg |= JMP_ICODE; /* So its not done twice */
}
else
{
/* This jump cannot be linked to a label */
pc[i].ic.ll.flg |= NO_LABEL;
}
}
}
/* Window initially scrolled with entry point on top */
pcCur = pcTop = pProc->procEntry;
labelSrch(pc,numIcode, pcCur, &icCur);
/* pcLast is set properly in updateScr(), at least for now */
pcLast = (dword)-1;
}
/****************************************************************************
* interactDis - interactive disassembler *
****************************************************************************/
void interactDis(Function * initProc, Int initIC)
{
#ifdef __UNIX__
printf("Sorry - interactive disasassembler option not available for Unix\n");
return;
#else
boolT fInteract;
int nEsc = 0; /* This cycles 0 1 2 for Esc [ X under Unix */
/* and 0 1 for NULL X under Dos */
int ch;
Int i;
pProc = initProc; /* Keep copy of init proc */
NSCROLL = max(3, LINES >> 3); /* Number of lines to scroll */
/* Allocate the position stack */
posStack = (POSSTACK_ENTRY*)allocMem(256 * sizeof(POSSTACK_ENTRY));
iPS = 0;
memset(posStack, -1, 256 * sizeof(POSSTACK_ENTRY));
/* Initialise the console interface, if required */
initConsole();
/* Initially, work on the given proc */
setProc(initProc);
if (initIC)
{
icCur = initIC;
pcCur = pc[icCur].ic.ll.label;
}
/* Initialise the symbol table */
createSymTables();
strcpy(cbuf, "label"); /* Provide a default label string */
updateScr(TRUE);
fInteract = TRUE;
while (fInteract)
{
ch = ::_getch(); // Mike: need a Unix equivalent of getch()!
#ifdef __MSDOS__
if (nEsc)
{
ch += EXT; /* Got the NULL before, so this is extended */
nEsc = 0;
}
else if (ch == 0)
{
nEsc = 1; /* Got one escape (actually, NULL) char */
break;
}
#endif
#ifdef __UNIX__
switch (nEsc)
{
case 1: /* Already got one escape */
if (ch == '[')
{
nEsc++; /* Got 2 chars in the escape sequence */
break;
}
else
{
/* Escape something else. Ignore */
nEsc = 0;
}
break;
case 2:
/* Already got Esc [ ... */
ch += EXT; /* Make it an extended key */
nEsc = 0; /* Reset the escape state */
break;
case 0:
/* No escapes... yet */
if (ch == 0x1B)
{
nEsc++; /* That's one escape... */
break;
}
}
#endif
// For consoles, we get a 0xE0 then KEY_DOWN for the normal down arrow character.
// We simply ignore the 0xE0; this has the effect that the numeric keypad keys
// work as well (regardless of numlock state).
oldPcCur = pcCur;
switch (ch)
{
case KEY_DOWN:
if (pcCur >= pcLast) continue; /* Ignore it */
pcCur += pc[icCur].ic.ll.numBytes;
labelSrch(pc,numIcode, pcCur, &icCur);
if (pcCur >= pcBot)
{
int j;
/* We have gone past the bottom line. Scroll a few lines */
for (j=0; j < NSCROLL; j++)
{
if (pcTop >= pcLast)
{
break;
}
pcTop += pc[icTop].ic.ll.numBytes;
if (labelSrch(pc,numIcode, pcTop, &i))
icTop = i;
else break; /* Some problem... no more scroll */
}
}
updateScr(FALSE);
break;
case KEY_UP:
/* First simply try the prev icode */
if ((icCur == 0) ||
pc[--icCur].ic.ll.label + (dword)pc[icCur].ic.ll.numBytes != pcCur)
{
for (i = 0; i < numIcode; i++)
{
if (pc[i].ic.ll.label + (dword)pc[i].ic.ll.numBytes == pcCur)
{
break; /* This is the one! */
}
}
if (pc[i].ic.ll.label + pc[i].ic.ll.numBytes != pcCur)
break; /* Not found. Sorry! */
icCur = i;
}
pcCur = pc[icCur].ic.ll.label;
updateScr(FALSE);
break;
case '2': /* Think up a better key... */
/* As for right arrow, but considers source operand first */
if (pc[icCur].ic.ll.src.off != 0)
{
pushPosStack();
pcCur = pc[icCur].ic.ll.src.off;
if (!labelSrch(pc,numIcode, pcCur, &icCur))
break;
updateScr(FALSE);
}
/* Fall through to KEY_RIGHT processing */
case KEY_RIGHT:
if (pc[icCur].ic.ll.flg & I)
{
if ((pc[icCur].ic.ll.opcode >= iJB) &&
(pc[icCur].ic.ll.opcode <= iJMPF))
{
/* An immediate jump op. Jump to it */
pushPosStack();
if (pc[icCur].ic.ll.flg & JMP_ICODE)
{
/* immed.op is an icode offset */
icCur = pc[icCur].ic.ll.immed.op;
pcCur = pc[icCur].ic.ll.label;
}
else
{
/* immed.op is still an image offset.
Quite likely we need to scan */
pcCur = pc[icCur].ic.ll.immed.op;
if ((icCur = checkScanned(pcCur)) == -1)
break;
}
}
else if ((pc[icCur].ic.ll.opcode == iCALL) ||
(pc[icCur].ic.ll.opcode == iCALLF))
{
/* The dest is a pointer to a proc struct */
// First check that the procedure has icodes (e.g. may be
// a library function, or just not disassembled yet)
Function * pp = (Function *)pc[icCur].ic.ll.immed.op;
if (pp->Icode.GetFirstIcode() != NULL)
{
pushPosStack();
setProc(pp);
}
}
else
{
/* Other immediate */
pushPosStack();
pcCur = pc[icCur].ic.ll.immed.op;
dispData(pProc->state.r[rDS]);
break;
}
}
else if (pc[icCur].ic.ll.dst.off != 0)
{
pushPosStack();
pcCur = pc[icCur].ic.ll.dst.off;
if (!labelSrch(pc,numIcode, pcCur, &icCur))
{
dispData(pProc->state.r[rDS]);
break;
}
}
else if (pc[icCur].ic.ll.src.off != 0)
{
pushPosStack();
pcCur = pc[icCur].ic.ll.src.off;
if (!labelSrch(pc,numIcode, pcCur, &icCur))
{
dispData(pProc->state.r[rDS]);
break;
}
}
updateScr(TRUE);
break;
case KEY_LEFT:
popPosStack();
pcCur = pc[icCur].ic.ll.label;
updateScr(TRUE);
break;
case KEY_NPAGE:
pcCur = pcTop = pcBot; /* Put bottom line at top now */
icCur = icTop = icBot;
updateScr(FALSE);
break;
case KEY_PPAGE:
pcTop -= (LINES-2) * 2; /* Average of 2 bytes per inst */
for (i = 0; i < numIcode; i++)
{
if ((pc[i].ic.ll.label <= pcTop) &&
(pc[i].ic.ll.label + (dword)pc[i].ic.ll.numBytes >= pcTop))
{
break; /* This is the spot! */
}
}
if (i >= numIcode)
{
/* Something went wrong. Goto to first icode */
i = 0;
}
icCur = icTop = i;
pcCur = pcTop = pc[i].ic.ll.label;
updateScr(FALSE);
break;
case 'l': /* Add a symbolic label here */
{
char *pStr;
move(LINES, 0);
printf("Enter symbol: ");
gets(cbuf); /* Get a string to buf */
move (LINES, 0);
printf("%50c", ' ');
if (strlen(cbuf) >= SYMLEN)
{
/* Name too ling. Truncate */
cbuf[SYMLEN-1] = '\0';
}
pStr = addStrTbl(cbuf); /* Add to the string table */
selectTable(Label); /* Select the label table */
/* Add the symbol to both value- and symbol- hashed tables */
enterSym(pStr, pcCur, pProc, TRUE);
if (icCur == 0)
{
/* We are at the first icode of a function.
Assume it is the entry point, and rename the function */
strcpy(pProc->name, cbuf);
}
updateScr(FALSE);
break;
}
case ';':
{
char *pStr;
word w;
if (findVal(pcCur, 0, &w))
{
readVal(cbuf, pcCur, 0);/* Make it the default string */
deleteVal(pcCur, 0, FALSE);
}
else
{
cbuf[0] = '\0'; /* Remove prev string */
}
/* Enter a comment here, from a window */
move(LINES, 0);
printf("Enter comment: ");
gets(cbuf); /* Get a string to buf */
move(LINES, 0);
printf("%50c", ' ');
pStr = addStrTbl(cbuf); /* Add to the string table */
selectTable(Comment);
enterSym(pStr, pcCur, pProc, FALSE);/* Add the symbol */
updateScr(FALSE);
break;
}
case 'X' & 0x1F: /* Control X; can't use Alt with Unix */
fInteract = FALSE; /* Exit interactive mode */
attrSet(A_NORMAL); /* Normal attributes */
break;
}
}
free(posStack);
destroySymTables();
#endif // #ifdef unix
}
/****************************************************************************
* Display the current image position as data *
****************************************************************************/
static void
dispData(word dataSeg)
{
int y, c, i;
Int pc, pcStart;
Int off = (Int)dataSeg << 4;
char szOffset[6], szByte[4];
if (pcCur >= (dword)prog.cbImage)
{
/* We're at an invalid address. Use 0x100 instead */
pcCur = 0;
}
erase();
dispTitle();
pcStart = pc = pcCur; /* pc at start of line */
for (y=1; y < LINES-1; y++)
{
move (y, 1);
sprintf(szOffset, "%04lX ", pc);
printfd(szOffset);
for (i=0; i < 16; i++)
{
sprintf(szByte, "%02X ", prog.Image[pc++ + off]);
printfd(szByte);
if ((pc + off) > prog.cbImage) break;
}
pc = pcStart;
for (i=0; i < 16; i++)
{
c = prog.Image[pc++ + off];
if ((c < 0x20) || (c > 0x7E))
{
c = '.';
}
szByte[0] = (char)c;
szByte[1] = '\0';
printfd(szByte);
if ((pc + off) > prog.cbImage) break;
}
dis_newline();
pcStart = pc;
if ((pc + off) > prog.cbImage) break;
/* getyx(stdscr, y, x); */
}
}
boolT callArg(word off, char *sym)
{
dword imageOff;
imageOff = off + ((dword)pProc->state.r[rCS] << 4);
/* Search procedure list for one with appropriate entry point */
FunctionListType::iterator iter= std::find_if(pProcList.begin(),pProcList.end(),
[imageOff](const Function &f) -> bool { return f.procEntry==imageOff; });
if(iter==pProcList.end())
{
/* No existing proc entry */
//ERROR: dereferencing NULL !?!
//LibCheck(*iter);
Function *x=Function::Create();
x->procEntry=imageOff;
LibCheck(*x);
if (x->flg & PROC_ISLIB)
{
/* No entry for this proc, but it is a library function.
Create an entry for it */
pProcList.push_back(x);
iter = (++pProcList.rbegin()).base();
}
}
if(iter==pProcList.end())
return false;
/* We have a proc entry for this procedure. Copy the name */
strcpy(sym, iter->name);
return true;
}
/* Handle the floating point opcodes (icode iESC) */

View File

@ -97,8 +97,7 @@ chop(byte pat[])
memset(&pat[pc], 0, PATLEN - pc);
}
static bool
op0F(byte pat[])
static bool op0F(byte pat[])
{
/* The two byte opcodes */
byte op = pat[pc++];

View File

@ -218,7 +218,7 @@ void Function::compressCFG()
if (pBB->numOutEdges) /* Might have been clobbered */
{
pBB->edges[i].BBptr = pNxt;
Icode.SetImmediateOp(ip, (dword)pNxt->start);
Icode.SetImmediateOp(ip, (dword)pNxt->begin());
}
}
}
@ -270,7 +270,7 @@ static BB * rmJMP(Function * pProc, Int marker, BB * pBB)
{
marker += DFS_JMP;
while (pBB->nodeType == ONE_BRANCH && pBB->length == 1)
while (pBB->nodeType == ONE_BRANCH && pBB->size() == 1)
{
if (pBB->traversed != marker)
{
@ -282,13 +282,15 @@ static BB * rmJMP(Function * pProc, Int marker, BB * pBB)
}
else
{
pProc->Icode.SetLlFlag(pBB->start, NO_CODE);
pProc->Icode.SetLlInvalid(pBB->start, TRUE);
pBB->front().SetLlFlag(NO_CODE);
pBB->front().invalidate(); //pProc->Icode.SetLlInvalid(pBB->begin(), TRUE);
}
pBB = pBB->edges[0].BBptr;
}
else { /* We are going around in circles */
else
{
/* We are going around in circles */
pBB->nodeType = NOWHERE_NODE;
pProc->Icode.GetIcode(pBB->start)->ic.ll.immed.op = (dword)pBB->start;
pProc->Icode.SetImmediateOp(pBB->start, (dword)pBB->start);

View File

@ -227,7 +227,8 @@ static Int idiom2(ICODE * pIcode, ICODE * pEnd, Int ip, Function * pProc)
static Int idiom3(ICODE * pIcode, ICODE * pEnd)
{
/* Match ADD SP, immed */
if ((++pIcode < pEnd) && (pIcode->ic.ll.flg & I) &&
++pIcode;
if ((pIcode < pEnd) && (pIcode->ic.ll.flg & I) &&
(pIcode->ic.ll.opcode == iADD) && (pIcode->ic.ll.dst.regi == rSP))
return (pIcode->ic.ll.immed.op);
else if ((pIcode->ic.ll.opcode == iMOV) && (pIcode->ic.ll.dst.regi == rSP)
@ -254,15 +255,20 @@ static Int idiom17 (ICODE * pIcode, ICODE * pEnd)
byte regi;
/* Match POP reg */
if ((++pIcode < pEnd) && (pIcode->ic.ll.opcode == iPOP))
++pIcode;
if ((pIcode < pEnd) && (pIcode->ic.ll.opcode == iPOP))
{
regi = pIcode->ic.ll.dst.regi;
if ((regi >= rAX) && (regi <= rBX))
i++;
while ((++pIcode)->ic.ll.opcode == iPOP)
++pIcode;
while (pIcode->ic.ll.opcode == iPOP)
{
if (pIcode->ic.ll.dst.regi == regi)
{
i++;
++pIcode;
}
else
break;
}
@ -1082,10 +1088,15 @@ void Function::findIdioms()
(pIcode++)->invalidate();
ip++;
}
else
{
printf("Indirect call at idiom3\n");
pIcode++;
}
}
else if (idx = idiom17 (pIcode, pEnd)) /* idiom 17 */
{
if (pIcode->ic.ll.flg & I)
if (pIcode->isLlFlag(I))
{
(pIcode->ic.ll.immed.proc.proc)->cbParam = (int16)idx;
pIcode->ic.ll.immed.proc.cb = idx;
@ -1095,6 +1106,12 @@ void Function::findIdioms()
for (idx /= 2; idx > 0; idx--)
(pIcode++)->invalidate();
}
// TODO : it's a calculated call
else
{
printf("Indirect call at idiom17\n");
pIcode++;
}
}
else
pIcode++;

View File

@ -85,9 +85,9 @@ void parse (CALL_GRAPH * *pcallGraph)
}
static void updateSymType (dword symbol, hlType symType, Int size)
/* Updates the type of the symbol in the symbol table. The size is updated
* if necessary (0 means no update necessary). */
static void updateSymType (dword symbol, hlType symType, Int size)
{ Int i;
for (i = 0; i < symtab.csym; i++)

View File

@ -11,19 +11,7 @@
/* Private data structures */
static int NumEntry; /* Number of entries in the hash table (# keys) */
static int EntryLen; /* Size (bytes) of each entry (size of keys) */
static int SetSize; /* Size of the char set */
static char SetMin; /* First char in the set */
static int NumVert; /* c times NumEntry */
static word *T1base, *T2base; /* Pointers to start of T1, T2 */
static word *T1, *T2; /* Pointers to T1[i], T2[i] */
static int *graphNode; /* The array of edges */
static int *graphNext; /* Linked list of edges */
static int *graphFirst;/* First edge at a vertex */
static short *g; /* g[] */
static int numEdges; /* An edge counter */
@ -34,9 +22,10 @@ static void initGraph(void);
static void addToGraph(int e, int v1, int v2);
static bool isCycle(void);
static void duplicateKeys(int v1, int v2);
PatternHasher g_pattern_hasher;
void
hashParams(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,
PatternHasher::init(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,
int _NumVert)
{
/* These parameters are stored in statics so as to obviate the need for
@ -84,12 +73,11 @@ hashParams(int _NumEntry, int _EntryLen, int _SetSize, char _SetMin,
BadAlloc:
printf("Could not allocate memory\n");
hashCleanup();
cleanup();
exit(1);
}
void
hashCleanup(void)
void PatternHasher::cleanup(void)
{
/* Free the storage for variable sized tables etc */
if (T1base) free(T1base);
@ -100,264 +88,7 @@ hashCleanup(void)
if (g) free(g);
}
void
map(void)
{
int i, j, c;
word f1, f2;
bool cycle;
byte *keys;
c = 0;
do
{
initGraph();
cycle = FALSE;
/* Randomly generate T1 and T2 */
for (i=0; i < SetSize*EntryLen; i++)
{
T1base[i] = rand() % NumVert;
T2base[i] = rand() % NumVert;
}
for (i=0; i < NumEntry; i++)
{
f1 = 0; f2 = 0;
getKey(i, &keys);
for (j=0; j < EntryLen; j++)
{
T1 = T1base + j * SetSize;
T2 = T2base + j * SetSize;
f1 += T1[keys[j] - SetMin];
f2 += T2[keys[j] - SetMin];
}
f1 %= (word)NumVert;
f2 %= (word)NumVert;
if (f1 == f2)
{
/* A self loop. Reject! */
printf("Self loop on vertex %d!\n", f1);
cycle = TRUE;
break;
}
addToGraph(numEdges++, f1, f2);
}
if (cycle || (cycle = isCycle())) /* OK - is there a cycle? */
{
printf("Iteration %d\n", ++c);
}
else
{
break;
}
}
while (/* there is a cycle */ 1);
}
/* Initialise the graph */
static void
initGraph(void)
{
int i;
for (i=1; i <= NumVert; i++)
{
graphFirst[i] = 0;
}
for (i= -NumEntry; i <= NumEntry; i++)
{
/* No need to init graphNode[] as they will all be filled by successive
calls to addToGraph() */
graphNext[NumEntry+i] = 0;
}
numEdges = 0;
}
/* Add an edge e between vertices v1 and v2 */
/* e, v1, v2 are 0 based */
static void
addToGraph(int e, int v1, int v2)
{
e++; v1++; v2++; /* So much more convenient */
graphNode[NumEntry+e] = v2; /* Insert the edge information */
graphNode[NumEntry-e] = v1;
graphNext[NumEntry+e] = graphFirst[v1]; /* Insert v1 to list of alphas */
graphFirst[v1]= e;
graphNext[NumEntry-e] = graphFirst[v2]; /* Insert v2 to list of omegas */
graphFirst[v2]= -e;
}
bool DFS(int parentE, int v)
{
int e, w;
/* Depth first search of the graph, starting at vertex v, looking for
cycles. parent and v are origin 1. Note parent is an EDGE,
not a vertex */
visited[v] = TRUE;
/* For each e incident with v .. */
for (e = graphFirst[v]; e; e = graphNext[NumEntry+e])
{
byte *key1;
getKey(abs(e)-1, &key1);
if (*(long *)key1 == 0)
{
/* A deleted key. Just ignore it */
continue;
}
w = graphNode[NumEntry+e];
if (visited[w])
{
/* Did we just come through this edge? If so, ignore it. */
if (abs(e) != abs(parentE))
{
/* There is a cycle in the graph. There is some subtle code here
to work around the distinct possibility that there may be
duplicate keys. Duplicate keys will always cause unit
cycles, since f1 and f2 (used to select v and w) will be the
same for both. The edges (representing an index into the
array of keys) are distinct, but the key values are not.
The logic is as follows: for the candidate edge e, check to
see if it terminates in the parent vertex. If so, we test
the keys associated with e and the parent, and if they are
the same, we can safely ignore e for the purposes of cycle
detection, since edge e adds nothing to the cycle. Cycles
involving v, w, and e0 will still be found. The parent
edge was not similarly eliminated because at the time when
it was a candidate, v was not yet visited.
We still have to remove the key from further consideration,
since each edge is visited twice, but with a different
parent edge each time.
*/
/* We save some stack space by calculating the parent vertex
for these relatively few cases where it is needed */
int parentV = graphNode[NumEntry-parentE];
if (w == parentV)
{
byte *key2;
getKey(abs(parentE)-1, &key2);
if (memcmp(key1, key2, EntryLen) == 0)
{
printf("Duplicate keys with edges %d and %d (",
e, parentE);
dispKey(abs(e)-1);
printf(" & ");
dispKey(abs(parentE)-1);
printf(")\n");
/* *(long *)key1 = 0; /* Wipe the key */
memset(key1, 0, EntryLen);
}
else
{
/* A genuine (unit) cycle. */
printf("There is a unit cycle involving vertex %d and edge %d\n", v, e);
return TRUE;
}
}
else
{
/* We have reached a previously visited vertex not the
parent. Therefore, we have uncovered a genuine cycle */
printf("There is a cycle involving vertex %d and edge %d\n", v, e);
return TRUE;
}
}
}
else /* Not yet seen. Traverse it */
{
if (DFS(e, w))
{
/* Cycle found deeper down. Exit */
return TRUE;
}
}
}
return FALSE;
}
static bool
isCycle(void)
{
int v;
for (v=1; v <= NumVert; v++)
{
visited[v] = FALSE;
}
for (v=1; v <= NumVert; v++)
{
if (!visited[v])
{
if (DFS(-32767, v))
{
return TRUE;
}
}
}
return FALSE;
}
void
traverse(int u)
{
int w, e;
visited[u] = TRUE;
/* Find w, the neighbours of u, by searching the edges e associated with u */
e = graphFirst[1+u];
while (e)
{
w = graphNode[NumEntry+e]-1;
if (!visited[w])
{
g[w] = (abs(e)-1 - g[u]) % NumEntry;
if (g[w] < 0) g[w] += NumEntry; /* Keep these positive */
traverse(w);
}
e = graphNext[NumEntry+e];
}
}
void
assign(void)
{
int v;
for (v=0; v < NumVert; v++)
{
g[v] = 0; /* g is sparse; leave the gaps 0 */
visited[v] = FALSE;
}
for (v=0; v < NumVert; v++)
{
if (!visited[v])
{
g[v] = 0;
traverse(v);
}
}
}
int
hash(byte *string)
int PatternHasher::hash(byte *string)
{
word u, v;
int j;
@ -381,68 +112,18 @@ hash(byte *string)
return (g[u] + g[v]) % NumEntry;
}
word *
readT1(void)
word * PatternHasher::readT1(void)
{
return T1base;
}
word *
readT2(void)
word *PatternHasher::readT2(void)
{
return T2base;
}
word *
readG(void)
word * PatternHasher::readG(void)
{
return (word *)g;
}
#if 0
void dispRecord(int i);
void
duplicateKeys(int v1, int v2)
{
int i, j;
byte *keys;
int u, v;
v1--; v2--; /* These guys are origin 1 */
printf("Duplicate keys:\n");
for (i=0; i < NumEntry; i++)
{
getKey(i, &keys);
u = 0;
for (j=0; j < EntryLen; j++)
{
T1 = T1base + j * SetSize;
u += T1[keys[j] - SetMin];
}
u %= NumVert;
if ((u != v1) && (u != v2)) continue;
v = 0;
for (j=0; j < EntryLen; j++)
{
T2 = T2base + j * SetSize;
v += T2[keys[j] - SetMin];
}
v %= NumVert;
if ((v == v2) || (v == v1))
{
printf("Entry #%d key: ", i+1);
for (j=0; j < EntryLen; j++) printf("%02X ", keys[j]);
printf("\n");
dispRecord(i+1);
}
}
exit(1);
}
#endif

View File

@ -21,9 +21,10 @@ static boolT isJCond (llIcode opcode)
}
static boolT isLong23 (Int i, BB * pbb, ICODE * icode, Int *off, Int *arc)
/* Returns whether the conditions for a 2-3 long variable are satisfied */
{ BB * t, * e, * obb2;
static boolT isLong23 (Int i, BB * pbb, ICODE * icode, Int *off, Int *arc)
{
BB * t, * e, * obb2;
if (pbb->nodeType != TWO_BRANCH)
return false;
@ -224,17 +225,17 @@ static void longJCond22 (COND_EXPR *rhs, COND_EXPR *lhs, ICODE * pIcode,
* Arguments: i : index into the local identifier table
* pLocId: ptr to the long local identifier
* pProc : ptr to current procedure's record. */
static void propLongStk (Int i, ID *pLocId, Function * pProc)
void Function::propLongStk (Int i, ID *pLocId)
{
Int idx, off, arc;
COND_EXPR *lhs, *rhs; /* Pointers to left and right hand expression */
ICODE * pIcode, * pEnd;
/* Check all icodes for offHi:offLo */
pEnd = pProc->Icode.GetIcode(pProc->Icode.GetNumIcodes() -1);
for (idx = 0; idx < (pProc->Icode.GetNumIcodes() - 1); idx++)
pEnd = this->Icode.GetIcode(this->Icode.GetNumIcodes() -1);
for (idx = 0; idx < (this->Icode.GetNumIcodes() - 1); idx++)
{
pIcode = pProc->Icode.GetIcode(idx);
pIcode = this->Icode.GetIcode(idx);
if ((pIcode->type == HIGH_LEVEL) || (pIcode->invalid == TRUE))
continue;
@ -242,7 +243,7 @@ static void propLongStk (Int i, ID *pLocId, Function * pProc)
{
switch (pIcode->ic.ll.opcode) {
case iMOV:
if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, pProc,
if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, this,
&rhs, &lhs, 1) == TRUE)
{
pIcode->setAsgn(lhs, rhs);
@ -252,7 +253,7 @@ static void propLongStk (Int i, ID *pLocId, Function * pProc)
break;
case iAND: case iOR: case iXOR:
if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, pProc,
if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, this,
&rhs, &lhs, 1) == TRUE)
{
switch (pIcode->ic.ll.opcode) {
@ -270,7 +271,7 @@ static void propLongStk (Int i, ID *pLocId, Function * pProc)
break;
case iPUSH:
if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, pProc,
if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, this,
&rhs, &lhs, 1) == TRUE)
{
pIcode->setUnary( HLI_PUSH, lhs);
@ -282,10 +283,10 @@ static void propLongStk (Int i, ID *pLocId, Function * pProc)
}
/* Check long conditional (i.e. 2 CMPs and 3 branches */
else if ((pIcode->ic.ll.opcode == iCMP) && (isLong23 (idx, pIcode->inBB, pProc->Icode.GetFirstIcode(),&off, &arc)))
else if ((pIcode->ic.ll.opcode == iCMP) && (isLong23 (idx, pIcode->inBB, this->Icode.GetFirstIcode(),&off, &arc)))
{
if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, pProc, &rhs, &lhs, off) == TRUE)
longJCond23 (rhs, lhs, pIcode, &idx, pProc, arc, off);
if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, this, &rhs, &lhs, off) == TRUE)
longJCond23 (rhs, lhs, pIcode, &idx, this, arc, off);
}
/* Check for long conditional equality or inequality. This requires
@ -293,7 +294,7 @@ static void propLongStk (Int i, ID *pLocId, Function * pProc)
else if ((pIcode->ic.ll.opcode == iCMP) &&
isLong22 (pIcode, pEnd, &off))
{
if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, pProc,
if (checkLongEq (pLocId->id.longStkId, pIcode, i, idx, this,
&rhs, &lhs, off) == TRUE)
longJCond22 (rhs, lhs, pIcode, &idx);
}
@ -306,7 +307,7 @@ static void propLongStk (Int i, ID *pLocId, Function * pProc)
* Arguments: i : index into the local identifier table
* pLocId: ptr to the long local identifier
* pProc : ptr to current procedure's record. */
static void propLongReg (Int i, ID *pLocId, Function * pProc)
void Function::propLongReg (Int i, ID *pLocId)
{
COND_EXPR *lhs, *rhs;
Int idx, j, off, arc;
@ -314,13 +315,13 @@ static void propLongReg (Int i, ID *pLocId, Function * pProc)
ICODEMEM * pmH,* pmL; /* Pointers to dst LOW_LEVEL icodes */
/* Process all definitions/uses of long registers at an icode position */
pEnd = pProc->Icode.GetIcode(pProc->Icode.GetNumIcodes() -1);
pEnd = this->Icode.GetIcode(this->Icode.GetNumIcodes() -1);
for (j = 0; j < pLocId->idx.size(); j++)
{
/* Check backwards for a definition of this long register */
for (idx = pLocId->idx[j] - 1; idx > 0 ; idx--)
{
pIcode = pProc->Icode.GetIcode(idx-1);
pIcode = this->Icode.GetIcode(idx-1);
if ((pIcode->type == HIGH_LEVEL) || (pIcode->invalid == TRUE))
continue;
@ -333,9 +334,9 @@ static void propLongReg (Int i, ID *pLocId, Function * pProc)
if ((pLocId->id.longId.h == pmH->regi) && (pLocId->id.longId.l == pmL->regi))
{
lhs = COND_EXPR::idLongIdx (i);
pProc->localId.id_arr[i].idx.push_back(idx-1);
this->localId.id_arr[i].idx.push_back(idx-1);
pIcode->setRegDU( pmL->regi, eDEF);
rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, HIGH_FIRST, idx, eUSE, 1);
rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode, HIGH_FIRST, idx, eUSE, 1);
pIcode->setAsgn(lhs, rhs);
(pIcode+1)->invalidate();
idx = 0; /* to exit the loop */
@ -364,7 +365,7 @@ static void propLongReg (Int i, ID *pLocId, Function * pProc)
{
lhs = COND_EXPR::idLongIdx (i);
pIcode->setRegDU( pmH->regi, USE_DEF);
rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode, LOW_FIRST, idx, eUSE, 1);
rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode, LOW_FIRST, idx, eUSE, 1);
switch (pIcode->ic.ll.opcode) {
case iAND: rhs = COND_EXPR::boolOp (lhs, rhs, AND);
break;
@ -384,9 +385,9 @@ static void propLongReg (Int i, ID *pLocId, Function * pProc)
/* If no definition backwards, check forward for a use of this long reg */
if (idx <= 0)
for (idx = pLocId->idx[j] + 1; idx < pProc->Icode.GetNumIcodes() - 1; idx++)
for (idx = pLocId->idx[j] + 1; idx < this->Icode.GetNumIcodes() - 1; idx++)
{
pIcode = pProc->Icode.GetIcode(idx);
pIcode = this->Icode.GetIcode(idx);
if ((pIcode->type == HIGH_LEVEL) || (pIcode->invalid == TRUE))
continue;
@ -398,11 +399,11 @@ static void propLongReg (Int i, ID *pLocId, Function * pProc)
{
rhs = COND_EXPR::idLongIdx (i);
pIcode->setRegDU( (pIcode+1)->ic.ll.src.regi, eUSE);
lhs = COND_EXPR::idLong (&pProc->localId, DST, pIcode,
lhs = COND_EXPR::idLong (&this->localId, DST, pIcode,
HIGH_FIRST, idx, eDEF, 1);
pIcode->setAsgn(lhs, rhs);
(pIcode+1)->invalidate();
idx = pProc->Icode.GetNumIcodes(); /* to exit the loop */
idx = this->Icode.GetNumIcodes(); /* to exit the loop */
}
break;
@ -415,7 +416,7 @@ static void propLongReg (Int i, ID *pLocId, Function * pProc)
pIcode->setUnary(HLI_PUSH, lhs);
(pIcode+1)->invalidate();
}
idx = pProc->Icode.GetNumIcodes(); /* to exit the loop */
idx = this->Icode.GetNumIcodes(); /* to exit the loop */
break;
/*** others missing ****/
@ -428,7 +429,7 @@ static void propLongReg (Int i, ID *pLocId, Function * pProc)
{
lhs = COND_EXPR::idLongIdx (i);
pIcode->setRegDU( pmH->regi, USE_DEF);
rhs = COND_EXPR::idLong (&pProc->localId, SRC, pIcode,
rhs = COND_EXPR::idLong (&this->localId, SRC, pIcode,
LOW_FIRST, idx, eUSE, 1);
switch (pIcode->ic.ll.opcode) {
case iAND: rhs = COND_EXPR::boolOp (lhs, rhs, AND);
@ -447,12 +448,12 @@ static void propLongReg (Int i, ID *pLocId, Function * pProc)
/* Check long conditional (i.e. 2 CMPs and 3 branches */
else if ((pIcode->ic.ll.opcode == iCMP) &&
(isLong23 (idx, pIcode->inBB, pProc->Icode.GetFirstIcode(),
(isLong23 (idx, pIcode->inBB, this->Icode.GetFirstIcode(),
&off, &arc)))
{
if (checkLongRegEq (pLocId->id.longId, pIcode, i, idx, pProc,
if (checkLongRegEq (pLocId->id.longId, pIcode, i, idx, this,
&rhs, &lhs, off) == TRUE)
longJCond23 (rhs, lhs, pIcode, &idx, pProc, arc, off);
longJCond23 (rhs, lhs, pIcode, &idx, this, arc, off);
}
/* Check for long conditional equality or inequality. This requires
@ -460,7 +461,7 @@ static void propLongReg (Int i, ID *pLocId, Function * pProc)
else if ((pIcode->ic.ll.opcode == iCMP) &&
(isLong22 (pIcode, pEnd, &off)))
{
if (checkLongRegEq (pLocId->id.longId, pIcode, i, idx, pProc,
if (checkLongRegEq (pLocId->id.longId, pIcode, i, idx, this,
&rhs, &lhs, off) == TRUE)
longJCond22 (rhs, lhs, pIcode, &idx);
}
@ -493,9 +494,9 @@ static void propLongReg (Int i, ID *pLocId, Function * pProc)
/* Propagates the long global address across all LOW_LEVEL icodes.
* Transforms some LOW_LEVEL icodes into HIGH_LEVEL */
static void propLongGlb (Int i, ID *pLocId, Function * pProc)
void Function::propLongGlb (Int i, ID *pLocId)
{
printf("WARN: Function::propLongGlb not implemented");
}
@ -514,13 +515,13 @@ void Function::propLong()
switch (pLocId->loc)
{
case STK_FRAME:
propLongStk (i, pLocId, this);
propLongStk (i, pLocId);
break;
case REG_FRAME:
propLongReg (i, pLocId, this);
propLongReg (i, pLocId);
break;
case GLB_FRAME:
propLongGlb (i, pLocId, this);
propLongGlb (i, pLocId);
break;
}
}

View File

@ -603,11 +603,9 @@ static void trans(Int i)
pIcode->ic.ll.flagDU.d = df[REG(*pInst)];
rm(i);
memcpy(&pIcode->ic.ll.src, &pIcode->ic.ll.dst, sizeof(ICODEMEM));
if (pIcode->ic.ll.opcode == iJMP || pIcode->ic.ll.opcode == iCALL ||
pIcode->ic.ll.opcode == iCALLF)
if (pIcode->ic.ll.opcode == iJMP || pIcode->ic.ll.opcode == iCALL || pIcode->ic.ll.opcode == iCALLF)
pIcode->ic.ll.flg |= NO_OPS;
else if (pIcode->ic.ll.opcode == iINC || pIcode->ic.ll.opcode == iPUSH
|| pIcode->ic.ll.opcode == iDEC)
else if (pIcode->ic.ll.opcode == iINC || pIcode->ic.ll.opcode == iPUSH || pIcode->ic.ll.opcode == iDEC)
pIcode->ic.ll.flg |= NO_SRC;
}
}

View File

@ -52,18 +52,9 @@ static tableType curTableType; /* Which table is current */
struct TABLEINFO_TYPE
{
void deleteVal(dword symOff, Function *symProc, boolT bSymToo);
void enterSym(const char *symName, dword symOff, Function *symProc, boolT bSymToo);
std::string findVal(dword symOff, Function *symProc, word &pIndex);
void create(tableType type);
void destroy();
private:
void deleteSym(char *symName);
boolT findSym(const char *symName, word &pIndex);
boolT readSym(char *symName, dword *pSymOff, Function **pSymProc);
void expandSym(void);
word findBlankSym(const std::string &symName);
word symHash(const char *name, word *pre);
word valHash(dword symOff, Function *symProc, word *pre);
SYMTABLE *symTab; /* Pointer to the symbol hashed table */
SYMTABLE *valTab; /* Pointer to the value hashed table */
@ -149,478 +140,8 @@ void destroySymTables(void)
currentTabInfo.destroy();
}
/* Hash the symbolic name */
word TABLEINFO_TYPE::symHash(const char *name, word *pre)
{
int i;
word h = 0;
char ch;
for (i=0; i < (int)strlen(name); i++)
{
ch = name[i];
h = (h << 2) ^ ch;
h += (ch >> 2) + (ch << 5);
}
*pre = h; /* Pre modulo hash value */
return h % tableSize; /* Post modulo hash value */
}
/* Hash the symOff and symProc fields */
/* Note: for the time being, there no use is made of the symProc field */
word TABLEINFO_TYPE::valHash(dword symOff, Function * symProc, word *pre)
{
word h = 0;
h = (word)(symOff ^ (symOff >> 8));
*pre = h; /* Pre modulo hash value */
return h % tableSize; /* Post modulo hash value */
}
void TABLEINFO_TYPE::enterSym(const char *symName, dword symOff, Function * symProc, boolT bSymToo)
{
word h, pre, j;
SYMTABLE entry;
entry.pSymName= symName; /* Symbol name ptr */
entry.symOff = symOff; /* Offset of the symbol */
entry.symProc = symProc; /* Symbol's proc num */
entry.preHash = pre; /* Pre modulo hash value */
entry.postHash= h; /* Post modulo hash value */
entry.nextOvf = NIL; /* No overflow */
entry.prevOvf = NIL; /* No back link */
z[symName] = entry;
z2[entry] = symName;
if ((numEntry / 9 * 10) >= tableSize)
{
/* Table is full. Expand it */
expandSym();
}
/* Enter it into the value hashed table first */
h = valHash(symOff, symProc, &pre); /* Ideal spot for this entry */
if (valTab[h].symProc == 0) /* Collision? */
{
/* No. Just insert here */
valTab[h].pSymName= symName; /* Symbol name ptr */
valTab[h].symOff = symOff; /* Offset of the symbol */
valTab[h].symProc = symProc; /* Symbol's proc num */
valTab[h].preHash = pre; /* Pre modulo hash value */
valTab[h].postHash= h; /* Post modulo hash value */
valTab[h].nextOvf = NIL; /* No overflow */
valTab[h].prevOvf = NIL; /* No back link */
}
else
{
/* Linear probing, for now */
j = (h+1) % tableSize;
while (j != h)
{
if (valTab[j].symProc == 0)
{
/* Insert here */
valTab[j].pSymName= symName; /* Symbol name ptr */
valTab[j].symOff = symOff; /* Offset of the symbol */
valTab[j].symProc = symProc; /* Symbol's proc num */
valTab[j].preHash = pre; /* Pre modulo hash value */
valTab[j].postHash= h; /* Post modulo hash value */
/* Insert after the primary entry in the table */
valTab[j].nextOvf = valTab[h].nextOvf;
valTab[h].nextOvf = j;
valTab[j].prevOvf = h; /* The backlink */
break;
}
else
{
/* Probe further */
j = (j+1) % tableSize;
}
}
if (j == h)
{
printf("enterSym: val table overflow!\n");
exit(1);
}
}
/* Now enter into the symbol hashed table as well, if reqd */
if (!bSymToo) return;
h = symHash(symName, &pre); /* Ideal spot for this entry */
if (symTab[h].pSymName.empty()) /* Collision? */
{
/* No. Just insert here */
symTab[h].pSymName= symName; /* Symbol name ptr */
symTab[h].symOff = symOff; /* Offset of the symbol */
symTab[h].symProc = symProc; /* Symbol's proc num */
symTab[h].preHash = pre; /* Pre modulo hash value */
symTab[h].postHash= h; /* Post modulo hash value */
symTab[h].nextOvf = NIL; /* No overflow */
symTab[h].prevOvf = NIL; /* No back link */
}
else
{
/* Linear probing, for now */
j = (h+1) % tableSize;
while (j != h)
{
if (symTab[j].pSymName.empty())
{
/* Insert here */
symTab[j].pSymName= symName; /* Symbol name ptr */
symTab[j].symOff = symOff; /* Offset of the symbol */
symTab[j].symProc = symProc; /* Symbol's proc num */
symTab[j].preHash = pre; /* Pre modulo hash value */
symTab[j].postHash= h; /* Post modulo hash value */
/* Insert after the primary entry in the table */
symTab[j].nextOvf = symTab[h].nextOvf;
symTab[h].nextOvf = j;
symTab[j].prevOvf = h; /* The backlink */
break;
}
else
{
/* Probe further */
j = (j+1) % tableSize;
}
}
if (j == h)
{
printf("enterSym: sym table overflow!\n");
exit(1);
}
}
}
void enterSym(char *symName, dword symOff, Function * symProc, boolT bSymToo)
{
currentTabInfo.enterSym(symName,symOff,symProc,bSymToo);
}
boolT TABLEINFO_TYPE::findSym(const char *symName, word &pIndex)
{
word h, j, pre;
h = symHash(symName, &pre);
j = h;
bool found=false;
do
{
if (symTab[j].pSymName.empty())
{
return FALSE; /* No entry at all */
}
if (strcmp(symName, symTab[j].pSymName.c_str()) == 0)
{
pIndex = j;
found=true;
break; /* Symbol found */
}
j = symTab[j].nextOvf; /* Follow the chain */
}
while (j != NIL);
auto iter = z.find(symName);
if(iter!=z.end())
{
assert(iter->second==symTab[j]);
}
return found; /* End of chain */
}
/* Find symbol by value */
std::string TABLEINFO_TYPE::findVal(dword symOff, Function * symProc, word &pIndex)
{
word h, j, pre;
std::string res="";
h = valHash(symOff, symProc, &pre);
j = h;
do
{
if (valTab[j].symProc == 0)
break; /* No entry at all */
if ((valTab[j].symOff == symOff) /*&& (valTab[j].symProc == symProc)*/)
{
pIndex = j;
res=valTab[j].pSymName;
break; /* Symbol found */
}
j = valTab[j].nextOvf; /* Follow the chain */
}
while (j != NIL);
auto iter = z2.find(SYMTABLE(symOff,symProc));
if(iter!=z2.end())
{
assert(iter->second==res);
}
return res; /* End of chain */
}
word TABLEINFO_TYPE::findBlankSym(const std::string &symName)
{
word h, j, pre;
h = symHash(symName.c_str(), &pre);
j = h;
do
{
if (symTab[j].pSymName.empty())
{
return j; /* Empty entry. Terminate probing */
}
j = (++j) % tableSize; /* Linear probing */
}
while (j != h);
printf("Could not find blank entry in table! Num entries is %ld of %ld\n",
(long)numEntry, (long)tableSize);
return 0;
}
/* Using the symbolic name, read the value */
boolT TABLEINFO_TYPE::readSym(char *symName, dword *pSymOff, Function * *pSymProc)
{
word i;
if (!findSym(symName, i))
{
return FALSE;
}
*pSymOff = symTab[i].symOff;
*pSymProc= symTab[i].symProc;
return TRUE;
}
/* A doubly linked list of entries belonging to the same hash bucket is
maintained, to prevent the need for many entries to be moved when deleting
an entry. It is implemented with indexes, and is not an open hashing system.
Symbols are deleted from both hash tables.
*/
/* Known limitation: strings are never deleted from the string table */
void TABLEINFO_TYPE::deleteSym(char *symName)
{
word i, j, back;
dword symOff;
Function * symProc;
/* Delete from symbol hashed table first */
if (!findSym(symName, i))
{
printf("Could not delete non existant symbol name %s\n", symName);
exit(1);
}
symOff = symTab[i].symOff; /* Remember these for valTab */
symProc= symTab[i].symProc;
j = symTab[i].nextOvf; /* Look at next overflowed entry */
if (j == NIL) /* Any overflows? */
{
/* No, so we just wipe out this record. Must NIL the pointer of
the previous record, however */
symTab[symTab[i].prevOvf].nextOvf = NIL;
j = i; /* So we wipe out the current name */
}
else
{
/* Yes, move this entry to this vacated spot. Note that the nextOvf
field will still point to the next record in the overflow chain,
but we need to preserve the backlink for adjusting the current
item's backlink */
back = symTab[j].prevOvf;
symTab[i] = symTab[j];
symTab[i].prevOvf = back;
}
/* And now mark the vacated record as empty */
symTab[j].pSymName.clear(); /* Rub out the name */
/* Delete from value hashed table */
if (findVal(symOff, symProc, i).empty())
{
printf("Could not delete non existant symbol off %04X proc %d\n",symOff, symProc);
exit(1);
}
j = valTab[i].nextOvf; /* Look at next overflowed entry */
if (j == NIL) /* Any overflows? */
{
/* No, so we just wipe out this record. Must NIL the pointer of
the previous record, however */
valTab[valTab[i].prevOvf].nextOvf = NIL;
j = i; /* So we wipe out the current entry */
}
else
{
/* Yes, move this entry to this vacated spot. Note that the nextOvf
field will still point to the next record in the overflow chain,
but we need to preserve the backlink for adjusting the current
item's backlink */
back = valTab[j].prevOvf;
valTab[i]= valTab[j];
valTab[i].prevOvf = back;
}
/* And now mark the vacated record as empty */
valTab[j].symProc = 0; /* Rub out the entry */
}
void TABLEINFO_TYPE::deleteVal(dword symOff, Function * symProc, boolT bSymToo)
{
word i, j, back;
std::string symName;
/* Delete from value hashed table */
if (findVal(symOff, symProc, i).empty())
{
printf("Could not delete non existant symbol off %04X proc %p\n",
symOff, symProc);
exit(1);
}
symName = symTab[i].pSymName; /* Remember this for symTab */
j = valTab[i].nextOvf; /* Look at next overflowed entry */
if (j == NIL) /* Any overflows? */
{
/* No, so we just wipe out this record. Must NIL the pointer of
the previous record, however */
valTab[valTab[i].prevOvf].nextOvf = NIL;
j = i; /* So we wipe out the current entry */
}
else
{
/* Yes, move this entry to this vacated spot. Note that the nextOvf
field will still point to the next record in the overflow chain,
but we need to preserve the backlink for adjusting the current
item's backlink */
back = valTab[j].prevOvf;
memcpy(&valTab[i], &valTab[j], sizeof(SYMTABLE));
valTab[i].prevOvf = back;
}
/* And now mark the vacated record as empty */
valTab[j].symProc = 0; /* Rub out the entry */
/* If requested, delete from symbol hashed table now */
if (!bSymToo) return;
if (!findSym(symName.c_str(), i))
{
printf("Could not delete non existant symbol name %s\n", symName.c_str());
exit(1);
}
j = symTab[i].nextOvf; /* Look at next overflowed entry */
if (j == NIL) /* Any overflows? */
{
/* No, so we just wipe out this record. Must NIL the pointer of
the previous record, however */
symTab[symTab[i].prevOvf].nextOvf = NIL;
j = i; /* So we wipe out the current name */
}
else
{
/* Yes, move this entry to this vacated spot. Note that the nextOvf
field will still point to the next record in the overflow chain,
but we need to preserve the backlink for adjusting the current
item's backlink */
back = symTab[j].prevOvf;
symTab[i] = symTab[j];
symTab[i].prevOvf = back;
}
/* And now mark the vacated record as empty */
symTab[j].pSymName.clear(); /* Rub out the name */
}
void TABLEINFO_TYPE::expandSym(void)
{
word i, j, n, newPost;
printf("\nResizing table...\r");
/* We double the table size each time, so on average only half of the
entries move to the new half. This works because we are effectively
shifting the "binary point" of the hash value to the left each time,
thereby leaving the number unchanged or adding an MSBit of 1. */
tableSize <<= 2;
symTab = (SYMTABLE*)reallocVar(symTab, tableSize * sizeof(SYMTABLE));
memset (&symTab[tableSize/2], 0, (tableSize/2) * sizeof(SYMTABLE));
/* Now we have to move some of the entries to take advantage of the extra
space */
for (i=0; i < numEntry; i++)
{
newPost = symTab[i].preHash % tableSize;
if (newPost != symTab[i].postHash)
{
/* This entry is now in the wrong place. Copy it to the new position,
then delete it. */
j = findBlankSym(symTab[i].pSymName);
memcpy(&symTab[j], &symTab[i], sizeof(SYMTABLE));
/* Correct the post hash value */
symTab[j].postHash = newPost;
/* Now adjust links */
n = symTab[j].prevOvf;
if (n != NIL)
{
symTab[n].nextOvf = j;
}
n = symTab[j].nextOvf;
if (n != NIL)
{
symTab[n].prevOvf = j;
}
/* Mark old position as deleted */
symTab[i].pSymName.clear();
}
}
}
/* This function adds to the string table. At this stage, strings are not
deleted */
char * addStrTbl(char *pStr)
{
char *p;
if ((strTabNext + strlen(pStr) + 1) >= STRTABSIZE)
{
/* We can't realloc the old string table pointer, since that will
potentially move the string table, and pointers will be invalid.
So we realloc this one to its present usage (hopefully it won't
move), and allocate a new one */
if (reallocVar((void *)pStrTab, strTabNext) != pStrTab)
{
printf("Damn it! String table moved on shrinking!\n");
exit(1);
}
pStrTab = (char *)allocMem(STRTABSIZE);
strTabNext = 0;
}
p = strcpy(&pStrTab[strTabNext], pStr);
strTabNext += strlen(pStr) +1;
return p;
}
void deleteVal(dword symOff, Function * symProc, boolT bSymToo)
{
currentTabInfo.deleteVal(symOff,symProc,bSymToo);
}
std::string findVal(dword symOff, Function * symProc, word *pIndex)
{
return currentTabInfo.findVal(symOff,symProc,*pIndex);
}
/* Using the value, read the symbolic name */
boolT readVal(char *symName, dword symOff, Function * symProc)
{
word i;
std::string r=currentTabInfo.findVal(symOff, symProc, i);
if (r.empty())
{
return false;
}
strcpy(symName, r.c_str());
return true;
return false; // no symbolic names for now
}