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, 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(); }