?? oxccai.c
字號:
/*
oxccai.c -- v1.430 ANF to intel asmcode generator
Copyright (c) 1995
Norman D. Culver dba
Oxbow Software
1323 S.E. 17th Street #662
Ft. Lauderdale, FL 33316
(954) 463-4754
ndc@icanect.net
All rights reserved.
* Redistribution and use in source and binary forms are permitted
* provided that: (1) source distributions retain this entire copyright
* notice and comment, and (2) distributions including binaries display
* the following acknowledgement: ``This product includes software
* developed by Norman D. Culver dba Oxbow Software''
* in the documentation or other materials provided with the distribution
* and in all advertising materials mentioning features or use of this
* software.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#define MAJOR_VERSION 1
#define MINOR_VERSION 433
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <setjmp.h>
#include <time.h>
#define SUPPORT_LONG_DOUBLE 0
#define SUPPORT_LONG_LONG 1
#define NEED_FUNCTHUNK 1
#define NEED_ANFDEFS 1
#include "oxanf.h"
#define PROG oxccai
#define USING_FRAMEWORK 1
#define HOST_IS_LITTLE_ENDIAN 1
#define REALLY_NEED_OFFSETS 0
#define FUNCDATA (iv->category+1)
#define VFPRINTF(a,b) vfprintf(stderr,a,b)
#define PERROR prerror
#define PWARN prwarn
#define PRINTF info
static void prerror(const char *, ...);
static void prwarn(const char *, ...);
static void info(const char *, ...);
int cfeprintf(const char *, ...);
#define FILEWRITE(buf, cnt)\
{if(!iv->errors){if(fwrite(buf, 1, cnt, iv->outfile) != cnt)iv->errors = 12;}}
#define ROUNDING(a,b) ((a+(b-1))&~(b-1))
#define ROUNDUP(a,b) a += ROUNDING(a,b)
#define KEYEQ(a,b) ((a)[0] == (b)[0] && (a)[1] == (b)[1])
#define KEYLT(a,b) (((a)[1] < (b)[1]) || ((a)[1] == (b)[1] && (a)[0] < (b)[0]))
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
/* ======================== CONCATENIZATION MACROS ==================== */
#define _cat2_(a, b) a##b
#define _cat_(a, b) _cat2_(a, b)
#define Global(a) _cat_(PROG, a)
#define _pname2_(x) #x
#define _pname1_(x) _pname2_(x)
#define pName _pname1_(PROG)
/* ============== ENDIAN MACROS (input format is litle endian) ==== */
#if HOST_IS_LITTLE_ENDIAN
#define GL(a) a
#define GS(a) a
#define PL(a) a
#define PS(a) a
#else
#endif
/* =================== INPUT DATA FORMATS ========================== */
#define INFILE_SYMNUM 1
#define OUTFILE_SYMNUM 2
/* ====================== STRUCTURES AND TYPEDEFS ======================== */
typedef struct _jl {
struct _jl *next;
void *p;
char *q;
long *plabelval;
long offset;
} *PJL;
typedef struct _el {
struct _el *next;
long spot;
short symnum;
} *PEL;
typedef struct _afile {
unsigned char *file_p;
PopI header_p;
PopI size_p;
unsigned char *symtext_p;
unsigned char *prog_p;
unsigned char *data_p;
unsigned char *switch_p;
unsigned char *decl_p;
unsigned char *maxtemp_p;
unsigned char *seg_p;
unsigned char **symaddr;
unsigned char **decladdr;
unsigned long thunk_offset;
unsigned long bss_offset;
int maxtemp;
int maxtempclass;
void *datatbl;
short *symtran;
unsigned short *decltran;
int filenum;
int numsyms;
int numdecls;
int numrelocs;
int numsegs;
} *Pafile;
typedef struct _iv {
int category;
FILE *outfile;
char *outname;
char *infile_name;
int remove_infile;
int argc;
char **argv;
unsigned char **symaddr;
unsigned char **decladdr;
struct _nodeO *ob_usedhead;
struct _nodeO *ob_usedtail;
struct _nodeO *ob;
unsigned char *ob_buf;
int ob_bufcnt;
int ob_nodecnt;
struct _nodeO *first_ob;
struct _nodeC *cod_usedhead;
struct _nodeC *cod_usedtail;
struct _nodeC *cod;
unsigned char *cod_buf;
int cod_nodecnt;
int cod_bufcnt;
struct _nodeC *first_cod;
struct _nodeC *regcode;
long regsave;
long stksiz;
int numfiles;
int lastlabel;
int labelnum;
int botlabel;
int errors;
int numsyms;
int numdecls;
int numsegs;
int maxtemp;
int maxtempclass;
unsigned long total_size;
unsigned long thunk_offset;
unsigned long bss_offset;
long first_temp;
long killop;
long numnested;
long lastline;
void *reloctbl;
void *newreloctbl;
void *extrntbl;
void *gbltbl;
void *symtbl;
void *labeltbl;
void *newlabeltbl;
void *tmptbl;
void *segtbl;
void *functbl;
void *finalsymtbl;
void *finalstringpack;
long finalpacksize;
void *datatbl;
void *builtintbl;
int in_builtin;
int has_structret;
int temps_written;
PJL jbuf;
void *jbufstart;
int jmpcnt;
int jbufcnt;
long out_offset;
long func_offset;
int extmark;
short markedsym[10];
char *markedbuf[10];
int filenum;
Pafile files[1024];
char debug;
char only_debug;
char strip;
char listing_wanted;
char target_assembler;
char target_hardware;
char target_debugger;
char target_os;
char memory_model;
char obj_format;
} *Piv;
struct _gloval {
char *symname;
int symnum;
unsigned char *p;
Pafile pf;
};
struct _dkey {
unsigned long offset;
long pad;
};
struct _dval {
unsigned long size;
unsigned char *p;
unsigned char *prevp;
long locid;
short fileno;
};
struct _rkey {/* key area of reloctbl node */
unsigned long spot;
long fileno;
};
struct _rval {/* value area of reloctbl node */
unsigned char *p;
unsigned long base;
long offset;
short rsym;
unsigned char opcode;
char rsize;
short fileno;
};
/* Internal User API */
static void *Cmalloc(int category, unsigned amount);
static void *Ccalloc(int category, unsigned nelems, unsigned elemsize);
static void *Crealloc(int category, void* buf, unsigned newsize);
static void Cfree(int category, void* buf);
static void Cfreecat(int category);
static int Cmemrange(int category, unsigned* minp, unsigned* maxp);
static int Cusedrange(int category, unsigned* minp, unsigned* maxp);
static void Ctotrange(unsigned* minp,unsigned* maxp);
static int Cnewcat(void);
static void Cguard(int category);
static void* NewSymTable(int category, int nbins);
static int SymFind(void *tbl, void *key, void *result);
static int SymFindRange(void *tbl, void *key, void *result);
static void *SymInsert(void *tbl, void *key, void *value, int datsiz);
static int StringInsert(void *tbl, char *string, void *result);
static int StringFind(void *tbl, char *string, void *result);
static void SymDelete(void *tbl, void *key);
static int SymHead(void *tbl);
static int SymNext(void *tbl);
static void SymGetMark(void *tbl, void *markptr);
static int SymMarkNext(void *tbl, void *mark);
static void SymSetMark(void *tbl, void *markptr);
static void SymKey(void *tbl, void *keyptr);
static void SymValue(void *tbl, void *datptr);
static void *seg_find(Piv iv, int id);
static char *filenameof(char *path);
static char *propernameof(Piv iv, char *name);
/* END: User API */
/* ====================== PUT UNIQUE CODE HERE ========================= */
static void *do_stmt(Piv iv, unsigned char *p);
static void *do_expr(Piv iv, unsigned char *p);
static void do_bracket(Piv iv, unsigned char *p, unsigned char *q);
static void *do_something(Piv iv, unsigned char *p);
extern char *ctime();
/* ===================== ASMCODE OUTPUT GENERATOR ======================= */
#define DUMP(args...) fprintf(((Piv)iv)->outfile, ## args)
#define QDUMP(arg) fputs(arg, ((Piv)iv)->outfile)
#define QDUMPC(arg) fputc(arg, ((Piv)iv)->outfile)
#define SOURCE 0
#define DESTINATION 1
#define USE_ADDR (0x0001)
#define NEEDS_CONVERSION (0x0002)
#define BWORD (1)
#define SWORD (2)
#define LWORD (3)
#define INDIRECT (0x01)
#define INDEXED (0x02)
/* WARNING ONLY GCC WILL COMPILE THIS */
#define ENCODE(args...) \
{iv->cod->ee = (struct _nodeE){## args}; link_cod(iv);}
typedef struct _nodeE
{
unsigned short inst;
unsigned char size;
unsigned char s1;
unsigned char s1m;
unsigned char s2;
unsigned char s2m;
unsigned char d1;
unsigned char d1m;
unsigned char d2;
unsigned char d2m;
unsigned char cdat;
long dat;
void *ptr;
} NODEE, *PNODEE;
typedef struct _nodeC
{
struct _nodeC *next;
struct _nodeE ee;
} NODEC, *PNODEC;
typedef struct _nodeO
{
struct _nodeO *next;
unsigned char *p;
ND d;
ND l;
ND r;
PNODEC startinst;
PNODEC endinst;
} NODEO, *PNODEO;
static char *notice =
" Generated by Oxbow Software Asmcode Backend `oxccai' version %d.%d\n\n";
static char *opnames[] = {"",
"aaa","aad","aam","aas","adc","add","and","arpl",
"bound","bsf","bsr","bswap","bt","btc","btr","bts",
"call","cbw","cdq","clc","cld","cli","clts",
"cmc","cmp","cmps","cmpxchg","cwd","cwde",
"daa","das","dec","div",
"enter","esc",
"hlt",
"idiv","imul","in","inc","ins",
"int","into","invd","invlpg","iret","iretd","iretdf","iretf",
"ja","jae","jb","jbe","jc","jcxz","je","jecxz","jg","jge","jl","jle","jmp",
"jna","jnae","jnb","jnbe","jnc","jne","jng","jnge","jnl","jnle","jno","jnp",
"jns","jnz","jo","jp","jpe","jpo","js","jz",
"lar","lds","lea","leave","les","lfs",
"lgdt","lgs","lidt","lldt","lmsw","lock",
"lods","loop","loope","loopne","loopnz","loopz",
"lsl","lss","ltr",
"mov","movs","movsx","movzx","mul",
"neg","nop","not",
"or","out","outs",
"pop","popa","popf","push","pusha","pushf",
"rcl","rcr","ret","retf","retn","rol","ror",
"rep","repe","repne","repnz","repz",
"sahf","sal","sar","sbb","scas","shl","shr",
"seta","setae","setb","setbe","setc","sete","setg","setge","setl","setle",
"setna","setnae","setnb","setnbe","setnc","setne","setng","setnge","setnl",
"setnle","setno","setnp","setns","setnz","seto","setp","setpe","setpo",
"sets","setz","sgdt","sidt","sldt","smsw",
"stc","std","sti","stos","str","sub",
"test",
"verr","verw",
"wait","wbinvd",
"xadd","xchg","xlat","xlatb","xor",
"fabs","fadd","faddp","fbld","fbstp","fchs","fclex",
"fcom","fcomp","fcompp","fcos",
"fdecstp","fdisi",
"fdiv","fdivp","fdivr","fdivrp","feni","ffree","fiadd",
"ficom","ficomp","fidiv","fidivr","fild","fimul","fincstp","finit",
"fist","fistp","fisub","fisubr",
"fld","fld1","fldcw","fldenv","fldlg2","fldln2","fldl2e","fldl2t","fldpi","fldz",
"fmul","fmulp",
"fnclex","fndisi","fneni","fninit","fnop","fnsave","fnstcw","fnstenv","fnsts",
"fpatan","fprem","fprem1","fptan","frndint","frstor","fsave",
"fscale","fsin","fsincos","fsqrt","fst","fstcw","fstenv",
"fstp",
"fstsw","fsub","fsubr",
"ftst","fucom","fucomp","fucompp","fwait","fxam","fxch","fxtract",
"fyl2x","fyl2xpi","f2xmi"
};
enum {
aaa=1,aad,aam,aas,adc,add,and,arpl,
bound,bsf,bsr,bswap,bt,btc,btr,bts,
call,cbw,cdq,clc,cld,cli,clts,
cmc,cmp,cmps,cmpxchg,cwd,cwde,
daa,das,dec,DIV,
enter,esc,
hlt,
idiv,imul,in,inc,ins,
INT,into,invd,invlpg,iret,iretd,iretdf,iretf,
ja,jae,jb,jbe,jc,jcxz,je,jecxz,jg,jge,jl,jle,jmp,
jna,jnae,jnb,jnbe,jnc,jne,jng,jnge,jnl,jnle,jno,jnp,
jns,jnz,jo,jp,jpe,jpo,js,jz,
lar,lds,lea,leave,les,lfs,
lgdt,lgs,lidt,lldt,lmsw,lock,
lods,loop,loope,loopne,loopnz,loopz,
lsl,lss,ltr,
mov,movs,movsx,movzx,mul,
neg,nop,not,
or,out,outs,
pop,popa,popf,push,pusha,pushf,
rcl,rcr,ret,retf,retn,rol,ror,
rep,repe,repne,repnz,repz,
sahf,sal,sar,sbb,scas,shl,shr,
seta,setae,setb,setbe,setc,sete,setg,setge,setl,setle,
setna,setnae,setnb,setnbe,setnc,setne,setng,setnge,setnl,
setnle,setno,setnp,setns,setnz,seto,setp,setpe,setpo,
sets,setz,sgdt,sidt,sldt,smsw,
stc,std,sti,stos,str,sub,
test,
verr,verw,
WAIT,wbinvd,
xadd,xchg,xlat,xlatb,xor,
fabs,fadd,faddp,fbld,fbstp,fchs,fclex,
fcom,fcomp,fcompp,fcos,
fdecstp,fdisi,
fdiv,fdivp,fdivr,fdivrp,feni,ffree,fiadd,
ficom,ficomp,fidiv,fidivr,fild,fimul,fincstp,finit,
fist,fistp,fisub,fisubr,
fld,fld1,fldcw,fldenv,fldlg2,fldln2,fldl2e,fldl2t,fldpi,fldz,
fmul,fmulp,
fnclex,fndisi,fneni,fninit,fnop,fnsave,fnstcw,fnstenv,fnsts,
fpatan,fprem,fprem1,fptan,frndint,frstor,fsave,
fscale,fsin,fsincos,fsqrt,fst,fstcw,fstenv,
fstp,
fstsw,fsub,fsubr,
ftst,fucom,fucomp,fucompp,fwait,fxam,fxch,fxtract,
fyl2x,fyl2xpi,f2xmi,
ENDCODES,
ALIGN,PUSHREGS,POPREGS,LABEL,LINE,FUNCNAME,LINEFEED
};
static char *udatnames[] = {"",
"%al","%ah","%ax","%eax","%bl","%bh","%bx","%ebx","%cl","%ch","%cx","%ecx",
"%dl","%dh","%dx","%edx","%sp","%esp","%bp","%ebp",
"%si","%esi","%di","%edi","%ss","%ds","%es","%fs","%gs","","",""
};
static char *datnames[] = {"",
"al","ah","ax","eax","bl","bh","bx","ebx","cl","ch","cx","ecx",
"dl","dh","dx","edx","sp","esp","bp","ebp",
"si","esi","di","edi","ss","ds","es","fs","gs","","",""
};
enum {
AL=1,AH,AX,EAX,BL,BH,BX,EBX,CL,CH,CX,ECX,DL,DH,DX,EDX,SP,ESP,BP,EBP,
SI,ESI,DI,EDI,SS,DS,ES,FS,GS,CONST,VARNAME,LOCATION
};
static char uwordsize[] = {' ','b','w','l'};
static char dwordsize[] = {' ','b','w','d'};
static long
symnumof(Piv iv, char *symb)
{
struct _gloval *valp;
if(StringFind(iv->gbltbl, symb, &valp))
return (long)valp->pf->symtran[valp->symnum];
return 0;
}
static void
buildin(Piv iv, char *symb, unsigned char code)
{
long key[2];
if((key[0] = symnumof(iv, symb)))
{
key[1] = 0;
SymInsert(iv->builtintbl, key, &code, 1);
}
}
static void
install_builtins(Piv iv)
{/* USE THIS TO INSTALL WHATEVER BUILTINS ARE IN THE TARGET INTERPRETER */
#define BUILDIN(a,b) buildin(iv,#a,b)
iv->builtintbl = NewSymTable(iv->category, 191);
BUILDIN(alloca,0);
#undef BUILDIN
}
static long
final_strofs(Piv iv, char *string)
{
long *result;
if(StringFind(iv->finalsymtbl, string, &result))
return result[2];
return 0;
}
static short
final_symnum(Piv iv, short symnum)
{
long *result;
if(StringFind(iv->finalsymtbl, iv->symaddr[symnum], &result))
return result[1]-1;
return 0;
}
static void
make_final_symtab(Piv iv)
{
int i;
iv->finalsymtbl = NewSymTable(iv->category, 0);
if(SymHead(iv->gbltbl))
{
i = 0;
while(SymNext(iv->gbltbl))
{
long *result;
struct _gloval *valp;
SymValue(iv->gbltbl, &valp);
if(*(valp->p))
{
if(!StringInsert(iv->finalsymtbl, valp->symname, &result))
{/* New Entry */
result[1] = ++i;
}
}
}
}
}
static void *
new_nodeO(Piv iv)
{
PNODEO p;
if(iv->ob_bufcnt < sizeof(NODEO))
{/* Allocate a new chunk of linked list space */
iv->ob_bufcnt = 4080;
iv->ob_buf = Ccalloc(FUNCDATA, 1, iv->ob_bufcnt);
}
p = (PNODEO)iv->ob_buf;
iv->ob_buf += sizeof(NODEO);
iv->ob_bufcnt -= sizeof(NODEO);
++iv->ob_nodecnt;
return p;
}
static void
link_ob(Piv iv)
{/* Attach to the used list */
if(!iv->ob_usedhead)
{
iv->ob_usedhead = iv->ob;
iv->ob_usedtail = iv->ob;
}
else
{
iv->ob_usedtail->next = iv->ob;
iv->ob_usedtail = iv->ob;
}
iv->ob = new_nodeO(iv);
}
static void *
new_nodeC(Piv iv)
{
PNODEC p;
if(iv->cod_bufcnt < sizeof(NODEC))
{/* Allocate a new chunk of linked list space */
iv->cod_bufcnt = 4080;
iv->cod_buf = Ccalloc(FUNCDATA, 1, iv->cod_bufcnt);
}
p = (PNODEC)iv->cod_buf;
iv->cod_buf += sizeof(NODEC);
iv->cod_bufcnt -= sizeof(NODEC);
++iv->cod_nodecnt;
return p;
}
static void
link_cod(Piv iv)
{/* Attach to the used list */
if(!iv->cod_usedhead)
{
iv->cod_usedhead = iv->cod;
iv->cod_usedtail = iv->cod;
}
else
{
iv->cod_usedtail->next = iv->cod;
iv->cod_usedtail = iv->cod;
}
iv->cod = new_nodeC(iv);
}
static PNODEC
gen_inst(Piv iv, PNODEO pnode)
{
unsigned char opcode;
unsigned char *p;
PND d,l,r;
d = &pnode->d;
l = &pnode->l;
r = &pnode->r;
p = pnode->p;
opcode = *p;
switch(opcode)
{
/* 0 ADDRESS MODE */
case regainop:
case grabop:
break;
case retvoidop:
ENCODE(jmp, LWORD, s1: LOCATION, dat: iv->botlabel);
break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -