3 #define KMASK 0xF0000000
4 #define JMPSZ sizeof(u32int) /* size of bootstrap jump section */
27 void strnput(char*, int);
36 if(*a >= '0' && *a <= '9')
41 if(dlm && s->type == SDATA)
42 return s->value+INITDAT;
43 if(s->type != STEXT && s->type != SLEAF)
44 diag("entry not text: %s", s->name);
57 Bprint(&bso, "%5.2f asm\n", cputime());
60 /* emit text segment */
62 prevpc = pc = INITTEXT;
63 for(p = firstp; p != P; p = p->link) {
66 autosize = p->to.offset + 4;
67 if(p->from3.type == D_CONST) {
68 for(; pc < p->pc; pc++)
73 diag("phase error %lux sb %lux",
80 o = oplook(p); /* could probably avoid this call */
86 if (prevpc & (1<<31) && (pc & (1<<31)) == 0) {
90 if(curtext != P && curtext->from.sym != S)
91 tn = curtext->from.sym->name;
92 Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn);
96 /* for virtex 4, inject a jmp instruction after other text */
98 /* branch to absolute entry address (0xfffe2100) */
99 lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2);
106 /* emit data segment */
116 seek(cout, HEADR+textsize, 0);
119 seek(cout, rnd(HEADR+textsize, 4), 0);
122 seek(cout, rnd(HEADR+textsize, 4096), 0);
129 write(cout, buf, INITDAT-textsize);
133 for(t = 0; t < datsize; t += sizeof(buf)-100) {
134 if(datsize-t > sizeof(buf)-100)
135 datblk(t, sizeof(buf)-100);
137 datblk(t, datsize-t);
144 Bprint(&bso, "%5.2f sym\n", cputime());
152 seek(cout, HEADR+textsize+datsize, 0);
155 seek(cout, rnd(HEADR+textsize, 4)+datsize, 0);
158 seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0);
164 Bprint(&bso, "%5.2f sp\n", cputime());
170 if(HEADTYPE == 0 || HEADTYPE == 1) /* round up file length for boot image */
171 if((symsize+lcsize) & 1)
180 /* back up and write the header */
184 lput(0x1030107); /* magic and sections */
185 lput(textsize); /* sizes */
188 lput(symsize); /* nsyms */
189 lput(entryvalue()); /* va of entry */
194 lput(0x4a6f7921); /* Joy! */
195 lput(0x70656666); /* peff */
196 lput(0x70777063); /* pwpc */
202 lput(0x30002); /*YY*/
206 lput(textsize+datsize);
207 lput(textsize+datsize);
208 lput(textsize+datsize);
209 lput(0xd0); /* header size */
242 lput(0x3100); /* load address */
249 lput(0x80000000 | (4*21*21+7)); /* magic */
251 lput(4*21*21+7); /* magic */
252 lput(textsize); /* sizes */
255 lput(symsize); /* nsyms */
256 lput(entryvalue()); /* va of entry */
263 lput((0x1DFL<<16)|3L); /* magic and sections */
264 lput(time(0)); /* time and date */
265 lput(rnd(HEADR+textsize, 4096)+datsize);
266 lput(symsize); /* nsyms */
267 lput((0x48L<<16)|15L); /* size of optional hdr and flags */
269 lput((0413<<16)|01L); /* magic and version */
270 lput(textsize); /* sizes */
273 lput(entryvalue()); /* va of entry */
274 lput(INITTEXT); /* va of base of text */
275 lput(INITDAT); /* va of base of data */
276 lput(INITDAT); /* address of TOC */
277 lput((1L<<16)|1); /* sn(entry) | sn(text) */
278 lput((2L<<16)|1); /* sn(data) | sn(toc) */
279 lput((0L<<16)|3); /* sn(loader) | sn(bss) */
280 lput((3L<<16)|3); /* maxalign(text) | maxalign(data) */
281 lput(('1'<<24)|('L'<<16)|0); /* type field, and reserved */
282 lput(0); /* max stack allowed */
283 lput(0); /* max data allowed */
284 lput(0); lput(0); lput(0); /* reserved */
286 strnput(".text", 8); /* text segment */
287 lput(INITTEXT); /* address */
292 lput(HEADR+textsize+datsize+symsize);
293 lput(lcsize); /* line number size */
294 lput(0x20L); /* flags */
296 strnput(".data", 8); /* data segment */
297 lput(INITDAT); /* address */
300 lput(rnd(HEADR+textsize, 4096));/* sizes */
304 lput(0x40L); /* flags */
306 strnput(".bss", 8); /* bss segment */
307 lput(INITDAT+datsize); /* address */
308 lput(INITDAT+datsize);
314 lput(0x80L); /* flags */
318 * customised for blue/gene,
319 * notably the alignment and KMASK masking.
321 strnput("\177ELF", 4); /* e_ident */
322 CPUT(1); /* class = 32 bit */
323 CPUT(2); /* data = MSB */
324 CPUT(1); /* version = CURRENT */
326 lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */
327 lput(1L); /* version = CURRENT */
328 lput(entryvalue() & ~KMASK); /* entry vaddr */
329 lput(52L); /* offset to first phdr */
332 lput(HEADR+textsize+datsize+symsize); /* offset to first shdr */
333 lput(0L); /* flags = PPC */
334 lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/
335 lput((3L<<16)|40L); /* # Phdrs & Shdr size */
336 lput((3L<<16)|2L); /* # Shdrs & shdr string size */
340 lput(0L); /* flags = PPC */
341 lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/
342 lput((3L<<16)|0L); /* # Phdrs & Shdr size */
343 lput((3L<<16)|0L); /* # Shdrs & shdr string size */
346 lput(1L); /* text - type = PT_LOAD */
347 lput(HEADR); /* file offset */
348 lput(INITTEXT & ~KMASK); /* vaddr */
349 lput(INITTEXT); /* paddr */
350 lput(textsize); /* file size */
351 lput(textsize); /* memory size */
352 lput(0x05L); /* protections = RX */
353 lput(0x10000L); /* alignment */
355 lput(1L); /* data - type = PT_LOAD */
356 lput(HEADR+textsize); /* file offset */
357 lput(INITDAT & ~KMASK); /* vaddr */
358 lput(INITDAT); /* paddr */
359 lput(datsize); /* file size */
360 lput(datsize); /* memory size */
361 lput(0x07L); /* protections = RWX */
362 lput(0x10000L); /* alignment */
364 lput(0L); /* data - type = PT_NULL */
365 lput(HEADR+textsize+datsize); /* file offset */
366 lput(0L); /* vaddr */
367 lput(0L); /* paddr */
368 lput(symsize); /* symbol table size */
369 lput(lcsize); /* line number size */
370 lput(0x04L); /* protections = R */
371 lput(0x04L); /* alignment code?? */
377 seek(cout, HEADR+textsize+datsize+symsize, 0);
378 lput(1); /* Section name (string tbl index) */
379 lput(1); /* Section type */
380 lput(2|4); /* Section flags */
381 lput(INITTEXT & ~KMASK); /* Section virtual addr at execution */
382 lput(HEADR); /* Section file offset */
383 lput(textsize); /* Section size in bytes */
384 lput(0); /* Link to another section */
385 lput(0); /* Additional section information */
386 lput(0x10000L); /* Section alignment */
387 lput(0); /* Entry size if section holds table */
389 lput(7); /* Section name (string tbl index) */
390 lput(1); /* Section type */
391 lput(2|1); /* Section flags */
392 lput(INITDAT & ~KMASK); /* Section virtual addr at execution */
393 lput(HEADR+textsize); /* Section file offset */
394 lput(datsize); /* Section size in bytes */
395 lput(0); /* Link to another section */
396 lput(0); /* Additional section information */
397 lput(0x10000L); /* Section alignment */
398 lput(0); /* Entry size if section holds table */
400 /* string section header */
401 lput(12); /* Section name (string tbl index) */
402 lput(3); /* Section type */
403 lput(1 << 5); /* Section flags */
404 lput(0); /* Section virtual addr at execution */
405 lput(HEADR+textsize+datsize+symsize+3*40); /* Section file offset */
406 lput(14); /* Section size in bytes */
407 lput(0); /* Link to another section */
408 lput(0); /* Additional section information */
409 lput(1); /* Section alignment */
410 lput(0); /* Entry size if section holds table */
418 strnput(".strtab", 7);
425 * customised for virtex 4 boot,
426 * notably the alignment and KMASK masking.
428 strnput("\177ELF", 4); /* e_ident */
429 CPUT(1); /* class = 32 bit */
430 CPUT(2); /* data = MSB */
431 CPUT(1); /* version = CURRENT */
433 lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */
434 lput(1L); /* version = CURRENT */
435 lput(entryvalue()); /* entry vaddr */
436 lput(52L); /* offset to first phdr */
438 debug['S'] = 1; /* no symbol table */
440 lput(HEADR+textsize+datsize+symsize); /* offset to first shdr */
441 lput(0L); /* flags = PPC */
442 lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/
443 lput((4L<<16)|40L); /* # Phdrs & Shdr size */
444 lput((4L<<16)|2L); /* # Shdrs & shdr string size */
448 lput(0L); /* flags = PPC */
449 lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/
450 lput((4L<<16)|0L); /* # Phdrs & Shdr size */
451 lput((4L<<16)|0L); /* # Shdrs & shdr string size */
454 lput(1L); /* text - type = PT_LOAD */
455 lput(HEADR); /* file offset */
456 lput(INITTEXT); /* vaddr */
457 lput(INITTEXT); /* paddr */
458 lput(textsize-JMPSZ); /* file size */
459 lput(textsize-JMPSZ); /* memory size */
460 lput(0x05L); /* protections = RX */
461 lput(0); /* alignment */
463 lput(1L); /* data - type = PT_LOAD */
464 lput(HEADR+textsize); /* file offset */
465 lput(INITDAT); /* vaddr */
466 lput(INITDAT); /* paddr */
467 lput(datsize); /* file size */
468 lput(datsize+bsssize); /* memory size */
469 lput(0x07L); /* protections = RWX */
470 lput(0); /* alignment */
472 lput(0L); /* data - type = PT_NULL */
473 lput(HEADR+textsize+datsize); /* file offset */
474 lput(0L); /* vaddr */
475 lput(0L); /* paddr */
476 lput(symsize); /* symbol table size */
477 lput(lcsize); /* line number size */
478 lput(0x04L); /* protections = R */
479 lput(0x04L); /* alignment code?? */
481 /* add tiny text section at end with jmp to start */
482 lput(1L); /* text - type = PT_LOAD */
483 lput(HEADR+textsize-JMPSZ); /* file offset */
484 lput(0xFFFFFFFC); /* vaddr */
485 lput(0xFFFFFFFC); /* paddr */
486 lput(JMPSZ); /* file size */
487 lput(JMPSZ); /* memory size */
488 lput(0x05L); /* protections = RX */
489 lput(0); /* disable alignment */
498 strnput(char *s, int n)
537 n = sizeof(buf.cbuf) - cbc;
539 write(cout, buf.cbuf, n);
541 cbc = sizeof(buf.cbuf);
552 s = lookup("etext", 0);
554 putsymb(s->name, 'T', s->value, s->version);
556 for(h=0; h<NHASH; h++)
557 for(s=hash[h]; s!=S; s=s->link)
560 putsymb(s->name, 'D', s->value, s->version);
564 putsymb(s->name, 'D', s->value+INITDAT, s->version);
568 putsymb(s->name, 'B', s->value+INITDAT, s->version);
572 putsymb(s->name, 'f', s->value, s->version);
576 for(p=textp; p!=P; p=p->cond) {
578 if(s->type != STEXT && s->type != SLEAF)
581 /* filenames first */
582 for(a=p->to.autom; a; a=a->link)
583 if(a->type == D_FILE)
584 putsymb(a->sym->name, 'z', a->aoffset, 0);
586 if(a->type == D_FILE1)
587 putsymb(a->sym->name, 'Z', a->aoffset, 0);
590 putsymb(s->name, 'T', s->value, s->version);
592 putsymb(s->name, 'L', s->value, s->version);
594 /* frame, auto and param after */
595 putsymb(".frame", 'm', p->to.offset+4, 0);
596 for(a=p->to.autom; a; a=a->link)
597 if(a->type == D_AUTO)
598 putsymb(a->sym->name, 'a', -a->aoffset, 0);
600 if(a->type == D_PARAM)
601 putsymb(a->sym->name, 'p', a->aoffset, 0);
603 if(debug['v'] || debug['n'])
604 Bprint(&bso, "symsize = %lud\n", symsize);
609 putsymb(char *s, int t, long v, int ver)
618 CPUT(t+0x80); /* 0x80 is variable length */
620 if(t == 'Z' || t == 'z') {
622 for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
635 symsize += 4 + 1 + i + 1;
638 if(t == 'z' || t == 'Z') {
639 Bprint(&bso, "%c %.8lux ", t, v);
640 for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
641 f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
642 Bprint(&bso, "/%x", f);
648 Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
650 Bprint(&bso, "%c %.8lux %s\n", t, v, s);
664 for(p = firstp; p != P; p = p->link) {
665 if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
669 Bprint(&bso, "%6lux %P\n",
674 Bprint(&bso, "\t\t%6ld", lcsize);
675 v = (p->pc - oldpc) / MINLC;
680 CPUT(s+128); /* 129-255 +pc */
682 Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
688 oldpc = p->pc + MINLC;
689 if(s > 64 || s < -64) {
690 CPUT(0); /* 0 vv +lc */
697 Bprint(&bso, " lc+%ld(%d,%ld)\n",
700 Bprint(&bso, " lc%ld(%d,%ld)\n",
702 Bprint(&bso, "%6lux %P\n",
709 CPUT(0+s); /* 1-64 +lc */
711 Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
712 Bprint(&bso, "%6lux %P\n",
716 CPUT(64-s); /* 65-128 -lc */
718 Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
719 Bprint(&bso, "%6lux %P\n",
730 if(debug['v'] || debug['L'])
731 Bprint(&bso, "lcsize = %ld\n", lcsize);
736 datblk(long s, long n)
743 memset(buf.dbuf, 0, n+100);
744 for(p = datap; p != P; p = p->link) {
746 l = p->from.sym->value + p->from.offset - s;
759 if(p->as != AINIT && p->as != ADYNT && !p->from.sym->dupok) {
760 for(j=l+(c-i)-1; j>=l; j--)
763 diag("multiple initialization");
769 diag("unknown mode in initialization\n%P", p);
776 fl = ieeedtof(&p->to.ieee);
779 buf.dbuf[l] = cast[fnuxi8[i+4]];
784 cast = (char*)&p->to.ieee;
786 buf.dbuf[l] = cast[fnuxi8[i]];
795 buf.dbuf[l] = p->to.sval[i];
803 if(p->to.sym->type == SUNDEF){
805 d += p->to.sym->value;
807 if(p->to.sym->type == STEXT ||
808 p->to.sym->type == SLEAF)
809 d += p->to.sym->value;
810 if(p->to.sym->type == SDATA)
811 d += p->to.sym->value + INITDAT;
812 if(p->to.sym->type == SBSS)
813 d += p->to.sym->value + INITDAT;
815 dynreloc(p->to.sym, l+s+INITDAT, 1, 0, 0);
820 diag("bad nuxi %d %d\n%P", c, i, curp);
824 buf.dbuf[l] = cast[inuxi1[i]];
830 buf.dbuf[l] = cast[inuxi2[i]];
836 buf.dbuf[l] = cast[inuxi4[i]];
844 write(cout, buf.dbuf, n);