// Inferno utils/6l/l.h // http://code.google.com/p/inferno-os/source/browse/utils/6l/l.h // // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) // Portions Copyright © 1997-1999 Vita Nuova Limited // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) // Portions Copyright © 2004,2006 Bruce Ellis // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others // Portions Copyright © 2009 The Go Authors. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #include #include #include #include "../6l/6.out.h" #ifndef EXTERN #define EXTERN extern #endif enum { PtrSize = 8 }; #define P ((Prog*)0) #define S ((Sym*)0) #define TNAME (curtext?curtext->from.sym->name:noname) #define cput(c)\ { *cbp++ = c;\ if(--cbc <= 0)\ cflush(); } typedef struct Adr Adr; typedef struct Prog Prog; typedef struct Sym Sym; typedef struct Auto Auto; typedef struct Optab Optab; typedef struct Movtab Movtab; struct Adr { union { vlong u0offset; char u0scon[8]; Prog *u0cond; /* not used, but should be D_BRANCH */ Ieee u0ieee; char *u0sbig; } u0; union { Auto* u1autom; Sym* u1sym; } u1; short type; char index; char scale; }; #define offset u0.u0offset #define scon u0.u0scon #define cond u0.u0cond #define ieee u0.u0ieee #define sbig u0.u0sbig #define autom u1.u1autom #define sym u1.u1sym struct Prog { Adr from; Adr to; Prog *forwd; Prog* link; Prog* dlink; Prog* pcond; /* work on this */ vlong pc; int32 line; short as; char ft; /* oclass cache */ char tt; uchar mark; /* work on these */ uchar back; char width; /* fake for DATA */ char mode; /* 16, 32, or 64 */ }; struct Auto { Sym* asym; Auto* link; int32 aoffset; short type; Sym* gotype; }; struct Sym { char *name; short type; short version; short become; short frame; uchar subtype; uchar dupok; uchar reachable; vlong value; vlong size; int32 sig; Sym* link; Prog* text; Prog* data; Sym* gotype; char* file; char* dynldname; char* dynldlib; }; struct Optab { short as; uchar* ytab; uchar prefix; uchar op[20]; }; struct Movtab { short as; uchar ft; uchar tt; uchar code; uchar op[4]; }; enum { Sxxx, STEXT = 1, SDATA, SBSS, SDATA1, SXREF, SFILE, SCONST, SUNDEF, SIMPORT, SEXPORT, SMACHO, NHASH = 10007, NHUNK = 100000, MINSIZ = 8, STRINGSZ = 200, MINLC = 1, MAXIO = 8192, MAXHIST = 20, /* limit of path elements for history symbols */ Yxxx = 0, Ynone, Yi0, Yi1, Yi8, Ys32, Yi32, Yi64, Yiauto, Yal, Ycl, Yax, Ycx, Yrb, Yrl, Yrf, Yf0, Yrx, Ymb, Yml, Ym, Ybr, Ycol, Ycs, Yss, Yds, Yes, Yfs, Ygs, Ygdtr, Yidtr, Yldtr, Ymsw, Ytask, Ycr0, Ycr1, Ycr2, Ycr3, Ycr4, Ycr5, Ycr6, Ycr7, Ycr8, Ydr0, Ydr1, Ydr2, Ydr3, Ydr4, Ydr5, Ydr6, Ydr7, Ytr0, Ytr1, Ytr2, Ytr3, Ytr4, Ytr5, Ytr6, Ytr7, Yrl32, Yrl64, Ymr, Ymm, Yxr, Yxm, Ymax, Zxxx = 0, Zlit, Z_rp, Zbr, Zcall, Zib_, Zib_rp, Zibo_m, Zibo_m_xm, Zil_, Zil_rp, Ziq_rp, Zilo_m, Ziqo_m, Zjmp, Zloop, Zo_iw, Zm_o, Zm_r, Zm_r_xm, Zm_r_i_xm, Zm_r_3d, Zm_r_xm_nr, Zr_m_xm_nr, Zibm_r, /* mmx1,mmx2/mem64,imm8 */ Zmb_r, Zaut_r, Zo_m, Zo_m64, Zpseudo, Zr_m, Zr_m_xm, Zr_m_i_xm, Zrp_, Z_ib, Z_il, Zm_ibo, Zm_ilo, Zib_rr, Zil_rr, Zclr, Zbyte, Zmax, Px = 0, P32 = 0x32, /* 32-bit only */ Pe = 0x66, /* operand escape */ Pm = 0x0f, /* 2byte opcode escape */ Pq = 0xff, /* both escape */ Pb = 0xfe, /* byte operands */ Pf2 = 0xf2, /* xmm escape 1 */ Pf3 = 0xf3, /* xmm escape 2 */ Pw = 0x48, /* Rex.w */ Py = 0x80, /* defaults to 64-bit mode */ Rxf = 1<<9, /* internal flag for Rxr on from */ Rxt = 1<<8, /* internal flag for Rxr on to */ Rxw = 1<<3, /* =1, 64-bit operand size */ Rxr = 1<<2, /* extend modrm reg */ Rxx = 1<<1, /* extend sib index */ Rxb = 1<<0, /* extend modrm r/m, sib base, or opcode reg */ Roffset = 22, /* no. bits for offset in relocation address */ Rindex = 10, /* no. bits for index in relocation address */ Maxand = 10, /* in -a output width of the byte codes */ }; EXTERN union { struct { char obuf[MAXIO]; /* output buffer */ uchar ibuf[MAXIO]; /* input buffer */ } u; char dbuf[1]; } buf; #define cbuf u.obuf #define xbuf u.ibuf #pragma varargck type "A" uint #pragma varargck type "D" Adr* #pragma varargck type "P" Prog* #pragma varargck type "R" int #pragma varargck type "S" char* EXTERN int32 HEADR; EXTERN int32 HEADTYPE; EXTERN vlong INITDAT; EXTERN int32 INITRND; EXTERN vlong INITTEXT; EXTERN char* INITENTRY; /* entry point */ EXTERN Biobuf bso; EXTERN int32 bsssize; EXTERN int cbc; EXTERN char* cbp; EXTERN char* pcstr; EXTERN Auto* curauto; EXTERN Auto* curhist; EXTERN Prog* curp; EXTERN Prog* curtext; EXTERN Prog* datap; EXTERN Prog* edatap; EXTERN vlong datsize; EXTERN char debug[128]; EXTERN char literal[32]; EXTERN Prog* etextp; EXTERN Prog* firstp; EXTERN int xrefresolv; EXTERN char ycover[Ymax*Ymax]; EXTERN uchar* andptr; EXTERN uchar* rexptr; EXTERN uchar and[30]; EXTERN int reg[D_NONE]; EXTERN int regrex[D_NONE+1]; EXTERN Prog* lastp; EXTERN int32 lcsize; EXTERN int nerrors; EXTERN char* noname; EXTERN char* outfile; EXTERN vlong pc; EXTERN char* rpath; EXTERN int32 spsize; EXTERN Sym* symlist; EXTERN int32 symsize; EXTERN Prog* textp; EXTERN vlong textsize; EXTERN int version; EXTERN Prog zprg; EXTERN int dtype; EXTERN char* paramspace; EXTERN Sym* adrgotype; // type symbol on last Adr read EXTERN Sym* fromgotype; // type symbol on last p->from read EXTERN Adr* reloca; EXTERN int doexp; // export table EXTERN int dlm; // dynamically loadable module EXTERN int imports, nimports; EXTERN int exports, nexports; EXTERN char* EXPTAB; EXTERN Prog undefp; EXTERN vlong textstksiz; EXTERN vlong textarg; extern char thechar; EXTERN int dynptrsize; EXTERN int elfstrsize; EXTERN char* elfstrdat; EXTERN int elftextsh; #define UP (&undefp) extern Optab optab[]; extern Optab* opindex[]; extern char* anames[]; int Aconv(Fmt*); int Dconv(Fmt*); int Pconv(Fmt*); int Rconv(Fmt*); int Sconv(Fmt*); void addhist(int32, int); void addstackmark(void); Prog* appendp(Prog*); vlong addstring(Sym*, char*); vlong adduint32(Sym*, uint32); vlong adduint64(Sym*, uint64); vlong addaddr(Sym*, Sym*); vlong addsize(Sym*, Sym*); void asmb(void); void asmdyn(void); void asmins(Prog*); void asmlc(void); void asmsp(void); void asmsym(void); void asmelfsym(void); vlong atolwhex(char*); Prog* brchain(Prog*); Prog* brloop(Prog*); void buildop(void); void cflush(void); void ckoff(Sym*, int32); Prog* copyp(Prog*); double cputime(void); void datblk(int32, int32); void deadcode(void); void diag(char*, ...); void dobss(void); void dodata(void); void doelf(void); void doinit(void); void domacho(void); void doprof1(void); void doprof2(void); void dostkoff(void); void dynreloc(Sym*, uint32, int); vlong entryvalue(void); void export(void); void follow(void); void gethunk(void); void gotypestrings(void); void import(void); void listinit(void); Sym* lookup(char*, int); void lputb(int32); void lputl(int32); void main(int, char*[]); void mkfwd(void); void* mysbrk(uint32); Prog* newdata(Sym*, int, int, int); Prog* newtext(Prog*, Sym*); void nopout(Prog*); int opsize(Prog*); void patch(void); Prog* prg(void); void parsetextconst(vlong); int relinv(int); int32 reuse(Prog*, Sym*); vlong rnd(vlong, vlong); void span(void); void strnput(char*, int); void undef(void); vlong vaddr(Adr*); vlong symaddr(Sym*); void vputl(uint64); void wputb(uint16); void wputl(uint16); void xdefine(char*, int, vlong); void xfol(Prog*); void zaddr(Biobuf*, Adr*, Sym*[]); void machseg(char*, vlong, vlong, vlong, vlong, uint32, uint32, uint32, uint32); void machsymseg(uint32, uint32); void machsect(char*, char*, vlong, vlong, uint32, uint32, uint32, uint32, uint32); void machstack(vlong); void machdylink(void); uint32 machheadr(void); /* Native is little-endian */ #define LPUT(a) lputl(a) #define WPUT(a) wputl(a) #define VPUT(a) vputl(a) #pragma varargck type "D" Adr* #pragma varargck type "P" Prog* #pragma varargck type "R" int #pragma varargck type "A" int #pragma varargck argpos diag 1