summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/kl/l.h4
-rw-r--r--utils/vl/asm.c186
-rw-r--r--utils/vl/l.h4
-rw-r--r--utils/vl/obj.c105
-rw-r--r--utils/vl/pass.c2
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 {