1 // Inferno utils/6l/l.h
2 // http://code.google.com/p/inferno-os/source/browse/utils/6l/l.h
3 //
4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
6 // Portions Copyright © 1997-1999 Vita Nuova Limited
7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
8 // Portions Copyright © 2004,2006 Bruce Ellis
9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
11 // Portions Copyright © 2009 The Go Authors. All rights reserved.
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a copy
14 // of this software and associated documentation files (the "Software"), to deal
15 // in the Software without restriction, including without limitation the rights
16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 // copies of the Software, and to permit persons to whom the Software is
18 // furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included in
21 // all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 // THE SOFTWARE.
30
31 #include <u.h>
32 #include <libc.h>
33 #include <bio.h>
34 #include "6.out.h"
35
36 #ifndef EXTERN
37 #define EXTERN extern
38 #endif
39
40 enum
41 {
42 thechar = '6',
43 PtrSize = 8
44 };
45
46 #define P ((Prog*)0)
47 #define S ((Sym*)0)
48 #define TNAME (cursym?cursym->name:noname)
49
50 typedef struct Adr Adr;
51 typedef struct Prog Prog;
52 typedef struct Sym Sym;
53 typedef struct Auto Auto;
54 typedef struct Optab Optab;
55 typedef struct Movtab Movtab;
56 typedef struct Reloc Reloc;
57
58 struct Adr
59 {
60 union
61 {
62 vlong u0offset;
63 char u0scon[8];
64 Prog *u0cond; /* not used, but should be D_BRANCH */
65 Ieee u0ieee;
66 char *u0sbig;
67 } u0;
68 Sym* sym;
69 short type;
70 char index;
71 char scale;
72 };
73
74 #define offset u0.u0offset
75 #define scon u0.u0scon
76 #define cond u0.u0cond
77 #define ieee u0.u0ieee
78 #define sbig u0.u0sbig
79
80 struct Reloc
81 {
82 int32 off;
83 uchar siz;
84 int32 type;
85 int64 add;
86 Sym* sym;
87 };
88
89 struct Prog
90 {
91 Adr from;
92 Adr to;
93 Prog* forwd;
94 Prog* comefrom;
95 Prog* link;
96 Prog* pcond; /* work on this */
97 vlong pc;
98 int32 spadj;
99 int32 line;
100 short as;
101 char ft; /* oclass cache */
102 char tt;
103 uchar mark; /* work on these */
104 uchar back;
105
106 char width; /* fake for DATA */
107 char mode; /* 16, 32, or 64 */
108 };
109 #define datasize from.scale
110 #define textflag from.scale
111 #define iscall(p) ((p)->as == ACALL)
112
113 struct Auto
114 {
115 Sym* asym;
116 Auto* link;
117 int32 aoffset;
118 short type;
119 Sym* gotype;
120 };
121 struct Sym
122 {
123 char* name;
124 short type;
125 short version;
126 uchar dupok;
127 uchar reachable;
128 uchar dynexport;
129 uchar special;
130 uchar stkcheck;
131 uchar hide;
132 int32 dynid;
133 int32 sig;
134 int32 plt;
135 int32 got;
136 Sym* hash; // in hash table
137 Sym* allsym; // in all symbol list
138 Sym* next; // in text or data list
139 Sym* sub; // in SSUB list
140 Sym* outer; // container of sub
141 vlong value;
142 vlong size;
143 Sym* gotype;
144 char* file;
145 char* dynimpname;
146 char* dynimplib;
147 char* dynimpvers;
148
149 // STEXT
150 Auto* autom;
151 Prog* text;
152
153 // SDATA, SBSS
154 uchar* p;
155 int32 np;
156 int32 maxp;
157 Reloc* r;
158 int32 nr;
159 int32 maxr;
160 };
161 struct Optab
162 {
163 short as;
164 uchar* ytab;
165 uchar prefix;
166 uchar op[20];
167 };
168 struct Movtab
169 {
170 short as;
171 uchar ft;
172 uchar tt;
173 uchar code;
174 uchar op[4];
175 };
176
177 enum
178 {
179 MINSIZ = 8,
180 STRINGSZ = 200,
181 MINLC = 1,
182 MAXIO = 8192,
183 MAXHIST = 20, /* limit of path elements for history symbols */
184
185 Yxxx = 0,
186 Ynone,
187 Yi0,
188 Yi1,
189 Yi8,
190 Ys32,
191 Yi32,
192 Yi64,
193 Yiauto,
194 Yal,
195 Ycl,
196 Yax,
197 Ycx,
198 Yrb,
199 Yrl,
200 Yrf,
201 Yf0,
202 Yrx,
203 Ymb,
204 Yml,
205 Ym,
206 Ybr,
207 Ycol,
208
209 Ycs, Yss, Yds, Yes, Yfs, Ygs,
210 Ygdtr, Yidtr, Yldtr, Ymsw, Ytask,
211 Ycr0, Ycr1, Ycr2, Ycr3, Ycr4, Ycr5, Ycr6, Ycr7, Ycr8,
212 Ydr0, Ydr1, Ydr2, Ydr3, Ydr4, Ydr5, Ydr6, Ydr7,
213 Ytr0, Ytr1, Ytr2, Ytr3, Ytr4, Ytr5, Ytr6, Ytr7, Yrl32, Yrl64,
214 Ymr, Ymm,
215 Yxr, Yxm,
216 Ymax,
217
218 Zxxx = 0,
219
220 Zlit,
221 Zlitm_r,
222 Z_rp,
223 Zbr,
224 Zcall,
225 Zib_,
226 Zib_rp,
227 Zibo_m,
228 Zibo_m_xm,
229 Zil_,
230 Zil_rp,
231 Ziq_rp,
232 Zilo_m,
233 Ziqo_m,
234 Zjmp,
235 Zloop,
236 Zo_iw,
237 Zm_o,
238 Zm_r,
239 Zm_r_xm,
240 Zm_r_i_xm,
241 Zm_r_3d,
242 Zm_r_xm_nr,
243 Zr_m_xm_nr,
244 Zibm_r, /* mmx1,mmx2/mem64,imm8 */
245 Zmb_r,
246 Zaut_r,
247 Zo_m,
248 Zo_m64,
249 Zpseudo,
250 Zr_m,
251 Zr_m_xm,
252 Zr_m_i_xm,
253 Zrp_,
254 Z_ib,
255 Z_il,
256 Zm_ibo,
257 Zm_ilo,
258 Zib_rr,
259 Zil_rr,
260 Zclr,
261 Zbyte,
262 Zmax,
263
264 Px = 0,
265 P32 = 0x32, /* 32-bit only */
266 Pe = 0x66, /* operand escape */
267 Pm = 0x0f, /* 2byte opcode escape */
268 Pq = 0xff, /* both escape */
269 Pb = 0xfe, /* byte operands */
270 Pf2 = 0xf2, /* xmm escape 1 */
271 Pf3 = 0xf3, /* xmm escape 2 */
272 Pw = 0x48, /* Rex.w */
273 Py = 0x80, /* defaults to 64-bit mode */
274
275 Rxf = 1<<9, /* internal flag for Rxr on from */
276 Rxt = 1<<8, /* internal flag for Rxr on to */
277 Rxw = 1<<3, /* =1, 64-bit operand size */
278 Rxr = 1<<2, /* extend modrm reg */
279 Rxx = 1<<1, /* extend sib index */
280 Rxb = 1<<0, /* extend modrm r/m, sib base, or opcode reg */
281
282 Maxand = 10, /* in -a output width of the byte codes */
283 };
284
285 #pragma varargck type "A" uint
286 #pragma varargck type "D" Adr*
287 #pragma varargck type "I" uchar*
288 #pragma varargck type "P" Prog*
289 #pragma varargck type "R" int
290 #pragma varargck type "S" char*
291 #pragma varargck type "i" char*
292
293 EXTERN int32 HEADR;
294 EXTERN int32 HEADTYPE;
295 EXTERN int32 INITRND;
296 EXTERN vlong INITTEXT;
297 EXTERN vlong INITDAT;
298 EXTERN char* INITENTRY; /* entry point */
299 EXTERN char* pcstr;
300 EXTERN Auto* curauto;
301 EXTERN Auto* curhist;
302 EXTERN Prog* curp;
303 EXTERN Sym* cursym;
304 EXTERN Sym* datap;
305 EXTERN vlong elfdatsize;
306 EXTERN char debug[128];
307 EXTERN char literal[32];
308 EXTERN Sym* textp;
309 EXTERN Sym* etextp;
310 EXTERN char ycover[Ymax*Ymax];
311 EXTERN uchar* andptr;
312 EXTERN uchar* rexptr;
313 EXTERN uchar and[30];
314 EXTERN int reg[D_NONE];
315 EXTERN int regrex[D_NONE+1];
316 EXTERN int32 lcsize;
317 EXTERN int nerrors;
318 EXTERN char* noname;
319 EXTERN char* outfile;
320 EXTERN vlong pc;
321 EXTERN char* interpreter;
322 EXTERN char* rpath;
323 EXTERN int32 spsize;
324 EXTERN Sym* symlist;
325 EXTERN int32 symsize;
326 EXTERN int tlsoffset;
327 EXTERN int version;
328 EXTERN Prog zprg;
329 EXTERN int dtype;
330 EXTERN char* paramspace;
331 EXTERN Sym* adrgotype; // type symbol on last Adr read
332 EXTERN Sym* fromgotype; // type symbol on last p->from read
333
334 EXTERN vlong textstksiz;
335 EXTERN vlong textarg;
336
337 extern Optab optab[];
338 extern Optab* opindex[];
339 extern char* anames[];
340
341 int Aconv(Fmt*);
342 int Dconv(Fmt*);
343 int Iconv(Fmt*);
344 int Pconv(Fmt*);
345 int Rconv(Fmt*);
346 int Sconv(Fmt*);
347 void addhist(int32, int);
348 void addstackmark(void);
349 Prog* appendp(Prog*);
350 void asmb(void);
351 void asmdyn(void);
352 void asmins(Prog*);
353 void asmsym(void);
354 void asmelfsym(void);
355 vlong atolwhex(char*);
356 Prog* brchain(Prog*);
357 Prog* brloop(Prog*);
358 void buildop(void);
359 Prog* copyp(Prog*);
360 double cputime(void);
361 void datblk(int32, int32);
362 void deadcode(void);
363 void diag(char*, ...);
364 void dodata(void);
365 void doelf(void);
366 void domacho(void);
367 void doprof1(void);
368 void doprof2(void);
369 void dostkoff(void);
370 vlong entryvalue(void);
371 void follow(void);
372 void gethunk(void);
373 void gotypestrings(void);
374 void listinit(void);
375 Sym* lookup(char*, int);
376 void lputb(int32);
377 void lputl(int32);
378 void instinit(void);
379 void main(int, char*[]);
380 void* mysbrk(uint32);
381 Prog* newtext(Prog*, Sym*);
382 void nopout(Prog*);
383 int opsize(Prog*);
384 void patch(void);
385 Prog* prg(void);
386 void parsetextconst(vlong);
387 int relinv(int);
388 vlong rnd(vlong, vlong);
389 void span(void);
390 void undef(void);
391 vlong symaddr(Sym*);
392 void vputb(uint64);
393 void vputl(uint64);
394 void wputb(uint16);
395 void wputl(uint16);
396 void xdefine(char*, int, vlong);
397
398 void machseg(char*, vlong, vlong, vlong, vlong, uint32, uint32, uint32, uint32);
399 void machsymseg(uint32, uint32);
400 void machsect(char*, char*, vlong, vlong, uint32, uint32, uint32, uint32, uint32);
401 void machstack(vlong);
402 void machdylink(void);
403 uint32 machheadr(void);
404
405 /* Native is little-endian */
406 #define LPUT(a) lputl(a)
407 #define WPUT(a) wputl(a)
408 #define VPUT(a) vputl(a)
409
410 #pragma varargck type "D" Adr*
411 #pragma varargck type "P" Prog*
412 #pragma varargck type "R" int
413 #pragma varargck type "Z" char*
414 #pragma varargck type "A" int
415 #pragma varargck argpos diag 1
416
417 /* Used by ../ld/dwarf.c */
418 enum
419 {
420 DWARFREGSP = 7
421 };