diff options
Diffstat (limited to 'utils/ql/asm.c')
| -rw-r--r-- | utils/ql/asm.c | 104 |
1 files changed, 101 insertions, 3 deletions
diff --git a/utils/ql/asm.c b/utils/ql/asm.c index 25d4c772..be1a57a1 100644 --- a/utils/ql/asm.c +++ b/utils/ql/asm.c @@ -1,6 +1,7 @@ #include "l.h" #define KMASK 0xF0000000 +#define JMPSZ sizeof(u32int) /* size of bootstrap jump section */ #define LPUT(c)\ {\ @@ -50,12 +51,15 @@ 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); - pc = INITTEXT; + prevpc = pc = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; @@ -79,14 +83,32 @@ asmb(void) 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: @@ -126,6 +148,7 @@ asmb(void) case 1: case 2: case 5: + case 6: seek(cout, HEADR+textsize+datsize, 0); break; case 3: @@ -154,6 +177,7 @@ asmb(void) cflush(); } + /* back up and write the header */ seek(cout, 0L, 0); switch(HEADTYPE) { case 0: @@ -290,6 +314,10 @@ asmb(void) 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 */ @@ -335,8 +363,8 @@ asmb(void) lput(0L); /* data - type = PT_NULL */ lput(HEADR+textsize+datsize); /* file offset */ - lput(0L); - lput(0L); + lput(0L); /* vaddr */ + lput(0L); /* paddr */ lput(symsize); /* symbol table size */ lput(lcsize); /* line number size */ lput(0x04L); /* protections = R */ @@ -392,6 +420,76 @@ asmb(void) 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(); } |
