#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include "sym.h"
#include "decode.h"
#include "core.h"
#include "Scanalyzer.h"
#include "misc.h"
char xtran[256] = {
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
' ', '!', '"', '#', '$', '%', '&',0x27, '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[',0x5C, ']', '^', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.',
};
int dis = 0;
int stats = 0;
int trace = 0;
disb *disbuf = 0;
uint32_t level = 0;
uint32_t regfree = 0;
uint32_t regmalloc = 0;
uint32_t istatefree = 0;
uint32_t istatemalloc = 0;
void tossregfile(regfile *rg) {
int i;
if(rg->core) tosscore(rg);
for(i = 0; i < sizeof(regfile); i++) ((char *)rg)[i] = 0x55;
free(rg);
regfree++;
return;
}
istate *getistate(istate *ois) {
istate *is;
is = malloc(sizeof(istate));
if(!is) {
printf("Can't allocate instruction state block\n");
exit(1);
}
istatemalloc++;
if(!(uint32_t)ois) bzero((void *)is, sizeof(istate));
else bcopy(ois, is, sizeof(istate));
is->isBack = ois;
return is;
}
void tossistate(istate *is) {
int i;
for(i = 0; i < sizeof(istate); i++) ((char *)is)[i] = 0x55;
free(is);
istatefree++;
}
regfile *getregfile(regfile *org) {
regfile *rg;
rg = malloc(sizeof(regfile));
if(!rg) {
printf("Can't allocate register file block\n");
exit(1);
}
regmalloc++;
if(!(uint32_t)org) bzero((void *)rg, sizeof(regfile));
else bcopy(org, rg, sizeof(regfile));
rg->level = level;
rg->rgBack = org;
rg->core = 0;
rg->rgx[rfGpr - 1] = &rg->gprs[0];
rg->rgx[rfFpr - 1] = &rg->fprs[0];
rg->rgx[rfVpr - 1] = (uint64_t *)&rg->vprs[0];
rg->rgx[rfSpr - 1] = &rg->sprs[0];
rg->trx[rfGpr - 1] = &rg->trakGpr[0];
rg->trx[rfFpr - 1] = &rg->trakFpr[0];
rg->trx[rfVpr - 1] = &rg->trakVpr[0];
rg->trx[rfSpr - 1] = &rg->trakSpr[0];
return rg;
}
uint8_t trackReg(istate *is, uint8_t cl, uint8_t ex, uint8_t tt, uint8_t ta, uint8_t tb, uint8_t tc, uint8_t td) {
is->trakClear = cl;
is->trakExplicit = ex;
is->trakTarget = tt;
is->trakSourcea = ta;
is->trakSourceb = tb;
is->trakSourcec = tc;
is->trakSourced = td;
return trackRegNS(is, cl, ex, tt, ta, tb, tc, td);
}
uint8_t trackRegNS(istate *is, uint8_t cl, uint8_t ex, uint8_t tt, uint8_t ta, uint8_t tb, uint8_t tc, uint8_t td) {
uint8_t trakall, trakany, trak;
int numused;
trakall = 0xFF;
trakany = 0;
numused = 0;
if(ta && !(ta & gTundef)) {
trakany |= ta;
trakall &= ta;
numused++;
}
if(tb && !(tb & gTundef)) {
trakany |= tb;
trakall &= tb;
numused++;
}
if(tc && !(tc & gTundef)) {
trakany |= tc;
trakall &= tc;
numused++;
}
if(td && !(td & gTundef)) {
trakany |= td;
trakall &= td;
numused++;
}
if(!numused) trakall = 0;
trakall &= strakall;
trakany &= strakany;
trak = trakany | trakall;
trak &= ~cl;
trak |= ex;
if(trak & gTundef) trak = trak & (gTset | gTundef);
return (trak);
}
void pprint(char *data, uint64_t addr, int len, int indent) {
int fline, i, j, k, cc;
char idnt[256];
for(i = 0; i < indent; i++) idnt[i] = ' ';
idnt[i] = 0;
fline = (len + 15) & -16;
for(i = 0; i < fline; i += 16) {
cc = i;
printf("%s%08X.%08X ", idnt, (uint32_t)((addr + i) >> 32), (uint32_t)addr + i);
for(j = 0; j < 4; j++) {
for(k = 0; k < 4; k++) {
if(cc < len) printf("%02X", (data[cc] & 0xFF));
else printf(" ");
cc++;
}
printf(" ");
}
cc = i;
printf(" * ");
for(j = 0; j < 4; j++) {
for(k = 0; k < 4; k++) {
if(cc < len) printf("%c", xtran[(data[cc] & 0xFF)]);
else printf(" ");
cc++;
}
printf(" ");
}
printf(" *\n");
}
}
void disassemble(uint64_t addr, uint32_t *mem, uint8_t *isnflgs, int insts, char *fname, char *function) {
int i, btab, nr;
printf("\nDisassembling %s in %s\n\n", function, fname);
btab = 0;
nr = 0;
for(i = 0; i < insts; i++) {
if(nr) {
if(disbuf[i].out[0] == 0) continue;
printf("%08X.%08X - %08X.%08X **** Unreachable ****\n\n", (uint32_t)((addr + (nr * 4)) >> 32), (uint32_t)addr + (nr * 4) ,
(uint32_t)((addr + ((i - 1) * 4)) >> 32), (uint32_t)addr + ((i - 1) * 4));
nr = 0;
}
else {
if(disbuf[i].out[0] == 0) {
printf("\n");
nr = i;
continue;
}
}
if(isnflgs[i] & isnBTarg) printf("\n");
if(!btab && (isnflgs[i] & 0xF) == isBranchTbl) {
printf("\n");
btab = 1;
}
else if(btab && (isnflgs[i] & 0xF) != isBranchTbl) {
printf("\n");
btab = 0;
}
printf("%08X.%08X %02X %s\n", (uint32_t)((addr + (i * 4)) >> 32), (uint32_t)addr + (i * 4),
isnflgs[i], &disbuf[i].out[0]);
}
if(nr) {
printf("%08X.%08X - %08X.%08X **** Unreachable ****\n\n", (uint32_t)((addr + (nr * 4)) >> 32), (uint32_t)addr + (nr * 4) ,
(uint32_t)((addr + ((i - 1) * 4)) >> 32), (uint32_t)addr + ((i - 1) * 4));
nr = 0;
}
return;
}
char *isnname[] = {
"**** Unreachable ****",
"Branch",
"Syscall",
"Trap",
"Branch table",
"Scalar",
"Invalid",
"Branch/exit",
"Syscall/exit",
"Trap/exit",
"Scalar/exit",
"Privileged",
"Privileged/exit",
"Call",
"Call/exit",
"RFI",
"Pre-link call vectors",
"larx/stcx."
};
uint8_t xisn[256] = {
xiNR, xiSR, xiSR, xiSR, xiSR, xiSC, xiTR, 255, xiSR, xiSR, xiSR, xiBT, xiRsv, 255, 255, xiIN,
255, xiBRx, xiBRx, xiSRx, xiSRx, xiSCx, xiTRx, 255, xiSRx, xiSRx, xiSRx, 255, xiRsv, 255, 255, 255,
255, 255, 255, xiSRp, xiSRp, 255, 255, xiRIpx, xiSRp, xiSRp, xiSRp, 255, xiRsv, 255, 255, 255,
255, 255, 255, xiSRpx, xiSRpx, 255, 255, xiRIpx, xiSRpx, xiSRpx, xiSRpx, 255, xiRsv, 255, 255, 255,
255, xiSR, xiSR, 255, 255, 255, 255, 255, 255, 255, 255, 255, xiRsv, 255, 255, 255,
255, xiBRcx, xiBRcx, 255, 255, 255, 255, 255, 255, 255, 255, 255, xiRsv, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, xiRsv, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, xiRsv, 255, 255, 255,
255, xiSR, xiSR, xiSR, xiSR, xiSC, xiTR, 255, xiSR, xiSR, xiSR, xiBT, xiRsv, 255, 255, xiIN,
255, xiBRx, xiBRx, xiSRx, xiSRx, xiSCx, xiTRx, 255, xiSRx, xiSRx, xiSRx, 255, xiRsv, 255, 255, 255,
255, 255, 255, xiSRp, xiSRp, 255, 255, 255, xiSRp, xiSRp, xiSRp, 255, xiRsv, 255, 255, 255,
255, 255, 255, xiSRpx, xiSRpx, 255, 255, xiRIpx, xiSRpx, xiSRpx, xiSRpx, 255, xiRsv, 255, 255, 255,
255, xiSR, xiSR, 255, 255, 255, 255, 255, 255, 255, 255, 255, xiRsv, 255, 255, 255,
255, xiBRcx, xiBRcx, 255, 255, 255, 255, 255, 255, 255, 255, 255, xiRsv, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, xiRsv, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, xiRsv, 255, 255, 255
};
char *ent[2] = { "", "Entry/" };
void gendtrace(uint64_t addr, uint64_t funcstart, uint32_t *mem, uint8_t *isnflgs, int insts, char *fname, char *function) {
int i, lastinst, entinst;
uint32_t lasttype, currtype;
lasttype = xisn[isnflgs[0]];
if(lasttype == 255) {
printf("Invalid isnflgs %02X at %08X.%08X\n", isnflgs[0], (uint32_t)(addr >> 32), (uint32_t)addr);
exit(1);
}
if((lasttype == xiNR) && (mem[0] == 0x60000000)) lasttype = xiSR;
lastinst = 0;
entinst = (addr - funcstart) / 4;
if(entinst == 0) lasttype = lasttype | 0x100;
if (dis)
printf("\nAnalysis of %s in %s\n\n", function, fname);
for(i = lastinst; i < insts; i++) {
currtype = xisn[isnflgs[i]];
if(lasttype == 255) {
printf("Invalid isnflgs %02X at %08X.%08X\n", isnflgs[i], (uint32_t)((addr + (uint64_t)(i * 4)) >> 32),
(uint32_t)(addr + (uint64_t)(i * 4)));
exit(1);
}
if((currtype == xiNR) && (mem[i] == 0x60000000)) currtype = xiSR;
if(entinst == i) currtype = currtype | 0x100;
if(currtype == lasttype) continue;
if((lasttype > 255) || ((lasttype & 0xFF) != xiSR)) {
if (dis)
printf("%08X.%08X - %08X.%08X: %02X %03X %s%s\n",
(uint32_t)(addr + ((uint64_t)(lastinst * 4)) >> 32), (uint32_t)(addr + ((uint64_t)(lastinst * 4))),
(uint32_t)((addr + (uint64_t)((i - 1) * 4)) >> 32), (uint32_t)(addr + (uint64_t)((i - 1) * 4)),
isnflgs[lastinst], lasttype,
ent[lasttype >> 8], isnname[lasttype & 0xFF]);
}
lasttype = currtype;
lastinst = i;
}
if(lasttype == xiNR) lasttype = xiFunVec;
if (stats | trace) {
printf("%08X.%08X - %08X.%08X: %02X %03X %s%s\n",
(uint32_t)(addr + ((uint64_t)(lastinst * 4)) >> 32), (uint32_t)(addr + ((uint64_t)(lastinst * 4))),
(uint32_t)((addr + (uint64_t)((i - 1) * 4)) >> 32), (uint32_t)(addr + (uint64_t)((i - 1) * 4)),
isnflgs[lastinst], lasttype,
ent[lasttype >> 8],isnname[lasttype & 0xFF]);
}
return;
}
void diedie(char *xx) {
printf("ARGGGHHHHHHH!!!!!!! - %s\n", xx);
return;
}