diff options
Diffstat (limited to 'src/cmd/ld/data.c')
-rw-r--r-- | src/cmd/ld/data.c | 970 |
1 files changed, 0 insertions, 970 deletions
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c deleted file mode 100644 index f1132fc8b..000000000 --- a/src/cmd/ld/data.c +++ /dev/null @@ -1,970 +0,0 @@ -// Inferno utils/8l/asm.c -// http://code.google.com/p/inferno-os/source/browse/utils/8l/asm.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -// Data layout and relocation. - -#include "l.h" -#include "../ld/lib.h" -#include "../ld/elf.h" -#include "../ld/pe.h" - -void dynreloc(void); - -/* - * divide-and-conquer list-link - * sort of Sym* structures. - * Used for the data block. - */ -int -datcmp(Sym *s1, Sym *s2) -{ - if(s1->type != s2->type) - return (int)s1->type - (int)s2->type; - if(s1->size != s2->size) { - if(s1->size < s2->size) - return -1; - return +1; - } - return strcmp(s1->name, s2->name); -} - -Sym* -datsort(Sym *l) -{ - Sym *l1, *l2, *le; - - if(l == 0 || l->next == 0) - return l; - - l1 = l; - l2 = l; - for(;;) { - l2 = l2->next; - if(l2 == 0) - break; - l2 = l2->next; - if(l2 == 0) - break; - l1 = l1->next; - } - - l2 = l1->next; - l1->next = 0; - l1 = datsort(l); - l2 = datsort(l2); - - /* set up lead element */ - if(datcmp(l1, l2) < 0) { - l = l1; - l1 = l1->next; - } else { - l = l2; - l2 = l2->next; - } - le = l; - - for(;;) { - if(l1 == 0) { - while(l2) { - le->next = l2; - le = l2; - l2 = l2->next; - } - le->next = 0; - break; - } - if(l2 == 0) { - while(l1) { - le->next = l1; - le = l1; - l1 = l1->next; - } - break; - } - if(datcmp(l1, l2) < 0) { - le->next = l1; - le = l1; - l1 = l1->next; - } else { - le->next = l2; - le = l2; - l2 = l2->next; - } - } - le->next = 0; - return l; -} - -Reloc* -addrel(Sym *s) -{ - if(s->nr >= s->maxr) { - if(s->maxr == 0) - s->maxr = 4; - else - s->maxr <<= 1; - s->r = realloc(s->r, s->maxr*sizeof s->r[0]); - if(s->r == 0) { - diag("out of memory"); - errorexit(); - } - memset(s->r+s->nr, 0, (s->maxr-s->nr)*sizeof s->r[0]); - } - return &s->r[s->nr++]; -} - -void -relocsym(Sym *s) -{ - Reloc *r; - Prog p; - int32 i, off, siz, fl; - vlong o; - uchar *cast; - - cursym = s; - memset(&p, 0, sizeof p); - for(r=s->r; r<s->r+s->nr; r++) { - off = r->off; - siz = r->siz; - if(off < 0 || off+(siz&~Rbig) > s->np) { - diag("%s: invalid relocation %d+%d not in [%d,%d)", s->name, off, siz&~Rbig, 0, s->np); - continue; - } - if(r->sym != S && (r->sym->type == 0 || r->sym->type == SXREF)) { - diag("%s: not defined", r->sym->name); - continue; - } - if(r->type >= 256) - continue; - - if(r->sym != S && r->sym->type == SDYNIMPORT) - diag("unhandled relocation for %s (type %d rtype %d)", r->sym->name, r->sym->type, r->type); - - if(r->sym != S && !r->sym->reachable) - diag("unreachable sym in relocation: %s %s", s->name, r->sym->name); - - switch(r->type) { - default: - o = 0; - if(archreloc(r, s, &o) < 0) - diag("unknown reloc %d", r->type); - break; - case D_ADDR: - o = symaddr(r->sym) + r->add; - break; - case D_PCREL: - o = symaddr(r->sym) + r->add - (s->value + r->off + r->siz); - break; - case D_SIZE: - o = r->sym->size + r->add; - break; - } -//print("relocate %s %p %s => %p %p %p %p [%p]\n", s->name, s->value+off, r->sym ? r->sym->name : "<nil>", (void*)symaddr(r->sym), (void*)s->value, (void*)r->off, (void*)r->siz, (void*)o); - switch(siz) { - default: - cursym = s; - diag("bad reloc size %#ux for %s", siz, r->sym->name); - case 4 + Rbig: - fl = o; - s->p[off] = fl>>24; - s->p[off+1] = fl>>16; - s->p[off+2] = fl>>8; - s->p[off+3] = fl; - break; - case 4 + Rlittle: - fl = o; - s->p[off] = fl; - s->p[off+1] = fl>>8; - s->p[off+2] = fl>>16; - s->p[off+3] = fl>>24; - break; - case 4: - fl = o; - cast = (uchar*)&fl; - for(i=0; i<4; i++) - s->p[off+i] = cast[inuxi4[i]]; - break; - case 8: - cast = (uchar*)&o; - for(i=0; i<8; i++) - s->p[off+i] = cast[inuxi8[i]]; - break; - } - } -} - -void -reloc(void) -{ - Sym *s; - - if(debug['v']) - Bprint(&bso, "%5.2f reloc\n", cputime()); - Bflush(&bso); - - for(s=textp; s!=S; s=s->next) - relocsym(s); - for(s=datap; s!=S; s=s->next) - relocsym(s); -} - -void -dynrelocsym(Sym *s) -{ - Reloc *r; - - if(HEADTYPE == Hwindows) { - Sym *rel, *targ; - - rel = lookup(".rel", 0); - if(s == rel) - return; - for(r=s->r; r<s->r+s->nr; r++) { - targ = r->sym; - if(r->sym->plt == -2 && r->sym->got != -2) { // make dynimport JMP table for PE object files. - targ->plt = rel->size; - r->sym = rel; - r->add = targ->plt; - - // jmp *addr - adduint8(rel, 0xff); - adduint8(rel, 0x25); - addaddr(rel, targ); - adduint8(rel, 0x90); - adduint8(rel, 0x90); - } else if(r->sym->plt >= 0) { - r->sym = rel; - r->add = targ->plt; - } - } - return; - } - - for(r=s->r; r<s->r+s->nr; r++) - if(r->sym->type == SDYNIMPORT || r->type >= 256) - adddynrel(s, r); -} - -void -dynreloc(void) -{ - Sym *s; - - // -d supresses dynamic loader format, so we may as well not - // compute these sections or mark their symbols as reachable. - if(debug['d'] && HEADTYPE != Hwindows) - return; - if(debug['v']) - Bprint(&bso, "%5.2f reloc\n", cputime()); - Bflush(&bso); - - for(s=textp; s!=S; s=s->next) - dynrelocsym(s); - for(s=datap; s!=S; s=s->next) - dynrelocsym(s); - if(iself) - elfdynhash(); -} - -void -symgrow(Sym *s, int32 siz) -{ - if(s->np >= siz) - return; - - if(s->maxp < siz) { - if(s->maxp == 0) - s->maxp = 8; - while(s->maxp < siz) - s->maxp <<= 1; - s->p = realloc(s->p, s->maxp); - if(s->p == nil) { - diag("out of memory"); - errorexit(); - } - memset(s->p+s->np, 0, s->maxp-s->np); - } - s->np = siz; -} - -void -savedata(Sym *s, Prog *p, char *pn) -{ - int32 off, siz, i, fl; - uchar *cast; - vlong o; - Reloc *r; - - off = p->from.offset; - siz = p->datasize; - if(off < 0 || siz < 0 || off >= 1<<30 || siz >= 100) - mangle(pn); - symgrow(s, off+siz); - - switch(p->to.type) { - default: - diag("bad data: %P", p); - break; - - case D_FCONST: - switch(siz) { - default: - case 4: - fl = ieeedtof(&p->to.ieee); - cast = (uchar*)&fl; - for(i=0; i<4; i++) - s->p[off+i] = cast[fnuxi4[i]]; - break; - case 8: - cast = (uchar*)&p->to.ieee; - for(i=0; i<8; i++) - s->p[off+i] = cast[fnuxi8[i]]; - break; - } - break; - - case D_SCONST: - for(i=0; i<siz; i++) - s->p[off+i] = p->to.scon[i]; - break; - - case D_CONST: - if(p->to.sym) - goto Addr; - o = p->to.offset; - fl = o; - cast = (uchar*)&fl; - switch(siz) { - default: - diag("bad nuxi %d\n%P", siz, p); - break; - case 1: - s->p[off] = cast[inuxi1[0]]; - break; - case 2: - for(i=0; i<2; i++) - s->p[off+i] = cast[inuxi2[i]]; - break; - case 4: - for(i=0; i<4; i++) - s->p[off+i] = cast[inuxi4[i]]; - break; - case 8: - cast = (uchar*)&o; - for(i=0; i<8; i++) - s->p[off+i] = cast[inuxi8[i]]; - break; - } - break; - - case D_ADDR: - case D_SIZE: - Addr: - r = addrel(s); - r->off = off; - r->siz = siz; - r->sym = p->to.sym; - r->type = p->to.type; - if(r->type != D_SIZE) - r->type = D_ADDR; - r->add = p->to.offset; - break; - } -} - -static void -blk(Sym *allsym, int32 addr, int32 size) -{ - Sym *sym; - int32 eaddr; - uchar *p, *ep; - - for(sym = allsym; sym != nil; sym = sym->next) - if(!(sym->type&SSUB) && sym->value >= addr) - break; - - eaddr = addr+size; - for(; sym != nil; sym = sym->next) { - if(sym->type&SSUB) - continue; - if(sym->value >= eaddr) - break; - if(sym->value < addr) { - diag("phase error: addr=%#llx but sym=%#llx type=%d", (vlong)addr, (vlong)sym->value, sym->type); - errorexit(); - } - cursym = sym; - for(; addr < sym->value; addr++) - cput(0); - p = sym->p; - ep = p + sym->np; - while(p < ep) - cput(*p++); - addr += sym->np; - for(; addr < sym->value+sym->size; addr++) - cput(0); - if(addr != sym->value+sym->size) { - diag("phase error: addr=%#llx value+size=%#llx", (vlong)addr, (vlong)sym->value+sym->size); - errorexit(); - } - } - - for(; addr < eaddr; addr++) - cput(0); - cflush(); -} - -void -codeblk(int32 addr, int32 size) -{ - Sym *sym; - int32 eaddr, n, epc; - Prog *p; - uchar *q; - - if(debug['a']) - Bprint(&bso, "codeblk [%#x,%#x) at offset %#llx\n", addr, addr+size, seek(cout, 0, 1)); - - blk(textp, addr, size); - - /* again for printing */ - if(!debug['a']) - return; - - for(sym = textp; sym != nil; sym = sym->next) { - if(!sym->reachable) - continue; - if(sym->value >= addr) - break; - } - - eaddr = addr + size; - for(; sym != nil; sym = sym->next) { - if(!sym->reachable) - continue; - if(sym->value >= eaddr) - break; - - if(addr < sym->value) { - Bprint(&bso, "%-20s %.8llux|", "_", (vlong)addr); - for(; addr < sym->value; addr++) - Bprint(&bso, " %.2ux", 0); - Bprint(&bso, "\n"); - } - p = sym->text; - if(p == nil) { - Bprint(&bso, "%.6llux\t%-20s | foreign text\n", (vlong)addr, sym->name); - n = sym->size; - q = sym->p; - - while(n >= 16) { - Bprint(&bso, "%.6ux\t%-20.16I\n", addr, q); - addr += 16; - q += 16; - n -= 16; - } - if(n > 0) - Bprint(&bso, "%.6ux\t%-20.*I\n", addr, (int)n, q); - addr += n; - continue; - } - - Bprint(&bso, "%.6llux\t%-20s | %P\n", (vlong)sym->value, sym->name, p); - for(p = p->link; p != P; p = p->link) { - if(p->link != P) - epc = p->link->pc; - else - epc = sym->value + sym->size; - Bprint(&bso, "%.6ux\t", p->pc); - q = sym->p + p->pc - sym->value; - n = epc - p->pc; - Bprint(&bso, "%-20.*I | %P\n", (int)n, q, p); - addr += n; - } - } - - if(addr < eaddr) { - Bprint(&bso, "%-20s %.8llux|", "_", (vlong)addr); - for(; addr < eaddr; addr++) - Bprint(&bso, " %.2ux", 0); - } - Bflush(&bso); -} - -void -datblk(int32 addr, int32 size) -{ - Sym *sym; - int32 eaddr; - uchar *p, *ep; - - if(debug['a']) - Bprint(&bso, "datblk [%#x,%#x) at offset %#llx\n", addr, addr+size, seek(cout, 0, 1)); - - blk(datap, addr, size); - - /* again for printing */ - if(!debug['a']) - return; - - for(sym = datap; sym != nil; sym = sym->next) - if(sym->value >= addr) - break; - - eaddr = addr + size; - for(; sym != nil; sym = sym->next) { - if(sym->value >= eaddr) - break; - if(addr < sym->value) { - Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(pre-pad)", addr); - addr = sym->value; - } - Bprint(&bso, "%-20s %.8ux|", sym->name, (uint)addr); - p = sym->p; - ep = p + sym->np; - while(p < ep) - Bprint(&bso, " %.2ux", *p++); - addr += sym->np; - for(; addr < sym->value+sym->size; addr++) - Bprint(&bso, " %.2ux", 0); - Bprint(&bso, "\n"); - } - - if(addr < eaddr) - Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(post-pad)", (uint)addr); - Bprint(&bso, "%-20s %.8ux|\n", "", (uint)eaddr); -} - -void -strnput(char *s, int n) -{ - for(; *s && n > 0; s++) { - cput(*s); - n--; - } - while(n > 0) { - cput(0); - n--; - } -} - -vlong -addstring(Sym *s, char *str) -{ - int n; - int32 r; - - if(s->type == 0) - s->type = SDATA; - s->reachable = 1; - r = s->size; - n = strlen(str)+1; - if(strcmp(s->name, ".shstrtab") == 0) - elfsetstring(str, r); - symgrow(s, r+n); - memmove(s->p+r, str, n); - s->size += n; - return r; -} - -vlong -adduintxx(Sym *s, uint64 v, int wid) -{ - int32 i, r, fl; - vlong o; - uchar *cast; - - if(s->type == 0) - s->type = SDATA; - s->reachable = 1; - r = s->size; - s->size += wid; - symgrow(s, s->size); - assert(r+wid <= s->size); - fl = v; - cast = (uchar*)&fl; - switch(wid) { - case 1: - s->p[r] = cast[inuxi1[0]]; - break; - case 2: - for(i=0; i<2; i++) - s->p[r+i] = cast[inuxi2[i]]; - break; - case 4: - for(i=0; i<4; i++) - s->p[r+i] = cast[inuxi4[i]]; - break; - case 8: - o = v; - cast = (uchar*)&o; - for(i=0; i<8; i++) - s->p[r+i] = cast[inuxi8[i]]; - break; - } - return r; -} - -vlong -adduint8(Sym *s, uint8 v) -{ - return adduintxx(s, v, 1); -} - -vlong -adduint16(Sym *s, uint16 v) -{ - return adduintxx(s, v, 2); -} - -vlong -adduint32(Sym *s, uint32 v) -{ - return adduintxx(s, v, 4); -} - -vlong -adduint64(Sym *s, uint64 v) -{ - return adduintxx(s, v, 8); -} - -vlong -addaddrplus(Sym *s, Sym *t, int32 add) -{ - vlong i; - Reloc *r; - - if(s->type == 0) - s->type = SDATA; - s->reachable = 1; - i = s->size; - s->size += PtrSize; - symgrow(s, s->size); - r = addrel(s); - r->sym = t; - r->off = i; - r->siz = PtrSize; - r->type = D_ADDR; - r->add = add; - return i; -} - -vlong -addpcrelplus(Sym *s, Sym *t, int32 add) -{ - vlong i; - Reloc *r; - - if(s->type == 0) - s->type = SDATA; - s->reachable = 1; - i = s->size; - s->size += 4; - symgrow(s, s->size); - r = addrel(s); - r->sym = t; - r->off = i; - r->add = add; - r->type = D_PCREL; - r->siz = 4; - return i; -} - -vlong -addaddr(Sym *s, Sym *t) -{ - return addaddrplus(s, t, 0); -} - -vlong -addsize(Sym *s, Sym *t) -{ - vlong i; - Reloc *r; - - if(s->type == 0) - s->type = SDATA; - s->reachable = 1; - i = s->size; - s->size += PtrSize; - symgrow(s, s->size); - r = addrel(s); - r->sym = t; - r->off = i; - r->siz = PtrSize; - r->type = D_SIZE; - return i; -} - -void -dodata(void) -{ - int32 t, datsize; - Section *sect; - Sym *s, *last, **l; - - if(debug['v']) - Bprint(&bso, "%5.2f dodata\n", cputime()); - Bflush(&bso); - - last = nil; - datap = nil; - - for(s=allsym; s!=S; s=s->allsym) { - if(!s->reachable || s->special) - continue; - if(STEXT < s->type && s->type < SXREF) { - if(last == nil) - datap = s; - else - last->next = s; - s->next = nil; - last = s; - } - } - - for(s = datap; s != nil; s = s->next) { - if(s->np > 0 && s->type == SBSS) - s->type = SDATA; - if(s->np > s->size) - diag("%s: initialize bounds (%lld < %d)", - s->name, (vlong)s->size, s->np); - } - - /* - * now that we have the datap list, but before we start - * to assign addresses, record all the necessary - * dynamic relocations. these will grow the relocation - * symbol, which is itself data. - */ - dynreloc(); - - /* some symbols may no longer belong in datap (Mach-O) */ - for(l=&datap; (s=*l) != nil; ) { - if(s->type <= STEXT || SXREF <= s->type) - *l = s->next; - else - l = &s->next; - } - *l = nil; - - datap = datsort(datap); - - /* - * allocate data sections. list is sorted by type, - * so we can just walk it for each piece we want to emit. - */ - - /* read-only data */ - sect = addsection(&segtext, ".rodata", 04); - sect->vaddr = 0; - datsize = 0; - s = datap; - for(; s != nil && s->type < SSYMTAB; s = s->next) { - s->type = SRODATA; - t = rnd(s->size, PtrSize); - s->value = datsize; - datsize += t; - } - sect->len = datsize - sect->vaddr; - - /* gosymtab */ - sect = addsection(&segtext, ".gosymtab", 04); - sect->vaddr = datsize; - for(; s != nil && s->type < SPCLNTAB; s = s->next) { - s->type = SRODATA; - s->value = datsize; - datsize += s->size; - } - sect->len = datsize - sect->vaddr; - - /* gopclntab */ - sect = addsection(&segtext, ".gopclntab", 04); - sect->vaddr = datsize; - for(; s != nil && s->type < SDATA; s = s->next) { - s->type = SRODATA; - s->value = datsize; - datsize += s->size; - } - sect->len = datsize - sect->vaddr; - - /* data */ - datsize = 0; - sect = addsection(&segdata, ".data", 06); - sect->vaddr = 0; - for(; s != nil && s->type < SBSS; s = s->next) { - s->type = SDATA; - t = s->size; - if(t == 0 && s->name[0] != '.') { - diag("%s: no size", s->name); - t = 1; - } - if(t >= PtrSize) - t = rnd(t, PtrSize); - else if(t > 2) - t = rnd(t, 4); - if(t & 1) { - ; - } else if(t & 2) - datsize = rnd(datsize, 2); - else if(t & 4) - datsize = rnd(datsize, 4); - else - datsize = rnd(datsize, 8); - s->value = datsize; - datsize += t; - } - sect->len = datsize - sect->vaddr; - - /* bss */ - sect = addsection(&segdata, ".bss", 06); - sect->vaddr = datsize; - for(; s != nil; s = s->next) { - if(s->type != SBSS) { - cursym = s; - diag("unexpected symbol type %d", s->type); - } - t = s->size; - if(t >= PtrSize) - t = rnd(t, PtrSize); - else if(t > 2) - t = rnd(t, 4); - if(t & 1) { - ; - } else if(t & 2) - datsize = rnd(datsize, 2); - else if(t & 4) - datsize = rnd(datsize, 4); - else - datsize = rnd(datsize, 8); - s->value = datsize; - datsize += t; - } - sect->len = datsize - sect->vaddr; -} - -// assign addresses to text -void -textaddress(void) -{ - uvlong va; - Prog *p; - Section *sect; - Sym *sym, *sub; - - addsection(&segtext, ".text", 05); - - // Assign PCs in text segment. - // Could parallelize, by assigning to text - // and then letting threads copy down, but probably not worth it. - sect = segtext.sect; - va = INITTEXT; - sect->vaddr = va; - for(sym = textp; sym != nil; sym = sym->next) { - if(sym->type & SSUB) - continue; - sym->value = 0; - for(sub = sym; sub != S; sub = sub->sub) { - sub->value += va; - for(p = sub->text; p != P; p = p->link) - p->pc += sub->value; - } - if(sym->size == 0 && sym->sub != S) { - cursym = sym; - } - va += sym->size; - } - sect->len = va - sect->vaddr; -} - -// assign addresses -void -address(void) -{ - Section *s, *text, *data, *rodata, *symtab, *pclntab; - Sym *sym, *sub; - uvlong va; - - va = INITTEXT; - segtext.rwx = 05; - segtext.vaddr = va; - segtext.fileoff = HEADR; - for(s=segtext.sect; s != nil; s=s->next) { - s->vaddr = va; - va += s->len; - segtext.len = va - INITTEXT; - va = rnd(va, INITRND); - } - segtext.filelen = segtext.len; - - segdata.rwx = 06; - segdata.vaddr = va; - segdata.fileoff = va - segtext.vaddr + segtext.fileoff; - if(HEADTYPE == Hwindows) - segdata.fileoff = segtext.fileoff + rnd(segtext.len, PEFILEALIGN); - if(HEADTYPE == Hplan9x32) - segdata.fileoff = segtext.fileoff + segtext.filelen; - for(s=segdata.sect; s != nil; s=s->next) { - s->vaddr = va; - va += s->len; - segdata.len = va - segdata.vaddr; - } - segdata.filelen = segdata.sect->len; // assume .data is first - - text = segtext.sect; - rodata = text->next; - symtab = rodata->next; - pclntab = symtab->next; - data = segdata.sect; - - for(sym = datap; sym != nil; sym = sym->next) { - cursym = sym; - if(sym->type < SDATA) - sym->value += rodata->vaddr; - else - sym->value += data->vaddr; - for(sub = sym->sub; sub != nil; sub = sub->sub) - sub->value += sym->value; - } - - xdefine("text", STEXT, text->vaddr); - xdefine("etext", STEXT, text->vaddr + text->len); - xdefine("rodata", SRODATA, rodata->vaddr); - xdefine("erodata", SRODATA, rodata->vaddr + rodata->len); - xdefine("symtab", SRODATA, symtab->vaddr); - xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len); - xdefine("pclntab", SRODATA, pclntab->vaddr); - xdefine("epclntab", SRODATA, pclntab->vaddr + pclntab->len); - xdefine("data", SBSS, data->vaddr); - xdefine("edata", SBSS, data->vaddr + data->len); - xdefine("end", SBSS, segdata.vaddr + segdata.len); -} |