Commit b87e3e8b authored by Russ Cox's avatar Russ Cox

* move go-specific loader code

into gc directory, where it gets included as ../gc/ldbody
this is similar to the assemblers including ../cc/lexbody
and ../cc/macbody.

* hook go-specific loader code into 8l.

* make current 8.out.h and 6.out.h backward compatible
with plan 9's versions.  i had added some constants in
the middle of enums and have now moved them to the end.
this keeps us from invalidating old .8 and .6 files.
not sure how much it really matters, but easy to do.

R=r
DELTA=1314  (667 added, 623 deleted, 24 changed)
OCL=26938
CL=26941
parent b199035b
......@@ -820,10 +820,10 @@ enum
D_FILE,
D_FILE1,
D_SBIG, /* internal use by 6l only */
D_INDIR, /* additive */
D_SBIG = D_INDIR + D_INDIR,
T_TYPE = 1<<0,
T_INDEX = 1<<1,
T_OFFSET = 1<<2,
......
......@@ -36,3 +36,5 @@ clean:
install: $(TARG)
cp $(TARG) $(BIN)/$(TARG)
go.o: ../ld/go.c
This diff is collapsed.
......@@ -441,7 +441,6 @@ void xdefine(char*, int, vlong);
void xfol(Prog*);
void zaddr(Biobuf*, Adr*, Sym*[]);
void zerosig(char*);
int isinitfunc(Sym*);
void machseg(char*, vlong, vlong, vlong, vlong, uint32, uint32, uint32, uint32);
void machsymseg(uint32, uint32);
......
......@@ -79,9 +79,6 @@ enum as
ACMPSB,
ACMPSL,
ACMPSW,
ACMPXCHGB,
ACMPXCHGL,
ACMPXCHGW,
ADAA,
ADAS,
ADATA,
......@@ -387,6 +384,10 @@ enum as
ASIGNAME,
ACMPXCHGB,
ACMPXCHGL,
ACMPXCHGW,
ALAST
};
......@@ -441,13 +442,15 @@ enum
D_FCONST = 66,
D_SCONST = 67,
D_ADDR = 68,
D_CONST2 = 69,
D_FILE,
D_FILE1,
D_INDIR, /* additive */
D_SBIG = D_INDIR + D_INDIR,
D_CONST2,
T_TYPE = 1<<0,
T_INDEX = 1<<1,
T_OFFSET = 1<<2,
......
......@@ -16,6 +16,7 @@ OFILES=\
optab.$O\
pass.$O\
span.$O\
go.$O\
HFILES=\
l.h\
......@@ -35,3 +36,6 @@ clean:
install: $(TARG)
cp $(TARG) $(BIN)/$(TARG)
go.o: ../ld/go.c
......@@ -58,6 +58,7 @@ struct Adr
char u0scon[8];
Prog *u0cond; /* not used, but should be D_BRANCH */
Ieee u0ieee;
char *u0sbig;
} u0;
union
{
......@@ -74,6 +75,7 @@ struct Adr
#define scon u0.u0scon
#define cond u0.u0cond
#define ieee u0.u0ieee
#define sbig u0.u0sbig
#define autom u1.u1autom
#define sym u1.u1sym
......@@ -84,6 +86,7 @@ struct Prog
Adr to;
Prog *forwd;
Prog* link;
Prog* dlink;
Prog* pcond; /* work on this */
int32 pc;
int32 line;
......@@ -108,10 +111,14 @@ struct Sym
short become;
short frame;
uchar subtype;
uchar dupok;
uchar reachable;
ushort file;
int32 value;
int32 sig;
Sym* link;
Prog* text;
Prog* data;
};
struct Optab
{
......@@ -123,7 +130,9 @@ struct Optab
enum
{
STEXT = 1,
Sxxx,
STEXT,
SDATA,
SBSS,
SDATA1,
......@@ -352,6 +361,8 @@ void lputl(int32);
void main(int, char*[]);
void mkfwd(void);
void* mal(uint32);
Prog* newdata(Sym*, int, int, int);
Prog* newtext(Prog*, Sym*);
void nuxiinit(void);
void objfile(char*);
int opsize(Prog*);
......@@ -375,6 +386,16 @@ uint32 machheadr(void);
uint32 elfheadr(void);
void whatsys(void);
/*
* go.c
*/
void deadcode(void);
void definetypestrings(void);
void definetypesigs(void);
char* gotypefor(char *name);
void ldpkg(Biobuf *f, int64 len, char *filename);
/* set by call to whatsys() */
extern char* goroot;
extern char* goarch;
......
......@@ -99,7 +99,7 @@ Dconv(Fmt *fp)
a = va_arg(fp->args, Adr*);
i = a->type;
if(i >= D_INDIR) {
if(i >= D_INDIR && i < 2*D_INDIR) {
if(a->offset)
sprint(str, "%ld(%R)", a->offset, i-D_INDIR);
else
......
......@@ -333,6 +333,10 @@ main(int argc, char *argv[])
sprint(a, "%s/lib/lib_%s_%s.a", goroot, goarch, goos);
objfile(a);
}
definetypestrings();
definetypesigs();
deadcode();
firstp = firstp->link;
if(firstp == P)
errorexit();
......@@ -848,7 +852,7 @@ ldobj(Biobuf *f, int32 len, char *pn)
import1 = Boffset(f);
Bseek(f, import0, 0);
// ldpkg(f, import1 - import0 - 2, pn); // -2 for !\n
ldpkg(f, import1 - import0 - 2, pn); // -2 for !\n
Bseek(f, import1, 0);
newloop:
......@@ -1017,6 +1021,20 @@ loop:
case ADATA:
data:
// Assume that AGLOBL comes after ADATA.
// If we've seen an AGLOBL that said this sym was DUPOK,
// ignore any more ADATA we see, which must be
// redefinitions.
s = p->from.sym;
if(s != S && s->dupok) {
if(debug['v'])
Bprint(&bso, "skipping %s in %s: dupok", s->name, pn);
goto loop;
}
if(s != S) {
p->dlink = s->data;
s->data = p;
}
if(edatap == P)
datap = p;
else
......@@ -1056,19 +1074,7 @@ loop:
}
diag("%s: redefinition: %s\n%P", pn, s->name, p);
}
s->type = STEXT;
s->value = pc;
lastp->link = p;
lastp = p;
p->pc = pc;
pc++;
if(textp == P) {
textp = p;
etextp = p;
goto loop;
}
etextp->pcond = p;
etextp = p;
newtext(p, s);
goto loop;
case AFMOVF:
......
......@@ -388,9 +388,6 @@ Optab optab[] =
{ ACMPSB, ynone, Pb, 0xa6 },
{ ACMPSL, ynone, Px, 0xa7 },
{ ACMPSW, ynone, Pe, 0xa7 },
{ ACMPXCHGB, yrb_mb, Pm, 0xb0 },
{ ACMPXCHGL, yrl_ml, Pm, 0xb1 },
{ ACMPXCHGW, yrl_ml, Pm, 0xb1 },
{ ADAA, ynone, Px, 0x27 },
{ ADAS, ynone, Px, 0x2f },
{ ADATA },
......@@ -688,5 +685,11 @@ Optab optab[] =
{ AFYL2X, ynone, Px, 0xd9, 0xf1 },
{ AFYL2XP1, ynone, Px, 0xd9, 0xf9 },
{ AEND },
{ ADYNT },
{ AINIT },
{ ASIGNAME },
{ ACMPXCHGB, yrb_mb, Pm, 0xb0 },
{ ACMPXCHGL, yrl_ml, Pm, 0xb1 },
{ ACMPXCHGW, yrl_ml, Pm, 0xb1 },
0
};
......@@ -802,7 +802,7 @@ ckoff(Sym *s, int32 v)
diag("relocation offset %ld for %s out of range", v, s->name);
}
static Prog*
Prog*
newdata(Sym *s, int o, int w, int t)
{
Prog *p;
......@@ -820,6 +820,30 @@ newdata(Sym *s, int o, int w, int t)
p->from.sym = s;
p->from.offset = o;
p->to.type = D_CONST;
p->dlink = s->data;
s->data = p;
return p;
}
Prog*
newtext(Prog *p, Sym *s)
{
if(p == P) {
p = prg();
p->as = ATEXT;
p->from.sym = s;
}
s->type = STEXT;
s->text = p;
s->value = pc;
lastp->link = p;
lastp = p;
p->pc = pc++;
if(textp == P)
textp = p;
else
etextp->pcond = p;
etextp = p;
return p;
}
......
......@@ -146,12 +146,9 @@ xdefine(char *p, int t, int32 v)
}
void
putsymb(char *s, int t, int32 v, int ver)
putsymb(char *s, int t, int32 v, int ver, char *go)
{
int i, j, f;
char *go;
go = nil; // TODO
if(t == 'f')
s++;
......@@ -211,25 +208,25 @@ asmsym(void)
s = lookup("etext", 0);
if(s->type == STEXT)
putsymb(s->name, 'T', s->value, s->version);
putsymb(s->name, 'T', s->value, s->version, nil);
for(h=0; h<NHASH; h++)
for(s=hash[h]; s!=S; s=s->link)
switch(s->type) {
case SCONST:
putsymb(s->name, 'D', s->value, s->version);
putsymb(s->name, 'D', s->value, s->version, gotypefor(s->name));
continue;
case SDATA:
putsymb(s->name, 'D', s->value+INITDAT, s->version);
putsymb(s->name, 'D', s->value+INITDAT, s->version, gotypefor(s->name));
continue;
case SBSS:
putsymb(s->name, 'B', s->value+INITDAT, s->version);
putsymb(s->name, 'B', s->value+INITDAT, s->version, gotypefor(s->name));
continue;
case SFILE:
putsymb(s->name, 'f', s->value, s->version);
putsymb(s->name, 'f', s->value, s->version, nil);
continue;
}
......@@ -241,22 +238,22 @@ asmsym(void)
/* filenames first */
for(a=p->to.autom; a; a=a->link)
if(a->type == D_FILE)
putsymb(a->asym->name, 'z', a->aoffset, 0);
putsymb(a->asym->name, 'z', a->aoffset, 0, nil);
else
if(a->type == D_FILE1)
putsymb(a->asym->name, 'Z', a->aoffset, 0);
putsymb(a->asym->name, 'Z', a->aoffset, 0, nil);
putsymb(s->name, 'T', s->value, s->version);
putsymb(s->name, 'T', s->value, s->version, gotypefor(s->name));
/* frame, auto and param after */
putsymb(".frame", 'm', p->to.offset+4, 0);
putsymb(".frame", 'm', p->to.offset+4, 0, nil);
for(a=p->to.autom; a; a=a->link)
if(a->type == D_AUTO)
putsymb(a->asym->name, 'a', -a->aoffset, 0);
putsymb(a->asym->name, 'a', -a->aoffset, 0, nil);
else
if(a->type == D_PARAM)
putsymb(a->asym->name, 'p', a->aoffset, 0);
putsymb(a->asym->name, 'p', a->aoffset, 0, nil);
}
if(debug['v'] || debug['n'])
Bprint(&bso, "symsize = %lud\n", symsize);
......@@ -366,7 +363,7 @@ oclass(Adr *a)
{
int32 v;
if(a->type >= D_INDIR || a->index != D_NONE) {
if((a->type >= D_INDIR && a->type < 2*D_INDIR) || a->index != D_NONE) {
if(a->index != D_NONE && a->scale == 0) {
if(a->type == D_ADDR) {
switch(a->index) {
......@@ -615,7 +612,7 @@ asmand(Adr *a, int r)
v = a->offset;
t = a->type;
if(a->index != D_NONE) {
if(t >= D_INDIR) {
if(t >= D_INDIR && t < 2*D_INDIR) {
t -= D_INDIR;
if(t == D_NONE) {
*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
......@@ -663,7 +660,7 @@ asmand(Adr *a, int r)
*andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
return;
}
if(t >= D_INDIR) {
if(t >= D_INDIR && t < 2*D_INDIR) {
t -= D_INDIR;
if(t == D_NONE || (D_CS <= t && t <= D_GS)) {
*andptr++ = (0 << 6) | (5 << 0) | (r << 3);
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment