diff options
Diffstat (limited to 'src/cmd/ld/ldpe.c')
-rw-r--r-- | src/cmd/ld/ldpe.c | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/src/cmd/ld/ldpe.c b/src/cmd/ld/ldpe.c index feb8620bd..39c15e6a1 100644 --- a/src/cmd/ld/ldpe.c +++ b/src/cmd/ld/ldpe.c @@ -145,7 +145,6 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) PeSym *sym; USED(len); - USED(pkg); if(debug['v']) Bprint(&bso, "%5.2f ldpe %s\n", cputime(), pn); @@ -213,7 +212,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) if(map(obj, sect) < 0) goto bad; - name = smprint("%s(%s)", pn, sect->name); + name = smprint("%s(%s)", pkg, sect->name); s = lookup(name, version); free(name); switch(sect->sh.Characteristics&(IMAGE_SCN_CNT_UNINITIALIZED_DATA|IMAGE_SCN_CNT_INITIALIZED_DATA| @@ -237,13 +236,6 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) s->p = sect->base; s->np = sect->size; s->size = sect->size; - if(s->type == STEXT) { - if(etextp) - etextp->next = s; - else - textp = s; - etextp = s; - } sect->sym = s; if(strcmp(sect->name, ".rsrc") == 0) setpersrc(sect->sym); @@ -300,6 +292,11 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) rp->add = le64(rsect->base+rp->off); break; } + // ld -r could generate multiple section symbols for the + // same section but with different values, we have to take + // that into account + if (obj->pesym[symindex].name[0] == '.') + rp->add += obj->pesym[symindex].value; } qsort(r, rsect->sh.NumberOfRelocations, sizeof r[0], rbyoff); @@ -341,6 +338,13 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) if(sect == nil) return; + + if(s->outer != S) { + if(s->dupok) + continue; + diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s->name, s->outer->name, sect->sym->name); + errorexit(); + } s->sub = sect->sym->sub; sect->sym->sub = s; s->type = sect->sym->type | SSUB; @@ -363,9 +367,27 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn) p->link = nil; p->pc = pc++; s->text = p; - - etextp->next = s; + } + } + + // Sort outer lists by address, adding to textp. + // This keeps textp in increasing address order. + for(i=0; i<obj->nsect; i++) { + s = obj->sect[i].sym; + if(s == S) + continue; + if(s->sub) + s->sub = listsort(s->sub, valuecmp, offsetof(Sym, sub)); + if(s->type == STEXT) { + if(etextp) + etextp->next = s; + else + textp = s; etextp = s; + for(s = s->sub; s != S; s = s->sub) { + etextp->next = s; + etextp = s; + } } } |