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/6l | |
| 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/6l')
| -rw-r--r-- | src/cmd/6l/asm.c | 102 | ||||
| -rw-r--r-- | src/cmd/6l/pass.c | 17 | ||||
| -rw-r--r-- | src/cmd/6l/span.c | 37 |
3 files changed, 73 insertions, 83 deletions
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c index 53d539363c..d46721568c 100644 --- a/src/cmd/6l/asm.c +++ b/src/cmd/6l/asm.c @@ -138,6 +138,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)) @@ -236,8 +237,8 @@ addsize(Sym *s, Sym *t) vlong datoff(vlong addr) { - if(addr >= INITDAT) - return addr - INITDAT + rnd(HEADR+textsize, INITRND); + if(addr >= segdata.vaddr) + return addr - segdata.vaddr + segdata.fileoff; diag("datoff %#llx", addr); return 0; } @@ -297,6 +298,8 @@ doelf(void) elfstr[ElfStrText] = addstring(shstrtab, ".text"); elfstr[ElfStrData] = addstring(shstrtab, ".data"); elfstr[ElfStrBss] = addstring(shstrtab, ".bss"); + addstring(shstrtab, ".elfdata"); + addstring(shstrtab, ".rodata"); if(!debug['s']) { elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts"); elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab"); @@ -466,16 +469,18 @@ asmb(void) int32 v, magic; int a, dynsym; uchar *op1; - vlong vl, va, startva, fo, w, symo, elfsymo, elfstro, elfsymsize, machlink, etext; + vlong vl, va, startva, fo, w, symo, elfsymo, elfstro, elfsymsize, machlink, erodata; vlong symdatva = SYMDATVA; ElfEhdr *eh; ElfPhdr *ph, *pph; ElfShdr *sh; + Section *sect; if(debug['v']) Bprint(&bso, "%5.2f asmb\n", cputime()); Bflush(&bso); + segtext.fileoff = 0; elftextsh = 0; elfsymsize = 0; elfstro = 0; @@ -521,12 +526,13 @@ asmb(void) 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) + 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); else - datblk(v, etext-v); + datblk(v, erodata-v); } switch(HEADTYPE) { @@ -573,6 +579,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+INITDAT, sizeof(buf)-Dbufslop); @@ -736,40 +743,16 @@ asmb(void) phsh(ph, sh); } - ph = newElfPhdr(); - ph->type = PT_LOAD; - ph->flags = PF_X+PF_R; - ph->vaddr = va - fo; - ph->paddr = va - fo; - ph->off = 0; - ph->filesz = w + fo; - ph->memsz = w + fo; - ph->align = INITRND; - - fo = rnd(fo+w, INITRND); - va = rnd(va+w, INITRND); - 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); + elfphload(&segdata); if(!debug['s']) { - 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 */ @@ -851,43 +834,14 @@ asmb(void) ph->flags = PF_W+PF_R; ph->align = 8; - fo = ELFRESERVE; - va = startva + fo; - w = textsize; - if(elftextsh != eh->shnum) diag("elftextsh = %d, want %d", elftextsh, eh->shnum); - 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 = 8; - - 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 = 8; - - 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 = 8; + 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/6l/pass.c b/src/cmd/6l/pass.c index 275844c9b4..ea3351239f 100644 --- a/src/cmd/6l/pass.c +++ b/src/cmd/6l/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) { curtext = p; // for diag messages s = p->from.sym; @@ -79,6 +84,9 @@ dodata(void) datsize += t; } elfdatsize = datsize; + + sect = addsection(&segdata, ".data", 06); + sect->vaddr = datsize; /* allocate small guys */ for(i=0; i<NHASH; i++) @@ -147,6 +155,7 @@ dodata(void) } datsize += u; } + sect->len = datsize - sect->vaddr; } void @@ -155,12 +164,16 @@ dobss(void) int i; Sym *s; int32 t; + Section *sect; if(dynptrsize > 0) { /* dynamic pointer section between data and bss */ datsize = rnd(datsize, 8); } + sect = addsection(&segdata, ".bss", 06); + sect->vaddr = datsize; + /* now the bss */ bsssize = 0; for(i=0; i<NHASH; i++) @@ -175,6 +188,10 @@ dobss(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/6l/span.c b/src/cmd/6l/span.c index f18398a23a..49efa9a2e7 100644 --- a/src/cmd/6l/span.c +++ b/src/cmd/6l/span.c @@ -40,9 +40,10 @@ span(void) { Prog *p, *q; int32 i, v; - vlong c, idat; + vlong c, idat, etext, rodata, erodata; int m, n, again; Sym *s; + Section *sect; xdefine("etext", STEXT, 0L); xdefine("rodata", SRODATA, 0L); @@ -125,12 +126,13 @@ loop: textsize = c; goto loop; } - xdefine("etext", STEXT, c); + etext = c; /* * allocate read-only data to the text segment. */ c = rnd(c, 8); + rodata = c; xdefine("rodata", SRODATA, c); for(i=0; i<NHASH; i++) for(s = hash[i]; s != S; s = s->link) { @@ -142,7 +144,7 @@ loop: s->value = c; c += v; } - xdefine("erodata", SRODATA, c); + erodata = c; if(INITRND) { INITDAT = rnd(c, INITRND); @@ -151,6 +153,10 @@ loop: goto start; } } + + xdefine("etext", STEXT, etext); + xdefine("rodata", SRODATA, rodata); + xdefine("erodata", SRODATA, erodata); if(debug['v']) Bprint(&bso, "etext = %llux\n", c); @@ -158,6 +164,23 @@ loop: for(p = textp; p != P; p = p->pcond) p->from.sym->value = p->pc; textsize = c - INITTEXT; + + segtext.rwx = 05; + segtext.vaddr = INITTEXT - HEADR; + segtext.len = INITDAT - INITTEXT + HEADR; + segtext.filelen = textsize + HEADR; + + sect = addsection(&segtext, ".text", 05); + sect->vaddr = INITTEXT; + sect->len = etext - sect->vaddr; + + 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 @@ -166,12 +189,8 @@ xdefine(char *p, int t, vlong 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 |
