void asmb(void) { Prog *p; long t, etext; Optab *o; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); OFFSET = HEADR; seek(cout, OFFSET, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; } if(p->pc != pc) { diag("phase error %lux sb %lux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ asmout(p, o); pc += o->size; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); /* output strings in text segment */ etext = INITTEXT + textsize; for(t = pc; t < etext; t += sizeof(buf)-100) { if(etext-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100, 1); else datblk(t, etext-t, 1); } curtext = P; switch(HEADTYPE) { case 0: case 1: case 2: case 5: case 7: OFFSET = HEADR+textsize; seek(cout, OFFSET, 0); break; case 3: case 6: /* no header, padded segments */ OFFSET = rnd(HEADR+textsize, 4096); seek(cout, OFFSET, 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100, 0); else datblk(t, datsize-t, 0); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 1: case 4: case 5: debug['s'] = 1; break; case 2: OFFSET = HEADR+textsize+datsize; seek(cout, OFFSET, 0); break; case 3: case 6: /* no header, padded segments */ OFFSET += rnd(datsize, 4096); seek(cout, OFFSET, 0); break; case 7: break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f pc\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(dlm) asmdyn(); cflush(); } else if(dlm){ seek(cout, HEADR+textsize+datsize, 0); asmdyn(); cflush(); } if(debug['v']) Bprint(&bso, "%5.2f header\n", cputime()); Bflush(&bso); OFFSET = 0; seek(cout, OFFSET, 0); switch(HEADTYPE) { case 0: /* no header */ case 6: /* no header, padded segments */ break; case 1: /* aif for risc os */ lputl(0xe1a00000); /* NOP - decompress code */ lputl(0xe1a00000); /* NOP - relocation code */ lputl(0xeb000000 + 12); /* BL - zero init code */ lputl(0xeb000000 + (entryvalue() - INITTEXT + HEADR - 12 - 8) / 4); /* BL - entry code */ lputl(0xef000011); /* SWI - exit code */ lputl(textsize+HEADR); /* text size */ lputl(datsize); /* data size */ lputl(0); /* sym size */ lputl(bsssize); /* bss size */ lputl(0); /* sym type */ lputl(INITTEXT-HEADR); /* text addr */ lputl(0); /* workspace - ignored */ lputl(32); /* addr mode / data addr flag */ lputl(0); /* data addr */ for(t=0; t<2; t++) lputl(0); /* reserved */ for(t=0; t<15; t++) lputl(0xe1a00000); /* NOP - zero init code */ lputl(0xe1a0f00e); /* B (R14) - zero init return */ break; case 2: /* plan 9 */ if(dlm) lput(0x80000000|0x647); /* magic */ else lput(0x647); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 3: /* boot for NetBSD */ lput((143<<16)|0413); /* magic */ lputl(rnd(HEADR+textsize, 4096)); lputl(rnd(datsize, 4096)); lputl(bsssize); lputl(symsize); /* nsyms */ lputl(entryvalue()); /* va of entry */ lputl(0L); lputl(0L); break; case 4: /* boot for IXP1200 */ break; case 5: /* boot for ipaq */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ break; case 7: /* elf */ debug['S'] = 1; /* symbol table */ elf32(ARM, ELFDATA2LSB, 0, nil); break; } cflush(); }
void asmb(void) { Prog *p; long t; Optab *o; long prevpc; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); /* emit text segment */ seek(cout, HEADR, 0); prevpc = pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; if(p->from3.type == D_CONST) { for(; pc < p->pc; pc++) CPUT(0); } } if(p->pc != pc) { diag("phase error %lux sb %lux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ if(asmout(p, o, 0)) { p = p->link; pc += 4; } pc += o->size; if (prevpc & (1<<31) && (pc & (1<<31)) == 0) { char *tn; tn = "??none??"; if(curtext != P && curtext->from.sym != S) tn = curtext->from.sym->name; Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn); } prevpc = pc; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); /* emit data segment */ curtext = P; switch(HEADTYPE) { case 6: /* * but first, for virtex 4, inject a jmp instruction after * other text: branch to absolute entry address (0xfffe2100). */ lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2); textsize += JMPSZ; cflush(); /* fall through */ case 0: case 1: case 2: case 5: seek(cout, HEADR+textsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4), 0); break; case 4: seek(cout, rnd(HEADR+textsize, 4096), 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100); else datblk(t, datsize-t); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 1: case 2: case 5: case 6: seek(cout, HEADR+textsize+datsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4)+datsize, 0); break; case 4: seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0); break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(dlm) asmdyn(); if(HEADTYPE == 0 || HEADTYPE == 1) /* round up file length for boot image */ if((symsize+lcsize) & 1) CPUT(0); cflush(); } else if(dlm){ asmdyn(); cflush(); } /* back up and write the header */ seek(cout, 0L, 0); switch(HEADTYPE) { case 0: lput(0x1030107); /* magic and sections */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 1: lput(0x4a6f7921); /* Joy! */ lput(0x70656666); /* peff */ lput(0x70777063); /* pwpc */ lput(1); lput(0); lput(0); lput(0); lput(0); lput(0x30002); /*YY*/ lput(0); lput(~0); lput(0); lput(textsize+datsize); lput(textsize+datsize); lput(textsize+datsize); lput(0xd0); /* header size */ lput(0x10400); lput(~0); lput(0); lput(0xc); lput(0xc); lput(0xc); lput(0xc0); lput(0x01010400); lput(~0); lput(0); lput(0x38); lput(0x38); lput(0x38); lput(0x80); lput(0x04040400); lput(0); lput(1); lput(0); lput(~0); lput(0); lput(~0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0x3100); /* load address */ lput(0); lput(0); lput(0); /* whew! */ break; case 2: if(dlm) lput(0x80000000 | (4*21*21+7)); /* magic */ else lput(4*21*21+7); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 3: break; case 4: lput((0x1DFL<<16)|3L); /* magic and sections */ lput(time(0)); /* time and date */ lput(rnd(HEADR+textsize, 4096)+datsize); lput(symsize); /* nsyms */ lput((0x48L<<16)|15L); /* size of optional hdr and flags */ lput((0413<<16)|01L); /* magic and version */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(entryvalue()); /* va of entry */ lput(INITTEXT); /* va of base of text */ lput(INITDAT); /* va of base of data */ lput(INITDAT); /* address of TOC */ lput((1L<<16)|1); /* sn(entry) | sn(text) */ lput((2L<<16)|1); /* sn(data) | sn(toc) */ lput((0L<<16)|3); /* sn(loader) | sn(bss) */ lput((3L<<16)|3); /* maxalign(text) | maxalign(data) */ lput(('1'<<24)|('L'<<16)|0); /* type field, and reserved */ lput(0); /* max stack allowed */ lput(0); /* max data allowed */ lput(0); lput(0); lput(0); /* reserved */ strnput(".text", 8); /* text segment */ lput(INITTEXT); /* address */ lput(INITTEXT); lput(textsize); lput(HEADR); lput(0L); lput(HEADR+textsize+datsize+symsize); lput(lcsize); /* line number size */ lput(0x20L); /* flags */ strnput(".data", 8); /* data segment */ lput(INITDAT); /* address */ lput(INITDAT); lput(datsize); lput(rnd(HEADR+textsize, 4096));/* sizes */ lput(0L); lput(0L); lput(0L); lput(0x40L); /* flags */ strnput(".bss", 8); /* bss segment */ lput(INITDAT+datsize); /* address */ lput(INITDAT+datsize); lput(bsssize); lput(0L); lput(0L); lput(0L); lput(0L); lput(0x80L); /* flags */ break; case 5: /* * intended for blue/gene */ elf32(POWER, ELFDATA2MSB, 0, nil); break; case 6: /* * intended for virtex 4 boot */ debug['S'] = 1; /* symbol table */ elf32(POWER, ELFDATA2MSB, 1, elf32jmp); break; } cflush(); }
void asmb(void) { Prog *p; long t; Optab *o; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); seek(cout, HEADR, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; } if(p->pc != pc) { diag("phase error %lux sb %lux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ if(asmout(p, o, 0)) { p = p->link; pc += 4; } pc += o->size; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); curtext = P; switch(HEADTYPE) { case 0: case 3: seek(cout, HEADR+textsize, 0); break; case 1: case 2: seek(cout, HEADR+textsize, 0); break; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100); else datblk(t, datsize-t); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 3: seek(cout, HEADR+textsize+datsize, 0); break; case 2: case 1: seek(cout, HEADR+textsize+datsize, 0); break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); /* round up file length for boot image */ if(HEADTYPE == 0 || HEADTYPE == 3) if((symsize+lcsize) & 1) CPUT(0); cflush(); } seek(cout, 0L, 0); switch(HEADTYPE) { case 0: lput(0x1030107); /* magic and sections */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 1: break; case 2: lput(4*13*13+7); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 3: lput(0x1030107); /* magic and sections */ lput(0x90100000); #define SPARC_NOOP 0x01000000 lput(SPARC_NOOP); lput(SPARC_NOOP); lput(SPARC_NOOP); lput(SPARC_NOOP); lput(SPARC_NOOP); lput(SPARC_NOOP); break; } cflush(); }
void asmb(void) { Prog *p; long t; Optab *o; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); seek(cout, HEADR, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; if(p->from3.type == D_CONST) { for(; pc < p->pc; pc++) CPUT(0); } } if(p->pc != pc) { diag("phase error %lux sb %lux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ if(asmout(p, o, 0)) { p = p->link; pc += 4; } pc += o->size; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); curtext = P; switch(HEADTYPE) { case 0: case 1: case 2: case 5: seek(cout, HEADR+textsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4), 0); break; case 4: seek(cout, rnd(HEADR+textsize, 4096), 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100); else datblk(t, datsize-t); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 1: case 2: case 5: seek(cout, HEADR+textsize+datsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4)+datsize, 0); break; case 4: seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0); break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(dlm) asmdyn(); if(HEADTYPE == 0 || HEADTYPE == 1) /* round up file length for boot image */ if((symsize+lcsize) & 1) CPUT(0); cflush(); } else if(dlm){ asmdyn(); cflush(); } seek(cout, 0L, 0); switch(HEADTYPE) { case 0: lput(0x1030107); /* magic and sections */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 1: lput(0x4a6f7921); /* Joy! */ lput(0x70656666); /* peff */ lput(0x70777063); /* pwpc */ lput(1); lput(0); lput(0); lput(0); lput(0); lput(0x30002); /*YY*/ lput(0); lput(~0); lput(0); lput(textsize+datsize); lput(textsize+datsize); lput(textsize+datsize); lput(0xd0); /* header size */ lput(0x10400); lput(~0); lput(0); lput(0xc); lput(0xc); lput(0xc); lput(0xc0); lput(0x01010400); lput(~0); lput(0); lput(0x38); lput(0x38); lput(0x38); lput(0x80); lput(0x04040400); lput(0); lput(1); lput(0); lput(~0); lput(0); lput(~0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0x3100); /* load address */ lput(0); lput(0); lput(0); /* whew! */ break; case 2: if(dlm) lput(0x80000000 | (4*21*21+7)); /* magic */ else lput(4*21*21+7); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 3: break; case 4: lput((0x1DFL<<16)|3L); /* magic and sections */ lput(time(0)); /* time and date */ lput(rnd(HEADR+textsize, 4096)+datsize); lput(symsize); /* nsyms */ lput((0x48L<<16)|15L); /* size of optional hdr and flags */ lput((0413<<16)|01L); /* magic and version */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(entryvalue()); /* va of entry */ lput(INITTEXT); /* va of base of text */ lput(INITDAT); /* va of base of data */ lput(INITDAT); /* address of TOC */ lput((1L<<16)|1); /* sn(entry) | sn(text) */ lput((2L<<16)|1); /* sn(data) | sn(toc) */ lput((0L<<16)|3); /* sn(loader) | sn(bss) */ lput((3L<<16)|3); /* maxalign(text) | maxalign(data) */ lput(('1'<<24)|('L'<<16)|0); /* type field, and reserved */ lput(0); /* max stack allowed */ lput(0); /* max data allowed */ lput(0); lput(0); lput(0); /* reserved */ strnput(".text", 8); /* text segment */ lput(INITTEXT); /* address */ lput(INITTEXT); lput(textsize); lput(HEADR); lput(0L); lput(HEADR+textsize+datsize+symsize); lput(lcsize); /* line number size */ lput(0x20L); /* flags */ strnput(".data", 8); /* data segment */ lput(INITDAT); /* address */ lput(INITDAT); lput(datsize); lput(rnd(HEADR+textsize, 4096));/* sizes */ lput(0L); lput(0L); lput(0L); lput(0x40L); /* flags */ strnput(".bss", 8); /* bss segment */ lput(INITDAT+datsize); /* address */ lput(INITDAT+datsize); lput(bsssize); lput(0L); lput(0L); lput(0L); lput(0L); lput(0x80L); /* flags */ break; case 5: strnput("\177ELF", 4); /* e_ident */ CPUT(1); /* class = 32 bit */ CPUT(2); /* data = MSB */ CPUT(1); /* version = CURRENT */ strnput("", 9); lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */ lput(1L); /* version = CURRENT */ lput(entryvalue() & ~KMASK); /* entry vaddr */ lput(52L); /* offset to first phdr */ lput(0L); /* offset to first shdr */ lput(0L); /* flags = PPC */ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ lput((3L<<16)|0L); /* # Phdrs & Shdr size */ lput((0L<<16)|0L); /* # Shdrs & shdr string size */ lput(1L); /* text - type = PT_LOAD */ lput(HEADR); /* file offset */ lput(INITTEXT & ~KMASK); /* vaddr */ lput(INITTEXT); /* paddr */ lput(textsize); /* file size */ lput(textsize); /* memory size */ lput(0x05L); /* protections = RX */ lput(0x10000L); /* alignment */ lput(1L); /* data - type = PT_LOAD */ lput(HEADR+textsize); /* file offset */ lput(INITDAT & ~KMASK); /* vaddr */ lput(INITDAT); /* paddr */ lput(datsize); /* file size */ lput(datsize); /* memory size */ lput(0x07L); /* protections = RWX */ lput(0x10000L); /* alignment */ lput(0L); /* data - type = PT_NULL */ lput(HEADR+textsize+datsize); /* file offset */ lput(0L); lput(0L); lput(symsize); /* symbol table size */ lput(lcsize); /* line number size */ lput(0x04L); /* protections = R */ lput(0x04L); /* alignment code?? */ break; } cflush(); }
void asmb(void) { Prog *p; long t, magic; Optab *o; vlong vl; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); seek(cout, HEADR, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 8; if(p->from3.type == D_CONST) { for(; pc < p->pc; pc++) CPUT(0); } } if(p->pc != pc) { diag("phase error %llux sb %llux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ if(asmout(p, o, 0)) { p = p->link; pc += 4; } pc += o->size; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); curtext = P; switch(HEADTYPE) { case 0: case 1: case 2: case 5: case 9: case 10: seek(cout, HEADR+textsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4), 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100); else datblk(t, datsize-t); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 1: case 2: case 5: case 9: case 10: seek(cout, HEADR+textsize+datsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4)+datsize, 0); break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(dlm) asmdyn(); if(HEADTYPE == 0 || HEADTYPE == 1) /* round up file length for boot image */ if((symsize+lcsize) & 1) CPUT(0); cflush(); } else if(dlm){ asmdyn(); cflush(); } seek(cout, 0L, 0); switch(HEADTYPE) { case 0: lput(0x1030107); /* magic and sections */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 1: if(dlm) lput(0x80000000 | (4*21*21+7)); /* q.out magic */ else lput(4*21*21+7); /* q.out magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 2: /* plan9 */ magic = 4*27*27+7; magic |= 0x00008000; /* fat header */ if(dlm) magic |= 0x80000000; /* dlm */ lput(magic); lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ vl = entryvalue(); lput(PADDR(vl)); /* va of entry (real mode on boot) */ lput(0L); lput(lcsize); llput(vl); /* va of entry */ break; case 3: break; case 5: elf32(POWER, ELFDATA2MSB, 0, nil); break; case 9: /* ELF64 Header */ case 10: /* A2 weirdness */ elf64(POWER64, ELFDATA2MSB, 0, nil); break; } cflush(); }
void asmb(void) { Prog *p; long v; int a; short *op1; if(debug['v']) Bprint(&bso, "%5.2f asmb\n", cputime()); Bflush(&bso); seek(cout, HEADR, 0); pc = INITTEXT; curp = firstp; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) curtext = p; if(p->pc != pc) { if(!debug['a']) print("%P\n", curp); diag("phase error %.4lux sb %.4lux in %s", p->pc, pc, TNAME); pc = p->pc; } curp = p; if(debug['a']) Bprint(&bso, "%lux:%P\n", pc, curp); asmins(p); if(cbc < sizeof(opa)) cflush(); for(op1 = opa; op1 < op; op1++) { a = *op1; *cbp++ = a >> 8; *cbp++ = a; } a = 2*(op - opa); pc += a; cbc -= a; if(debug['a']) { for(op1 = opa; op1 < op; op1++) if(op1 == opa) Bprint(&bso, "\t\t%4ux", *op1 & 0xffff); else Bprint(&bso, " %4ux", *op1 & 0xffff); if(op != opa) Bprint(&bso, "\n"); } } cflush(); switch(HEADTYPE) { case 0: /* this is garbage */ seek(cout, rnd(HEADR+textsize, 8192), 0); break; case 1: /* plan9 boot data goes into text */ seek(cout, rnd(HEADR+textsize, INITRND), 0); break; case 2: /* plan 9 */ seek(cout, HEADR+textsize, 0); break; case 3: /* next boot */ seek(cout, HEADR+rnd(textsize, INITRND), 0); break; case 4: /* preprocess pilot */ seek(cout, HEADR+textsize, 0); break; } if(debug['v']) Bprint(&bso, "%5.2f datblk\n", cputime()); Bflush(&bso); for(v = 0; v < datsize; v += sizeof(buf)-100) { if(datsize-v > sizeof(buf)-100) datblk(v, sizeof(buf)-100); else datblk(v, datsize-v); } symsize = 0; spsize = 0; lcsize = 0; relocsize = 0; Bflush(&bso); switch(HEADTYPE) { default: seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0); break; case 1: /* plan9 boot data goes into text */ seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0); break; case 2: /* plan 9 */ seek(cout, HEADR+textsize+datsize, 0); break; case 3: /* next boot */ seek(cout, HEADR+rnd(textsize, INITRND)+datsize, 0); break; case 4: /* preprocess pilot */ seek(cout, HEADR+textsize+datsize, 0); break; } if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); asmsym(); } Bflush(&bso); if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); asmsp(); } Bflush(&bso); if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f pc\n", cputime()); asmlc(); } Bflush(&bso); if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f reloc\n", cputime()); asmreloc(); } cflush(); if(debug['v']) Bprint(&bso, "%5.2f headr\n", cputime()); Bflush(&bso); seek(cout, 0L, 0); switch(HEADTYPE) { default: lput(0x160L<<16); /* magic and sections */ lput(0L); /* time and date */ lput(rnd(HEADR+textsize, 4096)+datsize); lput(symsize); /* nsyms */ lput((0x38L<<16)|7L); /* size of optional hdr and flags */ lput((0413<<16)|0437L); /* magic and version */ lput(rnd(HEADR+textsize, 4096)); /* sizes */ lput(datsize); lput(bsssize); lput(entryvalue()); /* va of entry */ lput(INITTEXT-HEADR); /* va of base of text */ lput(INITDAT); /* va of base of data */ lput(INITDAT+datsize); /* va of base of bss */ lput(~0L); /* gp reg mask */ lput(0L); lput(0L); lput(0L); lput(0L); lput(~0L); /* gp value ?? */ break; case 1: /* plan9 boot data goes into text */ lput(0407); /* magic */ lput(rnd(HEADR+textsize, INITRND)-HEADR+datsize); /* sizes */ lput(0); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(spsize); /* sp offsets */ lput(lcsize); /* line offsets */ break; case 2: /* plan 9 */ lput(0407); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(spsize); /* sp offsets */ lput(lcsize); /* line offsets */ break; case 3: /* next boot */ /* header */ lput(0xfeedfaceL); /* magic */ lput(6); /* 68040 */ lput(1); /* more 68040 */ lput(5); /* file type 'boot' */ lput(HEADTYPE); /* number commands */ lput(HEADR-7*4); /* sizeof commands */ lput(1); /* no undefineds */ /* command 1 text */ lput(1); /* command = 'segment' */ lput(124); /* command size */ s16put("__TEXT"); /* botch?? entryvalue() */ lput(INITTEXT); /* va of start */ lput(rnd(textsize, 8192)); /* va size */ lput(HEADR); /* file offset */ lput(rnd(textsize, 8192)); /* file size */ lput(7); /* max prot */ lput(7); /* init prot */ lput(1); /* number of sections */ lput(0); /* flags */ /* text section */ s16put("__text"); s16put("__TEXT"); /* botch?? entryvalue() */ lput(INITTEXT); /* va of start */ lput(textsize); /* va size */ lput(HEADR); /* file offset */ lput(2); /* align */ lput(0); /* reloff */ lput(0); /* nreloc */ lput(0); /* flags */ lput(0); /* reserved1 */ lput(0); /* reserved2 */ /* command 1 data */ lput(1); /* command = 'segment' */ lput(192); /* command size */ s16put("__DATA"); lput(INITDAT); /* va of start */ lput(rnd(datsize, 8192)); /* va size */ lput(HEADR+rnd(textsize, 8192)); /* file offset */ lput(rnd(datsize, 8192)); /* file size */ lput(7); /* max prot */ lput(7); /* init prot */ lput(2); /* number of sections */ lput(0); /* flags */ /* data section */ s16put("__data"); s16put("__DATA"); lput(INITDAT); /* va of start */ lput(datsize); /* va size */ lput(HEADR+rnd(textsize, 8192)); /* file offset */ lput(2); /* align */ lput(0); /* reloff */ lput(0); /* nreloc */ lput(0); /* flags */ lput(0); /* reserved1 */ lput(0); /* reserved2 */ /* bss section */ s16put("__bss"); s16put("__DATA"); lput(INITDAT+datsize); /* va of start */ lput(bsssize); /* va size */ lput(0); /* file offset */ lput(2); /* align */ lput(0); /* reloff */ lput(0); /* nreloc */ lput(1); /* flags = zero fill */ lput(0); /* reserved1 */ lput(0); /* reserved2 */ /* command 2 symbol */ lput(2); /* command = 'symbol' */ lput(24); /* command size */ lput(HEADR+rnd(textsize, INITRND) +datsize); /* symoff */ lput(symsize); /* nsyms */ lput(spsize); /* sp offsets */ lput(lcsize); /* line offsets */ break; case 4: /* preprocess pilot */ lput(0407); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(spsize); /* sp offsets */ lput(lcsize); /* line offsets */ lput(relocsize); /* relocation */ break; } cflush(); }
void asmb(void) { Prog *p; long t; Optab *o; long prevpc; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); /* emit text segment */ seek(cout, HEADR, 0); prevpc = pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; if(p->from3.type == D_CONST) { for(; pc < p->pc; pc++) CPUT(0); } } if(p->pc != pc) { diag("phase error %lux sb %lux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ if(asmout(p, o, 0)) { p = p->link; pc += 4; } pc += o->size; if (prevpc & (1<<31) && (pc & (1<<31)) == 0) { char *tn; tn = "?none?"; if(curtext != P && curtext->from.sym != S) tn = curtext->from.sym->name; Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn); } prevpc = pc; } /* for virtex 4, inject a jmp instruction after other text */ if(HEADTYPE == 6) /* branch to absolute entry address (0xfffe2100) */ lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2); if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); /* emit data segment */ curtext = P; switch(HEADTYPE) { case 6: textsize += JMPSZ; /* fall through */ case 0: case 1: case 2: case 5: seek(cout, HEADR+textsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4), 0); break; case 4: seek(cout, rnd(HEADR+textsize, 4096), 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100); else datblk(t, datsize-t); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 1: case 2: case 5: case 6: seek(cout, HEADR+textsize+datsize, 0); break; case 3: seek(cout, rnd(HEADR+textsize, 4)+datsize, 0); break; case 4: seek(cout, rnd(HEADR+textsize, 4096)+datsize, 0); break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(dlm) asmdyn(); if(HEADTYPE == 0 || HEADTYPE == 1) /* round up file length for boot image */ if((symsize+lcsize) & 1) CPUT(0); cflush(); } else if(dlm){ asmdyn(); cflush(); } /* back up and write the header */ seek(cout, 0L, 0); switch(HEADTYPE) { case 0: lput(0x1030107); /* magic and sections */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 1: lput(0x4a6f7921); /* Joy! */ lput(0x70656666); /* peff */ lput(0x70777063); /* pwpc */ lput(1); lput(0); lput(0); lput(0); lput(0); lput(0x30002); /*YY*/ lput(0); lput(~0); lput(0); lput(textsize+datsize); lput(textsize+datsize); lput(textsize+datsize); lput(0xd0); /* header size */ lput(0x10400); lput(~0); lput(0); lput(0xc); lput(0xc); lput(0xc); lput(0xc0); lput(0x01010400); lput(~0); lput(0); lput(0x38); lput(0x38); lput(0x38); lput(0x80); lput(0x04040400); lput(0); lput(1); lput(0); lput(~0); lput(0); lput(~0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0); lput(0x3100); /* load address */ lput(0); lput(0); lput(0); /* whew! */ break; case 2: if(dlm) lput(0x80000000 | (4*21*21+7)); /* magic */ else lput(4*21*21+7); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 3: break; case 4: lput((0x1DFL<<16)|3L); /* magic and sections */ lput(time(0)); /* time and date */ lput(rnd(HEADR+textsize, 4096)+datsize); lput(symsize); /* nsyms */ lput((0x48L<<16)|15L); /* size of optional hdr and flags */ lput((0413<<16)|01L); /* magic and version */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(entryvalue()); /* va of entry */ lput(INITTEXT); /* va of base of text */ lput(INITDAT); /* va of base of data */ lput(INITDAT); /* address of TOC */ lput((1L<<16)|1); /* sn(entry) | sn(text) */ lput((2L<<16)|1); /* sn(data) | sn(toc) */ lput((0L<<16)|3); /* sn(loader) | sn(bss) */ lput((3L<<16)|3); /* maxalign(text) | maxalign(data) */ lput(('1'<<24)|('L'<<16)|0); /* type field, and reserved */ lput(0); /* max stack allowed */ lput(0); /* max data allowed */ lput(0); lput(0); lput(0); /* reserved */ strnput(".text", 8); /* text segment */ lput(INITTEXT); /* address */ lput(INITTEXT); lput(textsize); lput(HEADR); lput(0L); lput(HEADR+textsize+datsize+symsize); lput(lcsize); /* line number size */ lput(0x20L); /* flags */ strnput(".data", 8); /* data segment */ lput(INITDAT); /* address */ lput(INITDAT); lput(datsize); lput(rnd(HEADR+textsize, 4096));/* sizes */ lput(0L); lput(0L); lput(0L); lput(0x40L); /* flags */ strnput(".bss", 8); /* bss segment */ lput(INITDAT+datsize); /* address */ lput(INITDAT+datsize); lput(bsssize); lput(0L); lput(0L); lput(0L); lput(0L); lput(0x80L); /* flags */ break; case 5: /* * customised for blue/gene, * notably the alignment and KMASK masking. */ strnput("\177ELF", 4); /* e_ident */ CPUT(1); /* class = 32 bit */ CPUT(2); /* data = MSB */ CPUT(1); /* version = CURRENT */ strnput("", 9); lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */ lput(1L); /* version = CURRENT */ lput(entryvalue() & ~KMASK); /* entry vaddr */ lput(52L); /* offset to first phdr */ if(debug['S']){ lput(HEADR+textsize+datsize+symsize); /* offset to first shdr */ lput(0L); /* flags = PPC */ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ lput((3L<<16)|40L); /* # Phdrs & Shdr size */ lput((3L<<16)|2L); /* # Shdrs & shdr string size */ } else{ lput(0L); lput(0L); /* flags = PPC */ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ lput((3L<<16)|0L); /* # Phdrs & Shdr size */ lput((3L<<16)|0L); /* # Shdrs & shdr string size */ } lput(1L); /* text - type = PT_LOAD */ lput(HEADR); /* file offset */ lput(INITTEXT & ~KMASK); /* vaddr */ lput(INITTEXT); /* paddr */ lput(textsize); /* file size */ lput(textsize); /* memory size */ lput(0x05L); /* protections = RX */ lput(0x10000L); /* alignment */ lput(1L); /* data - type = PT_LOAD */ lput(HEADR+textsize); /* file offset */ lput(INITDAT & ~KMASK); /* vaddr */ lput(INITDAT); /* paddr */ lput(datsize); /* file size */ lput(datsize); /* memory size */ lput(0x07L); /* protections = RWX */ lput(0x10000L); /* alignment */ lput(0L); /* data - type = PT_NULL */ lput(HEADR+textsize+datsize); /* file offset */ lput(0L); /* vaddr */ lput(0L); /* paddr */ lput(symsize); /* symbol table size */ lput(lcsize); /* line number size */ lput(0x04L); /* protections = R */ lput(0x04L); /* alignment code?? */ cflush(); if(!debug['S']) break; seek(cout, HEADR+textsize+datsize+symsize, 0); lput(1); /* Section name (string tbl index) */ lput(1); /* Section type */ lput(2|4); /* Section flags */ lput(INITTEXT & ~KMASK); /* Section virtual addr at execution */ lput(HEADR); /* Section file offset */ lput(textsize); /* Section size in bytes */ lput(0); /* Link to another section */ lput(0); /* Additional section information */ lput(0x10000L); /* Section alignment */ lput(0); /* Entry size if section holds table */ lput(7); /* Section name (string tbl index) */ lput(1); /* Section type */ lput(2|1); /* Section flags */ lput(INITDAT & ~KMASK); /* Section virtual addr at execution */ lput(HEADR+textsize); /* Section file offset */ lput(datsize); /* Section size in bytes */ lput(0); /* Link to another section */ lput(0); /* Additional section information */ lput(0x10000L); /* Section alignment */ lput(0); /* Entry size if section holds table */ /* string section header */ lput(12); /* Section name (string tbl index) */ lput(3); /* Section type */ lput(1 << 5); /* Section flags */ lput(0); /* Section virtual addr at execution */ lput(HEADR+textsize+datsize+symsize+3*40); /* Section file offset */ lput(14); /* Section size in bytes */ lput(0); /* Link to another section */ lput(0); /* Additional section information */ lput(1); /* Section alignment */ lput(0); /* Entry size if section holds table */ /* string table */ cput(0); strnput(".text", 5); cput(0); strnput(".data", 5); cput(0); strnput(".strtab", 7); cput(0); cput(0); break; case 6: /* * customised for virtex 4 boot, * notably the alignment and KMASK masking. */ strnput("\177ELF", 4); /* e_ident */ CPUT(1); /* class = 32 bit */ CPUT(2); /* data = MSB */ CPUT(1); /* version = CURRENT */ strnput("", 9); lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */ lput(1L); /* version = CURRENT */ lput(entryvalue()); /* entry vaddr */ lput(52L); /* offset to first phdr */ debug['S'] = 1; /* no symbol table */ if(debug['S']){ lput(HEADR+textsize+datsize+symsize); /* offset to first shdr */ lput(0L); /* flags = PPC */ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ lput((4L<<16)|40L); /* # Phdrs & Shdr size */ lput((4L<<16)|2L); /* # Shdrs & shdr string size */ } else{ lput(0L); lput(0L); /* flags = PPC */ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/ lput((4L<<16)|0L); /* # Phdrs & Shdr size */ lput((4L<<16)|0L); /* # Shdrs & shdr string size */ } lput(1L); /* text - type = PT_LOAD */ lput(HEADR); /* file offset */ lput(INITTEXT); /* vaddr */ lput(INITTEXT); /* paddr */ lput(textsize-JMPSZ); /* file size */ lput(textsize-JMPSZ); /* memory size */ lput(0x05L); /* protections = RX */ lput(0); /* alignment */ lput(1L); /* data - type = PT_LOAD */ lput(HEADR+textsize); /* file offset */ lput(INITDAT); /* vaddr */ lput(INITDAT); /* paddr */ lput(datsize); /* file size */ lput(datsize+bsssize); /* memory size */ lput(0x07L); /* protections = RWX */ lput(0); /* alignment */ lput(0L); /* data - type = PT_NULL */ lput(HEADR+textsize+datsize); /* file offset */ lput(0L); /* vaddr */ lput(0L); /* paddr */ lput(symsize); /* symbol table size */ lput(lcsize); /* line number size */ lput(0x04L); /* protections = R */ lput(0x04L); /* alignment code?? */ /* add tiny text section at end with jmp to start */ lput(1L); /* text - type = PT_LOAD */ lput(HEADR+textsize-JMPSZ); /* file offset */ lput(0xFFFFFFFC); /* vaddr */ lput(0xFFFFFFFC); /* paddr */ lput(JMPSZ); /* file size */ lput(JMPSZ); /* memory size */ lput(0x05L); /* protections = RX */ lput(0); /* disable alignment */ cflush(); break; } cflush(); }
void asmb(void) { Prog *p; int32 t, etext; int np; vlong va, fo, w, symo; int strtabsize; vlong symdatva = 0x99LL<<24; Optab *o; strtabsize = 0; symo = 0; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); OFFSET = HEADR; seek(cout, OFFSET, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { setarch(p); if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + 4; } if(p->pc != pc) { diag("phase error %lux sb %lux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ if(thumb) thumbasmout(p, o); else asmout(p, o); pc += o->size; } while(pc-INITTEXT < textsize) { cput(0); pc++; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); /* output strings in text segment */ etext = INITTEXT + textsize; for(t = pc; t < etext; t += sizeof(buf)-100) { if(etext-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100, 1); else datblk(t, etext-t, 1); } /* output section header strings */ curtext = P; switch(HEADTYPE) { case 0: case 1: case 2: case 5: OFFSET = HEADR+textsize; seek(cout, OFFSET, 0); break; case 3: OFFSET = rnd(HEADR+textsize, 4096); seek(cout, OFFSET, 0); break; case 6: seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0); strtabsize = linuxstrtable(); cflush(); t = rnd(HEADR+textsize, INITRND); seek(cout, t, 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100, 0); else datblk(t, datsize-t, 0); } cflush(); /* output symbol table */ symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: case 1: case 4: case 5: debug['s'] = 1; break; case 2: OFFSET = HEADR+textsize+datsize; seek(cout, OFFSET, 0); break; case 3: OFFSET += rnd(datsize, 4096); seek(cout, OFFSET, 0); break; case 6: symo = rnd(HEADR+textsize, INITRND)+datsize+strtabsize; symo = rnd(symo, INITRND); seek(cout, symo + 8, 0); break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f pc\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(!debug['s']) asmthumbmap(); if(dlm) asmdyn(); cflush(); } else if(dlm){ seek(cout, HEADR+textsize+datsize, 0); asmdyn(); cflush(); } curtext = P; if(debug['v']) Bprint(&bso, "%5.2f header\n", cputime()); Bflush(&bso); OFFSET = 0; seek(cout, OFFSET, 0); switch(HEADTYPE) { case 0: /* no header */ break; case 1: /* aif for risc os */ lputl(0xe1a00000); /* NOP - decompress code */ lputl(0xe1a00000); /* NOP - relocation code */ lputl(0xeb000000 + 12); /* BL - zero init code */ lputl(0xeb000000 + (entryvalue() - INITTEXT + HEADR - 12 - 8) / 4); /* BL - entry code */ lputl(0xef000011); /* SWI - exit code */ lputl(textsize+HEADR); /* text size */ lputl(datsize); /* data size */ lputl(0); /* sym size */ lputl(bsssize); /* bss size */ lputl(0); /* sym type */ lputl(INITTEXT-HEADR); /* text addr */ lputl(0); /* workspace - ignored */ lputl(32); /* addr mode / data addr flag */ lputl(0); /* data addr */ for(t=0; t<2; t++) lputl(0); /* reserved */ for(t=0; t<15; t++) lputl(0xe1a00000); /* NOP - zero init code */ lputl(0xe1a0f00e); /* B (R14) - zero init return */ break; case 2: /* plan 9 */ if(dlm) lput(0x80000000|0x647); /* magic */ else lput(0x647); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(0L); lput(lcsize); break; case 3: /* boot for NetBSD */ lput((143<<16)|0413); /* magic */ lputl(rnd(HEADR+textsize, 4096)); lputl(rnd(datsize, 4096)); lputl(bsssize); lputl(symsize); /* nsyms */ lputl(entryvalue()); /* va of entry */ lputl(0L); lputl(0L); break; case 4: /* boot for IXP1200 */ break; case 5: /* boot for ipaq */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ lputl(0xe3300000); /* nop */ break; case 6: /* elf arm */ strnput("\177ELF", 4); /* e_ident */ cput(1); /* class = 32 bit */ cput(1); /* data = LSB */ cput(1); /* version = CURRENT */ strnput("", 9); wputl(2); /* type = EXEC */ wputl(40); /* machine = ARM */ lputl(1L); /* version = CURRENT */ lputl(entryvalue()); /* entry vaddr */ lputl(52L); /* offset to first phdr */ np = 3; if(!debug['s']) np++; lputl(52L+32*np); /* offset to first shdr */ lputl(0L); /* processor specific flags */ wputl(52); /* Ehdr size */ wputl(32); /* Phdr size */ wputl(np); /* # of Phdrs */ wputl(40); /* Shdr size */ if (!debug['s']) wputl(7); /* # of Shdrs */ else wputl(5); /* # of Shdrs */ wputl(4); /* Shdr with strings */ fo = 0; va = INITTEXT & ~((vlong)INITRND - 1); w = HEADR+textsize; linuxphdr(1, /* text - type = PT_LOAD */ 1L+4L, /* text - flags = PF_X+PF_R */ 0, /* file offset */ va, /* vaddr */ va, /* paddr */ w, /* file size */ w, /* memory size */ INITRND); /* alignment */ fo = rnd(fo+w, INITRND); va = rnd(va+w, INITRND); w = datsize; linuxphdr(1, /* data - type = PT_LOAD */ 2L+4L, /* data - flags = PF_W+PF_R */ fo, /* file offset */ va, /* vaddr */ va, /* paddr */ w, /* file size */ w+bsssize, /* memory size */ INITRND); /* alignment */ if(!debug['s']) { linuxphdr(1, /* data - type = PT_LOAD */ 2L+4L, /* data - flags = PF_W+PF_R */ symo, /* file offset */ symdatva, /* vaddr */ symdatva, /* paddr */ 8+symsize+lcsize, /* file size */ 8+symsize+lcsize, /* memory size */ INITRND); /* alignment */ } linuxphdr(0x6474e551, /* gok - type = gok */ 1L+2L+4L, /* gok - flags = PF_X+PF_W+PF_R */ 0, /* file offset */ 0, /* vaddr */ 0, /* paddr */ 0, /* file size */ 0, /* memory size */ 8); /* alignment */ linuxshdr(nil, /* name */ 0, /* type */ 0, /* flags */ 0, /* addr */ 0, /* off */ 0, /* size */ 0, /* link */ 0, /* info */ 0, /* align */ 0); /* entsize */ stroffset = 1; /* 0 means no name, so start at 1 */ fo = HEADR; va = (INITTEXT & ~((vlong)INITRND - 1)) + HEADR; w = textsize; linuxshdr(".text", /* name */ 1, /* type */ 6, /* flags */ va, /* addr */ fo, /* off */ w, /* size */ 0, /* link */ 0, /* info */ 8, /* align */ 0); /* entsize */ fo = rnd(fo+w, INITRND); va = rnd(va+w, INITRND); w = datsize; linuxshdr(".data", /* name */ 1, /* type */ 3, /* flags */ va, /* addr */ fo, /* off */ w, /* size */ 0, /* link */ 0, /* info */ 8, /* align */ 0); /* entsize */ fo += w; va += w; w = bsssize; linuxshdr(".bss", /* name */ 8, /* type */ 3, /* flags */ va, /* addr */ fo, /* off */ w, /* size */ 0, /* link */ 0, /* info */ 8, /* align */ 0); /* entsize */ w = strtabsize; linuxshdr(".shstrtab", /* name */ 3, /* type */ 0, /* flags */ 0, /* addr */ fo, /* off */ w, /* size */ 0, /* link */ 0, /* info */ 1, /* align */ 0); /* entsize */ if (debug['s']) break; fo = symo+8; w = symsize; linuxshdr(".gosymtab", /* name */ 1, /* type 1 = SHT_PROGBITS */ 0, /* flags */ 0, /* addr */ fo, /* off */ w, /* size */ 0, /* link */ 0, /* info */ 1, /* align */ 24); /* entsize */ fo += w; w = lcsize; linuxshdr(".gopclntab", /* name */ 1, /* type 1 = SHT_PROGBITS*/ 0, /* flags */ 0, /* addr */ fo, /* off */ w, /* size */ 0, /* link */ 0, /* info */ 1, /* align */ 24); /* entsize */ break; } cflush(); if(debug['c']){ print("textsize=%ld\n", textsize); print("datsize=%ld\n", datsize); print("bsssize=%ld\n", bsssize); print("symsize=%ld\n", symsize); print("lcsize=%ld\n", lcsize); print("total=%ld\n", textsize+datsize+bsssize+symsize+lcsize); } }
void asmb(void) { Prog *p; long magic, t, etext; vlong vl; Optab *o; if(debug['v']) Bprint(&bso, "%5.2f asm\n", cputime()); Bflush(&bso); OFFSET = HEADR; seek(cout, OFFSET, 0); pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; autosize = p->to.offset + PCSZ; } if(p->as == ADWORD && (pc & 7) != 0) { lputl(0); pc += 4; } if(p->pc != pc) { diag("phase error %llux sb %llux", p->pc, pc); if(!debug['a']) prasm(curp); pc = p->pc; } curp = p; o = oplook(p); /* could probably avoid this call */ asmout(p, o); pc += o->size; } if(debug['a']) Bprint(&bso, "\n"); Bflush(&bso); cflush(); /* output strings in text segment */ etext = INITTEXT + textsize; for(t = pc; t < etext; t += sizeof(buf)-100) { if(etext-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100, 1); else datblk(t, etext-t, 1); } curtext = P; switch(HEADTYPE) { case 0: case 2: case 7: OFFSET = HEADR+textsize; seek(cout, OFFSET, 0); break; case 6: /* no header, padded segments */ OFFSET = rnd(HEADR+textsize, 4096); seek(cout, OFFSET, 0); break; } if(dlm){ char buf[8]; write(cout, buf, INITDAT-textsize); textsize = INITDAT; } for(t = 0; t < datsize; t += sizeof(buf)-100) { if(datsize-t > sizeof(buf)-100) datblk(t, sizeof(buf)-100, 0); else datblk(t, datsize-t, 0); } symsize = 0; lcsize = 0; if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); Bflush(&bso); switch(HEADTYPE) { case 0: debug['s'] = 1; break; case 2: OFFSET = HEADR+textsize+datsize; seek(cout, OFFSET, 0); break; case 6: /* no header, padded segments */ OFFSET += rnd(datsize, 4096); seek(cout, OFFSET, 0); break; case 7: break; } if(!debug['s']) asmsym(); if(debug['v']) Bprint(&bso, "%5.2f pc\n", cputime()); Bflush(&bso); if(!debug['s']) asmlc(); if(dlm) asmdyn(); cflush(); } else if(dlm){ seek(cout, HEADR+textsize+datsize, 0); asmdyn(); cflush(); } if(debug['v']) Bprint(&bso, "%5.2f header\n", cputime()); Bflush(&bso); OFFSET = 0; seek(cout, OFFSET, 0); switch(HEADTYPE) { case 0: /* no header */ case 6: /* no header, padded segments */ break; case 2: /* plan 9 */ magic = 4*28*28+7; magic |= 0x00008000; /* fat header */ if(dlm) magic |= 0x80000000; /* dlm */ lput(magic); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ vl = entryvalue(); lput(PADDR(vl)); /* va of entry */ lput(0L); lput(lcsize); llput(vl); /* va of entry */ break; case 7: /* elf */ debug['S'] = 1; /* symbol table */ elf64(ARM64, ELFDATA2LSB, 0, nil); break; } cflush(); }