summaryrefslogtreecommitdiff
path: root/src/cmd/ld/ldpe.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/ld/ldpe.c')
-rw-r--r--src/cmd/ld/ldpe.c44
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;
+ }
}
}