summaryrefslogtreecommitdiff
path: root/utils/ql
diff options
context:
space:
mode:
Diffstat (limited to 'utils/ql')
-rw-r--r--utils/ql/Ins203
-rw-r--r--utils/ql/Notes21
-rw-r--r--utils/ql/Nt.c88
-rw-r--r--utils/ql/Plan9.c57
-rw-r--r--utils/ql/Posix.c80
-rw-r--r--utils/ql/asm.c248
-rw-r--r--utils/ql/l.h12
-rw-r--r--utils/ql/list.c2
-rw-r--r--utils/ql/mkfile8
-rw-r--r--utils/ql/obj.c150
10 files changed, 203 insertions, 666 deletions
diff --git a/utils/ql/Ins b/utils/ql/Ins
deleted file mode 100644
index d113e845..00000000
--- a/utils/ql/Ins
+++ /dev/null
@@ -1,203 +0,0 @@
-a OR XO(31,10)
-abs OR XO(31,360)
-ae OR XO(31,138)
-ai 0 D(12) +
-
-ai. 0 D(13)
-ame OR XO(31,234)
-and R X(31,28)
-andc R X(31,60)
-
-andil. 0 D(28,0)
-andiu. 0 D(29,0)
-aze OR XO(31,202)
-cal 0 D(14)
-
-cau 0 D(15)
-cax OR XO(31,266)
-cmp 0 X(31,0)
-cmpi 0 D(11)
-
-cmpl 0 X(31,32)
-cmpli 0 D(10)
-cntlz R X(31,26)
-crand 0 XL(19,257)
-
-crandc 0 XL(19,129)
-creqv 0 XL(19,289)
-crnand 0 XL(19,225)
-crnor 0 XL(19,33)
-
-cror 0 XL(19,449)
-crorc 0 XL(19,417)
-crxor 0 XL(19,193)
-div OR XO(31,331)
-
-divs OR XO(31,331)
-doz OR XO(31,264)
-dozi 0 D(9)
-
-eqv R X(31,284)
-exts R X(31,922)
-fa R A(63,21)
-fabs R X(63,264)
-fcmpo 0 X(63,32)
-
-fcmpu 0 X(63,0)
-fd R A(63,8)
-fm R A(63,5)
-fma R A(63,29)
-
-fmr R X(63,72)
-fms R A(63,28)
-fnabs R X(63,136)
-fneg R X(63,40)
-
-fnma R A(63,31)
-fnms R A(63,30)
-frsp R X(63,12)
-fs R A(63,20)
-
-l 0 D(32)
-lbrx 0 X(31,534)
-lbz 0 D(34)
-lbzu 0 D(35)
-
-lbzux 0 X(31,119)
-lbzx 0 X(31,87)
-lfd 0 D(50)
-lfdu 0 D(51)
-
-lfdux 0 X(31,631)
-lfdx 0 X(31,599)
-lfs 0 D(48)
-lfsu 0 D(49)
-
-lfsux 0 X(31,567)
-lfsx 0 X(31,535)
-lha 0 D(42)
-lhau 0 D(43)
-
-lhaux 0 X(31,375)
-lhax 0 X(31,343)
-lhbrx 0 X(31,790)
-lhz 0 D(40)
-
-lhzu 0 D(41)
-lhzux 0 X(31,311)
-lhzx 0 X(31,279)
-lm 0 D(46)
-
-lscbx R X(31,277)
-lsi 0 X(31,597)
-lsx 0 X(31,533)
-lu 0 D(33)
-
-lux 0 X(31,55)
-lx 0 X(31,23)
-maskg R X(31,29)
-maskir R X(31,541)
-
-mcrf 0 XL(19,0)
-mcrfs 0 X(63,64)
-mcrxr 0 X(31,512)
-mfcr 0 X(31,19)
-
-mffs R X(63,583)
-mfmsr 0 X(31,83)
-mfspr 0 X(31,339)
-mtcrf 0 XFX(31,144)
-
-mtfsb0 R X(63,70)
-mtfsb1 R X(63,38)
-mtfsf R XFL(63,711)
-mtfsfi R X(63,134)
-
-mtspr 0 X(31,467)
-mul OR XO(31,107)
-muli 0 D(7)
-muls OR XO(31,235)
-
-nabs OR XO(31,488)
-nand R X(31,476)
-neg OR XO(31,104)
-
-nor R X(31,124)
-or R X(31,444)
-orc R X(31,412)
-oril 0 D(24)
-
-oriu 0 D(25)
-rlmi R M(20)
-rlinm R M(21)
-rlmi R M(22)
-
-rlnm R M(23)
-rrib R X(31,537)
-sf OR XO(31,8)
-sfe OR XO(31,36)
-
-sfi 0 D(8)
-sfme OR XO(31,232)
-sfze OR XO(31,200)
-sl R X(31,24)
-
-sle R X(31,153)
-sleq R X(31,217)
-sliq R X(31,184)
-slliq R X(31,248)
-
-sllq R X(31,216)
-slq R X(31,152)
-sr R X(31,536)
-sra R X(31,792)
-
-srai R X(31,824)
-sraiq R X(31,952)
-sraq R X(31,920)
-sre R X(31,665)
-
-srea R X(31,921)
-sreq R X(31,729)
-sriq R X(31,696)
-srliq R X(31,760)
-srlq R X(31,728)
-
-srq R X(31,664)
-st 0 D(36)
-stb 0 D(38)
-stbrx 0 X(31,662)
-
-stbu 0 D(39)
-stbux 0 X(31,247)
-stbx 0 X(31,215)
-stfd 0 D(54)
-
-stfdu 0 D(55)
-stfdux 0 X(31,759)
-stfdx 0 X(31,727)
-stfs 0 D(52)
-
-stfsu 0 D(53)
-stfsux 0 X(31,695)
-stfsx 0 X(31,663)
-sth 0 D(44)
-
-sthbrx 0 X(31,918)
-sthu 0 D(45)
-sthux 0 X(31,439)
-sthx 0 X(3,407)
-
-stm 0 D(47)
-stsi 0 X(31,725)
-stsx 0 X(31,661)
-stu 0 D(37)
-
-stux 0 X(31,183)
-stx 0 X(31,151)
-svc 0 SC(17)
-t 0 X(31,4)
-ti 0 D(3)
-xor R X(31,316)
-xoril 0 D(26)
-xoriu 0 D(27)
diff --git a/utils/ql/Notes b/utils/ql/Notes
deleted file mode 100644
index 1620b508..00000000
--- a/utils/ql/Notes
+++ /dev/null
@@ -1,21 +0,0 @@
-possible input transformations
- adde $-1,X => addme X
- adde $0,X => addze X
- subw $s,X => addw $-s,X
- orn $v,X => or $~v,X
-
-qa:
- subc r1,$s,r2 => subc $s,r1,r2
- movw sreg(Rn),Rm => movw sreg(NREG),Rn,Rm [and v.v.]
-
-others?
- andn $m => and $~m
- slw $sh,s,a => rliwnm
- srw $sh,s,a => rliwnm
-
-support for C_LCON needed since addresses are literals?
-
-- moves
-- branch distance
-
-- could rewrite movwu x,d(r) as movw $d,tmp; movwu x,(tmp+d) when d is large?
diff --git a/utils/ql/Nt.c b/utils/ql/Nt.c
deleted file mode 100644
index c6748abd..00000000
--- a/utils/ql/Nt.c
+++ /dev/null
@@ -1,88 +0,0 @@
-#include <windows.h>
-
-/*
- * We can't include l.h, because Windoze wants to use some names
- * like FLOAT and ABC which we declare. Define what we need here.
- */
-typedef unsigned char uchar;
-typedef unsigned int uint;
-typedef unsigned long ulong;
-
-extern char *hunk;
-extern long nhunk;
-
-void gethunk(void);
-
-/*
- * fake malloc
- */
-void*
-malloc(uint n)
-{
- void *p;
-
- while(n & 7)
- n++;
- while(nhunk < n)
- gethunk();
- p = hunk;
- nhunk -= n;
- hunk += n;
- return p;
-}
-
-void
-free(void *p)
-{
-}
-
-void*
-calloc(uint m, uint n)
-{
- void *p;
-
- n *= m;
- p = malloc(n);
- memset(p, 0, n);
- return p;
-}
-
-void*
-realloc(void *p, uint n)
-{
- void *new;
-
- new = malloc(n);
- if(new && p)
- memmove(new, p, n);
- return new;
-}
-
-#define Chunk (1*1024*1024)
-
-void*
-mysbrk(ulong size)
-{
- void *v;
- static int chunk;
- static uchar *brk;
-
- if(chunk < size) {
- chunk = Chunk;
- if(chunk < size)
- chunk = Chunk + size;
- brk = VirtualAlloc(NULL, chunk, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- if(brk == 0)
- return (void*)-1;
- }
- v = brk;
- chunk -= size;
- brk += size;
- return v;
-}
-
-double
-cputime(void)
-{
- return ((double)0);
-}
diff --git a/utils/ql/Plan9.c b/utils/ql/Plan9.c
deleted file mode 100644
index f4cf23f4..00000000
--- a/utils/ql/Plan9.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "l.h"
-
-/*
- * fake malloc
- */
-void*
-malloc(ulong n)
-{
- void *p;
-
- while(n & 7)
- n++;
- while(nhunk < n)
- gethunk();
- p = hunk;
- nhunk -= n;
- hunk += n;
- return p;
-}
-
-void
-free(void *p)
-{
- USED(p);
-}
-
-void*
-calloc(ulong m, ulong n)
-{
- void *p;
-
- n *= m;
- p = malloc(n);
- memset(p, 0, n);
- return p;
-}
-
-void*
-realloc(void *p, ulong n)
-{
- USED(p);
- USED(n);
- fprint(2, "realloc called\n");
- abort();
- return 0;
-}
-
-void*
-mysbrk(ulong size)
-{
- return sbrk(size);
-}
-
-void
-setmalloctag(void*, ulong)
-{
-}
diff --git a/utils/ql/Posix.c b/utils/ql/Posix.c
deleted file mode 100644
index 0da0ee0c..00000000
--- a/utils/ql/Posix.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include "l.h"
-#include <sys/types.h>
-#include <sys/times.h>
-#undef getwd
-#include <unistd.h> /* For sysconf() and _SC_CLK_TCK */
-
-/*
- * fake malloc
- */
-void*
-malloc(size_t n)
-{
- void *p;
-
- while(n & 7)
- n++;
- while(nhunk < n)
- gethunk();
- p = hunk;
- nhunk -= n;
- hunk += n;
- return p;
-}
-
-void
-free(void *p)
-{
- USED(p);
-}
-
-void*
-calloc(size_t m, size_t n)
-{
- void *p;
-
- n *= m;
- p = malloc(n);
- memset(p, 0, n);
- return p;
-}
-
-void*
-realloc(void *p, size_t n)
-{
- fprint(2, "realloc called\n", p, n);
- abort();
- return 0;
-}
-
-void*
-mysbrk(ulong size)
-{
- return (void*)sbrk(size);
-}
-
-double
-cputime(void)
-{
-
- struct tms tmbuf;
- double ret_val;
-
- /*
- * times() only fails if &tmbuf is invalid.
- */
- (void)times(&tmbuf);
- /*
- * Return the total time (in system clock ticks)
- * spent in user code and system
- * calls by both the calling process and its children.
- */
- ret_val = (double)(tmbuf.tms_utime + tmbuf.tms_stime +
- tmbuf.tms_cutime + tmbuf.tms_cstime);
- /*
- * Convert to seconds.
- */
- ret_val *= sysconf(_SC_CLK_TCK);
- return ret_val;
-
-}
diff --git a/utils/ql/asm.c b/utils/ql/asm.c
index be1a57a1..abcab5e3 100644
--- a/utils/ql/asm.c
+++ b/utils/ql/asm.c
@@ -1,6 +1,5 @@
#include "l.h"
-#define KMASK 0xF0000000
#define JMPSZ sizeof(u32int) /* size of bootstrap jump section */
#define LPUT(c)\
@@ -45,6 +44,14 @@ entryvalue(void)
return s->value;
}
+static void
+elf32jmp(Putl putl)
+{
+ /* describe a tiny text section at end with jmp to start; see below */
+ elf32phdr(putl, PT_LOAD, HEADR+textsize-JMPSZ, 0xFFFFFFFC, 0xFFFFFFFC,
+ JMPSZ, JMPSZ, R|X, 0); /* text */
+}
+
void
asmb(void)
{
@@ -86,17 +93,13 @@ asmb(void)
if (prevpc & (1<<31) && (pc & (1<<31)) == 0) {
char *tn;
- tn = "?none?";
+ 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");
@@ -107,7 +110,13 @@ asmb(void)
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:
@@ -315,180 +324,16 @@ asmb(void)
break;
case 5:
/*
- * customised for blue/gene,
- * notably the alignment and KMASK masking.
+ * intended for blue/gene
*/
- 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);
-
+ elf32(POWER, ELFDATA2MSB, 0, nil);
break;
case 6:
/*
- * customised for virtex 4 boot,
- * notably the alignment and KMASK masking.
+ * intended for virtex 4 boot
*/
- 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();
+ debug['S'] = 1; /* symbol table */
+ elf32(POWER, ELFDATA2MSB, 1, elf32jmp);
break;
}
cflush();
@@ -523,13 +368,50 @@ wput(long l)
}
void
-lput(long l)
+wputl(long l)
{
+ cbp[0] = l;
+ cbp[1] = l>>8;
+ cbp += 2;
+ cbc -= 2;
+ if(cbc <= 0)
+ cflush();
+}
+void
+lput(long l)
+{
LPUT(l);
}
void
+lputl(long c)
+{
+ cbp[0] = (c);
+ cbp[1] = (c)>>8;
+ cbp[2] = (c)>>16;
+ cbp[3] = (c)>>24;
+ cbp += 4;
+ cbc -= 4;
+ if(cbc <= 0)
+ cflush();
+}
+
+void
+llput(vlong v)
+{
+ lput(v>>32);
+ lput(v);
+}
+
+void
+llputl(vlong v)
+{
+ lputl(v);
+ lputl(v>>32);
+}
+
+void
cflush(void)
{
int n;
@@ -665,12 +547,12 @@ asmlc(void)
if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
if(p->as == ATEXT)
curtext = p;
- if(debug['L'])
+ if(debug['V'])
Bprint(&bso, "%6lux %P\n",
p->pc, p);
continue;
}
- if(debug['L'])
+ if(debug['V'])
Bprint(&bso, "\t\t%6ld", lcsize);
v = (p->pc - oldpc) / MINLC;
while(v) {
@@ -678,7 +560,7 @@ asmlc(void)
if(v < 127)
s = v;
CPUT(s+128); /* 129-255 +pc */
- if(debug['L'])
+ if(debug['V'])
Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
v -= s;
lcsize++;
@@ -692,7 +574,7 @@ asmlc(void)
CPUT(s>>16);
CPUT(s>>8);
CPUT(s);
- if(debug['L']) {
+ if(debug['V']) {
if(s > 0)
Bprint(&bso, " lc+%ld(%d,%ld)\n",
s, 0, s);
@@ -707,14 +589,14 @@ asmlc(void)
}
if(s > 0) {
CPUT(0+s); /* 1-64 +lc */
- if(debug['L']) {
+ if(debug['V']) {
Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
Bprint(&bso, "%6lux %P\n",
p->pc, p);
}
} else {
CPUT(64-s); /* 65-128 -lc */
- if(debug['L']) {
+ if(debug['V']) {
Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
Bprint(&bso, "%6lux %P\n",
p->pc, p);
@@ -727,7 +609,7 @@ asmlc(void)
CPUT(s);
lcsize++;
}
- if(debug['v'] || debug['L'])
+ if(debug['v'] || debug['V'])
Bprint(&bso, "lcsize = %ld\n", lcsize);
Bflush(&bso);
}
diff --git a/utils/ql/l.h b/utils/ql/l.h
index 4ef775c0..6a33c606 100644
--- a/utils/ql/l.h
+++ b/utils/ql/l.h
@@ -1,11 +1,14 @@
#include <lib9.h>
#include <bio.h>
#include "../qc/q.out.h"
+#include "../8l/elf.h"
#ifndef EXTERN
#define EXTERN extern
#endif
+#define LIBNAMELEN 300
+
typedef struct Adr Adr;
typedef struct Sym Sym;
typedef struct Autom Auto;
@@ -186,6 +189,7 @@ EXTERN int HEADTYPE; /* type of header */
EXTERN long INITDAT; /* data location */
EXTERN long INITRND; /* data round above text location */
EXTERN long INITTEXT; /* text location */
+EXTERN long INITTEXTP; /* text location (physical) */
EXTERN char* INITENTRY; /* entry point */
EXTERN long autosize;
EXTERN Biobuf bso;
@@ -259,6 +263,7 @@ int Rconv(Fmt*);
int aclass(Adr*);
void addhist(long, int);
void histtoauto(void);
+void addlibpath(char*);
void addnop(Prog*);
void append(Prog*, Prog*);
void asmb(void);
@@ -285,7 +290,9 @@ long entryvalue(void);
void errorexit(void);
void exchange(Prog*);
void export(void);
+int fileexists(char*);
int find1(long, int);
+char* findlib(char*);
void follow(void);
void gethunk(void);
double ieeedtod(Ieee*);
@@ -297,7 +304,10 @@ void loadlib(void);
void listinit(void);
void initmuldiv(void);
Sym* lookup(char*, int);
+void llput(vlong);
+void llputl(vlong);
void lput(long);
+void lputl(long);
void mkfwd(void);
void* mysbrk(ulong);
void names(void);
@@ -321,9 +331,11 @@ int relinv(int);
long rnd(long, long);
void sched(Prog*, Prog*);
void span(void);
+void strnput(char*, int);
void undef(void);
void undefsym(Sym*);
void wput(long);
+void wputl(long);
void xdefine(char*, int, long);
void xfol(Prog*);
void zerosig(char*);
diff --git a/utils/ql/list.c b/utils/ql/list.c
index 04139dfc..90fa2af3 100644
--- a/utils/ql/list.c
+++ b/utils/ql/list.c
@@ -63,7 +63,7 @@ Aconv(Fmt *fp)
int a;
a = va_arg(fp->args, int);
- s = "???";
+ s = "?";
if(a >= AXXX && a < ALAST)
s = anames[a];
return fmtstrcpy(fp, s);
diff --git a/utils/ql/mkfile b/utils/ql/mkfile
index 1296b005..183d1a90 100644
--- a/utils/ql/mkfile
+++ b/utils/ql/mkfile
@@ -15,6 +15,7 @@ OFILES=\
cnam.$O\
sched.$O\
$TARGMODEL.$O\
+ elf.$O\
HFILES=\
l.h\
@@ -27,10 +28,15 @@ BIN=$ROOT/$OBJDIR/bin
<$ROOT/mkfiles/mkone-$SHELLTYPE
-CFLAGS= $CFLAGS -I../include
+CFLAGS= $CFLAGS -I../include -I.
enam.$O: ../qc/enam.c
$CC $CFLAGS ../qc/enam.c
+elf.$O: ../ld/elf.c
+ $CC $CFLAGS ../ld/elf.c
#cnam.c: l.h
# rc mkcname
+
+$TARGMODEL.$O: ../ld/$TARGMODEL.c
+ $CC $CFLAGS ../ld/$TARGMODEL.c
diff --git a/utils/ql/obj.c b/utils/ql/obj.c
index 8026a0de..620d6536 100644
--- a/utils/ql/obj.c
+++ b/utils/ql/obj.c
@@ -14,6 +14,10 @@ char symname[] = SYMDEF;
char thechar = 'q';
char *thestring = "power";
+char** libdir;
+int nlibdir = 0;
+static int maxlibdir = 0;
+
/*
* -H0 -T0x200000 -R0 is boot
* -H1 -T0x100000 -R4 is Be boot
@@ -26,6 +30,13 @@ char *thestring = "power";
* appropriate for virtex 4 boot
*/
+void
+usage(void)
+{
+ diag("usage: %s [-options] objects", argv0);
+ errorexit();
+}
+
static int
isobjfile(char *f)
{
@@ -53,6 +64,7 @@ main(int argc, char *argv[])
{
int c;
char *a;
+ char name[LIBNAMELEN];
Binit(&bso, 1, OWRITE);
cout = -1;
@@ -62,6 +74,7 @@ main(int argc, char *argv[])
curtext = P;
HEADTYPE = -1;
INITTEXT = -1;
+ INITTEXTP = -1;
INITDAT = -1;
INITRND = -1;
INITENTRY = 0;
@@ -85,6 +98,11 @@ main(int argc, char *argv[])
if(a)
INITTEXT = atolwhex(a);
break;
+ case 'P':
+ a = ARGF();
+ if(a)
+ INITTEXTP = atolwhex(a);
+ break;
case 'D':
a = ARGF();
if(a)
@@ -100,6 +118,9 @@ main(int argc, char *argv[])
if(a)
HEADTYPE = atolwhex(a);
break;
+ case 'L':
+ addlibpath(EARGF(usage()));
+ break;
case 'x': /* produce export table */
doexp = 1;
if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1]))
@@ -112,12 +133,20 @@ main(int argc, char *argv[])
break;
} ARGEND
USED(argc);
- if(*argv == 0) {
- diag("usage: ql [-options] objects");
- errorexit();
- }
+ if(*argv == 0)
+ usage();
if(!debug['9'] && !debug['U'] && !debug['B'])
debug[DEFAULT] = 1;
+ a = getenv("ccroot");
+ if(a != nil && *a != '\0') {
+ if(!fileexists(a)) {
+ diag("nonexistent $ccroot: %s", a);
+ errorexit();
+ }
+ }else
+ a = "";
+ snprint(name, sizeof(name), "%s/%s/lib", a, thestring);
+ addlibpath(name);
r0iszero = debug['0'] == 0;
if(HEADTYPE == -1) {
if(debug['U'])
@@ -180,8 +209,16 @@ main(int argc, char *argv[])
INITRND = 0;
break;
case 5: /* elf executable */
+ HEADR = rnd(Ehdr32sz+3*Phdr32sz, 16);
+ if(INITTEXT == -1)
+ INITTEXT = 0x00400000L+HEADR;
+ if(INITDAT == -1)
+ INITDAT = 0x10000000;
+ if(INITRND == -1)
+ INITRND = 0;
+ break;
case 6: /* elf for virtex 4 */
- HEADR = rnd(52L+3*32L, 16);
+ HEADR = rnd(Ehdr32sz+4*Phdr32sz, 16); /* extra phdr for JMP */
if(INITTEXT == -1)
INITTEXT = 0x00400000L+HEADR;
if(INITDAT == -1)
@@ -190,6 +227,8 @@ main(int argc, char *argv[])
INITRND = 0;
break;
}
+ if (INITTEXTP == -1)
+ INITTEXTP = INITTEXT;
if(INITDAT != 0 && INITRND != 0)
print("warning: -D0x%lux is ignored because of -R0x%lux\n",
INITDAT, INITRND);
@@ -214,7 +253,7 @@ main(int argc, char *argv[])
outfile = "q.out";
cout = create(outfile, 1, 0775);
if(cout < 0) {
- diag("%s: cannot create", outfile);
+ diag("cannot create %s: %r", outfile);
errorexit();
}
nuxiinit();
@@ -230,7 +269,7 @@ main(int argc, char *argv[])
INITENTRY = "_mainp";
if(!debug['l'])
lookup(INITENTRY, 0)->type = SXREF;
- } else
+ } else if(!(*INITENTRY >= '0' && *INITENTRY <= '9'))
lookup(INITENTRY, 0)->type = SXREF;
while(*argv)
@@ -281,6 +320,42 @@ out:
}
void
+addlibpath(char *arg)
+{
+ char **p;
+
+ if(nlibdir >= maxlibdir) {
+ if(maxlibdir == 0)
+ maxlibdir = 8;
+ else
+ maxlibdir *= 2;
+ p = malloc(maxlibdir*sizeof(*p));
+ if(p == nil) {
+ diag("out of memory");
+ errorexit();
+ }
+ memmove(p, libdir, nlibdir*sizeof(*p));
+ free(libdir);
+ libdir = p;
+ }
+ libdir[nlibdir++] = strdup(arg);
+}
+
+char*
+findlib(char *file)
+{
+ int i;
+ char name[LIBNAMELEN];
+
+ for(i = 0; i < nlibdir; i++) {
+ snprint(name, sizeof(name), "%s/%s", libdir[i], file);
+ if(fileexists(name))
+ return libdir[i];
+ }
+ return nil;
+}
+
+void
loadlib(void)
{
int i;
@@ -321,25 +396,26 @@ objfile(char *file)
int f, work;
Sym *s;
char magbuf[SARMAG];
- char name[100], pname[150];
+ char name[LIBNAMELEN], pname[LIBNAMELEN];
struct ar_hdr arhdr;
char *e, *start, *stop;
- if(file[0] == '-' && file[1] == 'l') {
- if(debug['9'])
- sprint(name, "/%s/lib/lib", thestring);
- else
- sprint(name, "/usr/%clib/lib", thechar);
- strcat(name, file+2);
- strcat(name, ".a");
- file = name;
- }
if(debug['v'])
Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file);
Bflush(&bso);
+ if(file[0] == '-' && file[1] == 'l') {
+ snprint(pname, sizeof(pname), "lib%s.a", file+2);
+ e = findlib(pname);
+ if(e == nil) {
+ diag("cannot find library: %s", file);
+ errorexit();
+ }
+ snprint(name, sizeof(name), "%s/%s", e, pname);
+ file = name;
+ }
f = open(file, 0);
if(f < 0) {
- diag("cannot open file: %s", file);
+ diag("cannot open %s: %r", file);
errorexit();
}
l = read(f, magbuf, SARMAG);
@@ -425,7 +501,7 @@ int
zaddr(uchar *p, Adr *a, Sym *h[])
{
int i, c;
- long l;
+ int l;
Sym *s;
Auto *u;
@@ -516,25 +592,24 @@ out:
void
addlib(char *obj)
{
- char name[1024], comp[256], *p;
- int i;
+ char fn1[LIBNAMELEN], fn2[LIBNAMELEN], comp[LIBNAMELEN], *p, *name;
+ int i, search;
if(histfrogp <= 0)
return;
+ name = fn1;
+ search = 0;
if(histfrog[0]->name[1] == '/') {
sprint(name, "");
i = 1;
- } else
- if(histfrog[0]->name[1] == '.') {
+ } else if(histfrog[0]->name[1] == '.') {
sprint(name, ".");
i = 0;
} else {
- if(debug['9'])
- sprint(name, "/%s/lib", thestring);
- else
- sprint(name, "/usr/%clib", thechar);
+ sprint(name, "");
i = 0;
+ search = 1;
}
for(; i<histfrogp; i++) {
@@ -557,13 +632,25 @@ addlib(char *obj)
memmove(p+strlen(thestring), p+2, strlen(p+2)+1);
memmove(p, thestring, strlen(thestring));
}
- if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) {
+ if(strlen(fn1) + strlen(comp) + 3 >= sizeof(fn1)) {
diag("library component too long");
return;
}
- strcat(name, "/");
- strcat(name, comp);
+ if(i > 0 || !search)
+ strcat(fn1, "/");
+ strcat(fn1, comp);
+ }
+
+ cleanname(name);
+
+ if(search){
+ p = findlib(name);
+ if(p != nil){
+ snprint(fn2, sizeof(fn2), "%s/%s", p, name);
+ name = fn2;
+ }
}
+
for(i=0; i<libraryp; i++)
if(strcmp(name, library[i]) == 0)
return;
@@ -1065,8 +1152,7 @@ lookup(char *symb, int v)
for(p=symb; c = *p; p++)
h = h+h+h + c;
l = (p - symb) + 1;
- if(h < 0)
- h = ~h;
+ h &= 0xffffff;
h %= NHASH;
for(s = hash[h]; s != S; s = s->link)
if(s->version == v)