diff options
| author | forsyth <forsyth@vitanuova.com> | 2010-04-27 21:20:56 +0100 |
|---|---|---|
| committer | forsyth <forsyth@vitanuova.com> | 2010-04-27 21:20:56 +0100 |
| commit | 4206ee1aeaccb7703f3f3613a98a5447f51d6367 (patch) | |
| tree | a998be4d94c2860775413dbbba21000819ea496e | |
| parent | c0927006217e7a7e0214add5828659287c7498d6 (diff) | |
20100427-2120
| -rw-r--r-- | utils/kl/l.h | 4 | ||||
| -rw-r--r-- | utils/vl/asm.c | 186 | ||||
| -rw-r--r-- | utils/vl/l.h | 4 | ||||
| -rw-r--r-- | utils/vl/obj.c | 105 | ||||
| -rw-r--r-- | utils/vl/pass.c | 2 |
5 files changed, 228 insertions, 73 deletions
diff --git a/utils/kl/l.h b/utils/kl/l.h index 21ca6294..c036e14d 100644 --- a/utils/kl/l.h +++ b/utils/kl/l.h @@ -1,4 +1,3 @@ -/* #include <u.h> */ #include <lib9.h> #include <bio.h> #include "../kc/k.out.h" @@ -250,11 +249,14 @@ extern Optab optab[]; extern char* anames[]; #pragma varargck type "A" int +#pragma varargck type "A" uint #pragma varargck type "D" Adr* #pragma varargck type "N" Adr* #pragma varargck type "P" Prog* #pragma varargck type "S" char* +#pragma varargck argpos diag 1 + int Aconv(Fmt*); int Dconv(Fmt*); int Nconv(Fmt*); diff --git a/utils/vl/asm.c b/utils/vl/asm.c index 28ec1a89..1e7039f1 100644 --- a/utils/vl/asm.c +++ b/utils/vl/asm.c @@ -13,7 +13,27 @@ long BADOFFSET = -1; OFFSET++;\ */ -#define LPUT(c)\ +#define LPUT(l) { \ + if (little) { \ + LLEPUT(l); \ + } else { \ + LBEPUT(l); \ + } \ + } + +#define LLEPUT(c)\ + {\ + cbp[0] = (c);\ + cbp[1] = (c)>>8;\ + cbp[2] = (c)>>16;\ + cbp[3] = (c)>>24;\ + cbp += 4;\ + cbc -= 4;\ + if(cbc <= 0)\ + cflush();\ + } + +#define LBEPUT(c)\ {\ cbp[0] = (c)>>24;\ cbp[1] = (c)>>16;\ @@ -25,6 +45,35 @@ long BADOFFSET = -1; cflush();\ } +#define HPUT(h) { \ + if (little) { \ + HLEPUT(h); \ + } else { \ + HBEPUT(h); \ + } \ + } + +#define HLEPUT(c)\ + {\ + cbp[0] = (c);\ + cbp[1] = (c)>>8;\ + cbp += 2;\ + cbc -= 2;\ + if(cbc <= 0)\ + cflush();\ + } + +#define HBEPUT(c)\ + {\ + cbp[0] = (c)>>8;\ + cbp[1] = (c);\ + cbp += 2;\ + cbc -= 2;\ + if(cbc <= 0)\ + cflush();\ + } + + #define CPUT(c)\ {\ cbp[0] = (c);\ @@ -34,6 +83,24 @@ long BADOFFSET = -1; cflush();\ } +void +objput(long l) /* emit long in byte order appropriate to object machine */ +{ + LPUT(l); +} + +void +objhput(short s) +{ + HPUT(s); +} + +void +lput(long l) /* emit long in big-endian byte order */ +{ + LBEPUT(l); +} + long entryvalue(void) { @@ -111,6 +178,7 @@ asmb(void) case 2: case 3: case 5: + case 6: OFFSET = HEADR+textsize; seek(cout, OFFSET, 0); break; @@ -138,6 +206,7 @@ asmb(void) case 2: case 1: case 5: + case 6: OFFSET = HEADR+textsize+datsize; seek(cout, OFFSET, 0); break; @@ -203,7 +272,11 @@ asmb(void) lput(0L); /* complete mystery */ break; case 2: - lput(0x407); /* magic */ + if (little) + t = 24; + else + t = 16; + lput(((((4*t)+0)*t)+7)); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); @@ -318,47 +391,67 @@ asmb(void) lput(0x80L); /* flags */ break; case 5: + /* first part of ELF is byte-wide parts, thus no byte-order issues */ strnput("\177ELF", 4); /* e_ident */ CPUT(1); /* class = 32 bit */ - CPUT(2); /* data = MSB */ - CPUT(1); /* version = CURRENT */ - strnput("", 9); - lput((2L<<16)|8L); /* type = EXEC; machine = MIPS */ - lput(1L); /* version = CURRENT */ - lput(entryvalue()); /* entry vaddr */ - lput(52L); /* offset to first phdr */ - lput(0L); /* offset to first shdr */ - lput(0L); /* flags = MIPS */ - 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(0L); /* file offset */ - lput(INITTEXT-HEADR); /* vaddr */ - lput(INITTEXT-HEADR); /* paddr */ - lput(HEADR+textsize); /* file size */ - lput(HEADR+textsize); /* memory size */ - lput(0x05L); /* protections = RX */ - lput(0x10000L); /* alignment code?? */ - - 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(0x06L); /* protections = RW */ - lput(0x10000L); /* alignment code?? */ - - 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?? */ + CPUT(little? 1: 2); /* data: 1 = LSB, 2 = MSB */ + CPUT(1); /* version = 1 */ + strnput("", 9); /* reserved for expansion */ + /* entire remainder of ELF file is in target byte order */ + + /* file header part of ELF header */ + objhput(2); /* type = EXEC */ + objhput(8); /* machine = MIPS */ + objput(1L); /* version = CURRENT */ + objput(entryvalue()); /* entry vaddr */ + objput(52L); /* offset to first phdr */ + objput(0L); /* offset to first shdr */ + objput(0L); /* flags (no MIPS flags defined) */ + objhput(52); /* Ehdr size */ + objhput(32); /* Phdr size */ + objhput(3); /* # of Phdrs */ + objhput(0); /* Shdr size */ + objhput(0); /* # of Shdrs */ + objhput(0); /* Shdr string size */ + + /* "Program headers" - one per chunk of file to load */ + + /* + * include ELF headers in text -- 8l doesn't, + * but in theory it aids demand loading. + */ + objput(1L); /* text: type = PT_LOAD */ + objput(0L); /* file offset */ + objput(INITTEXT-HEADR); /* vaddr */ + objput(INITTEXT-HEADR); /* paddr */ + objput(HEADR+textsize); /* file size */ + objput(HEADR+textsize); /* memory size */ + objput(0x05L); /* protections = RX */ + objput(0x1000L); /* page-align text off's & vaddrs */ + + objput(1L); /* data: type = PT_LOAD */ + objput(HEADR+textsize); /* file offset */ + objput(INITDAT); /* vaddr */ + objput(INITDAT); /* paddr */ + objput(datsize); /* file size */ + objput(datsize+bsssize); /* memory size */ + objput(0x06L); /* protections = RW */ + if(INITDAT % 4096 == 0 && (HEADR + textsize) % 4096 == 0) + objput(0x1000L); /* page-align data off's & vaddrs */ + else + objput(0L); /* do not claim alignment */ + + objput(0L); /* P9 symbols: type = PT_NULL */ + objput(HEADR+textsize+datsize); /* file offset */ + objput(0L); + objput(0L); + objput(symsize); /* symbol table size */ + objput(lcsize); /* line number size */ + objput(0x04L); /* protections = R */ + objput(0L); /* do not claim alignment */ + break; + case 6: + break; } cflush(); } @@ -375,13 +468,6 @@ strnput(char *s, int n) } void -lput(long l) -{ - - LPUT(l); -} - -void cflush(void) { int n; @@ -477,7 +563,7 @@ putsymb(char *s, int t, long v, int ver) if(t == 'f') s++; - LPUT(v); + LBEPUT(v); if(ver) t += 'a' - 'A'; CPUT(t+0x80); /* 0x80 is variable length */ @@ -820,7 +906,7 @@ asmout(Prog *p, Optab *o, int aflag) else v = (p->cond->pc - pc-4) >> 2; if(((v << 16) >> 16) != v) - diag("short branch too far: %d\n%P", v, p); + diag("short branch too far: %ld\n%P", v, p); o1 = OP_IRR(opirr(p->as), v, p->from.reg, p->reg); break; diff --git a/utils/vl/l.h b/utils/vl/l.h index 1cac8768..75243ad8 100644 --- a/utils/vl/l.h +++ b/utils/vl/l.h @@ -236,6 +236,7 @@ EXTERN int version; EXTERN char xcmp[32][32]; EXTERN Prog zprg; EXTERN int dtype; +EXTERN int little; EXTERN struct { @@ -256,6 +257,8 @@ extern Optab optab[]; #pragma varargck type "P" Prog* #pragma varargck type "S" char* +#pragma varargck argpos diag 1 + int Aconv(Fmt*); int Dconv(Fmt*); int Nconv(Fmt*); @@ -297,6 +300,7 @@ void loadlib(void); void listinit(void); Sym* lookup(char*, int); void lput(long); +void bput(long); void mkfwd(void); void* mysbrk(ulong); void names(void); diff --git a/utils/vl/obj.c b/utils/vl/obj.c index 4c9cafb7..8289c588 100644 --- a/utils/vl/obj.c +++ b/utils/vl/obj.c @@ -18,8 +18,11 @@ char *thestring = "mips"; * -H3 -T0x80020000 -R8 is bootp() format for 4k * -H4 -T0x400000 -R4 is sgi unix coff executable * -H5 -T0x4000A0 -R4 is sgi unix elf executable + * -H6 is headerless */ +int little; + void main(int argc, char *argv[]) { @@ -52,6 +55,11 @@ main(int argc, char *argv[]) if(a) INITENTRY = a; break; + case 'L': /* for little-endian mips */ + thechar = '0'; + thestring = "spim"; + little = 1; + break; case 'T': a = ARGF(); if(a) @@ -78,7 +86,7 @@ main(int argc, char *argv[]) USED(argc); if(*argv == 0) { - diag("usage: vl [-options] objects"); + diag("usage: %cl [-options] objects", thechar); errorexit(); } if(!debug['9'] && !debug['U'] && !debug['B']) @@ -150,6 +158,15 @@ main(int argc, char *argv[]) if(INITRND == -1) INITRND = 0; break; + case 6: /* headerless */ + HEADR = 0; + if(INITTEXT == -1) + INITTEXT = 0x80000000L+HEADR; + if(INITDAT == -1) + INITDAT = 0; + if(INITRND == -1) + INITRND = 4096; + break; } if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%lux is ignored because of -R0x%lux\n", @@ -170,8 +187,12 @@ main(int argc, char *argv[]) datap = P; pc = 0; dtype = 4; - if(outfile == 0) - outfile = "v.out"; + if(outfile == 0) { + static char name[20]; + + snprint(name, sizeof name, "%c.out", thechar); + outfile = name; + } cout = create(outfile, 1, 0775); if(cout < 0) { diag("%s: cannot create", outfile); @@ -677,7 +698,7 @@ loop: o = bloc[0]; /* as */ if(o <= AXXX || o >= ALAST) { diag("%s: line %ld: opcode out of range %d", pn, pc-ipc, o); - print(" probably not a .v file\n"); + print(" probably not a .%c file\n", thechar); errorexit(); } if(o == ANAME || o == ASIGNAME) { @@ -1150,15 +1171,24 @@ void doprof2(void) { Sym *s2, *s4; - Prog *p, *q, *ps2, *ps4; + Prog *p, *q, *q2, *ps2, *ps4; if(debug['v']) Bprint(&bso, "%5.2f profile 2\n", cputime()); Bflush(&bso); - s2 = lookup("_profin", 0); - s4 = lookup("_profout", 0); + + if(debug['e']){ + s2 = lookup("_tracein", 0); + s4 = lookup("_traceout", 0); + }else{ + s2 = lookup("_profin", 0); + s4 = lookup("_profout", 0); + } if(s2->type != STEXT || s4->type != STEXT) { - diag("_profin/_profout not defined"); + if(debug['e']) + diag("_tracein/_traceout not defined %d %d", s2->type, s4->type); + else + diag("_profin/_profout not defined"); return; } @@ -1197,7 +1227,20 @@ doprof2(void) q->line = p->line; q->pc = p->pc; q->link = p->link; - p->link = q; + if(debug['e']){ /* embedded tracing */ + q2 = prg(); + p->link = q2; + q2->link = q; + + q2->line = p->line; + q2->pc = p->pc; + + q2->as = AJMP; + q2->to.type = D_BRANCH; + q2->to.sym = p->to.sym; + q2->cond = q->link; + }else + p->link = q; p = q; p->as = AJAL; p->to.type = D_BRANCH; @@ -1208,6 +1251,17 @@ doprof2(void) } if(p->as == ARET) { /* + * RET (default) + */ + if(debug['e']){ /* embedded tracing */ + q = prg(); + q->line = p->line; + q->pc = p->pc; + q->link = p->link; + p->link = q; + p = q; + } + /* * RET */ q = prg(); @@ -1239,17 +1293,27 @@ nuxiinit(void) { int i, c; - for(i=0; i<4; i++) { - c = find1(0x01020304L, i+1); - if(i >= 2) - inuxi2[i-2] = c; - if(i >= 3) - inuxi1[i-3] = c; - inuxi4[i] = c; - - fnuxi8[i] = c+4; - fnuxi8[i+4] = c; - } + for(i=0; i<4; i++) + if (!little) { /* normal big-endian case */ + c = find1(0x01020304L, i+1); + if(i >= 2) + inuxi2[i-2] = c; + if(i >= 3) + inuxi1[i-3] = c; + inuxi4[i] = c; + fnuxi8[i] = c+4; + fnuxi8[i+4] = c; + } else { /* oddball little-endian case */ + c = find1(0x04030201L, i+1); + if(i < 2) + inuxi2[i] = c; + if(i < 1) + inuxi1[i] = c; + inuxi4[i] = c; + fnuxi4[i] = c; + fnuxi8[i] = c; + fnuxi8[i+4] = c+4; + } if(debug['v']) { Bprint(&bso, "inuxi = "); for(i=0; i<1; i++) @@ -1268,7 +1332,6 @@ nuxiinit(void) Bflush(&bso); } -int find1(long l, int c) { char *p; diff --git a/utils/vl/pass.c b/utils/vl/pass.c index 7dc2e5dd..7abe22d4 100644 --- a/utils/vl/pass.c +++ b/utils/vl/pass.c @@ -133,7 +133,7 @@ dodata(void) continue; /* size should be 19 max */ if(strlen(s->name) >= 10) /* has loader address */ - sprint(literal, "$%lux.%lux", (long)s, p->from.offset); + sprint(literal, "$%p.%lux", s, p->from.offset); else sprint(literal, "$%s.%d.%lux", s->name, s->version, p->from.offset); } else { |
