summaryrefslogtreecommitdiff
path: root/utils/8l/obj.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/8l/obj.c')
-rw-r--r--utils/8l/obj.c187
1 files changed, 149 insertions, 38 deletions
diff --git a/utils/8l/obj.c b/utils/8l/obj.c
index a2cd7c9a..d8a4bed1 100644
--- a/utils/8l/obj.c
+++ b/utils/8l/obj.c
@@ -11,6 +11,10 @@ char symname[] = SYMDEF;
char thechar = '8';
char *thestring = "386";
+char** libdir;
+int nlibdir = 0;
+static int maxlibdir = 0;
+
/*
* -H0 -T0x40004C -D0x10000000 is garbage unix
* -H1 -T0xd0 -R4 is unix coff
@@ -20,6 +24,13 @@ char *thestring = "386";
* -H5 -T0x80100020 -R4096 is ELF
*/
+void
+usage(void)
+{
+ diag("usage: %s [-options] objects", argv0);
+ errorexit();
+}
+
static int
isobjfile(char *f)
{
@@ -47,6 +58,7 @@ main(int argc, char *argv[])
{
int i, c;
char *a;
+ char name[LIBNAMELEN];
Binit(&bso, 1, OWRITE);
cout = -1;
@@ -56,6 +68,7 @@ main(int argc, char *argv[])
outfile = "8.out";
HEADTYPE = -1;
INITTEXT = -1;
+ INITTEXTP = -1;
INITDAT = -1;
INITRND = -1;
INITENTRY = 0;
@@ -78,11 +91,19 @@ main(int argc, char *argv[])
if(a)
HEADTYPE = atolwhex(a);
break;
+ case 'L':
+ addlibpath(EARGF(usage()));
+ break;
case 'T':
a = ARGF();
if(a)
INITTEXT = atolwhex(a);
break;
+ case 'P':
+ a = ARGF();
+ if(a)
+ INITTEXTP = atolwhex(a);
+ break;
case 'D':
a = ARGF();
if(a)
@@ -111,12 +132,20 @@ main(int argc, char *argv[])
break;
} ARGEND
USED(argc);
- if(*argv == 0) {
- diag("usage: 8l [-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);
if(HEADTYPE == -1) {
if(debug['U'])
HEADTYPE = 1;
@@ -179,7 +208,7 @@ main(int argc, char *argv[])
Bprint(&bso, "HEADR = 0x%ld\n", HEADR);
break;
case 5: /* elf executable */
- HEADR = rnd(52L+3*32L, 16);
+ HEADR = rnd(Ehdr32sz+3*Phdr32sz, 16);
if(INITTEXT == -1)
INITTEXT = 0x80100020L;
if(INITDAT == -1)
@@ -188,6 +217,8 @@ main(int argc, char *argv[])
INITRND = 4096;
break;
}
+ if (INITTEXTP == -1)
+ INITTEXTP = INITTEXT;
if(INITDAT != 0 && INITRND != 0)
print("warning: -D0x%lux is ignored because of -R0x%lux\n",
INITDAT, INITRND);
@@ -269,7 +300,7 @@ main(int argc, char *argv[])
dtype = 4;
cout = create(outfile, 1, 0775);
if(cout < 0) {
- diag("cannot create %s", outfile);
+ diag("cannot create %s: %r", outfile);
errorexit();
}
version = 0;
@@ -284,7 +315,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)
@@ -335,6 +366,42 @@ main(int argc, char *argv[])
}
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;
@@ -374,25 +441,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);
@@ -451,7 +519,8 @@ objfile(char *file)
l |= (e[3] & 0xff) << 16;
l |= (e[4] & 0xff) << 24;
seek(f, l, 0);
- l = read(f, &arhdr, SAR_HDR);
+ /* need readn to read the dumps (at least) */
+ l = readn(f, &arhdr, SAR_HDR);
if(l != SAR_HDR)
goto bad;
if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag)))
@@ -478,7 +547,7 @@ int
zaddr(uchar *p, Adr *a, Sym *h[])
{
int c, t, i;
- long l;
+ int l;
Sym *s;
Auto *u;
@@ -554,25 +623,24 @@ zaddr(uchar *p, Adr *a, Sym *h[])
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++) {
@@ -595,13 +663,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;
@@ -1087,8 +1167,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)
@@ -1236,16 +1315,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;
}
@@ -1286,7 +1373,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->pcond = q->link;
+ }else
+ p->link = q;
p = q;
p->as = ACALL;
p->to.type = D_BRANCH;
@@ -1297,6 +1397,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();