summaryrefslogtreecommitdiff
path: root/utils/5l/obj.c
diff options
context:
space:
mode:
authorforsyth <forsyth@lavoro.terzarima.net>2013-06-03 21:01:14 +0000
committerforsyth <forsyth@lavoro.terzarima.net>2013-06-03 21:01:14 +0000
commit45a20ab721a513710138340faff3d59a31c3e01e (patch)
treeeea29d2684c51cc73725b8992a2125bede48e118 /utils/5l/obj.c
parentcd8e99851af33e52bcdf8faf34f9d4e62fa0cbaf (diff)
sync compilers with Plan 9
remove 1[acl] 2[acl]
Diffstat (limited to 'utils/5l/obj.c')
-rw-r--r--utils/5l/obj.c337
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;