diff options
| author | Russ Cox <rsc@golang.org> | 2010-09-19 22:10:34 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2010-09-19 22:10:34 -0400 |
| commit | af12feb8d514b5970c984be61b07c56e0e72b2ce (patch) | |
| tree | c18b5c9b0cabfd8ba2cf0abb12f73bfbf8c4d96b /src/cmd/8l | |
| parent | afbee9d87d1ce9fd98e1beb9ac8945263c1f3e52 (diff) | |
| download | go-af12feb8d514b5970c984be61b07c56e0e72b2ce.tar.xz | |
6l, 8l: clean up ELF code, fix NaCl
R=r
CC=golang-dev
https://golang.org/cl/2221042
Diffstat (limited to 'src/cmd/8l')
| -rw-r--r-- | src/cmd/8l/asm.c | 141 | ||||
| -rw-r--r-- | src/cmd/8l/pass.c | 15 | ||||
| -rw-r--r-- | src/cmd/8l/span.c | 59 |
3 files changed, 108 insertions, 107 deletions
diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c index 9e5790ecdc..0675b904b9 100644 --- a/src/cmd/8l/asm.c +++ b/src/cmd/8l/asm.c @@ -129,6 +129,7 @@ addstring(Sym *s, char *str) s->reachable = 1; r = s->size; n = strlen(str)+1; + elfsetstring(str, r); while(n > 0) { m = n; if(m > sizeof(p->to.scon)) @@ -227,11 +228,8 @@ addsize(Sym *s, Sym *t) vlong datoff(vlong addr) { - if(addr >= INITDAT) { - if(HEADTYPE == 8) - return addr - INITDAT + rnd(HEADR+textsize, 4096); - return addr - INITDAT + rnd(HEADR+textsize, INITRND); - } + if(addr >= segdata.vaddr) + return addr - segdata.vaddr + segdata.fileoff; diag("datoff %#llx", addr); return 0; } @@ -290,6 +288,10 @@ doelf(void) elfstr[ElfStrText] = addstring(shstrtab, ".text"); elfstr[ElfStrData] = addstring(shstrtab, ".data"); elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); + addstring(shstrtab, ".elfdata"); + if(HEADTYPE == 8) + addstring(shstrtab, ".closure"); + addstring(shstrtab, ".rodata"); if(!debug['s']) { elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts"); elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab"); @@ -455,12 +457,13 @@ asmb(void) Prog *p; int32 v, magic; int a, dynsym; - uint32 va, fo, w, symo, startva, machlink, etext; + uint32 va, fo, w, symo, startva, machlink, erodata; uchar *op1; ulong expectpc; ElfEhdr *eh; ElfPhdr *ph, *pph; ElfShdr *sh; + Section *sect; if(debug['v']) Bprint(&bso, "%5.2f asmb\n", cputime()); @@ -523,20 +526,31 @@ asmb(void) cbc -= a; } if(HEADTYPE == 8) { - while(pc < INITDAT) { + int32 etext; + + etext = rnd(segtext.vaddr + segtext.filelen, 4096); + while(pc < etext) { cput(0xf4); // hlt pc++; } + pc = segrodata.vaddr; } 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) + if(HEADTYPE == 8) { + // Native Client + sect = segrodata.sect; + segrodata.fileoff = seek(cout, 0, 1); + } else + sect = segtext.sect->next; + + erodata = sect->vaddr + sect->len; + for(v = pc; v < erodata; v += sizeof(buf)-Dbufslop) { + if(erodata-v > sizeof(buf)-Dbufslop) datblk(v, sizeof(buf)-Dbufslop, 1); else - datblk(v, etext-v, 1); + datblk(v, erodata-v, 1); } switch(HEADTYPE) { @@ -573,12 +587,12 @@ asmb(void) // text segment file address to 4096 bytes, // but text segment memory address rounds // to INITRND (65536). - v = rnd(HEADR+textsize, 4096); + v = rnd(segrodata.fileoff+segrodata.filelen, 4096); seek(cout, v, 0); break; Elfseek: case 10: - v = rnd(HEADR+textsize, INITRND); + v = rnd(segtext.fileoff+segtext.filelen, INITRND); seek(cout, v, 0); break; } @@ -594,6 +608,7 @@ asmb(void) textsize = INITDAT; } + segdata.fileoff = seek(cout, 0, 1); for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) { if(datsize-v > sizeof(buf)-Dbufslop) datblk(v, sizeof(buf)-Dbufslop, 0); @@ -859,50 +874,18 @@ asmb(void) phsh(ph, sh); } - ph = newElfPhdr(); - ph->type = PT_LOAD; - ph->flags = PF_X+PF_R; - if(HEADTYPE != 8) { // Include header, but not on Native Client. - va -= fo; - w += fo; - fo = 0; - } - ph->vaddr = va; - ph->paddr = va; - ph->off = fo; - ph->filesz = w; - ph->memsz = INITDAT - va; - ph->align = INITRND; - - // NaCl text segment file address rounds to 4096; - // only memory address rounds to INITRND. - if(HEADTYPE == 8) - fo = rnd(fo+w, 4096); - else - fo = rnd(fo+w, INITRND); - va = INITDAT; - w = datsize; - - ph = newElfPhdr(); - ph->type = PT_LOAD; - ph->flags = PF_W+PF_R; - ph->off = fo; - ph->vaddr = va; - ph->paddr = va; - ph->filesz = w; - ph->memsz = w+bsssize; - ph->align = INITRND; + elfphload(&segtext); + if(segrodata.len > 0) + elfphload(&segrodata); + elfphload(&segdata); if(!debug['s'] && HEADTYPE != 8 && HEADTYPE != 11) { - ph = newElfPhdr(); - ph->type = PT_LOAD; - ph->flags = PF_R; - ph->off = symo; - ph->vaddr = symdatva; - ph->paddr = symdatva; - ph->filesz = rnd(8+symsize+lcsize, INITRND); - ph->memsz = rnd(8+symsize+lcsize, INITRND); - ph->align = INITRND; + segsym.rwx = 04; + segsym.vaddr = symdatva; + segsym.len = rnd(8+symsize+lcsize, INITRND); + segsym.fileoff = symo; + segsym.filelen = segsym.len; + elfphload(&segsym); } /* Dynamic linking sections */ @@ -984,46 +967,12 @@ asmb(void) ph->flags = PF_W+PF_R; ph->align = 4; - fo = HEADR; - va = startva + fo; - w = textsize; - - sh = newElfShdr(elfstr[ElfStrText]); - sh->type = SHT_PROGBITS; - sh->flags = SHF_ALLOC+SHF_EXECINSTR; - sh->addr = va; - sh->off = fo; - sh->size = w; - sh->addralign = 4; - - // NaCl text segment file address rounds to 4096; - // only memory address rounds to INITRND. - if(HEADTYPE == 8) - fo = rnd(fo+w, 4096); - else - fo = rnd(fo+w, INITRND); - va = rnd(va+w, INITRND); - w = datsize; - - sh = newElfShdr(elfstr[ElfStrData]); - sh->type = SHT_PROGBITS; - sh->flags = SHF_WRITE+SHF_ALLOC; - sh->addr = va + elfdatsize; - sh->off = fo + elfdatsize; - sh->size = w - elfdatsize; - sh->addralign = 4; - - fo += w; - va += w; - w = bsssize; - - sh = newElfShdr(elfstr[ElfStrBss]); - sh->type = SHT_NOBITS; - sh->flags = SHF_WRITE+SHF_ALLOC; - sh->addr = va; - sh->off = fo; - sh->size = w; - sh->addralign = 4; + for(sect=segtext.sect; sect!=nil; sect=sect->next) + elfshbits(sect); + for(sect=segrodata.sect; sect!=nil; sect=sect->next) + elfshbits(sect); + for(sect=segdata.sect; sect!=nil; sect=sect->next) + elfshbits(sect); if (!debug['s']) { fo = symo; diff --git a/src/cmd/8l/pass.c b/src/cmd/8l/pass.c index dd27878725..bf09fd9111 100644 --- a/src/cmd/8l/pass.c +++ b/src/cmd/8l/pass.c @@ -45,10 +45,15 @@ dodata(void) Sym *s; Prog *p; int32 t, u; + Section *sect; if(debug['v']) Bprint(&bso, "%5.2f dodata\n", cputime()); Bflush(&bso); + + segdata.rwx = 06; + segdata.vaddr = 0; /* span will += INITDAT */ + for(p = datap; p != P; p = p->link) { s = p->from.sym; if(p->as == ADYNT || p->as == AINIT) @@ -79,6 +84,9 @@ dodata(void) } elfdatsize = datsize; + sect = addsection(&segdata, ".data", 06); + sect->vaddr = datsize; + /* allocate small guys */ for(i=0; i<NHASH; i++) for(s = hash[i]; s != S; s = s->link) { @@ -143,8 +151,11 @@ dodata(void) /* dynamic pointer section between data and bss */ datsize = rnd(datsize, 4); } + sect->len = datsize - sect->vaddr; /* now the bss */ + sect = addsection(&segdata, ".bss", 06); + sect->vaddr = datsize; bsssize = 0; for(i=0; i<NHASH; i++) for(s = hash[i]; s != S; s = s->link) { @@ -156,6 +167,10 @@ dodata(void) s->value = bsssize + dynptrsize + datsize; bsssize += t; } + sect->len = bsssize; + + segdata.len = datsize+bsssize; + segdata.filelen = datsize; xdefine("data", SBSS, 0); xdefine("edata", SBSS, datsize); diff --git a/src/cmd/8l/span.c b/src/cmd/8l/span.c index 373ab8a9c6..105d18b9f8 100644 --- a/src/cmd/8l/span.c +++ b/src/cmd/8l/span.c @@ -35,9 +35,10 @@ void span(void) { Prog *p, *q; - int32 i, v, c, idat; + int32 i, v, c, idat, etext, rodata, erodata; int m, n, again; Sym *s; + Section *sect; xdefine("etext", STEXT, 0L); xdefine("rodata", SRODATA, 0L); @@ -110,13 +111,16 @@ start: textsize = c; n++; }while(again); - xdefine("etext", STEXT, c); + etext = c; + c += textpad; /* * allocate read-only data to the text segment. */ + if(HEADTYPE == 8) + c = rnd(c, INITRND); c = rnd(c, 8); - xdefine("rodata", SRODATA, c); + rodata = c; for(i=0; i<NHASH; i++) for(s = hash[i]; s != S; s = s->link) { if(s->type != SRODATA) @@ -127,22 +131,59 @@ start: s->value = c; c += v; } - xdefine("erodata", SRODATA, c); + erodata = c; if(INITRND) { - INITDAT = rnd(c+textpad, INITRND); + INITDAT = rnd(c, INITRND); if(INITDAT != idat) { idat = INITDAT; goto start; } } + xdefine("etext", STEXT, etext); + xdefine("rodata", SRODATA, rodata); + xdefine("erodata", SRODATA, erodata); + if(debug['v']) Bprint(&bso, "etext = %lux\n", c); Bflush(&bso); for(p = textp; p != P; p = p->pcond) p->from.sym->value = p->pc; textsize = c - INITTEXT; + + segtext.rwx = 05; + if(HEADTYPE == 8) { + segtext.vaddr = INITTEXT; + segtext.len = rodata - INITTEXT; + segtext.fileoff = HEADR; + segtext.filelen = etext - INITTEXT; + + segrodata.rwx = 04; + segrodata.vaddr = rodata; + segrodata.len = erodata - rodata; + segrodata.filelen = segrodata.len; + } else { + segtext.vaddr = INITTEXT - HEADR; + segtext.len = INITDAT - INITTEXT + HEADR; + segtext.fileoff = 0; + segtext.filelen = segtext.len; + } + + sect = addsection(&segtext, ".text", 05); + sect->vaddr = INITTEXT; + sect->len = etext - sect->vaddr; + + if(HEADTYPE == 8) + sect = addsection(&segrodata, ".rodata", 04); + else + sect = addsection(&segtext, ".rodata", 04); + sect->vaddr = rodata; + sect->len = erodata - rodata; + + segdata.vaddr += INITDAT; + for(sect=segdata.sect; sect!=nil; sect=sect->next) + sect->vaddr += INITDAT; } void @@ -151,12 +192,8 @@ xdefine(char *p, int t, int32 v) Sym *s; s = lookup(p, 0); - if(s->type == 0 || s->type == SXREF) { - s->type = t; - s->value = v; - } - if(s->type == STEXT && s->value == 0) - s->value = v; + s->type = t; + s->value = v; } void |
