1
0
mirror of https://github.com/golang/go synced 2024-11-25 15:08:02 -07:00

6g, 6l, 8g, 8l: move read-only data to text segment

Changing 5g and 5l too, but it doesn't work yet.

R=ken2
CC=golang-dev
https://golang.org/cl/2136047
This commit is contained in:
Russ Cox 2010-09-12 00:17:44 -04:00
parent be443ee8bc
commit 698fb4f192
22 changed files with 228 additions and 153 deletions

View File

@ -147,6 +147,8 @@ ggloblnod(Node *nam, int32 width)
p->to.sym = S; p->to.sym = S;
p->to.type = D_CONST; p->to.type = D_CONST;
p->to.offset = width; p->to.offset = width;
if(nam->readonly)
p->from.scale = RODATA;
} }
void void
@ -163,6 +165,7 @@ ggloblsym(Sym *s, int32 width, int dupok)
p->to.offset = width; p->to.offset = width;
if(dupok) if(dupok)
p->from.scale = DUPOK; p->from.scale = DUPOK;
p->from.scale |= RODATA;
} }
int int

View File

@ -47,13 +47,17 @@ Pconv(Fmt *fp)
{ {
char str[STRINGSZ]; char str[STRINGSZ];
Prog *p; Prog *p;
char scale[40];
p = va_arg(fp->args, Prog*); p = va_arg(fp->args, Prog*);
sconsize = 8; sconsize = 8;
scale[0] = '\0';
if(p->from.scale != 0 && (p->as == AGLOBL || p->as == ATEXT))
snprint(scale, sizeof scale, "%d,", p->from.scale);
switch(p->as) { switch(p->as) {
default: default:
snprint(str, sizeof(str), "%.4ld (%L) %-7A %D,%D", snprint(str, sizeof(str), "%.4ld (%L) %-7A %D,%s%D",
p->loc, p->lineno, p->as, &p->from, &p->to); p->loc, p->lineno, p->as, &p->from, scale, &p->to);
break; break;
case ADATA: case ADATA:
@ -63,8 +67,8 @@ Pconv(Fmt *fp)
break; break;
case ATEXT: case ATEXT:
snprint(str, sizeof(str), "%.4ld (%L) %-7A %D,%lD", snprint(str, sizeof(str), "%.4ld (%L) %-7A %D,%s%lD",
p->loc, p->lineno, p->as, &p->from, &p->to); p->loc, p->lineno, p->as, &p->from, scale, &p->to);
break; break;
} }
return fmtstrcpy(fp, str); return fmtstrcpy(fp, str);

View File

@ -33,6 +33,7 @@
#define NOPROF (1<<0) #define NOPROF (1<<0)
#define DUPOK (1<<1) #define DUPOK (1<<1)
#define NOSPLIT (1<<2) #define NOSPLIT (1<<2)
#define RODATA (1<<3)
/* /*
* amd64 * amd64

View File

@ -136,16 +136,16 @@ addstring(Sym *s, char *str)
if(s->type == 0) if(s->type == 0)
s->type = SDATA; s->type = SDATA;
s->reachable = 1; s->reachable = 1;
r = s->value; r = s->size;
n = strlen(str)+1; n = strlen(str)+1;
while(n > 0) { while(n > 0) {
m = n; m = n;
if(m > sizeof(p->to.scon)) if(m > sizeof(p->to.scon))
m = sizeof(p->to.scon); m = sizeof(p->to.scon);
p = newdata(s, s->value, m, D_EXTERN); p = newdata(s, s->size, m, D_EXTERN);
p->to.type = D_SCONST; p->to.type = D_SCONST;
memmove(p->to.scon, str, m); memmove(p->to.scon, str, m);
s->value += m; s->size += m;
str += m; str += m;
n -= m; n -= m;
} }
@ -161,9 +161,9 @@ adduintxx(Sym *s, uint64 v, int wid)
if(s->type == 0) if(s->type == 0)
s->type = SDATA; s->type = SDATA;
s->reachable = 1; s->reachable = 1;
r = s->value; r = s->size;
p = newdata(s, s->value, wid, D_EXTERN); p = newdata(s, s->size, wid, D_EXTERN);
s->value += wid; s->size += wid;
p->to.type = D_CONST; p->to.type = D_CONST;
p->to.offset = v; p->to.offset = v;
return r; return r;
@ -203,9 +203,9 @@ addaddr(Sym *s, Sym *t)
if(s->type == 0) if(s->type == 0)
s->type = SDATA; s->type = SDATA;
s->reachable = 1; s->reachable = 1;
r = s->value; r = s->size;
p = newdata(s, s->value, Ptrsize, D_EXTERN); p = newdata(s, s->size, Ptrsize, D_EXTERN);
s->value += Ptrsize; s->size += Ptrsize;
p->to.type = D_ADDR; p->to.type = D_ADDR;
p->to.index = D_EXTERN; p->to.index = D_EXTERN;
p->to.offset = 0; p->to.offset = 0;
@ -223,9 +223,9 @@ addsize(Sym *s, Sym *t)
if(s->type == 0) if(s->type == 0)
s->type = SDATA; s->type = SDATA;
s->reachable = 1; s->reachable = 1;
r = s->value; r = s->size;
p = newdata(s, s->value, Ptrsize, D_EXTERN); p = newdata(s, s->size, Ptrsize, D_EXTERN);
s->value += Ptrsize; s->size += Ptrsize;
p->to.type = D_SIZE; p->to.type = D_SIZE;
p->to.index = D_EXTERN; p->to.index = D_EXTERN;
p->to.offset = 0; p->to.offset = 0;
@ -321,13 +321,12 @@ doelf(void)
s = lookup(".dynsym", 0); s = lookup(".dynsym", 0);
s->type = SELFDATA; s->type = SELFDATA;
s->reachable = 1; s->reachable = 1;
s->value += ELF64SYMSIZE; s->size += ELF64SYMSIZE;
/* dynamic string table */ /* dynamic string table */
s = lookup(".dynstr", 0); s = lookup(".dynstr", 0);
s->type = SELFDATA; s->type = SELFDATA;
s->reachable = 1; s->reachable = 1;
s->value += ELF64SYMSIZE;
addstring(s, ""); addstring(s, "");
dynstr = s; dynstr = s;
@ -467,7 +466,7 @@ asmb(void)
int32 v, magic; int32 v, magic;
int a, dynsym; int a, dynsym;
uchar *op1; uchar *op1;
vlong vl, va, startva, fo, w, symo, elfsymo, elfstro, elfsymsize, machlink; vlong vl, va, startva, fo, w, symo, elfsymo, elfstro, elfsymsize, machlink, etext;
vlong symdatva = SYMDATVA; vlong symdatva = SYMDATVA;
ElfEhdr *eh; ElfEhdr *eh;
ElfPhdr *ph, *pph; ElfPhdr *ph, *pph;
@ -519,6 +518,16 @@ asmb(void)
} }
cflush(); cflush();
datap = datsort(datap);
/* output read-only data in text segment */
etext = INITTEXT + textsize;
for(v = pc; v < etext; v += sizeof(buf)-Dbufslop) {
if(etext - v > sizeof(buf)-Dbufslop)
datblk(v, sizeof(buf)-Dbufslop);
else
datblk(v, etext-v);
}
switch(HEADTYPE) { switch(HEADTYPE) {
default: default:
@ -564,12 +573,11 @@ asmb(void)
textsize = INITDAT; textsize = INITDAT;
} }
datap = datsort(datap);
for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) { for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) {
if(datsize-v > sizeof(buf)-Dbufslop) if(datsize-v > sizeof(buf)-Dbufslop)
datblk(v, sizeof(buf)-Dbufslop); datblk(v+INITDAT, sizeof(buf)-Dbufslop);
else else
datblk(v, datsize-v); datblk(v+INITDAT, datsize-v);
} }
machlink = 0; machlink = 0;
@ -1102,6 +1110,8 @@ datsort(Prog *l)
for(p = l; p != P; p = p->link) { for(p = l; p != P; p = p->link) {
a = &p->from; a = &p->from;
a->offset += a->sym->value; a->offset += a->sym->value;
if(a->sym->type != SRODATA)
a->offset += INITDAT;
} }
datp = dsort(l); datp = dsort(l);
return datp; return datp;
@ -1202,10 +1212,10 @@ datblk(int32 s, int32 n)
diag("missing symbol %s", p->to.sym->name); diag("missing symbol %s", p->to.sym->name);
} }
o += p->to.sym->value; o += p->to.sym->value;
if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF) if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF && p->to.sym->type != SRODATA)
o += INITDAT; o += INITDAT;
if(dlm) if(dlm)
dynreloc(p->to.sym, l+s+INITDAT, 1); dynreloc(p->to.sym, l+s, 1);
} }
} }
fl = o; fl = o;
@ -1266,6 +1276,7 @@ datblk(int32 s, int32 n)
if(a->sym->type == SMACHO) if(a->sym->type == SMACHO)
continue; continue;
curp = p;
switch(p->to.type) { switch(p->to.type) {
case D_FCONST: case D_FCONST:
switch(c) { switch(c) {
@ -1273,17 +1284,17 @@ datblk(int32 s, int32 n)
case 4: case 4:
fl = ieeedtof(&p->to.ieee); fl = ieeedtof(&p->to.ieee);
cast = (uchar*)&fl; cast = (uchar*)&fl;
outa(c, cast, fnuxi4, l+s+INITDAT); outa(c, cast, fnuxi4, l+s);
break; break;
case 8: case 8:
cast = (uchar*)&p->to.ieee; cast = (uchar*)&p->to.ieee;
outa(c, cast, fnuxi8, l+s+INITDAT); outa(c, cast, fnuxi8, l+s);
break; break;
} }
break; break;
case D_SCONST: case D_SCONST:
outa(c, (uchar*)p->to.scon, nil, l+s+INITDAT); outa(c, (uchar*)p->to.scon, nil, l+s);
break; break;
default: default:
@ -1293,7 +1304,7 @@ datblk(int32 s, int32 n)
if(p->to.type == D_ADDR) { if(p->to.type == D_ADDR) {
if(p->to.sym) { if(p->to.sym) {
o += p->to.sym->value; o += p->to.sym->value;
if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF) if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF && p->to.sym->type != SRODATA)
o += INITDAT; o += INITDAT;
} }
} }
@ -1301,17 +1312,17 @@ datblk(int32 s, int32 n)
cast = (uchar*)&fl; cast = (uchar*)&fl;
switch(c) { switch(c) {
case 1: case 1:
outa(c, cast, inuxi1, l+s+INITDAT); outa(c, cast, inuxi1, l+s);
break; break;
case 2: case 2:
outa(c, cast, inuxi2, l+s+INITDAT); outa(c, cast, inuxi2, l+s);
break; break;
case 4: case 4:
outa(c, cast, inuxi4, l+s+INITDAT); outa(c, cast, inuxi4, l+s);
break; break;
case 8: case 8:
cast = (uchar*)&o; cast = (uchar*)&o;
outa(c, cast, inuxi8, l+s+INITDAT); outa(c, cast, inuxi8, l+s);
break; break;
} }
break; break;

View File

@ -169,6 +169,7 @@ enum
SMACHO, SMACHO,
SFIXED, SFIXED,
SELFDATA, SELFDATA,
SRODATA,
NHASH = 10007, NHASH = 10007,
NHUNK = 100000, NHUNK = 100000,

View File

@ -47,41 +47,30 @@ listinit(void)
int int
Pconv(Fmt *fp) Pconv(Fmt *fp)
{ {
char str[STRINGSZ], str1[STRINGSZ];
Prog *p; Prog *p;
p = va_arg(fp->args, Prog*); p = va_arg(fp->args, Prog*);
if(p == P)
return fmtstrcpy(fp, "<P>");
bigP = p; bigP = p;
snprint(str1, sizeof(str1), "(%ld)", p->line);
switch(p->as) { switch(p->as) {
case ATEXT: case ATEXT:
if(p->from.scale) { if(p->from.scale) {
snprint(str, sizeof(str), "%-7s %-7A %D,%d,%lD", fmtprint(fp, "(%d) %A %D,%d,%D",
str1, p->as, &p->from, p->from.scale, &p->to); p->line, p->as, &p->from, p->from.scale, &p->to);
break; break;
} }
snprint(str, sizeof(str), "%-7s %-7A %D,%lD",
str1, p->as, &p->from, &p->to);
break;
default: default:
snprint(str, sizeof(str), "%-7s %-7A %D,%D", fmtprint(fp, "(%d) %A %D,%D",
str1, p->as, &p->from, &p->to); p->line, p->as, &p->from, &p->to);
break; break;
case ADATA: case ADATA:
case AINIT: case AINIT:
case ADYNT: case ADYNT:
snprint(str, sizeof(str), "%-7s %-7A %D/%d,%D", fmtprint(fp, "(%d) %A %D/%d,%D",
str1, p->as, &p->from, p->from.scale, &p->to); p->line, p->as, &p->from, p->from.scale, &p->to);
break; break;
} }
bigP = P; bigP = P;
return fmtstrcpy(fp, str); return 0;
} }
int int

View File

@ -633,18 +633,20 @@ loop:
s = p->from.sym; s = p->from.sym;
if(s->type == 0 || s->type == SXREF) { if(s->type == 0 || s->type == SXREF) {
s->type = SBSS; s->type = SBSS;
s->value = 0; s->size = 0;
} }
if(s->type != SBSS) { if(s->type != SBSS && !s->dupok) {
diag("%s: redefinition: %s in %s", diag("%s: redefinition: %s in %s",
pn, s->name, TNAME); pn, s->name, TNAME);
s->type = SBSS; s->type = SBSS;
s->value = 0; s->size = 0;
} }
if(p->to.offset > s->value) if(p->to.offset > s->size)
s->value = p->to.offset; s->size = p->to.offset;
if(p->from.scale & DUPOK) if(p->from.scale & DUPOK)
s->dupok = 1; s->dupok = 1;
if(p->from.scale & RODATA)
s->type = SRODATA;
goto loop; goto loop;
case ADYNT: case ADYNT:
@ -791,7 +793,7 @@ loop:
s = lookup(literal, 0); s = lookup(literal, 0);
if(s->type == 0) { if(s->type == 0) {
s->type = SBSS; s->type = SBSS;
s->value = 4; s->size = 4;
t = prg(); t = prg();
t->as = ADATA; t->as = ADATA;
t->line = p->line; t->line = p->line;
@ -837,7 +839,7 @@ loop:
s = lookup(literal, 0); s = lookup(literal, 0);
if(s->type == 0) { if(s->type == 0) {
s->type = SBSS; s->type = SBSS;
s->value = 8; s->size = 8;
t = prg(); t = prg();
t->as = ADATA; t->as = ADATA;
t->line = p->line; t->line = p->line;
@ -967,7 +969,7 @@ doprof1(void)
q->to.offset = n; q->to.offset = n;
s->type = SBSS; s->type = SBSS;
s->value = n*4; s->size = n*4;
} }
void void

View File

@ -56,13 +56,13 @@ dodata(void)
s->value = dtype; s->value = dtype;
if(s->type == SBSS) if(s->type == SBSS)
s->type = SDATA; s->type = SDATA;
if(s->type != SDATA && s->type != SELFDATA) if(s->type != SDATA && s->type != SELFDATA && s->type != SRODATA)
diag("initialize non-data (%d): %s\n%P", diag("initialize non-data (%d): %s\n%P",
s->type, s->name, p); s->type, s->name, p);
t = p->from.offset + p->width; t = p->from.offset + p->width;
if(t > s->value) if(t > s->size)
diag("initialize bounds (%lld): %s\n%P", diag("initialize bounds (%lld): %s\n%P",
s->value, s->name, p); s->size, s->name, p);
} }
/* allocate elf guys - must be segregated from real data */ /* allocate elf guys - must be segregated from real data */
@ -73,7 +73,7 @@ dodata(void)
continue; continue;
if(s->type != SELFDATA) if(s->type != SELFDATA)
continue; continue;
t = rnd(s->value, 8); t = rnd(s->size, 8);
s->size = t; s->size = t;
s->value = datsize; s->value = datsize;
datsize += t; datsize += t;
@ -88,13 +88,12 @@ dodata(void)
if(s->type != SDATA) if(s->type != SDATA)
if(s->type != SBSS) if(s->type != SBSS)
continue; continue;
t = s->value; t = s->size;
if(t == 0 && s->name[0] != '.') { if(t == 0 && s->name[0] != '.') {
diag("%s: no size", s->name); diag("%s: no size", s->name);
t = 1; t = 1;
} }
t = rnd(t, 4); t = rnd(t, 4);
s->value = t;
if(t > MINSIZ) if(t > MINSIZ)
continue; continue;
if(t >= 8) if(t >= 8)
@ -115,10 +114,9 @@ dodata(void)
s->type = SDATA; s->type = SDATA;
continue; continue;
} }
t = s->value; t = s->size;
if(t >= 8) if(t >= 8)
datsize = rnd(datsize, 8); datsize = rnd(datsize, 8);
s->size = t;
s->value = datsize; s->value = datsize;
datsize += t; datsize += t;
} }
@ -171,8 +169,7 @@ dobss(void)
continue; continue;
if(s->type != SBSS) if(s->type != SBSS)
continue; continue;
t = s->value; t = s->size;
s->size = t;
if(t >= 8) if(t >= 8)
bsssize = rnd(bsssize, 8); bsssize = rnd(bsssize, 8);
s->value = bsssize + dynptrsize + datsize; s->value = bsssize + dynptrsize + datsize;
@ -1164,10 +1161,10 @@ export(void)
newdata(et, off, sizeof(int32), D_EXTERN); newdata(et, off, sizeof(int32), D_EXTERN);
off += sizeof(int32); off += sizeof(int32);
} }
et->value = off; et->size = off;
if(sv == 0) if(sv == 0)
sv = 1; sv = 1;
str->value = sv; str->size = sv;
exports = ne; exports = ne;
free(esyms); free(esyms);
} }

View File

@ -39,9 +39,10 @@ void
span(void) span(void)
{ {
Prog *p, *q; Prog *p, *q;
int32 v; int32 i, v;
vlong c, idat; vlong c, idat;
int m, n, again; int m, n, again;
Sym *s;
xdefine("etext", STEXT, 0L); xdefine("etext", STEXT, 0L);
idat = INITDAT; idat = INITDAT;
@ -121,6 +122,22 @@ loop:
textsize = c; textsize = c;
goto loop; goto loop;
} }
/*
* allocate read-only data to the text segment.
*/
c = rnd(c, 8);
for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->link) {
if(s->type != SRODATA)
continue;
v = s->size;
while(v & 7)
v++;
s->value = c;
c += v;
}
if(INITRND) { if(INITRND) {
INITDAT = rnd(c, INITRND); INITDAT = rnd(c, INITRND);
if(INITDAT != idat) { if(INITDAT != idat) {
@ -128,6 +145,7 @@ loop:
goto start; goto start;
} }
} }
xdefine("etext", STEXT, c); xdefine("etext", STEXT, c);
if(debug['v']) if(debug['v'])
Bprint(&bso, "etext = %llux\n", c); Bprint(&bso, "etext = %llux\n", c);
@ -228,6 +246,7 @@ genasmsym(void (*put)(char*, int, vlong, vlong, int, Sym*))
for(s=hash[h]; s!=S; s=s->link) { for(s=hash[h]; s!=S; s=s->link) {
switch(s->type) { switch(s->type) {
case SCONST: case SCONST:
case SRODATA:
if(!s->reachable) if(!s->reachable)
continue; continue;
put(s->name, 'D', s->value, s->size, s->version, s->gotype); put(s->name, 'D', s->value, s->size, s->version, s->gotype);
@ -809,6 +828,7 @@ vaddr(Adr *a)
ckoff(s, v); ckoff(s, v);
case STEXT: case STEXT:
case SCONST: case SCONST:
case SRODATA:
if(!s->reachable) if(!s->reachable)
diag("unreachable symbol in vaddr - %s", s->name); diag("unreachable symbol in vaddr - %s", s->name);
if((uvlong)s->value < (uvlong)INITTEXT) if((uvlong)s->value < (uvlong)INITTEXT)

View File

@ -149,6 +149,8 @@ ggloblnod(Node *nam, int32 width)
p->to.sym = S; p->to.sym = S;
p->to.type = D_CONST; p->to.type = D_CONST;
p->to.offset = width; p->to.offset = width;
if(nam->readonly)
p->from.scale = RODATA;
} }
void void
@ -165,6 +167,7 @@ ggloblsym(Sym *s, int32 width, int dupok)
p->to.offset = width; p->to.offset = width;
if(dupok) if(dupok)
p->from.scale = DUPOK; p->from.scale = DUPOK;
p->from.scale |= RODATA;
} }
int int

View File

@ -47,13 +47,17 @@ Pconv(Fmt *fp)
{ {
char str[STRINGSZ]; char str[STRINGSZ];
Prog *p; Prog *p;
char scale[40];
p = va_arg(fp->args, Prog*); p = va_arg(fp->args, Prog*);
sconsize = 8; sconsize = 8;
scale[0] = '\0';
if(p->from.scale != 0 && (p->as == AGLOBL || p->as == ATEXT))
snprint(scale, sizeof scale, "%d,", p->from.scale);
switch(p->as) { switch(p->as) {
default: default:
snprint(str, sizeof(str), "%.4ld (%L) %-7A %D,%D", snprint(str, sizeof(str), "%.4ld (%L) %-7A %D,%s%D",
p->loc, p->lineno, p->as, &p->from, &p->to); p->loc, p->lineno, p->as, &p->from, scale, &p->to);
break; break;
case ADATA: case ADATA:
@ -63,8 +67,8 @@ Pconv(Fmt *fp)
break; break;
case ATEXT: case ATEXT:
snprint(str, sizeof(str), "%.4ld (%L) %-7A %D,%lD", snprint(str, sizeof(str), "%.4ld (%L) %-7A %D,%s%lD",
p->loc, p->lineno, p->as, &p->from, &p->to); p->loc, p->lineno, p->as, &p->from, scale, &p->to);
break; break;
} }
return fmtstrcpy(fp, str); return fmtstrcpy(fp, str);

View File

@ -33,6 +33,7 @@
#define NOPROF (1<<0) #define NOPROF (1<<0)
#define DUPOK (1<<1) #define DUPOK (1<<1)
#define NOSPLIT (1<<2) #define NOSPLIT (1<<2)
#define RODATA (1<<3)
enum as enum as
{ {

View File

@ -127,16 +127,16 @@ addstring(Sym *s, char *str)
if(s->type == 0) if(s->type == 0)
s->type = SDATA; s->type = SDATA;
s->reachable = 1; s->reachable = 1;
r = s->value; r = s->size;
n = strlen(str)+1; n = strlen(str)+1;
while(n > 0) { while(n > 0) {
m = n; m = n;
if(m > sizeof(p->to.scon)) if(m > sizeof(p->to.scon))
m = sizeof(p->to.scon); m = sizeof(p->to.scon);
p = newdata(s, s->value, m, D_EXTERN); p = newdata(s, s->size, m, D_EXTERN);
p->to.type = D_SCONST; p->to.type = D_SCONST;
memmove(p->to.scon, str, m); memmove(p->to.scon, str, m);
s->value += m; s->size += m;
str += m; str += m;
n -= m; n -= m;
} }
@ -152,9 +152,9 @@ adduintxx(Sym *s, uint64 v, int wid)
if(s->type == 0) if(s->type == 0)
s->type = SDATA; s->type = SDATA;
s->reachable = 1; s->reachable = 1;
r = s->value; r = s->size;
p = newdata(s, s->value, wid, D_EXTERN); p = newdata(s, s->size, wid, D_EXTERN);
s->value += wid; s->size += wid;
p->to.type = D_CONST; p->to.type = D_CONST;
p->to.offset = v; p->to.offset = v;
return r; return r;
@ -194,9 +194,9 @@ addaddr(Sym *s, Sym *t)
if(s->type == 0) if(s->type == 0)
s->type = SDATA; s->type = SDATA;
s->reachable = 1; s->reachable = 1;
r = s->value; r = s->size;
p = newdata(s, s->value, Ptrsize, D_EXTERN); p = newdata(s, s->size, Ptrsize, D_EXTERN);
s->value += Ptrsize; s->size += Ptrsize;
p->to.type = D_ADDR; p->to.type = D_ADDR;
p->to.index = D_EXTERN; p->to.index = D_EXTERN;
p->to.offset = 0; p->to.offset = 0;
@ -214,9 +214,9 @@ addsize(Sym *s, Sym *t)
if(s->type == 0) if(s->type == 0)
s->type = SDATA; s->type = SDATA;
s->reachable = 1; s->reachable = 1;
r = s->value; r = s->size;
p = newdata(s, s->value, Ptrsize, D_EXTERN); p = newdata(s, s->size, Ptrsize, D_EXTERN);
s->value += Ptrsize; s->size += Ptrsize;
p->to.type = D_SIZE; p->to.type = D_SIZE;
p->to.index = D_EXTERN; p->to.index = D_EXTERN;
p->to.offset = 0; p->to.offset = 0;
@ -317,7 +317,7 @@ doelf(void)
s = lookup(".dynsym", 0); s = lookup(".dynsym", 0);
s->type = SELFDATA; s->type = SELFDATA;
s->reachable = 1; s->reachable = 1;
s->value += ELF32SYMSIZE; s->size += ELF32SYMSIZE;
/* dynamic string table */ /* dynamic string table */
s = lookup(".dynstr", 0); s = lookup(".dynstr", 0);
@ -455,7 +455,7 @@ asmb(void)
Prog *p; Prog *p;
int32 v, magic; int32 v, magic;
int a, dynsym; int a, dynsym;
uint32 va, fo, w, symo, startva, machlink; uint32 va, fo, w, symo, startva, machlink, etext;
uchar *op1; uchar *op1;
ulong expectpc; ulong expectpc;
ElfEhdr *eh; ElfEhdr *eh;
@ -530,6 +530,15 @@ asmb(void)
} }
cflush(); cflush();
/* output read-only data in text segment */
etext = INITTEXT + textsize;
for(v = pc; v < etext; v += sizeof(buf)-Dbufslop) {
if(etext-v > sizeof(buf)-Dbufslop)
datblk(v, sizeof(buf)-Dbufslop, 1);
else
datblk(v, etext-v, 1);
}
switch(HEADTYPE) { switch(HEADTYPE) {
default: default:
if(iself) if(iself)
@ -587,9 +596,9 @@ asmb(void)
for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) { for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) {
if(datsize-v > sizeof(buf)-Dbufslop) if(datsize-v > sizeof(buf)-Dbufslop)
datblk(v, sizeof(buf)-Dbufslop); datblk(v, sizeof(buf)-Dbufslop, 0);
else else
datblk(v, datsize-v); datblk(v, datsize-v, 0);
} }
machlink = 0; machlink = 0;
@ -1135,17 +1144,24 @@ cpos(void)
} }
void void
datblk(int32 s, int32 n) datblk(int32 s, int32 n, int32 rodata)
{ {
Prog *p; Prog *p;
char *cast; char *cast;
int32 l, fl, j; int32 l, fl, j;
int i, c; int i, c;
Adr *a; Adr *a;
int32 base;
base = INITDAT;
if(rodata)
base = 0;
memset(buf.dbuf, 0, n+Dbufslop); memset(buf.dbuf, 0, n+Dbufslop);
for(p = datap; p != P; p = p->link) { for(p = datap; p != P; p = p->link) {
a = &p->from; a = &p->from;
if(rodata != (a->sym->type == SRODATA))
continue;
l = a->sym->value + a->offset - s; l = a->sym->value + a->offset - s;
if(l >= n) if(l >= n)
@ -1214,7 +1230,7 @@ datblk(int32 s, int32 n)
if(p->to.sym->type == SUNDEF) if(p->to.sym->type == SUNDEF)
ckoff(p->to.sym, fl); ckoff(p->to.sym, fl);
fl += p->to.sym->value; fl += p->to.sym->value;
if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF) if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF && p->to.sym->type != SRODATA)
fl += INITDAT; fl += INITDAT;
if(dlm) if(dlm)
dynreloc(p->to.sym, l+s+INITDAT, 1); dynreloc(p->to.sym, l+s+INITDAT, 1);
@ -1257,6 +1273,8 @@ datblk(int32 s, int32 n)
*/ */
for(p = datap; p != P; p = p->link) { for(p = datap; p != P; p = p->link) {
a = &p->from; a = &p->from;
if(rodata != (a->sym->type == SRODATA))
continue;
l = a->sym->value + a->offset - s; l = a->sym->value + a->offset - s;
if(l < 0 || l >= n) if(l < 0 || l >= n)
@ -1272,26 +1290,26 @@ datblk(int32 s, int32 n)
case 4: case 4:
fl = ieeedtof(&p->to.ieee); fl = ieeedtof(&p->to.ieee);
cast = (char*)&fl; cast = (char*)&fl;
Bprint(&bso, pcstr, l+s+INITDAT); Bprint(&bso, pcstr, l+s+base);
for(j=0; j<c; j++) for(j=0; j<c; j++)
Bprint(&bso, "%.2ux", cast[fnuxi4[j]] & 0xff); Bprint(&bso, "%.2ux", cast[fnuxi4[j]] & 0xff);
Bprint(&bso, "\t%P\n", curp); Bprint(&bso, "\t%P\n", p);
break; break;
case 8: case 8:
cast = (char*)&p->to.ieee; cast = (char*)&p->to.ieee;
Bprint(&bso, pcstr, l+s+INITDAT); Bprint(&bso, pcstr, l+s+base);
for(j=0; j<c; j++) for(j=0; j<c; j++)
Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff); Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff);
Bprint(&bso, "\t%P\n", curp); Bprint(&bso, "\t%P\n", p);
break; break;
} }
break; break;
case D_SCONST: case D_SCONST:
Bprint(&bso, pcstr, l+s+INITDAT); Bprint(&bso, pcstr, l+s+base);
for(j=0; j<c; j++) for(j=0; j<c; j++)
Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff); Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff);
Bprint(&bso, "\t%P\n", curp); Bprint(&bso, "\t%P\n", p);
break; break;
default: default:
@ -1305,34 +1323,34 @@ datblk(int32 s, int32 n)
if(p->to.sym->type == SUNDEF) if(p->to.sym->type == SUNDEF)
ckoff(p->to.sym, fl); ckoff(p->to.sym, fl);
fl += p->to.sym->value; fl += p->to.sym->value;
if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF) if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF && p->to.sym->type != SRODATA)
fl += INITDAT; fl += INITDAT;
if(dlm) if(dlm)
dynreloc(p->to.sym, l+s+INITDAT, 1); dynreloc(p->to.sym, l+s+base, 1);
} }
} }
cast = (char*)&fl; cast = (char*)&fl;
switch(c) { switch(c) {
default: default:
diag("bad nuxi %d %d\n%P", c, i, curp); diag("bad nuxi %d %d\n%P", c, i, p);
break; break;
case 1: case 1:
Bprint(&bso, pcstr, l+s+INITDAT); Bprint(&bso, pcstr, l+s+base);
for(j=0; j<c; j++) for(j=0; j<c; j++)
Bprint(&bso, "%.2ux", cast[inuxi1[j]] & 0xff); Bprint(&bso, "%.2ux", cast[inuxi1[j]] & 0xff);
Bprint(&bso, "\t%P\n", curp); Bprint(&bso, "\t%P\n", p);
break; break;
case 2: case 2:
Bprint(&bso, pcstr, l+s+INITDAT); Bprint(&bso, pcstr, l+s+base);
for(j=0; j<c; j++) for(j=0; j<c; j++)
Bprint(&bso, "%.2ux", cast[inuxi2[j]] & 0xff); Bprint(&bso, "%.2ux", cast[inuxi2[j]] & 0xff);
Bprint(&bso, "\t%P\n", curp); Bprint(&bso, "\t%P\n", p);
break; break;
case 4: case 4:
Bprint(&bso, pcstr, l+s+INITDAT); Bprint(&bso, pcstr, l+s+base);
for(j=0; j<c; j++) for(j=0; j<c; j++)
Bprint(&bso, "%.2ux", cast[inuxi4[j]] & 0xff); Bprint(&bso, "%.2ux", cast[inuxi4[j]] & 0xff);
Bprint(&bso, "\t%P\n", curp); Bprint(&bso, "\t%P\n", p);
break; break;
} }
break; break;

View File

@ -163,6 +163,7 @@ enum
SFIXED, SFIXED,
SELFDATA, SELFDATA,
SRODATA,
NHASH = 10007, NHASH = 10007,
NHUNK = 100000, NHUNK = 100000,
@ -347,7 +348,7 @@ void ckoff(Sym*, int32);
Prog* copyp(Prog*); Prog* copyp(Prog*);
vlong cpos(void); vlong cpos(void);
double cputime(void); double cputime(void);
void datblk(int32, int32); void datblk(int32, int32, int32);
void diag(char*, ...); void diag(char*, ...);
void dodata(void); void dodata(void);
void doelf(void); void doelf(void);

View File

@ -47,7 +47,6 @@ static Prog *bigP;
int int
Pconv(Fmt *fp) Pconv(Fmt *fp)
{ {
char str[STRINGSZ];
Prog *p; Prog *p;
p = va_arg(fp->args, Prog*); p = va_arg(fp->args, Prog*);
@ -55,23 +54,23 @@ Pconv(Fmt *fp)
switch(p->as) { switch(p->as) {
case ATEXT: case ATEXT:
if(p->from.scale) { if(p->from.scale) {
sprint(str, "(%d) %A %D,%d,%D", fmtprint(fp, "(%d) %A %D,%d,%D",
p->line, p->as, &p->from, p->from.scale, &p->to); p->line, p->as, &p->from, p->from.scale, &p->to);
break; break;
} }
default: default:
sprint(str, "(%d) %A %D,%D", fmtprint(fp, "(%d) %A %D,%D",
p->line, p->as, &p->from, &p->to); p->line, p->as, &p->from, &p->to);
break; break;
case ADATA: case ADATA:
case AINIT: case AINIT:
case ADYNT: case ADYNT:
sprint(str, "(%d) %A %D/%d,%D", fmtprint(fp, "(%d) %A %D/%d,%D",
p->line, p->as, &p->from, p->from.scale, &p->to); p->line, p->as, &p->from, p->from.scale, &p->to);
break; break;
} }
bigP = P; bigP = P;
return fmtstrcpy(fp, str); return 0;
} }
int int
@ -102,15 +101,15 @@ Dconv(Fmt *fp)
i = a->type; i = a->type;
if(i >= D_INDIR && i < 2*D_INDIR) { if(i >= D_INDIR && i < 2*D_INDIR) {
if(a->offset) if(a->offset)
sprint(str, "%ld(%R)", (long)a->offset, i-D_INDIR); snprint(str, sizeof str, "%ld(%R)", (long)a->offset, i-D_INDIR);
else else
sprint(str, "(%R)", i-D_INDIR); snprint(str, sizeof str, "(%R)", i-D_INDIR);
goto brk; goto brk;
} }
switch(i) { switch(i) {
default: default:
sprint(str, "%R", i); snprint(str, sizeof str, "%R", i);
break; break;
case D_NONE: case D_NONE:
@ -120,54 +119,54 @@ Dconv(Fmt *fp)
case D_BRANCH: case D_BRANCH:
if(bigP != P && bigP->pcond != P) if(bigP != P && bigP->pcond != P)
if(a->sym != S) if(a->sym != S)
sprint(str, "%lux+%s", bigP->pcond->pc, snprint(str, sizeof str, "%lux+%s", bigP->pcond->pc,
a->sym->name); a->sym->name);
else else
sprint(str, "%lux", bigP->pcond->pc); snprint(str, sizeof str, "%lux", bigP->pcond->pc);
else else
sprint(str, "%ld(PC)", a->offset); snprint(str, sizeof str, "%ld(PC)", a->offset);
break; break;
case D_EXTERN: case D_EXTERN:
sprint(str, "%s+%ld(SB)", xsymname(a->sym), a->offset); snprint(str, sizeof str, "%s+%ld(SB)", xsymname(a->sym), a->offset);
break; break;
case D_STATIC: case D_STATIC:
sprint(str, "%s<%d>+%ld(SB)", xsymname(a->sym), snprint(str, sizeof str, "%s<%d>+%ld(SB)", xsymname(a->sym),
a->sym->version, a->offset); a->sym->version, a->offset);
break; break;
case D_AUTO: case D_AUTO:
sprint(str, "%s+%ld(SP)", xsymname(a->sym), a->offset); snprint(str, sizeof str, "%s+%ld(SP)", xsymname(a->sym), a->offset);
break; break;
case D_PARAM: case D_PARAM:
if(a->sym) if(a->sym)
sprint(str, "%s+%ld(FP)", a->sym->name, a->offset); snprint(str, sizeof str, "%s+%ld(FP)", a->sym->name, a->offset);
else else
sprint(str, "%ld(FP)", a->offset); snprint(str, sizeof str, "%ld(FP)", a->offset);
break; break;
case D_CONST: case D_CONST:
sprint(str, "$%ld", a->offset); snprint(str, sizeof str, "$%ld", a->offset);
break; break;
case D_CONST2: case D_CONST2:
sprint(str, "$%ld-%ld", a->offset, a->offset2); snprint(str, sizeof str, "$%ld-%ld", a->offset, a->offset2);
break; break;
case D_FCONST: case D_FCONST:
sprint(str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l); snprint(str, sizeof str, "$(%.8lux,%.8lux)", a->ieee.h, a->ieee.l);
break; break;
case D_SCONST: case D_SCONST:
sprint(str, "$\"%S\"", a->scon); snprint(str, sizeof str, "$\"%S\"", a->scon);
break; break;
case D_ADDR: case D_ADDR:
a->type = a->index; a->type = a->index;
a->index = D_NONE; a->index = D_NONE;
sprint(str, "$%D", a); snprint(str, sizeof str, "$%D", a);
a->index = a->type; a->index = a->type;
a->type = D_ADDR; a->type = D_ADDR;
goto conv; goto conv;

View File

@ -432,7 +432,7 @@ zsym(char *pn, Biobuf *f, Sym *h[])
void void
zaddr(char *pn, Biobuf *f, Adr *a, Sym *h[]) zaddr(char *pn, Biobuf *f, Adr *a, Sym *h[])
{ {
int o, t; int t;
int32 l; int32 l;
Sym *s; Sym *s;
Auto *u; Auto *u;
@ -652,18 +652,20 @@ loop:
s = p->from.sym; s = p->from.sym;
if(s->type == 0 || s->type == SXREF) { if(s->type == 0 || s->type == SXREF) {
s->type = SBSS; s->type = SBSS;
s->value = 0; s->size = 0;
} }
if(s->type != SBSS) { if(s->type != SBSS && !s->dupok) {
diag("%s: redefinition: %s in %s", diag("%s: redefinition: %s in %s",
pn, s->name, TNAME); pn, s->name, TNAME);
s->type = SBSS; s->type = SBSS;
s->value = 0; s->size = 0;
} }
if(p->to.offset > s->value) if(p->to.offset > s->size)
s->value = p->to.offset; s->size = p->to.offset;
if(p->from.scale & DUPOK) if(p->from.scale & DUPOK)
s->dupok = 1; s->dupok = 1;
if(p->from.scale & RODATA)
s->type = SRODATA;
goto loop; goto loop;
case ADYNT: case ADYNT:
@ -788,7 +790,7 @@ loop:
s = lookup(literal, 0); s = lookup(literal, 0);
if(s->type == 0) { if(s->type == 0) {
s->type = SBSS; s->type = SBSS;
s->value = 4; s->size = 4;
t = prg(); t = prg();
t->as = ADATA; t->as = ADATA;
t->line = p->line; t->line = p->line;
@ -827,7 +829,7 @@ loop:
s = lookup(literal, 0); s = lookup(literal, 0);
if(s->type == 0) { if(s->type == 0) {
s->type = SBSS; s->type = SBSS;
s->value = 8; s->size = 8;
t = prg(); t = prg();
t->as = ADATA; t->as = ADATA;
t->line = p->line; t->line = p->line;
@ -955,7 +957,7 @@ doprof1(void)
q->to.offset = n; q->to.offset = n;
s->type = SBSS; s->type = SBSS;
s->value = n*4; s->size = n*4;
} }
void void

View File

@ -55,13 +55,13 @@ dodata(void)
s->value = dtype; s->value = dtype;
if(s->type == SBSS) if(s->type == SBSS)
s->type = SDATA; s->type = SDATA;
if(s->type != SDATA && s->type != SELFDATA) if(s->type != SDATA && s->type != SELFDATA && s->type != SRODATA)
diag("initialize non-data (%d): %s\n%P", diag("initialize non-data (%d): %s\n%P",
s->type, s->name, p); s->type, s->name, p);
t = p->from.offset + p->width; t = p->from.offset + p->width;
if(t > s->value) if(t > s->size)
diag("initialize bounds (%ld): %s\n%P", diag("initialize bounds (%ld): %s\n%P",
s->value, s->name, p); s->size, s->name, p);
} }
/* allocate elf guys - must be segregated from real data */ /* allocate elf guys - must be segregated from real data */
@ -72,7 +72,7 @@ dodata(void)
continue; continue;
if(s->type != SELFDATA) if(s->type != SELFDATA)
continue; continue;
t = rnd(s->value, 4); t = rnd(s->size, 4);
s->size = t; s->size = t;
s->value = datsize; s->value = datsize;
datsize += t; datsize += t;
@ -87,14 +87,13 @@ dodata(void)
if(s->type != SDATA) if(s->type != SDATA)
if(s->type != SBSS) if(s->type != SBSS)
continue; continue;
t = s->value; t = s->size;
if(t == 0 && s->name[0] != '.') { if(t == 0 && s->name[0] != '.') {
diag("%s: no size", s->name); diag("%s: no size", s->name);
t = 1; t = 1;
} }
t = rnd(t, 4); t = rnd(t, 4);
s->size = t; s->size = t;
s->value = t;
if(t > MINSIZ) if(t > MINSIZ)
continue; continue;
s->value = datsize; s->value = datsize;
@ -110,8 +109,7 @@ dodata(void)
s->type = SDATA; s->type = SDATA;
continue; continue;
} }
t = s->value; t = s->size;
s->size = t;
s->value = datsize; s->value = datsize;
datsize += t; datsize += t;
} }
@ -154,8 +152,7 @@ dodata(void)
continue; continue;
if(s->type != SBSS) if(s->type != SBSS)
continue; continue;
t = s->value; t = s->size;
s->size = t;
s->value = bsssize + dynptrsize + datsize; s->value = bsssize + dynptrsize + datsize;
bsssize += t; bsssize += t;
} }
@ -1042,10 +1039,10 @@ export(void)
newdata(et, off, sizeof(int32), D_EXTERN); newdata(et, off, sizeof(int32), D_EXTERN);
off += sizeof(int32); off += sizeof(int32);
} }
et->value = off; et->size = off;
if(sv == 0) if(sv == 0)
sv = 1; sv = 1;
str->value = sv; str->size = sv;
exports = ne; exports = ne;
free(esyms); free(esyms);
} }

View File

@ -35,8 +35,9 @@ void
span(void) span(void)
{ {
Prog *p, *q; Prog *p, *q;
int32 v, c, idat; int32 i, v, c, idat;
int m, n, again; int m, n, again;
Sym *s;
xdefine("etext", STEXT, 0L); xdefine("etext", STEXT, 0L);
idat = INITDAT; idat = INITDAT;
@ -107,6 +108,21 @@ start:
n++; n++;
}while(again); }while(again);
/*
* allocate read-only data to the text segment.
*/
c = rnd(c, 8);
for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->link) {
if(s->type != SRODATA)
continue;
v = s->size;
while(v & 3)
v++;
s->value = c;
c += v;
}
if(INITRND) { if(INITRND) {
INITDAT = rnd(c+textpad, INITRND); INITDAT = rnd(c+textpad, INITRND);
if(INITDAT != idat) { if(INITDAT != idat) {
@ -114,6 +130,7 @@ start:
goto start; goto start;
} }
} }
xdefine("etext", STEXT, c); xdefine("etext", STEXT, c);
if(debug['v']) if(debug['v'])
Bprint(&bso, "etext = %lux\n", c); Bprint(&bso, "etext = %lux\n", c);
@ -208,6 +225,7 @@ asmsym(void)
for(s=hash[h]; s!=S; s=s->link) for(s=hash[h]; s!=S; s=s->link)
switch(s->type) { switch(s->type) {
case SCONST: case SCONST:
case SRODATA:
if(!s->reachable) if(!s->reachable)
continue; continue;
putsymb(s->name, 'D', s->value, s->version, s->gotype); putsymb(s->name, 'D', s->value, s->version, s->gotype);
@ -618,6 +636,7 @@ vaddr(Adr *a)
ckoff(s, v); ckoff(s, v);
case STEXT: case STEXT:
case SCONST: case SCONST:
case SRODATA:
if(!s->reachable) if(!s->reachable)
sysfatal("unreachable symbol in vaddr - %s", s->name); sysfatal("unreachable symbol in vaddr - %s", s->name);
v += s->value; v += s->value;

View File

@ -211,6 +211,7 @@ struct Node
uchar used; uchar used;
uchar isddd; uchar isddd;
uchar pun; // dont registerize variable ONAME uchar pun; // dont registerize variable ONAME
uchar readonly;
// most nodes // most nodes
Node* left; Node* left;

View File

@ -2600,6 +2600,7 @@ staticname(Type *t)
snprint(namebuf, sizeof(namebuf), "statictmp_%.4d", statuniqgen); snprint(namebuf, sizeof(namebuf), "statictmp_%.4d", statuniqgen);
statuniqgen++; statuniqgen++;
n = newname(lookup(namebuf)); n = newname(lookup(namebuf));
// n->readonly = 1;
addvar(n, t, PEXTERN); addvar(n, t, PEXTERN);
return n; return n;
} }

View File

@ -495,6 +495,7 @@ lookup(char *symb, int v)
s->version = v; s->version = v;
s->value = 0; s->value = 0;
s->sig = 0; s->sig = 0;
s->size = 0;
hash[h] = s; hash[h] = s;
nsymbol++; nsymbol++;
return s; return s;

View File

@ -533,7 +533,7 @@ asmbmacho(vlong symdatva, vlong symo)
ml->data[0] = 4; /* thread type */ ml->data[0] = 4; /* thread type */
ml->data[1] = 42; /* word count */ ml->data[1] = 42; /* word count */
ml->data[2+32] = entryvalue(); /* start pc */ ml->data[2+32] = entryvalue(); /* start pc */
ml->data[2+32+1] = entryvalue()>>32; ml->data[2+32+1] = entryvalue()>>16>>16; // hide >>32 for 8l
break; break;
case '8': case '8':
ml = newMachoLoad(5, 16+2); /* unix thread */ ml = newMachoLoad(5, 16+2); /* unix thread */