1 // Inferno utils/5l/l.h
2 // http://code.google.com/p/inferno-os/source/browse/utils/5l/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 "5.out.h"
35
36 enum
37 {
38 thechar = '5',
39 PtrSize = 4
40 };
41
42 #ifndef EXTERN
43 #define EXTERN extern
44 #endif
45
46 /* do not undefine this - code will be removed eventually */
47 #define CALLEEBX
48
49 #define dynptrsize 0
50
51 typedef struct Adr Adr;
52 typedef struct Sym Sym;
53 typedef struct Autom Auto;
54 typedef struct Prog Prog;
55 typedef struct Reloc Reloc;
56 typedef struct Optab Optab;
57 typedef struct Oprang Oprang;
58 typedef uchar Opcross[32][2][32];
59 typedef struct Count Count;
60
61 #define P ((Prog*)0)
62 #define S ((Sym*)0)
63 #define TNAME (cursym?cursym->name:noname)
64
65 struct Adr
66 {
67 union
68 {
69 int32 u0offset;
70 char* u0sval;
71 Ieee u0ieee;
72 char* u0sbig;
73 } u0;
74 Sym* sym;
75 char type;
76 uchar index; // not used on arm, required by ld/go.c
77 char reg;
78 char name;
79 int32 offset2; // argsize
80 char class;
81 Sym* gotype;
82 };
83
84 #define offset u0.u0offset
85 #define sval u0.u0sval
86 #define scon sval
87 #define ieee u0.u0ieee
88 #define sbig u0.u0sbig
89
90 struct Reloc
91 {
92 int32 off;
93 uchar siz;
94 int16 type;
95 int32 add;
96 Sym* sym;
97 };
98
99 struct Prog
100 {
101 Adr from;
102 Adr to;
103 union
104 {
105 int32 u0regused;
106 Prog* u0forwd;
107 } u0;
108 Prog* cond;
109 Prog* link;
110 Prog* dlink;
111 int32 pc;
112 int32 line;
113 int32 spadj;
114 uchar mark;
115 uchar optab;
116 uchar as;
117 uchar scond;
118 uchar reg;
119 uchar align;
120 };
121
122 #define regused u0.u0regused
123 #define forwd u0.u0forwd
124 #define datasize reg
125 #define textflag reg
126
127 #define iscall(p) ((p)->as == ABL)
128
129 struct Sym
130 {
131 char* name;
132 short type;
133 short version;
134 uchar dupok;
135 uchar reachable;
136 uchar dynexport;
137 uchar leaf;
138 uchar stkcheck;
139 uchar hide;
140 int32 dynid;
141 int32 plt;
142 int32 got;
143 int32 value;
144 int32 sig;
145 int32 size;
146 uchar special;
147 uchar fnptr; // used as fn ptr
148 Sym* hash; // in hash table
149 Sym* allsym; // in all symbol list
150 Sym* next; // in text or data list
151 Sym* sub; // in SSUB list
152 Sym* outer; // container of sub
153 Sym* gotype;
154 char* file;
155 char* dynimpname;
156 char* dynimplib;
157 char* dynimpvers;
158
159 // STEXT
160 Auto* autom;
161 Prog* text;
162
163 // SDATA, SBSS
164 uchar* p;
165 int32 np;
166 int32 maxp;
167 Reloc* r;
168 int32 nr;
169 int32 maxr;
170 };
171
172 #define SIGNINTERN (1729*325*1729)
173
174 struct Autom
175 {
176 Sym* asym;
177 Auto* link;
178 int32 aoffset;
179 short type;
180 Sym* gotype;
181 };
182 struct Optab
183 {
184 char as;
185 uchar a1;
186 char a2;
187 uchar a3;
188 uchar type;
189 char size;
190 char param;
191 char flag;
192 };
193 struct Oprang
194 {
195 Optab* start;
196 Optab* stop;
197 };
198 struct Count
199 {
200 int32 count;
201 int32 outof;
202 };
203
204 enum
205 {
206 LFROM = 1<<0,
207 LTO = 1<<1,
208 LPOOL = 1<<2,
209
210 C_NONE = 0,
211 C_REG,
212 C_REGREG,
213 C_SHIFT,
214 C_FREG,
215 C_PSR,
216 C_FCR,
217
218 C_RCON, /* 0xff rotated */
219 C_NCON, /* ~RCON */
220 C_SCON, /* 0xffff */
221 C_LCON,
222 C_ZFCON,
223 C_SFCON,
224 C_LFCON,
225
226 C_RACON,
227 C_LACON,
228
229 C_SBRA,
230 C_LBRA,
231
232 C_HAUTO, /* halfword insn offset (-0xff to 0xff) */
233 C_FAUTO, /* float insn offset (0 to 0x3fc, word aligned) */
234 C_HFAUTO, /* both H and F */
235 C_SAUTO, /* -0xfff to 0xfff */
236 C_LAUTO,
237
238 C_HOREG,
239 C_FOREG,
240 C_HFOREG,
241 C_SOREG,
242 C_ROREG,
243 C_SROREG, /* both S and R */
244 C_LOREG,
245
246 C_PC,
247 C_SP,
248 C_HREG,
249
250 C_ADDR, /* reference to relocatable address */
251
252 C_GOK,
253
254 /* mark flags */
255 FOLL = 1<<0,
256 LABEL = 1<<1,
257 LEAF = 1<<2,
258
259 STRINGSZ = 200,
260 MINSIZ = 64,
261 NENT = 100,
262 MAXIO = 8192,
263 MAXHIST = 20, /* limit of path elements for history symbols */
264 MINLC = 4,
265 };
266
267 #ifndef COFFCVT
268
269 EXTERN int32 HEADR; /* length of header */
270 EXTERN int HEADTYPE; /* type of header */
271 EXTERN int32 INITDAT; /* data location */
272 EXTERN int32 INITRND; /* data round above text location */
273 EXTERN int32 INITTEXT; /* text location */
274 EXTERN char* INITENTRY; /* entry point */
275 EXTERN int32 autosize;
276 EXTERN Auto* curauto;
277 EXTERN Auto* curhist;
278 EXTERN Prog* curp;
279 EXTERN Sym* cursym;
280 EXTERN Sym* datap;
281 EXTERN int32 elfdatsize;
282 EXTERN char debug[128];
283 EXTERN Sym* etextp;
284 EXTERN char* noname;
285 EXTERN Prog* lastp;
286 EXTERN int32 lcsize;
287 EXTERN char literal[32];
288 EXTERN int nerrors;
289 EXTERN int32 instoffset;
290 EXTERN Opcross opcross[8];
291 EXTERN Oprang oprange[ALAST];
292 EXTERN char* outfile;
293 EXTERN int32 pc;
294 EXTERN uchar repop[ALAST];
295 EXTERN char* interpreter;
296 EXTERN char* rpath;
297 EXTERN uint32 stroffset;
298 EXTERN int32 symsize;
299 EXTERN Sym* textp;
300 EXTERN int32 textsize;
301 EXTERN int version;
302 EXTERN char xcmp[C_GOK+1][C_GOK+1];
303 EXTERN Prog zprg;
304 EXTERN int dtype;
305 EXTERN int armsize;
306
307 extern char* anames[];
308 extern Optab optab[];
309
310 void addpool(Prog*, Adr*);
311 EXTERN Prog* blitrl;
312 EXTERN Prog* elitrl;
313
314 void initdiv(void);
315 EXTERN Prog* prog_div;
316 EXTERN Prog* prog_divu;
317 EXTERN Prog* prog_mod;
318 EXTERN Prog* prog_modu;
319
320 #pragma varargck type "A" int
321 #pragma varargck type "C" int
322 #pragma varargck type "D" Adr*
323 #pragma varargck type "I" uchar*
324 #pragma varargck type "N" Adr*
325 #pragma varargck type "P" Prog*
326 #pragma varargck type "S" char*
327 #pragma varargck type "Z" char*
328 #pragma varargck type "i" char*
329
330 int Aconv(Fmt*);
331 int Cconv(Fmt*);
332 int Dconv(Fmt*);
333 int Iconv(Fmt*);
334 int Nconv(Fmt*);
335 int Oconv(Fmt*);
336 int Pconv(Fmt*);
337 int Sconv(Fmt*);
338 int aclass(Adr*);
339 void addhist(int32, int);
340 Prog* appendp(Prog*);
341 void asmb(void);
342 void asmout(Prog*, Optab*, int32*);
343 int32 atolwhex(char*);
344 Prog* brloop(Prog*);
345 void buildop(void);
346 void buildrep(int, int);
347 void cflush(void);
348 int chipzero(Ieee*);
349 int chipfloat(Ieee*);
350 int cmp(int, int);
351 int compound(Prog*);
352 double cputime(void);
353 void diag(char*, ...);
354 void divsig(void);
355 void dodata(void);
356 void doprof1(void);
357 void doprof2(void);
358 int32 entryvalue(void);
359 void exchange(Prog*);
360 void follow(void);
361 void hputl(int);
362 int isnop(Prog*);
363 void listinit(void);
364 Sym* lookup(char*, int);
365 void cput(int);
366 void hput(int32);
367 void lput(int32);
368 void lputb(int32);
369 void lputl(int32);
370 void* mysbrk(uint32);
371 void names(void);
372 void nocache(Prog*);
373 int ocmp(const void*, const void*);
374 int32 opirr(int);
375 Optab* oplook(Prog*);
376 int32 oprrr(int, int);
377 int32 olr(int32, int, int, int);
378 int32 olhr(int32, int, int, int);
379 int32 olrr(int, int, int, int);
380 int32 olhrr(int, int, int, int);
381 int32 osr(int, int, int32, int, int);
382 int32 oshr(int, int32, int, int);
383 int32 ofsr(int, int, int32, int, int, Prog*);
384 int32 osrr(int, int, int, int);
385 int32 oshrr(int, int, int, int);
386 int32 omvl(Prog*, Adr*, int);
387 void patch(void);
388 void prasm(Prog*);
389 void prepend(Prog*, Prog*);
390 Prog* prg(void);
391 int pseudo(Prog*);
392 int32 regoff(Adr*);
393 int relinv(int);
394 int32 rnd(int32, int32);
395 void softfloat(void);
396 void span(void);
397 void strnput(char*, int);
398 int32 symaddr(Sym*);
399 void undef(void);
400 void wput(int32);
401 void wputl(ushort w);
402 void xdefine(char*, int, int32);
403 void noops(void);
404 int32 immrot(uint32);
405 int32 immaddr(int32);
406 int32 opbra(int, int);
407 int brextra(Prog*);
408 int isbranch(Prog*);
409 void fnptrs(void);
410 void doelf(void);
411
412 vlong addaddr(Sym *s, Sym *t);
413 vlong addsize(Sym *s, Sym *t);
414 vlong addstring(Sym *s, char *str);
415 vlong adduint16(Sym *s, uint16 v);
416 vlong adduint32(Sym *s, uint32 v);
417 vlong adduint64(Sym *s, uint64 v);
418 vlong adduint8(Sym *s, uint8 v);
419 vlong adduintxx(Sym *s, uint64 v, int wid);
420
421 /* Native is little-endian */
422 #define LPUT(a) lputl(a)
423 #define WPUT(a) wputl(a)
424 #define VPUT(a) abort()
425
426 #endif