]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/6l/asm.c
6l: fix warning, setmalloctag declaration, missing header type cases
[plan9front.git] / sys / src / cmd / 6l / asm.c
1 #include        "l.h"
2
3 #define Dbufslop        100
4
5 #define PADDR(a)        ((a) & ~0xfffffffff0000000ull)
6
7 vlong
8 entryvalue(void)
9 {
10         char *a;
11         Sym *s;
12
13         a = INITENTRY;
14         if(*a >= '0' && *a <= '9')
15                 return atolwhex(a);
16         s = lookup(a, 0);
17         if(s->type == 0)
18                 return INITTEXT;
19         switch(s->type) {
20         case STEXT:
21                 break;
22         case SDATA:
23                 if(dlm)
24                         return s->value+INITDAT;
25         default:
26                 diag("entry not text: %s", s->name);
27         }
28         return s->value;
29 }
30
31 void
32 wputl(ushort w)
33 {
34         cput(w);
35         cput(w>>8);
36 }
37
38 void
39 wput(ushort w)
40 {
41         cput(w>>8);
42         cput(w);
43 }
44
45 void
46 lput(long l)
47 {
48         cput(l>>24);
49         cput(l>>16);
50         cput(l>>8);
51         cput(l);
52 }
53
54 void
55 llput(vlong v)
56 {
57         lput(v>>32);
58         lput(v);
59 }
60
61 void
62 lputl(long l)
63 {
64         cput(l);
65         cput(l>>8);
66         cput(l>>16);
67         cput(l>>24);
68 }
69
70 void
71 strnput(char *s, int n)
72 {
73         for(; *s && n > 0; s++){
74                 cput(*s);
75                 n--;
76         }
77         while(n > 0){
78                 cput(0);
79                 n--;
80         }
81 }
82
83 void
84 asmb(void)
85 {
86         Prog *p;
87         long v, magic;
88         int a;
89         uchar *op1;
90         vlong vl;
91
92         if(debug['v'])
93                 Bprint(&bso, "%5.2f asmb\n", cputime());
94         Bflush(&bso);
95
96         seek(cout, HEADR, 0);
97         pc = INITTEXT;
98         curp = firstp;
99         for(p = firstp; p != P; p = p->link) {
100                 if(p->as == ATEXT)
101                         curtext = p;
102                 if(p->pc != pc) {
103                         if(!debug['a'])
104                                 print("%P\n", curp);
105                         diag("phase error %llux sb %llux in %s", p->pc, pc, TNAME);
106                         pc = p->pc;
107                 }
108                 curp = p;
109                 asmins(p);
110                 a = (andptr - and);
111                 if(cbc < a)
112                         cflush();
113                 if(debug['a']) {
114                         Bprint(&bso, pcstr, pc);
115                         for(op1 = and; op1 < andptr; op1++)
116                                 Bprint(&bso, "%.2ux", *op1 & 0xff);
117                         Bprint(&bso, "\t%P\n", curp);
118                 }
119                 if(dlm) {
120                         if(p->as == ATEXT)
121                                 reloca = nil;
122                         else if(reloca != nil)
123                                 diag("reloc failure: %P", curp);
124                 }
125                 memmove(cbp, and, a);
126                 cbp += a;
127                 pc += a;
128                 cbc -= a;
129         }
130         cflush();
131         switch(HEADTYPE) {
132         default:
133                 diag("unknown header type %ld", HEADTYPE);
134         case 2:
135         case 3:
136         case 5:
137                 seek(cout, HEADR+textsize, 0);
138                 break;
139         }
140
141         if(debug['v'])
142                 Bprint(&bso, "%5.2f datblk\n", cputime());
143         Bflush(&bso);
144
145         if(dlm){
146                 char buf[8];
147
148                 write(cout, buf, INITDAT-textsize);
149                 textsize = INITDAT;
150         }
151
152         for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) {
153                 if(datsize-v > sizeof(buf)-Dbufslop)
154                         datblk(v, sizeof(buf)-Dbufslop);
155                 else
156                         datblk(v, datsize-v);
157         }
158
159         symsize = 0;
160         spsize = 0;
161         lcsize = 0;
162         if(!debug['s']) {
163                 if(debug['v'])
164                         Bprint(&bso, "%5.2f sym\n", cputime());
165                 Bflush(&bso);
166                 switch(HEADTYPE) {
167                 default:
168                 case 2:
169                 case 3:
170                 case 5:
171                         seek(cout, HEADR+textsize+datsize, 0);
172                         break;
173                 }
174                 if(!debug['s'])
175                         asmsym();
176                 if(debug['v'])
177                         Bprint(&bso, "%5.2f sp\n", cputime());
178                 Bflush(&bso);
179                 if(debug['v'])
180                         Bprint(&bso, "%5.2f pc\n", cputime());
181                 Bflush(&bso);
182                 if(!debug['s'])
183                         asmlc();
184                 if(dlm)
185                         asmdyn();
186                 cflush();
187         }
188         else if(dlm){
189                 seek(cout, HEADR+textsize+datsize, 0);
190                 asmdyn();
191                 cflush();
192         }
193         if(debug['v'])
194                 Bprint(&bso, "%5.2f headr\n", cputime());
195         Bflush(&bso);
196         seek(cout, 0L, 0);
197         switch(HEADTYPE) {
198         default:
199         case 2: /* plan9 */
200                 magic = 4*26*26+7;
201                 magic |= 0x00008000;            /* fat header */
202                 if(dlm)
203                         magic |= 0x80000000;    /* dlm */
204                 lput(magic);                    /* magic */
205                 lput(textsize);                 /* sizes */
206                 lput(datsize);
207                 lput(bsssize);
208                 lput(symsize);                  /* nsyms */
209                 vl = entryvalue();
210                 lput(PADDR(vl));                /* va of entry */
211                 lput(spsize);                   /* sp offsets */
212                 lput(lcsize);                   /* line offsets */
213                 llput(vl);                      /* va of entry */
214                 break;
215         case 3: /* plan9 */
216                 magic = 4*26*26+7;
217                 if(dlm)
218                         magic |= 0x80000000;
219                 lput(magic);                    /* magic */
220                 lput(textsize);                 /* sizes */
221                 lput(datsize);
222                 lput(bsssize);
223                 lput(symsize);                  /* nsyms */
224                 lput(entryvalue());             /* va of entry */
225                 lput(spsize);                   /* sp offsets */
226                 lput(lcsize);                   /* line offsets */
227                 break;
228         case 5:
229                 strnput("\177ELF", 4);          /* e_ident */
230                 cput(1);                        /* class = 32 bit */
231                 cput(1);                        /* data = LSB */
232                 cput(1);                        /* version = CURRENT */
233                 strnput("", 9);
234                 wputl(2);                       /* type = EXEC */
235                 if(debug['8'])
236                         wputl(3);               /* machine = 386 */
237                 else
238                         wputl(62);              /* machine = AMD64 */
239                 lputl(1L);                      /* version = CURRENT */
240                 lputl(PADDR(entryvalue()));     /* entry vaddr */
241                 lputl(52L);                     /* offset to first phdr */
242                 lputl(0L);                      /* offset to first shdr */
243                 lputl(0L);                      /* processor specific flags */
244                 wputl(52);                      /* Ehdr size */
245                 wputl(32);                      /* Phdr size */
246                 wputl(3);                       /* # of Phdrs */
247                 wputl(0);                       /* Shdr size */
248                 wputl(0);                       /* # of Shdrs */
249                 wputl(0);                       /* Shdr string size */
250
251                 lputl(1L);                      /* text - type = PT_LOAD */
252                 lputl(HEADR);                   /* file offset */
253                 lputl(INITTEXT);                /* vaddr */
254                 lputl(PADDR(INITTEXT));         /* paddr */
255                 lputl(textsize);                /* file size */
256                 lputl(textsize);                /* memory size */
257                 lputl(0x05L);                   /* protections = RX */
258                 lputl(INITRND);                 /* alignment */
259
260                 lputl(1L);                      /* data - type = PT_LOAD */
261                 lputl(HEADR+textsize);          /* file offset */
262                 lputl(INITDAT);                 /* vaddr */
263                 lputl(PADDR(INITDAT));          /* paddr */
264                 lputl(datsize);                 /* file size */
265                 lputl(datsize+bsssize);         /* memory size */
266                 lputl(0x06L);                   /* protections = RW */
267                 lputl(INITRND);                 /* alignment */
268
269                 lputl(0L);                      /* symbols - type = PT_NULL */
270                 lputl(HEADR+textsize+datsize);  /* file offset */
271                 lputl(0L);
272                 lputl(0L);
273                 lputl(symsize);                 /* symbol table size */
274                 lputl(lcsize);                  /* line number size */
275                 lputl(0x04L);                   /* protections = R */
276                 lputl(0x04L);                   /* alignment */
277                 break;
278         }
279         cflush();
280 }
281
282 void
283 cflush(void)
284 {
285         int n;
286
287         n = sizeof(buf.cbuf) - cbc;
288         if(n)
289                 write(cout, buf.cbuf, n);
290         cbp = buf.cbuf;
291         cbc = sizeof(buf.cbuf);
292 }
293
294 void
295 datblk(long s, long n)
296 {
297         Prog *p;
298         uchar *cast;
299         long l, fl, j;
300         vlong o;
301         int i, c;
302
303         memset(buf.dbuf, 0, n+Dbufslop);
304         for(p = datap; p != P; p = p->link) {
305                 curp = p;
306                 l = p->from.sym->value + p->from.offset - s;
307                 c = p->from.scale;
308                 i = 0;
309                 if(l < 0) {
310                         if(l+c <= 0)
311                                 continue;
312                         while(l < 0) {
313                                 l++;
314                                 i++;
315                         }
316                 }
317                 if(l >= n)
318                         continue;
319                 if(p->as != AINIT && p->as != ADYNT) {
320                         for(j=l+(c-i)-1; j>=l; j--)
321                                 if(buf.dbuf[j]) {
322                                         print("%P\n", p);
323                                         diag("multiple initialization");
324                                         break;
325                                 }
326                 }
327                 switch(p->to.type) {
328                 case D_FCONST:
329                         switch(c) {
330                         default:
331                         case 4:
332                                 fl = ieeedtof(&p->to.ieee);
333                                 cast = (uchar*)&fl;
334                                 if(debug['a'] && i == 0) {
335                                         Bprint(&bso, pcstr, l+s+INITDAT);
336                                         for(j=0; j<c; j++)
337                                                 Bprint(&bso, "%.2ux", cast[fnuxi4[j]]);
338                                         Bprint(&bso, "\t%P\n", curp);
339                                 }
340                                 for(; i<c; i++) {
341                                         buf.dbuf[l] = cast[fnuxi4[i]];
342                                         l++;
343                                 }
344                                 break;
345                         case 8:
346                                 cast = (uchar*)&p->to.ieee;
347                                 if(debug['a'] && i == 0) {
348                                         Bprint(&bso, pcstr, l+s+INITDAT);
349                                         for(j=0; j<c; j++)
350                                                 Bprint(&bso, "%.2ux", cast[fnuxi8[j]]);
351                                         Bprint(&bso, "\t%P\n", curp);
352                                 }
353                                 for(; i<c; i++) {
354                                         buf.dbuf[l] = cast[fnuxi8[i]];
355                                         l++;
356                                 }
357                                 break;
358                         }
359                         break;
360
361                 case D_SCONST:
362                         if(debug['a'] && i == 0) {
363                                 Bprint(&bso, pcstr, l+s+INITDAT);
364                                 for(j=0; j<c; j++)
365                                         Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff);
366                                 Bprint(&bso, "\t%P\n", curp);
367                         }
368                         for(; i<c; i++) {
369                                 buf.dbuf[l] = p->to.scon[i];
370                                 l++;
371                         }
372                         break;
373                 default:
374                         o = p->to.offset;
375                         if(p->to.type == D_ADDR) {
376                                 if(p->to.index != D_STATIC && p->to.index != D_EXTERN)
377                                         diag("DADDR type%P", p);
378                                 if(p->to.sym) {
379                                         if(p->to.sym->type == SUNDEF)
380                                                 ckoff(p->to.sym, o);
381                                         o += p->to.sym->value;
382                                         if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF)
383                                                 o += INITDAT;
384                                         if(dlm)
385                                                 dynreloc(p->to.sym, l+s+INITDAT, 1);
386                                 }
387                         }
388                         fl = o;
389                         cast = (uchar*)&fl;
390                         switch(c) {
391                         default:
392                                 diag("bad nuxi %d %d\n%P", c, i, curp);
393                                 break;
394                         case 1:
395                                 if(debug['a'] && i == 0) {
396                                         Bprint(&bso, pcstr, l+s+INITDAT);
397                                         for(j=0; j<c; j++)
398                                                 Bprint(&bso, "%.2ux", cast[inuxi1[j]]);
399                                         Bprint(&bso, "\t%P\n", curp);
400                                 }
401                                 for(; i<c; i++) {
402                                         buf.dbuf[l] = cast[inuxi1[i]];
403                                         l++;
404                                 }
405                                 break;
406                         case 2:
407                                 if(debug['a'] && i == 0) {
408                                         Bprint(&bso, pcstr, l+s+INITDAT);
409                                         for(j=0; j<c; j++)
410                                                 Bprint(&bso, "%.2ux", cast[inuxi2[j]]);
411                                         Bprint(&bso, "\t%P\n", curp);
412                                 }
413                                 for(; i<c; i++) {
414                                         buf.dbuf[l] = cast[inuxi2[i]];
415                                         l++;
416                                 }
417                                 break;
418                         case 4:
419                                 if(debug['a'] && i == 0) {
420                                         Bprint(&bso, pcstr, l+s+INITDAT);
421                                         for(j=0; j<c; j++)
422                                                 Bprint(&bso, "%.2ux", cast[inuxi4[j]]);
423                                         Bprint(&bso, "\t%P\n", curp);
424                                 }
425                                 for(; i<c; i++) {
426                                         buf.dbuf[l] = cast[inuxi4[i]];
427                                         l++;
428                                 }
429                                 break;
430                         case 8:
431                                 cast = (uchar*)&o;
432                                 if(debug['a'] && i == 0) {
433                                         Bprint(&bso, pcstr, l+s+INITDAT);
434                                         for(j=0; j<c; j++)
435                                                 Bprint(&bso, "%.2ux", cast[inuxi8[j]]);
436                                         Bprint(&bso, "\t%P\n", curp);
437                                 }
438                                 for(; i<c; i++) {
439                                         buf.dbuf[l] = cast[inuxi8[i]];
440                                         l++;
441                                 }
442                                 break;
443                         }
444                         break;
445                 }
446         }
447         write(cout, buf.dbuf, n);
448 }
449
450 vlong
451 rnd(vlong v, vlong r)
452 {
453         vlong c;
454
455         if(r <= 0)
456                 return v;
457         v += r - 1;
458         c = v % r;
459         if(c < 0)
460                 c += r;
461         v -= c;
462         return v;
463 }