diff options
Diffstat (limited to 'src/cmd/ld/ldpe.c')
| -rw-r--r-- | src/cmd/ld/ldpe.c | 42 |
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) |
