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.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/src/cmd/ld/ldpe.c b/src/cmd/ld/ldpe.c
index 98c866fee..680557075 100644
--- a/src/cmd/ld/ldpe.c
+++ b/src/cmd/ld/ldpe.c
@@ -73,6 +73,24 @@
#define IMAGE_REL_I386_SECREL7 0x000D
#define IMAGE_REL_I386_REL32 0x0014
+#define IMAGE_REL_AMD64_ABSOLUTE 0x0000
+#define IMAGE_REL_AMD64_ADDR64 0x0001 // R_X86_64_64
+#define IMAGE_REL_AMD64_ADDR32 0x0002 // R_X86_64_PC32
+#define IMAGE_REL_AMD64_ADDR32NB 0x0003
+#define IMAGE_REL_AMD64_REL32 0x0004
+#define IMAGE_REL_AMD64_REL32_1 0x0005
+#define IMAGE_REL_AMD64_REL32_2 0x0006
+#define IMAGE_REL_AMD64_REL32_3 0x0007
+#define IMAGE_REL_AMD64_REL32_4 0x0008
+#define IMAGE_REL_AMD64_REL32_5 0x0009
+#define IMAGE_REL_AMD64_SECTION 0x000A
+#define IMAGE_REL_AMD64_SECREL 0x000B
+#define IMAGE_REL_AMD64_SECREL7 0x000C
+#define IMAGE_REL_AMD64_TOKEN 0x000D
+#define IMAGE_REL_AMD64_SREL32 0x000E
+#define IMAGE_REL_AMD64_PAIR 0x000F
+#define IMAGE_REL_AMD64_SSPAN32 0x0010
+
typedef struct PeSym PeSym;
typedef struct PeSect PeSect;
typedef struct PeObj PeObj;
@@ -204,6 +222,8 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
s->type = SRODATA;
break;
case IMAGE_SCN_CNT_UNINITIALIZED_DATA|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE: //.bss
+ s->type = SBSS;
+ break;
case IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE: //.data
s->type = SDATA;
break;
@@ -261,6 +281,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
default:
diag("%s: unknown relocation type %d;", pn, type);
case IMAGE_REL_I386_REL32:
+ case IMAGE_REL_AMD64_REL32:
rp->type = D_PCREL;
rp->add = 0;
break;
@@ -270,6 +291,16 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
// load addend from image
rp->add = le32(rsect->base+rp->off);
break;
+ case IMAGE_REL_AMD64_ADDR32: // R_X86_64_PC32
+ rp->type = D_PCREL;
+ rp->add += 4;
+ break;
+ case IMAGE_REL_AMD64_ADDR64: // R_X86_64_64
+ rp->siz = 8;
+ rp->type = D_ADDR;
+ // load addend from image
+ rp->add = le64(rsect->base+rp->off);
+ break;
}
}
qsort(r, rsect->sh.NumberOfRelocations, sizeof r[0], rbyoff);
@@ -280,8 +311,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
}
// enter sub-symbols into symbol table.
- // frist 2 entry is file name.
- for(i=2; i<obj->npesym; i++) {
+ for(i=0; i<obj->npesym; i++) {
if(obj->pesym[i].name == 0)
continue;
if(obj->pesym[i].name[0] == '.') //skip section
@@ -298,13 +328,17 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
if(sym->sectnum == 0) {// extern
if(s->type == SDYNIMPORT)
s->plt = -2; // flag for dynimport in PE object files.
+ if (s->type == SXREF && sym->value > 0) {// global data
+ s->type = SDATA;
+ s->size = sym->value;
+ }
continue;
} else if (sym->sectnum > 0) {
sect = &obj->sect[sym->sectnum-1];
if(sect->sym == 0)
diag("%s: %s sym == 0!", pn, s->name);
} else {
- diag("%s: %s sectnum <0!", pn, s->name, sym->sectnum);
+ diag("%s: %s sectnum < 0!", pn, s->name);
}
if(sect == nil)
@@ -349,6 +383,8 @@ map(PeObj *obj, PeSect *sect)
return 0;
sect->base = mal(sect->sh.SizeOfRawData);
+ if(sect->sh.PointerToRawData == 0) // .bss doesn't have data in object file
+ return 0;
werrstr("short read");
if(Bseek(obj->f, obj->base+sect->sh.PointerToRawData, 0) < 0 ||
Bread(obj->f, sect->base, sect->sh.SizeOfRawData) != sect->sh.SizeOfRawData)