?? oxccai.c
字號:
if(SymHead(iv->datatbl))
{
while(SymNext(iv->datatbl))
{
unsigned char *p;
long size;
unsigned char opcode, prevopcode = 0;
unsigned long *key;
struct _dval *val;
SymKey(iv->datatbl, &key);
SymValue(iv->datatbl, &val);
p = val->p;
opcode = *p;
if(val->prevp)
prevopcode = *(val->prevp);
size = val->size;
if(opcode == bssblockop)
{
if(prevopcode == globssop)
{
DUMP(".comm _%s,%ld\n",
iv->symaddr[GS(POP->data2)], size);
}
else
{
DUMP(".lcomm _%s,%ld\n",
iv->symaddr[GS(POP->data2)], size);
}
}
}
}
}
static int
dump_zero_bytes(Piv iv, unsigned char **pcp, int *pcnt, int cw)
{
unsigned char *cp = *pcp;
if(*cp == 0)
{
int cnt;
int zcnt = 0;
cnt = *pcnt;
while(*cp++ == 0 && cnt-- > 0)
++zcnt;
if(zcnt > 3)
{
if(cw)
DUMP("\n .space %d", zcnt);
else
DUMP(" .space %d", zcnt);
*pcp += zcnt;
*pcnt -= zcnt;
return 1;
}
}
return 0;
}
static int
dump_zero_shorts(Piv iv, unsigned short **pcp, int *pcnt, int cw)
{
unsigned short *cp = *pcp;
if(*cp == 0)
{
int cnt;
int zcnt = 0;
cnt = *pcnt;
while(*cp++ == 0 && cnt-- > 0)
++zcnt;
if(zcnt > 3)
{
if(cw)
DUMP("\n .space %d", zcnt*2);
else
DUMP(" .space %d", zcnt*2);
*pcp += zcnt;
*pcnt -= zcnt;
return 1;
}
}
return 0;
}
static int
dump_zero_longs(Piv iv, unsigned long **pcp, int *pcnt, int cw)
{
unsigned long *cp = *pcp;
if(*cp == 0)
{
int cnt;
int zcnt = 0;
cnt = *pcnt;
while(*cp++ == 0 && cnt-- > 0)
++zcnt;
if(zcnt > 3)
{
if(cw)
DUMP("\n .space %d", zcnt*4);
else
DUMP(" .space %d", zcnt*4);
*pcp += zcnt;
*pcnt -= zcnt;
return 1;
}
}
return 0;
}
static void
dump_unix_bytes(Piv iv, unsigned char *cp, int cnt)
{
int first=0, width = 0;
while(cnt > 0)
{
while(width <= 75 && cnt > 0)
{
if(dump_zero_bytes(iv, &cp, &cnt, width))
break;
if(width == 0) {
width = QDUMP(" .byte ");
first = 0;
}
if(!first++)
width += DUMP("0x%x", *cp++);
else
width += DUMP(",0x%x", *cp++);
--cnt;
}
QDUMPC('\n');
width = 0;
}
}
static void
dump_unix_shorts(Piv iv, unsigned short *cp, int cnt)
{
int first=0, width = 0;
while(cnt > 1)
{
while(width <= 73 && cnt > 0)
{
if(dump_zero_shorts(iv, &cp, &cnt, width))
break;
if(width == 0) {
width = QDUMP(" .word ");
first = 0;
}
if(!first++)
width += DUMP("0x%x", *cp++);
else
width += DUMP(",0x%x", *cp++);
cnt -= 2;
}
QDUMPC('\n');
width = 0;
}
if(cnt > 0)
dump_unix_bytes(iv, (unsigned char *)cp, cnt);
}
static void
dump_unix_longs(Piv iv, unsigned long *cp, int cnt, long offset)
{
int first = 0, width = 0;
int rtyp;
char *psymb;
int extra;
while(cnt > 3)
{
while(width <= 69 && cnt > 0)
{
if(dump_zero_longs(iv, &cp, &cnt, width))
break;
if(width == 0) {
width = QDUMP(" .long ");
first = 0;
}
if(!first++)
{
if((rtyp = isa_reloc_loc(iv, offset, &psymb, &extra)))
{
if(rtyp == 1)
{
if(extra == 0)
{
width += DUMP("_%s", psymb);
}
else if(extra < 0)
{
width += DUMP("_%s%d", psymb,extra);
}
else
{
width += DUMP("_%s+%d", psymb,extra);
}
}
else
{
if(extra == 0)
{
width += DUMP("_$%p", psymb);
}
else if(extra < 0)
{
width += DUMP("_$%p%d", psymb,extra);
}
else
{
width += DUMP("_$%p+%d", psymb,extra);
}
}
}
else
{
width += DUMP("0x%lx", *cp++);
}
}
else
{
if((rtyp = isa_reloc_loc(iv, offset, &psymb, &extra)))
{
if(rtyp == 1)
{
if(extra == 0)
{
width += DUMP(",_%s", psymb);
}
else if(extra < 0)
{
width += DUMP(",_%s%d", psymb,extra);
}
else
{
width += DUMP(",_%s+%d", psymb,extra);
}
}
else
{
if(extra == 0)
{
width += DUMP(",_$%p", psymb);
}
else if(extra < 0)
{
width += DUMP(",_$%p%d", psymb,extra);
}
else
{
width += DUMP(",_$%p+%d", psymb,extra);
}
}
}
else
{
width += DUMP(",0x%lx", *cp++);
}
}
offset += 4;
cnt -= 4;
}
QDUMPC('\n');
width = 0;
}
if(cnt > 0)
dump_unix_shorts(iv, (unsigned short*)cp, cnt);
}
static void
dump_unix_strings(Piv iv)
{
QDUMP("\n.data\n");
if(SymHead(iv->datatbl))
{
while(SymNext(iv->datatbl))
{
unsigned char *p;
long size;
unsigned char opcode;
unsigned long *key;
struct _dval *val;
SymKey(iv->datatbl, &key);
SymValue(iv->datatbl, &val);
p = val->p;
opcode = *p;
size = val->size;
if(opcode == stringblockop)
{
DUMP("_$%lx:\n", GL(POP->data1));
dump_unix_bytes(iv, p+24, size);
}
}
}
}
static void
dump_unix_data(Piv iv)
{
long mark[2];
QDUMPC('\n');
if(SymHead(iv->datatbl))
{
while(SymNext(iv->datatbl))
{
unsigned char *p;
long size;
unsigned char opcode;
unsigned long *key;
struct _dval *val;
long offset;
SymGetMark(iv->datatbl, mark);
SymKey(iv->datatbl, &key);
SymValue(iv->datatbl, &val);
p = val->p;
opcode = *p;
size = val->size;
offset = GL(POP->data1);
if(opcode == datablockop)
{
if(size > 3)
DUMP(".align 2\n_%s:\n",
iv->symaddr[GS(POP->data2)]);
else if(size > 1)
DUMP(".align 1\n_%s:\n",
iv->symaddr[GS(POP->data2)]);
dump_unix_longs(iv, (long*)(p+24), size, offset);
}
else if(opcode == mallocblockop)
{
DUMP(".align 2\n_$%lx:\n", offset);
dump_unix_longs(iv, (long*)(p+24), size, offset);
}
SymSetMark(iv->datatbl, mark);
}
}
}
static void
dump_unix_funcs(Piv iv)
{
Pafile pf;
unsigned char *p;
int i;
reset_funcdata(iv);
QDUMP("\n\n.text\n");
for(i = 0; i < iv->numfiles; ++i)
{
iv->filenum = i;
pf = iv->files[i];
p = pf->file_p;
while(*p != endfileop)
{
if(*p == labelop)
{
#if 0
DUMP("L%u:\n", GL(POP->data);
#endif
}
else if(*p == gfuncdefop || *p == sfuncdefop)
{
p = dumpa_unix_func(iv, p);
}
else if(*p == anfblockop)
{
PERROR(pName ": Sorry, Outer anf blocks not handled.\n");
}
p = POP->next;
}
}
}
static void
gen_unix_output(Piv iv)
{
long tim = time(0);
char *date = ctime(&tim);
DUMP("// `%s' %s// ", iv->outname, date);
DUMP(notice,MAJOR_VERSION,MINOR_VERSION);
QDUMP("\n\n");
dump_unix_header(iv);
dump_unix_globals(iv);
dump_unix_strings(iv);
dump_unix_data(iv);
dump_unix_funcs(iv);
dump_unix_bss(iv);
}
static void
gen_dos_output(Piv iv)
{
long tim = time(0);
char *date = ctime(&tim);
DUMP("; `%s' %s\n;", iv->outname, date);
DUMP(notice,MAJOR_VERSION,MINOR_VERSION);
QDUMP("\n\n");
}
static int
gen_output(Piv iv, char *outpath)
{/* Assembler output */
char *cp;
Pafile pf;
int i;
char outname[256];
strcpy(outname, outpath);
pf = iv->files[0];
iv->target_assembler = pf->header_p->hdr.target_assembler;
iv->target_hardware = pf->header_p->hdr.target_hardware;
iv->target_debugger = pf->header_p->hdr.target_debugger;
iv->target_os = pf->header_p->hdr.target_os;
iv->memory_model = pf->header_p->hdr.memory_model;
iv->obj_format = pf->header_p->hdr.obj_format;
if((cp = strrchr(outname, '.')))
{
#if 0
if(iv->target_assembler == UNIX || iv->target_assembler == GAS)
strcpy(cp, ".s");
else strcpy(cp, ".asm");
#endif
}
else
{
if(iv->target_assembler == UNIX || iv->target_assembler == GAS)
strcat(outname, ".s");
else
strcat(outname, ".asm");
}
for(i = 1; i < iv->argc; ++i)
{
if(!strcmp(outname, iv->argv[i]))
{
PERROR(pName ":ERROR: output file `%s' is same as input file\n", outname);
}
}
if(!(iv->outfile = fopen(outname, "wb")))
{
PERROR(pName ":ERROR: Cannot open output file %s\n", outname);
}
iv->outname = filenameof(outname);
make_final_symtab(iv);
if(iv->target_assembler == UNIX || iv->target_assembler == GAS)
gen_unix_output(iv);
else
gen_dos_output(iv);
fclose(iv->outfile);
iv->outfile = 0;
return iv->errors;
}
/* ======================= END ASMCODE OUTPUT GENERATOR ==================== */
/* ===================== GENERIC CODE BELOW THIS POINT ================== */
static jmp_buf run_env;
static void
prerror(const char *fmt, ...)
{
VFPRINTF(fmt, (char *)(((int *)(&fmt))+1));
longjmp(run_env, 3);
}
static void
prwarn(const char *fmt, ...)
{
VFPRINTF(fmt, (char *)(((int *)(&fmt))+1));
}
static void
info(const char *fmt, ...)
{
vfprintf(stdout, fmt, (char *)(((int *)(&fmt))+1));
}
/* ========================= MULTI HEAP MALLOC ========================== */
#define LOCAL static
#if USING_FRAMEWORK
#define THEWELL(a) mallocC(local_category, a)
static int local_category;
static int num_instance;
extern void *mallocC(int, int);
extern void freecat(int);
extern void oxlink_clear_bss();
extern int NewMallocCategory();
#endif /* USING_FRAMEWORK */
#define BASE_CATEGORY 0
#define MEMORY_BUG 0
#define PRINT_RAWDATA 0
#if MEMORY_BUG == 1
#define MPRINTF printf
#else
#define MPRINTF(args...)
#endif
#define PAGESIZE (4096) /* can use `pagesize' function in OS */
#define ALIGNMENTM (sizeof(unsigned long))
#define MAL_MAXLEVEL (12)
#define ROUNDINGM(a) ((a+(ALIGNMENTM-1))&~(ALIGNMENTM-1))
#define ALLOCSIZE (4096)
#define FRNTGUARD (0x544e5246UL)
#define BACKGUARD (0x48434142UL)
#ifndef THEWELL
#define THEWELL do_sbrk
#endif
#define NUMTYPES 3
#define SIZEH 0
#define FREEH 1
#define USEDH 2
#define SKIPVARS NodePM update[MAL_MAXLEVEL+1];NodePM node,prev;int level
#define DELETENODE(TYPE) \
{for(level=0;level<=bp->TYPE##level; level++)\
{if(update[level]->fptr[level] == node)\
update[level]->fptr[level] = node->fptr[level];else break;}\
while(bp->TYPE##level>0 && bp->TYPE##header->fptr[bp->TYPE##level]==_NILLL)\
bp->TYPE##level--;free_Mnode(bp,node,TYPE);}
#define INSERT() \
{while(level >= 0){\
node->fptr[level] = update[level]->fptr[level];\
update[level]->fptr[level] = node;level--;}}
#define SETLEVEL(TYPE) \
{level = getMlevel(bp, bp->TYPE##level);\
while(bp->TYPE##level < level)update[++bp->TYPE##level]=bp->TYPE##header;}
#define FINDKEY(TYPE, KEYVAL)\
{node = bp->TYPE##header;\
for(level = bp->TYPE##level; level >= 0; level--){\
while(node->fptr[level]->key < KEYVAL)\
node = node->fptr[level];\
update[level] = node;}prev=node;node=node->fptr[0];}
#define DETACH(SN)\
{SN->bptr->fptr=SN->fptr;if(SN->fptr)SN->fptr->bptr=SN->bptr;}
#define UNLINK(SN, N)\
{if(!sp->fptr&&sp->bptr->bptr<=(AddrP)(MAL_MAXLEVEL+1))dsize[N]=sp->size;\
DETACH(SN);free_addr(bp,SN);}
#define CHECKGUARDS(MSG)\
{if(bp->guarded){\
unsigned *p2;\
p2 = (void*)((char*)address+cursize-ALIGNMENTM);\
if(*address != FRNTGUARD)\
PERROR(pName #MSG ":%d: corrupted at 0x%x\n", bp->bincat, addr);\
if(*p2 != BACKGUARD)\
PERROR(pName #MSG ":%d: corrupted by 0x%x\n", bp->bincat, addr);}}
#if MEMORY_BUG == 1
#define HEAPCHECK \
{void *lastaddr;\
if(category > 0){\
Cguard(category);\
if((lastaddr = Cheapcheck(category, NULL))){\
FINDKEY(USEDH, (unsigned)lastaddr-ALIGNMENTM)\
MPRINTF("bad heap at %x c:%u size=%u\n", lastaddr, category, node->value);\
(void)print_rawdata(lastaddr-ALIGNMENTM, node->value);\
abort();}}}
#else
#define HEAPCHECK
#endif
struct _catlocs {
void *addr;
struct _catlocs *fptr;
};
typedef struct _nodeM
{
unsigned key;
unsigned value;
unsigned levels; /* must always be after value */
struct _nodeM *fptr[1];
} NodeM, *NodePM;
typedef struct _addr
{
struct _addr *fptr;
struct _addr *bptr;
NodePM maddr;
unsigned size;
} *AddrP;
struct _bins {
unsigned bits;
unsigned nbits;
NodePM SIZEHheader;
int SIZEHlevel;
NodePM FREEHheader;
int FREEHlevel;
NodePM USEDHheader;
int USEDHlevel;
unsigned bincat;
unsigned maxloc;
unsigned minloc;
struct _catlocs *catlocs;
struct _bins *fptr;
NodePM freenodes[NUMTYPES][MAL_MAXLEVEL+2];
struct _addr *freeaddrlocs;
char *chunkbase[NUMTYPES];
int chunksize[NUMTYPES];
int guarded;
int addrbump;
};
static struct _bins zbp;
static struct _bins *hmap[1009];
static struct _nodeM _nilll = {0xffffffff,0,0,{0}};
static struct _nodeM *_NILLL = &_nilll;
static unsigned maxloc;
static unsigned minloc;
static struct _bins *freebinlocs;
static struct _catlocs *freecatlocs;
static char *binbase;
static int binsize;
static int chunksizes[] = {ALLOCSIZE,3*ALLOCSIZE,2*ALLOCSIZE};
static long randtbl[32] = { 0L,
0x9a319039L, 0x32d9c024L, 0x9b663182L, 0x5da1f342L,
0xde3b81e0L, 0xdf0a6fb5L, 0xf103bc02L, 0x48f340fbL,
0x7449e56bL, 0xbeb1dbb0L, 0xab5c5918L, 0x946554fdL,
0x8c2e680fL, 0xeb3d799fL, 0xb11ee0b7L, 0x2d436b86L,
0xda672e2aL, 0x1588ca88L, 0xe369735dL, 0x904f35f7L,
0xd7158fd6L, 0x6fa6f051L, 0x616e6b96L, 0xac94efdcL,
0x36413f93L, 0xc622c298L, 0xf5a42ab8L, 0x8a88d77bL,
0xf5ad9d0eL, 0x8999220bL, 0x27fb47b9L
};
static long *fptr = &randtbl[4];
static long *rptr = &randtbl[1];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -