diff options
Diffstat (limited to 'src/cmd/ld/data.c')
-rw-r--r-- | src/cmd/ld/data.c | 429 |
1 files changed, 269 insertions, 160 deletions
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c index 6c6b1be43..23fc23e5f 100644 --- a/src/cmd/ld/data.c +++ b/src/cmd/ld/data.c @@ -33,11 +33,12 @@ #include "l.h" #include "../ld/lib.h" #include "../ld/elf.h" +#include "../ld/macho.h" #include "../ld/pe.h" #include "../../pkg/runtime/mgc0.h" void dynreloc(void); -static vlong addaddrplus4(Sym *s, Sym *t, int32 add); +static vlong addaddrplus4(Sym *s, Sym *t, vlong add); /* * divide-and-conquer list-link @@ -135,11 +136,7 @@ addrel(Sym *s) 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(); - } + s->r = erealloc(s->r, s->maxr*sizeof s->r[0]); memset(s->r+s->nr, 0, (s->maxr-s->nr)*sizeof s->r[0]); } return &s->r[s->nr++]; @@ -158,6 +155,7 @@ relocsym(Sym *s) cursym = s; memset(&p, 0, sizeof p); for(r=s->r; r<s->r+s->nr; r++) { + r->done = 1; off = r->off; siz = r->siz; if(off < 0 || off+siz > s->np) { @@ -174,41 +172,88 @@ relocsym(Sym *s) 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) + if(r->sym != S && r->sym->type != STLSBSS && !r->sym->reachable) diag("unreachable sym in relocation: %s %s", s->name, r->sym->name); switch(r->type) { default: o = 0; - if(isobj || archreloc(r, s, &o) < 0) + if(linkmode == LinkExternal || archreloc(r, s, &o) < 0) diag("unknown reloc %d", r->type); break; + case D_TLS: + r->done = 0; + o = 0; + break; case D_ADDR: - o = symaddr(r->sym) + r->add; - if(isobj && r->sym->type != SCONST) { - if(thechar == '6') - o = 0; - else { - // set up addend for eventual relocation via outer symbol - rs = r->sym; - while(rs->outer != nil) - rs = rs->outer; - o -= symaddr(rs); + if(linkmode == LinkExternal && r->sym->type != SCONST) { + r->done = 0; + + // set up addend for eventual relocation via outer symbol. + rs = r->sym; + r->xadd = r->add; + while(rs->outer != nil) { + r->xadd += symaddr(rs) - symaddr(rs->outer); + rs = rs->outer; } + if(rs->type != SHOSTOBJ && rs->sect == nil) + diag("missing section for %s", rs->name); + r->xsym = rs; + + o = r->xadd; + if(iself) { + if(thechar == '6') + o = 0; + } else if(HEADTYPE == Hdarwin) { + if(rs->type != SHOSTOBJ) + o += symaddr(rs); + } else { + diag("unhandled pcrel relocation for %s", headtype); + } + break; } + o = symaddr(r->sym) + r->add; break; case D_PCREL: // r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call. + if(linkmode == LinkExternal && r->sym && r->sym->type != SCONST && r->sym->sect != cursym->sect) { + r->done = 0; + + // set up addend for eventual relocation via outer symbol. + rs = r->sym; + r->xadd = r->add; + while(rs->outer != nil) { + r->xadd += symaddr(rs) - symaddr(rs->outer); + rs = rs->outer; + } + r->xadd -= r->siz; // relative to address after the relocated chunk + if(rs->type != SHOSTOBJ && rs->sect == nil) + diag("missing section for %s", rs->name); + r->xsym = rs; + + o = r->xadd; + if(iself) { + if(thechar == '6') + o = 0; + } else if(HEADTYPE == Hdarwin) { + if(rs->type != SHOSTOBJ) + o += symaddr(rs) - rs->sect->vaddr; + o -= r->off; // WTF? + } else { + diag("unhandled pcrel relocation for %s", headtype); + } + break; + } o = 0; if(r->sym) o += symaddr(r->sym); - o += r->add - (s->value + r->off + r->siz); - if(isobj && r->sym->type != SCONST) { - if(thechar == '6') - o = 0; - else - o = r->add - r->siz; - } + // NOTE: The (int32) cast on the next line works around a bug in Plan 9's 8c + // compiler. The expression s->value + r->off + r->siz is int32 + int32 + + // uchar, and Plan 9 8c incorrectly treats the expression as type uint32 + // instead of int32, causing incorrect values when sign extended for adding + // to o. The bug only occurs on Plan 9, because this C program is compiled by + // the standard host compiler (gcc on most other systems). + o += r->add - (s->value + r->off + (int32)r->siz); break; case D_SIZE: o = r->sym->size + r->add; @@ -220,6 +265,13 @@ relocsym(Sym *s) cursym = s; diag("bad reloc size %#ux for %s", siz, r->sym->name); case 4: + if(r->type == D_PCREL) { + if(o != (int32)o) + diag("pc-relative relocation address is too big: %#llx", o); + } else { + if(o != (int32)o && o != (uint32)o) + diag("non-pc-relative relocation address is too big: %#llux", o); + } fl = o; cast = (uchar*)&fl; for(i=0; i<4; i++) @@ -300,7 +352,7 @@ dynrelocsym(Sym *s) for(r=s->r; r<s->r+s->nr; r++) { if(r->sym != S && r->sym->type == SDYNIMPORT || r->type >= 256) adddynrel(s, r); - if(flag_shared && r->sym != S && (r->sym->dynimpname == nil || r->sym->dynexport) && r->type == D_ADDR + if(flag_shared && r->sym != S && s->type != SDYNIMPORT && r->type == D_ADDR && (s == got || s->type == SDATA || s->type == SGOSTRING || s->type == STYPE || s->type == SRODATA)) { // Create address based RELATIVE relocation adddynrela(rel, s, r); @@ -342,11 +394,7 @@ symgrow(Sym *s, int32 siz) 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(); - } + s->p = erealloc(s->p, s->maxp); memset(s->p+s->np, 0, s->maxp-s->np); } s->np = siz; @@ -560,8 +608,10 @@ void datblk(int32 addr, int32 size) { Sym *sym; - int32 eaddr; + int32 i, eaddr; uchar *p, *ep; + char *typ, *rsname; + Reloc *r; if(debug['a']) Bprint(&bso, "datblk [%#x,%#x) at offset %#llx\n", addr, addr+size, cpos()); @@ -581,23 +631,46 @@ datblk(int32 addr, int32 size) if(sym->value >= eaddr) break; if(addr < sym->value) { - Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(pre-pad)", addr); + Bprint(&bso, "\t%.8ux| 00 ...\n", addr); addr = sym->value; } - Bprint(&bso, "%-20s %.8ux|", sym->name, (uint)addr); + Bprint(&bso, "%s\n\t%.8ux|", sym->name, (uint)addr); p = sym->p; ep = p + sym->np; - while(p < ep) + while(p < ep) { + if(p > sym->p && (int)(p-sym->p)%16 == 0) + Bprint(&bso, "\n\t%.8ux|", (uint)(addr+(p-sym->p))); Bprint(&bso, " %.2ux", *p++); + } addr += sym->np; for(; addr < sym->value+sym->size; addr++) Bprint(&bso, " %.2ux", 0); Bprint(&bso, "\n"); + + if(linkmode == LinkExternal) { + for(i=0; i<sym->nr; i++) { + r = &sym->r[i]; + rsname = ""; + if(r->sym) + rsname = r->sym->name; + typ = "?"; + switch(r->type) { + case D_ADDR: + typ = "addr"; + break; + case D_PCREL: + typ = "pcrel"; + break; + } + Bprint(&bso, "\treloc %.8ux/%d %s %s+%#llx [%#llx]\n", + (uint)(sym->value+r->off), r->siz, typ, rsname, (vlong)r->add, (vlong)(r->sym->value+r->add)); + } + } } if(addr < eaddr) - Bprint(&bso, "%-20s %.8ux| 00 ...\n", "(post-pad)", (uint)addr); - Bprint(&bso, "%-20s %.8ux|\n", "", (uint)eaddr); + Bprint(&bso, "\t%.8ux| 00 ...\n", (uint)addr); + Bprint(&bso, "\t%.8ux|\n", (uint)eaddr); } void @@ -656,7 +729,7 @@ addstring(Sym *s, char *str) } vlong -setuintxx(Sym *s, vlong off, uint64 v, int wid) +setuintxx(Sym *s, vlong off, uint64 v, vlong wid) { int32 i, fl; vlong o; @@ -696,7 +769,7 @@ setuintxx(Sym *s, vlong off, uint64 v, int wid) vlong adduintxx(Sym *s, uint64 v, int wid) { - int32 off; + vlong off; off = s->size; setuintxx(s, off, v, wid); @@ -752,7 +825,7 @@ setuint64(Sym *s, vlong r, uint64 v) } vlong -addaddrplus(Sym *s, Sym *t, int32 add) +addaddrplus(Sym *s, Sym *t, vlong add) { vlong i; Reloc *r; @@ -773,7 +846,7 @@ addaddrplus(Sym *s, Sym *t, int32 add) } static vlong -addaddrplus4(Sym *s, Sym *t, int32 add) +addaddrplus4(Sym *s, Sym *t, vlong add) { vlong i; Reloc *r; @@ -794,7 +867,7 @@ addaddrplus4(Sym *s, Sym *t, int32 add) } vlong -addpcrelplus(Sym *s, Sym *t, int32 add) +addpcrelplus(Sym *s, Sym *t, vlong add) { vlong i; Reloc *r; @@ -821,7 +894,7 @@ addaddr(Sym *s, Sym *t) } vlong -setaddrplus(Sym *s, vlong off, Sym *t, int32 add) +setaddrplus(Sym *s, vlong off, Sym *t, vlong add) { Reloc *r; @@ -883,42 +956,47 @@ dosymtype(void) } static int32 -alignsymsize(int32 s) +symalign(Sym *s) { - if(s >= 8) - s = rnd(s, 8); - else if(s >= PtrSize) - s = rnd(s, PtrSize); - else if(s > 2) - s = rnd(s, 4); - return s; + int32 align; + + if(s->align != 0) + return s->align; + + align = MaxAlign; + while(align > s->size && align > 1) + align >>= 1; + if(align < s->align) + align = s->align; + return align; +} + +static vlong +aligndatsize(vlong datsize, Sym *s) +{ + return rnd(datsize, symalign(s)); } +// maxalign returns the maximum required alignment for +// the list of symbols s; the list stops when s->type exceeds type. static int32 -aligndatsize(int32 datsize, Sym *s) +maxalign(Sym *s, int type) { - int32 t; - - if(s->align != 0) { - datsize = rnd(datsize, s->align); - } else { - t = alignsymsize(s->size); - if(t & 1) { - ; - } else if(t & 2) - datsize = rnd(datsize, 2); - else if(t & 4) - datsize = rnd(datsize, 4); - else - datsize = rnd(datsize, 8); + int32 align, max; + + max = 0; + for(; s != S && s->type <= type; s = s->next) { + align = symalign(s); + if(max < align) + max = align; } - return datsize; + return max; } static void -gcaddsym(Sym *gc, Sym *s, int32 off) +gcaddsym(Sym *gc, Sym *s, vlong off) { - int32 a; + vlong a; Sym *gotype; if(s->size < PtrSize) @@ -944,9 +1022,23 @@ gcaddsym(Sym *gc, Sym *s, int32 off) } void +growdatsize(vlong *datsizep, Sym *s) +{ + vlong datsize; + + datsize = *datsizep; + if(s->size < 0) + diag("negative size (datsize = %lld, s->size = %lld)", datsize, s->size); + if(datsize + s->size < datsize) + diag("symbol too large (datsize = %lld, s->size = %lld)", datsize, s->size); + *datsizep = datsize + s->size; +} + +void dodata(void) { - int32 t, datsize; + int32 n; + vlong datsize; Section *sect; Sym *s, *last, **l; Sym *gcdata1, *gcbss1; @@ -956,11 +1048,11 @@ dodata(void) Bflush(&bso); // define garbage collection symbols - gcdata1 = lookup("gcdata1", 0); - gcdata1->type = SGCDATA; + gcdata1 = lookup("gcdata", 0); + gcdata1->type = STYPE; gcdata1->reachable = 1; - gcbss1 = lookup("gcbss1", 0); - gcbss1->type = SGCBSS; + gcbss1 = lookup("gcbss", 0); + gcbss1->type = STYPE; gcbss1->reachable = 1; // size of .data and .bss section. the zero value is later replaced by the actual size of the section. @@ -995,7 +1087,11 @@ dodata(void) * to assign addresses, record all the necessary * dynamic relocations. these will grow the relocation * symbol, which is itself data. + * + * on darwin, we need the symbol table numbers for dynreloc. */ + if(HEADTYPE == Hdarwin) + machosymorder(); dynreloc(); /* some symbols may no longer belong in datap (Mach-O) */ @@ -1034,52 +1130,54 @@ dodata(void) datsize = 0; for(; s != nil && s->type < SNOPTRDATA; s = s->next) { sect = addsection(&segdata, s->name, 06); - if(s->align != 0) - datsize = rnd(datsize, s->align); + sect->align = symalign(s); + datsize = rnd(datsize, sect->align); sect->vaddr = datsize; s->sect = sect; s->type = SDATA; s->value = datsize; - datsize += rnd(s->size, PtrSize); + growdatsize(&datsize, s); sect->len = datsize - sect->vaddr; } /* pointer-free data */ sect = addsection(&segdata, ".noptrdata", 06); + sect->align = maxalign(s, SDATARELRO-1); + datsize = rnd(datsize, sect->align); sect->vaddr = datsize; lookup("noptrdata", 0)->sect = sect; lookup("enoptrdata", 0)->sect = sect; for(; s != nil && s->type < SDATARELRO; s = s->next) { + datsize = aligndatsize(datsize, s); s->sect = sect; s->type = SDATA; - t = alignsymsize(s->size); - datsize = aligndatsize(datsize, s); s->value = datsize; - datsize += t; + growdatsize(&datsize, s); } sect->len = datsize - sect->vaddr; - datsize = rnd(datsize, PtrSize); /* dynamic relocated rodata */ if(flag_shared) { sect = addsection(&segdata, ".data.rel.ro", 06); + sect->align = maxalign(s, SDATARELRO); + datsize = rnd(datsize, sect->align); sect->vaddr = datsize; lookup("datarelro", 0)->sect = sect; lookup("edatarelro", 0)->sect = sect; for(; s != nil && s->type == SDATARELRO; s = s->next) { - if(s->align != 0) - datsize = rnd(datsize, s->align); + datsize = aligndatsize(datsize, s); s->sect = sect; s->type = SDATA; s->value = datsize; - datsize += rnd(s->size, PtrSize); + growdatsize(&datsize, s); } sect->len = datsize - sect->vaddr; - datsize = rnd(datsize, PtrSize); } /* data */ sect = addsection(&segdata, ".data", 06); + sect->align = maxalign(s, SBSS-1); + datsize = rnd(datsize, sect->align); sect->vaddr = datsize; lookup("data", 0)->sect = sect; lookup("edata", 0)->sect = sect; @@ -1090,158 +1188,166 @@ dodata(void) } s->sect = sect; s->type = SDATA; - t = alignsymsize(s->size); datsize = aligndatsize(datsize, s); s->value = datsize; gcaddsym(gcdata1, s, datsize - sect->vaddr); // gc - datsize += t; + growdatsize(&datsize, s); } sect->len = datsize - sect->vaddr; - datsize = rnd(datsize, PtrSize); adduintxx(gcdata1, GC_END, PtrSize); setuintxx(gcdata1, 0, sect->len, PtrSize); /* bss */ sect = addsection(&segdata, ".bss", 06); + sect->align = maxalign(s, SNOPTRBSS-1); + datsize = rnd(datsize, sect->align); sect->vaddr = datsize; lookup("bss", 0)->sect = sect; lookup("ebss", 0)->sect = sect; for(; s != nil && s->type < SNOPTRBSS; s = s->next) { s->sect = sect; - t = alignsymsize(s->size); datsize = aligndatsize(datsize, s); s->value = datsize; gcaddsym(gcbss1, s, datsize - sect->vaddr); // gc - datsize += t; + growdatsize(&datsize, s); } sect->len = datsize - sect->vaddr; - datsize = rnd(datsize, PtrSize); adduintxx(gcbss1, GC_END, PtrSize); setuintxx(gcbss1, 0, sect->len, PtrSize); /* pointer-free bss */ sect = addsection(&segdata, ".noptrbss", 06); + sect->align = maxalign(s, SNOPTRBSS); + datsize = rnd(datsize, sect->align); sect->vaddr = datsize; lookup("noptrbss", 0)->sect = sect; lookup("enoptrbss", 0)->sect = sect; - for(; s != nil; s = s->next) { - if(s->type > SNOPTRBSS) { - cursym = s; - diag("unexpected symbol type %d", s->type); - } - s->sect = sect; - t = alignsymsize(s->size); + for(; s != nil && s->type == SNOPTRBSS; s = s->next) { datsize = aligndatsize(datsize, s); + s->sect = sect; s->value = datsize; - datsize += t; + growdatsize(&datsize, s); } sect->len = datsize - sect->vaddr; lookup("end", 0)->sect = sect; + // 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits. + if(datsize != (uint32)datsize) { + diag("data or bss segment too large"); + } + + if(iself && linkmode == LinkExternal && s != nil && s->type == STLSBSS && HEADTYPE != Hopenbsd) { + sect = addsection(&segdata, ".tbss", 06); + sect->align = PtrSize; + sect->vaddr = 0; + datsize = 0; + for(; s != nil && s->type == STLSBSS; s = s->next) { + datsize = aligndatsize(datsize, s); + s->sect = sect; + s->value = datsize; + growdatsize(&datsize, s); + } + sect->len = datsize; + } + + if(s != nil) { + cursym = nil; + diag("unexpected symbol type %d for %s", s->type, s->name); + } + /* we finished segdata, begin segtext */ + s = datap; /* read-only data */ sect = addsection(&segtext, ".rodata", 04); + sect->align = maxalign(s, STYPELINK-1); sect->vaddr = 0; lookup("rodata", 0)->sect = sect; lookup("erodata", 0)->sect = sect; datsize = 0; - s = datap; for(; s != nil && s->type < STYPELINK; s = s->next) { + datsize = aligndatsize(datsize, s); s->sect = sect; - if(s->align != 0) - datsize = rnd(datsize, s->align); s->type = SRODATA; s->value = datsize; - datsize += rnd(s->size, PtrSize); + growdatsize(&datsize, s); } sect->len = datsize - sect->vaddr; - datsize = rnd(datsize, PtrSize); - /* type */ + /* typelink */ sect = addsection(&segtext, ".typelink", 04); + sect->align = maxalign(s, STYPELINK); + datsize = rnd(datsize, sect->align); sect->vaddr = datsize; lookup("typelink", 0)->sect = sect; lookup("etypelink", 0)->sect = sect; for(; s != nil && s->type == STYPELINK; s = s->next) { + datsize = aligndatsize(datsize, s); s->sect = sect; s->type = SRODATA; s->value = datsize; - datsize += s->size; - } - sect->len = datsize - sect->vaddr; - datsize = rnd(datsize, PtrSize); - - /* gcdata */ - sect = addsection(&segtext, ".gcdata", 04); - sect->vaddr = datsize; - lookup("gcdata", 0)->sect = sect; - lookup("egcdata", 0)->sect = sect; - for(; s != nil && s->type == SGCDATA; s = s->next) { - s->sect = sect; - s->type = SRODATA; - s->value = datsize; - datsize += s->size; - } - sect->len = datsize - sect->vaddr; - datsize = rnd(datsize, PtrSize); - - /* gcbss */ - sect = addsection(&segtext, ".gcbss", 04); - sect->vaddr = datsize; - lookup("gcbss", 0)->sect = sect; - lookup("egcbss", 0)->sect = sect; - for(; s != nil && s->type == SGCBSS; s = s->next) { - s->sect = sect; - s->type = SRODATA; - s->value = datsize; - datsize += s->size; + growdatsize(&datsize, s); } sect->len = datsize - sect->vaddr; - datsize = rnd(datsize, PtrSize); /* gosymtab */ sect = addsection(&segtext, ".gosymtab", 04); + sect->align = maxalign(s, SPCLNTAB-1); + datsize = rnd(datsize, sect->align); sect->vaddr = datsize; lookup("symtab", 0)->sect = sect; lookup("esymtab", 0)->sect = sect; for(; s != nil && s->type < SPCLNTAB; s = s->next) { + datsize = aligndatsize(datsize, s); s->sect = sect; s->type = SRODATA; s->value = datsize; - datsize += s->size; + growdatsize(&datsize, s); } sect->len = datsize - sect->vaddr; - datsize = rnd(datsize, PtrSize); /* gopclntab */ sect = addsection(&segtext, ".gopclntab", 04); + sect->align = maxalign(s, SELFROSECT-1); + datsize = rnd(datsize, sect->align); sect->vaddr = datsize; lookup("pclntab", 0)->sect = sect; lookup("epclntab", 0)->sect = sect; for(; s != nil && s->type < SELFROSECT; s = s->next) { + datsize = aligndatsize(datsize, s); s->sect = sect; s->type = SRODATA; s->value = datsize; - datsize += s->size; + growdatsize(&datsize, s); } sect->len = datsize - sect->vaddr; - datsize = rnd(datsize, PtrSize); - /* read-only ELF sections */ + /* read-only ELF, Mach-O sections */ for(; s != nil && s->type < SELFSECT; s = s->next) { sect = addsection(&segtext, s->name, 04); - if(s->align != 0) - datsize = rnd(datsize, s->align); + sect->align = symalign(s); + datsize = rnd(datsize, sect->align); sect->vaddr = datsize; s->sect = sect; s->type = SRODATA; s->value = datsize; - datsize += rnd(s->size, PtrSize); + growdatsize(&datsize, s); sect->len = datsize - sect->vaddr; } + + // 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits. + if(datsize != (uint32)datsize) { + diag("text segment too large"); + } + + /* number the sections */ + n = 1; + for(sect = segtext.sect; sect != nil; sect = sect->next) + sect->extnum = n++; + for(sect = segdata.sect; sect != nil; sect = sect->next) + sect->extnum = n++; } // assign addresses to text @@ -1259,6 +1365,7 @@ textaddress(void) // Could parallelize, by assigning to text // and then letting threads copy down, but probably not worth it. sect = segtext.sect; + sect->align = FuncAlign; lookup("text", 0)->sect = sect; lookup("etext", 0)->sect = sect; va = INITTEXT; @@ -1282,11 +1389,6 @@ textaddress(void) } va += sym->size; } - - // Align end of code so that rodata starts aligned. - // 128 bytes is likely overkill but definitely cheap. - va = rnd(va, 128); - sect->len = va - sect->vaddr; } @@ -1295,17 +1397,19 @@ void address(void) { Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr, *bss, *noptrbss, *datarelro; - Section *gcdata, *gcbss, *typelink; + Section *typelink; Sym *sym, *sub; uvlong va; + vlong vlen; va = INITTEXT; segtext.rwx = 05; segtext.vaddr = va; segtext.fileoff = HEADR; for(s=segtext.sect; s != nil; s=s->next) { + va = rnd(va, s->align); s->vaddr = va; - va += rnd(s->len, PtrSize); + va += s->len; } segtext.len = va - INITTEXT; segtext.filelen = segtext.len; @@ -1326,9 +1430,11 @@ address(void) noptrbss = nil; datarelro = nil; for(s=segdata.sect; s != nil; s=s->next) { + vlen = s->len; + if(s->next) + vlen = s->next->vaddr - s->vaddr; s->vaddr = va; - va += s->len; - segdata.filelen += s->len; + va += vlen; segdata.len = va - segdata.vaddr; if(strcmp(s->name, ".data") == 0) data = s; @@ -1341,14 +1447,12 @@ address(void) if(strcmp(s->name, ".data.rel.ro") == 0) datarelro = s; } - segdata.filelen -= bss->len + noptrbss->len; // deduct .bss + segdata.filelen = bss->vaddr - segdata.vaddr; text = segtext.sect; rodata = text->next; typelink = rodata->next; - gcdata = typelink->next; - gcbss = gcdata->next; - symtab = gcbss->next; + symtab = typelink->next; pclntab = symtab->next; for(sym = datap; sym != nil; sym = sym->next) { @@ -1371,10 +1475,15 @@ address(void) xdefine("datarelro", SRODATA, datarelro->vaddr); xdefine("edatarelro", SRODATA, datarelro->vaddr + datarelro->len); } - xdefine("gcdata", SGCDATA, gcdata->vaddr); - xdefine("egcdata", SGCDATA, gcdata->vaddr + gcdata->len); - xdefine("gcbss", SGCBSS, gcbss->vaddr); - xdefine("egcbss", SGCBSS, gcbss->vaddr + gcbss->len); + + sym = lookup("gcdata", 0); + xdefine("egcdata", STYPE, symaddr(sym) + sym->size); + lookup("egcdata", 0)->sect = sym->sect; + + sym = lookup("gcbss", 0); + xdefine("egcbss", STYPE, symaddr(sym) + sym->size); + lookup("egcbss", 0)->sect = sym->sect; + xdefine("symtab", SRODATA, symtab->vaddr); xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len); xdefine("pclntab", SRODATA, pclntab->vaddr); |