summaryrefslogtreecommitdiff
path: root/src/cmd/ld/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/ld/data.c')
-rw-r--r--src/cmd/ld/data.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index 210f10ab5..0551232cf 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -240,6 +240,33 @@ void
dynrelocsym(Sym *s)
{
Reloc *r;
+
+ if(thechar == '8' && HEADTYPE == 10) { // Windows PE
+ 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) { // 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)
@@ -871,7 +898,7 @@ address(void)
segdata.rwx = 06;
segdata.vaddr = va;
segdata.fileoff = va - segtext.vaddr + segtext.fileoff;
- if(thechar == '8' && HEADTYPE == 10) // Windows PE
+ if((thechar == '6' || thechar == '8') && HEADTYPE == 10) // Windows PE
segdata.fileoff = segtext.fileoff + rnd(segtext.len, PEFILEALIGN);
if(thechar == '8' && HEADTYPE == 2) { // Plan 9
segdata.vaddr = va = rnd(va, 4096);