typedef struct Addr Addr;
typedef struct Prog Prog;
typedef struct LSym LSym;
typedef struct Reloc Reloc;
typedef struct Auto Auto;
typedef struct Hist Hist;
typedef struct Link Link;
typedef struct Plist Plist;
typedef struct LinkArch LinkArch;
typedef struct Library Library;
typedef struct Pcln Pcln;
typedef struct Pcdata Pcdata;
typedef struct Pciter Pciter;
#pragma incomplete struct Node
struct Addr
{
vlong offset;
union
{
char sval[8];
float64 dval;
Prog* branch;
} u;
LSym* sym;
LSym* gotype;
short type;
uint8 index;
int8 scale;
int8 reg;
int8 name;
int8 class;
uint8 etype;
int32 offset2;
struct Node* node;
int64 width;
};
struct Reloc
{
int32 off;
uchar siz;
uchar done;
int32 type;
int64 add;
int64 xadd;
LSym* sym;
LSym* xsym;
};
struct Prog
{
vlong pc;
int32 lineno;
Prog* link;
short as;
uchar reg;
uchar scond;
Addr from;
Addr to;
void* opt;
Prog* forwd;
Prog* pcond;
Prog* comefrom;
Prog* pcrel;
int32 spadj;
uchar mark;
uchar back;
char ft;
char tt;
uchar optab;
uchar isize;
char width;
char mode;
};
#pragma incomplete struct Section
struct LSym
{
char* name;
char* extname;
short type;
short version;
uchar dupok;
uchar external;
uchar nosplit;
uchar reachable;
uchar cgoexport;
uchar special;
uchar stkcheck;
uchar hide;
uchar leaf;
uchar fnptr;
uchar seenglobl;
uchar onlist;
int16 symid;
int32 dynid;
int32 sig;
int32 plt;
int32 got;
int32 align;
int32 elfsym;
int32 args;
int32 locals;
vlong value;
vlong size;
LSym* hash;
LSym* allsym;
LSym* next;
LSym* sub;
LSym* outer;
LSym* gotype;
LSym* reachparent;
LSym* queue;
char* file;
char* dynimplib;
char* dynimpvers;
struct Section* sect;
Auto* autom;
Prog* text;
Prog* etext;
Pcln* pcln;
uchar* p;
int32 np;
int32 maxp;
Reloc* r;
int32 nr;
int32 maxr;
};
enum
{
Sxxx,
STEXT,
SELFRXSECT,
STYPE,
SSTRING,
SGOSTRING,
SGOFUNC,
SRODATA,
SFUNCTAB,
STYPELINK,
SSYMTAB,
SPCLNTAB,
SELFROSECT,
SMACHOPLT,
SELFSECT,
SMACHO,
SMACHOGOT,
SNOPTRDATA,
SINITARR,
SDATA,
SWINDOWS,
SBSS,
SNOPTRBSS,
STLSBSS,
SXREF,
SMACHOSYMSTR,
SMACHOSYMTAB,
SMACHOINDIRECTPLT,
SMACHOINDIRECTGOT,
SFILE,
SFILEPATH,
SCONST,
SDYNIMPORT,
SHOSTOBJ,
SSUB = 1<<8,
SMASK = SSUB - 1,
SHIDDEN = 1<<9,
};
enum
{
R_ADDR = 1,
R_SIZE,
R_CALL,
R_CALLARM,
R_CALLIND,
R_CONST,
R_PCREL,
R_TLS,
R_TLS_LE,
R_TLS_IE,
R_GOTOFF,
R_PLT0,
R_PLT1,
R_PLT2,
R_USEFIELD,
};
enum
{
A_AUTO = 1,
A_PARAM,
};
struct Auto
{
LSym* asym;
Auto* link;
int32 aoffset;
int16 type;
LSym* gotype;
};
enum
{
LINKHASH = 100003,
};
struct Hist
{
Hist* link;
char* name;
int32 line;
int32 offset;
};
struct Plist
{
LSym* name;
Prog* firstpc;
int recur;
Plist* link;
};
struct Library
{
char *objref;
char *srcref;
char *file;
char *pkg;
};
struct Pcdata
{
uchar *p;
int n;
int m;
};
struct Pcln
{
Pcdata pcsp;
Pcdata pcfile;
Pcdata pcline;
Pcdata *pcdata;
int npcdata;
LSym **funcdata;
int64 *funcdataoff;
int nfuncdata;
LSym **file;
int nfile;
int mfile;
LSym *lastfile;
int lastindex;
};
struct Pciter
{
Pcdata d;
uchar *p;
uint32 pc;
uint32 nextpc;
uint32 pcscale;
int32 value;
int start;
int done;
};
void pciterinit(Link*, Pciter*, Pcdata*);
void pciternext(Pciter*);
enum
{
HistVersion = 1,
};
struct Link
{
int32 thechar;
char* thestring;
int32 goarm;
int headtype;
LinkArch* arch;
int32 (*ignore)(char*);
int32 debugasm;
int32 debugline;
int32 debughist;
int32 debugread;
int32 debugvlog;
int32 debugstack;
int32 debugzerostack;
int32 debugdivmod;
int32 debugfloat;
int32 debugpcln;
int32 flag_shared;
int32 iself;
Biobuf* bso;
char* pathname;
int32 windows;
char* trimpath;
char* goroot;
char* goroot_final;
LSym* hash[LINKHASH];
LSym* allsym;
int32 nsymbol;
Hist* hist;
Hist* ehist;
Plist* plist;
Plist* plast;
LSym* sym_div;
LSym* sym_divu;
LSym* sym_mod;
LSym* sym_modu;
LSym* symmorestack[20];
LSym* gmsym;
LSym* plan9tos;
Prog* curp;
Prog* printp;
Prog* blitrl;
Prog* elitrl;
int rexflag;
int rep;
int repn;
int lock;
int asmode;
uchar* andptr;
uchar and[100];
int32 instoffset;
int32 autosize;
int32 armsize;
vlong pc;
char** libdir;
int32 nlibdir;
int32 maxlibdir;
Library* library;
int libraryp;
int nlibrary;
int tlsoffset;
void (*diag)(char*, ...);
int mode;
Auto* curauto;
Auto* curhist;
LSym* cursym;
int version;
LSym* textp;
LSym* etextp;
int32 histdepth;
int32 nhistfile;
LSym* filesyms;
};
struct LinkArch
{
char* name;
int thechar;
void (*addstacksplit)(Link*, LSym*);
void (*assemble)(Link*, LSym*);
int (*datasize)(Prog*);
void (*follow)(Link*, LSym*);
int (*iscall)(Prog*);
int (*isdata)(Prog*);
Prog* (*prg)(void);
void (*progedit)(Link*, Prog*);
void (*settextflag)(Prog*, int);
int (*symtype)(Addr*);
int (*textflag)(Prog*);
int minlc;
int ptrsize;
int regsize;
int D_ADDR;
int D_AUTO;
int D_BRANCH;
int D_CONST;
int D_EXTERN;
int D_FCONST;
int D_NONE;
int D_PARAM;
int D_SCONST;
int D_STATIC;
int ACALL;
int ADATA;
int AEND;
int AFUNCDATA;
int AGLOBL;
int AJMP;
int ANOP;
int APCDATA;
int ARET;
int ATEXT;
int ATYPE;
int AUSEFIELD;
};
enum {
Hunknown = 0,
Hdarwin,
Hdragonfly,
Helf,
Hfreebsd,
Hlinux,
Hnacl,
Hnetbsd,
Hopenbsd,
Hplan9,
Hsolaris,
Hwindows,
};
enum
{
LinkAuto = 0,
LinkInternal,
LinkExternal,
};
extern uchar fnuxi8[8];
extern uchar fnuxi4[4];
extern uchar inuxi1[1];
extern uchar inuxi2[2];
extern uchar inuxi4[4];
extern uchar inuxi8[8];
void span5(Link *ctxt, LSym *s);
int chipfloat5(Link *ctxt, float64 e);
int chipzero5(Link *ctxt, float64 e);
void span6(Link *ctxt, LSym *s);
void span8(Link *ctxt, LSym *s);
vlong addaddr(Link *ctxt, LSym *s, LSym *t);
vlong addaddrplus(Link *ctxt, LSym *s, LSym *t, vlong add);
vlong addaddrplus4(Link *ctxt, LSym *s, LSym *t, vlong add);
vlong addpcrelplus(Link *ctxt, LSym *s, LSym *t, vlong add);
Reloc* addrel(LSym *s);
vlong addsize(Link *ctxt, LSym *s, LSym *t);
vlong adduint16(Link *ctxt, LSym *s, uint16 v);
vlong adduint32(Link *ctxt, LSym *s, uint32 v);
vlong adduint64(Link *ctxt, LSym *s, uint64 v);
vlong adduint8(Link *ctxt, LSym *s, uint8 v);
vlong adduintxx(Link *ctxt, LSym *s, uint64 v, int wid);
void mangle(char *file);
void savedata(Link *ctxt, LSym *s, Prog *p, char *pn);
vlong setaddr(Link *ctxt, LSym *s, vlong off, LSym *t);
vlong setaddrplus(Link *ctxt, LSym *s, vlong off, LSym *t, vlong add);
vlong setuint16(Link *ctxt, LSym *s, vlong r, uint16 v);
vlong setuint32(Link *ctxt, LSym *s, vlong r, uint32 v);
vlong setuint64(Link *ctxt, LSym *s, vlong r, uint64 v);
vlong setuint8(Link *ctxt, LSym *s, vlong r, uint8 v);
vlong setuintxx(Link *ctxt, LSym *s, vlong off, uint64 v, vlong wid);
void symgrow(Link *ctxt, LSym *s, vlong siz);
void double2ieee(uint64 *ieee, double native);
void* emallocz(long n);
void* erealloc(void *p, long n);
char* estrdup(char *p);
char* expandpkg(char *t0, char *pkg);
void addhist(Link *ctxt, int32 line, int type);
void addlib(Link *ctxt, char *src, char *obj, char *path);
void addlibpath(Link *ctxt, char *srcref, char *objref, char *file, char *pkg);
void collapsefrog(Link *ctxt, LSym *s);
void copyhistfrog(Link *ctxt, char *buf, int nbuf);
int find1(int32 l, int c);
void linkgetline(Link *ctxt, int32 line, LSym **f, int32 *l);
void histtoauto(Link *ctxt);
void mkfwd(LSym*);
void nuxiinit(void);
void savehist(Link *ctxt, int32 line, int32 off);
Prog* copyp(Link*, Prog*);
Prog* appendp(Link*, Prog*);
vlong atolwhex(char*);
void listinit5(void);
void listinit6(void);
void listinit8(void);
int linklinefmt(Link *ctxt, Fmt *fp);
void linklinehist(Link *ctxt, int lineno, char *f, int offset);
Plist* linknewplist(Link *ctxt);
void linkprfile(Link *ctxt, int32 l);
void ldobjfile(Link *ctxt, Biobuf *b, char *pkg, int64 len, char *path);
void writeobj(Link *ctxt, Biobuf *b);
Prog* brchain(Link *ctxt, Prog *p);
Prog* brloop(Link *ctxt, Prog *p);
void linkpatch(Link *ctxt, LSym *sym);
void linkpcln(Link*, LSym*);
LSym* linklookup(Link *ctxt, char *name, int v);
Link* linknew(LinkArch*);
LSym* linknewsym(Link *ctxt, char *symb, int v);
LSym* linkrlookup(Link *ctxt, char *name, int v);
int linksymfmt(Fmt *f);
int headtype(char*);
char* headstr(int);
extern char* anames5[];
extern char* anames6[];
extern char* anames8[];
extern LinkArch link386;
extern LinkArch linkamd64;
extern LinkArch linkamd64p32;
extern LinkArch linkarm;
#pragma varargck type "A" int
#pragma varargck type "D" Addr*
#pragma varargck type "lD" Addr*
#pragma varargck type "P" Prog*
#pragma varargck type "R" int
#pragma varargck type "L" int32