diff options
| author | forsyth <forsyth@lavoro.terzarima.net> | 2013-06-03 21:01:14 +0000 |
|---|---|---|
| committer | forsyth <forsyth@lavoro.terzarima.net> | 2013-06-03 21:01:14 +0000 |
| commit | 45a20ab721a513710138340faff3d59a31c3e01e (patch) | |
| tree | eea29d2684c51cc73725b8992a2125bede48e118 /utils/5l/obj.c | |
| parent | cd8e99851af33e52bcdf8faf34f9d4e62fa0cbaf (diff) | |
sync compilers with Plan 9
remove 1[acl] 2[acl]
Diffstat (limited to 'utils/5l/obj.c')
| -rw-r--r-- | utils/5l/obj.c | 337 |
1 files changed, 210 insertions, 127 deletions
diff --git a/utils/5l/obj.c b/utils/5l/obj.c index 35c5f558..202f8eec 100644 --- a/utils/5l/obj.c +++ b/utils/5l/obj.c @@ -11,14 +11,28 @@ char symname[] = SYMDEF; char thechar = '5'; char *thestring = "arm"; +char** libdir; +int nlibdir = 0; +static int maxlibdir = 0; + /* + * -H0 no header * -H1 -T0x10005000 -R4 is aif for risc os * -H2 -T4128 -R4096 is plan9 format * -H3 -T0xF0000020 -R4 is NetBSD format * -H4 is IXP1200 (raw) * -H5 -T0xC0008010 -R1024 is ipaq + * -H6 -R4096 no header with segments padded to pages + * -H7 is elf */ +void +usage(void) +{ + diag("usage: %s [-options] objects", argv0); + errorexit(); +} + static int isobjfile(char *f) { @@ -46,9 +60,9 @@ main(int argc, char *argv[]) { int c; char *a; + char name[LIBNAMELEN]; Binit(&bso, 1, OWRITE); - srand(time(0)); cout = -1; listinit(); outfile = 0; @@ -56,6 +70,7 @@ main(int argc, char *argv[]) curtext = P; HEADTYPE = -1; INITTEXT = -1; + INITTEXTP = -1; INITDAT = -1; INITRND = -1; INITENTRY = 0; @@ -74,11 +89,19 @@ main(int argc, char *argv[]) if(a) INITENTRY = 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) @@ -102,7 +125,6 @@ main(int argc, char *argv[]) break; case 'u': /* produce dynamically loadable module */ dlm = 1; - debug['l']++; if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) readundefs(ARGF(), SIMPORT); break; @@ -110,12 +132,20 @@ main(int argc, char *argv[]) USED(argc); - if(*argv == 0) { - diag("usage: 5l [-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 = 0; @@ -129,6 +159,7 @@ main(int argc, char *argv[]) diag("unknown -H option"); errorexit(); case 0: /* no header */ + case 6: /* no header, padded segments */ HEADR = 0L; if(INITTEXT == -1) INITTEXT = 0; @@ -182,7 +213,18 @@ main(int argc, char *argv[]) if(INITRND == -1) INITRND = 1024; break; + case 7: /* elf executable */ + HEADR = rnd(Ehdr32sz+3*Phdr32sz, 16); + if(INITTEXT == -1) + INITTEXT = 4096+HEADR; + if(INITDAT == -1) + INITDAT = 0; + if(INITRND == -1) + INITRND = 4; + break; } + if (INITTEXTP == -1) + INITTEXTP = INITTEXT; if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%lux is ignored because of -R0x%lux\n", INITDAT, INITRND); @@ -198,7 +240,6 @@ main(int argc, char *argv[]) zprg.from.reg = NREG; zprg.to = zprg.from; buildop(); - thumbbuildop(); // could build on demand histgen = 0; textp = P; datap = P; @@ -208,7 +249,7 @@ main(int argc, char *argv[]) outfile = "5.out"; cout = create(outfile, 1, 0775); if(cout < 0) { - diag("%s: cannot create", outfile); + diag("cannot create %s: %r", outfile); errorexit(); } nuxiinit(); @@ -225,7 +266,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) @@ -259,11 +300,7 @@ main(int argc, char *argv[]) doprof1(); else doprof2(); - if(debug['u']) - reachable(); dodata(); - if(seenthumb && debug['f']) - fnptrs(); follow(); if(firstp == P) goto out; @@ -273,10 +310,6 @@ main(int argc, char *argv[]) undef(); out: - if(debug['c']){ - thumbcount(); - print("ARM size = %d\n", armsize); - } if(debug['v']) { Bprint(&bso, "%5.2f cpu time\n", cputime()); Bprint(&bso, "%ld memory used\n", thunk); @@ -288,6 +321,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; @@ -298,7 +367,7 @@ loop: xrefresolv = 0; for(i=0; i<libraryp; i++) { if(debug['v']) - Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]); + Bprint(&bso, "%5.2f autolib: %s\n", cputime(), library[i]); objfile(library[i]); } if(xrefresolv) @@ -312,7 +381,6 @@ void errorexit(void) { - Bflush(&bso); if(nerrors) { if(cout >= 0) remove(outfile); @@ -328,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); @@ -407,7 +476,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))) @@ -434,7 +504,7 @@ int zaddr(uchar *p, Adr *a, Sym *h[]) { int i, c; - long l; + int l; Sym *s; Auto *u; @@ -456,17 +526,6 @@ zaddr(uchar *p, Adr *a, Sym *h[]) return 0; /* force real diagnostic */ } - if(a->type == D_CONST || a->type == D_OCONST) { - if(a->name == D_EXTERN || a->name == D_STATIC) { - s = a->sym; - if(s != S && (s->type == STEXT || s->type == SLEAF || s->type == SCONST || s->type == SXREF)) { - if(0 && !s->fnptr && s->name[0] != '.') - print("%s used as function pointer\n", s->name); - s->fnptr = 1; // over the top cos of SXREF - } - } - } - switch(a->type) { default: print("unknown type %d\n", a->type); @@ -553,25 +612,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++) { @@ -594,13 +652,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; @@ -719,8 +789,6 @@ readsome(int f, uchar *buf, uchar *good, uchar *stop, int max) return stop + n; } -static void puntfp(Prog *); - void ldobj(int f, long c, char *pn) { @@ -955,9 +1023,6 @@ loop: break; case ATEXT: - setarch(p); - setthumb(p); - p->align = 4; if(curtext != P) { histtoauto(); curtext->to.autom = curauto; @@ -982,7 +1047,6 @@ loop: } s->type = STEXT; s->value = pc; - s->thumb = thumb; lastp->link = p; lastp = p; p->pc = pc; @@ -1014,31 +1078,7 @@ loop: } goto casedef; - case AMOVWD: - case AMOVWF: - case AMOVDW: - case AMOVFW: - case AMOVFD: - case AMOVDF: - // case AMOVF: - // case AMOVD: - case ACMPF: - case ACMPD: - case AADDF: - case AADDD: - case ASUBF: - case ASUBD: - case AMULF: - case AMULD: - case ADIVF: - case ADIVD: - if(thumb) - puntfp(p); - goto casedef; - case AMOVF: - if(thumb) - puntfp(p); if(skip) goto casedef; @@ -1068,8 +1108,6 @@ loop: goto casedef; case AMOVD: - if(thumb) - puntfp(p); if(skip) goto casedef; @@ -1130,8 +1168,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) @@ -1152,8 +1189,6 @@ lookup(char *symb, int v) s->version = v; s->value = 0; s->sig = 0; - s->used = s->thumb = s->foreign = s->fnptr = 0; - s->use = nil; hash[h] = s; return s; } @@ -1208,7 +1243,6 @@ doprof1(void) s = lookup("__mcount", 0); n = 1; for(p = firstp->link; p != P; p = p->link) { - setarch(p); if(p->as == ATEXT) { q = prg(); q->line = p->line; @@ -1235,7 +1269,7 @@ doprof1(void) p->from.sym = s; p->from.offset = n*4 + 4; p->to.type = D_REG; - p->to.reg = thumb ? REGTMPT : REGTMP; + p->to.reg = REGTMP; q = prg(); q->line = p->line; @@ -1247,7 +1281,7 @@ doprof1(void) p->from.type = D_CONST; p->from.offset = 1; p->to.type = D_REG; - p->to.reg = thumb ? REGTMPT : REGTMP; + p->to.reg = REGTMP; q = prg(); q->line = p->line; @@ -1257,7 +1291,7 @@ doprof1(void) p = q; p->as = AMOVW; p->from.type = D_REG; - p->from.reg = thumb ? REGTMPT : REGTMP; + p->from.reg = REGTMP; p->to.type = D_OREG; p->to.name = D_EXTERN; p->to.sym = s; @@ -1284,25 +1318,36 @@ doprof1(void) s->value = n*4; } +static int brcond[] = {ABEQ, ABNE, ABCS, ABCC, ABMI, ABPL, ABVS, ABVC, ABHI, ABLS, ABGE, ABLT, ABGT, ABLE}; + 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; } + ps2 = P; ps4 = P; for(p = firstp; p != P; p = p->link) { - setarch(p); if(p->as == ATEXT) { if(p->from.sym == s2) { ps2 = p; @@ -1315,7 +1360,6 @@ doprof2(void) } } for(p = firstp; p != P; p = p->link) { - setarch(p); if(p->as == ATEXT) { if(p->reg & NOPROF) { for(;;) { @@ -1330,13 +1374,26 @@ doprof2(void) } /* - * BL profin, R2 + * BL profin */ q = prg(); 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 = AB; + q2->to.type = D_BRANCH; + q2->to.sym = p->to.sym; + q2->cond = q->link; + }else + p->link = q; p = q; p->as = ABL; p->to.type = D_BRANCH; @@ -1347,27 +1404,64 @@ 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(); q->as = ARET; q->from = p->from; q->to = p->to; + q->cond = p->cond; q->link = p->link; + q->reg = p->reg; p->link = q; - /* - * BL profout - */ - p->as = ABL; - p->from = zprg.from; - p->to = zprg.to; - p->to.type = D_BRANCH; - p->cond = ps4; - p->to.sym = s4; - - p = q; - + if(p->scond != 14) { + q = prg(); + q->as = ABL; + q->from = zprg.from; + q->to = zprg.to; + q->to.type = D_BRANCH; + q->cond = ps4; + q->to.sym = s4; + q->link = p->link; + p->link = q; + + p->as = brcond[p->scond^1]; /* complement */ + p->scond = 14; + p->from = zprg.from; + p->to = zprg.to; + p->to.type = D_BRANCH; + p->cond = q->link->link; /* successor of RET */ + p->to.offset = q->link->link->pc; + + p = q->link->link; + } else { + + /* + * BL profout + */ + p->as = ABL; + p->from = zprg.from; + p->to = zprg.to; + p->to.type = D_BRANCH; + p->cond = ps4; + p->to.sym = s4; + p->scond = 14; + + p = q; + } continue; } } @@ -1387,7 +1481,7 @@ nuxiinit(void) inuxi1[i] = c; inuxi4[i] = c; fnuxi4[i] = c; - if(!debug['d']){ + if(debug['d'] == 0){ fnuxi8[i] = c; fnuxi8[i+4] = c+4; } @@ -1481,17 +1575,6 @@ ieeedtod(Ieee *ieeep) return ldexp(fr, exp); } -static void -puntfp(Prog *p) -{ - USED(p); - /* floating point - punt for now */ - curtext->reg = NREG; /* ARM */ - curtext->from.sym->thumb = 0; - thumb = 0; - // print("%s: generating ARM code (contains floating point ops %d)\n", curtext->from.sym->name, p->line); -} - void undefsym(Sym *s) { @@ -1544,7 +1627,7 @@ readundefs(char *f, int t) diag("%s: bad format", f); errorexit(); } - for(i = 0; i < n; i++){ + for(i = 0; i < n; i++) { s = lookup(fields[i], 0); s->type = SXREF; s->subtype = t; |
