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