From d08df51366ed7fff5dde879adba02ab38c8c8cfc Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Sat, 29 Jan 2011 23:13:40 +1100 Subject: [PATCH] 8l/6l: pe fixes - fixed length of amd64 .data pe section (don't need to include non-initialised data) - use correct oh/oh64 variable when updating data directory in addexports - simplify and cleanup R=vcc, rsc CC=golang-dev https://golang.org/cl/4106044 --- src/cmd/ld/lib.h | 1 + src/cmd/ld/pe.c | 151 ++++++++++++++++++----------------------------- 2 files changed, 60 insertions(+), 92 deletions(-) diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h index bcf29711681..4ac5d37f987 100644 --- a/src/cmd/ld/lib.h +++ b/src/cmd/ld/lib.h @@ -130,6 +130,7 @@ void ldobj1(Biobuf *f, char*, int64 len, char *pn); void ldobj(Biobuf*, char*, int64, char*, int); void ldelf(Biobuf*, char*, int64, char*); void ldmacho(Biobuf*, char*, int64, char*); +void ldpe(Biobuf*, char*, int64, char*); void ldpkg(Biobuf*, char*, int64, char*, int); void mark(Sym *s); void mkfwd(void); diff --git a/src/cmd/ld/pe.c b/src/cmd/ld/pe.c index 5663ae42d88..2c34daab4e0 100644 --- a/src/cmd/ld/pe.c +++ b/src/cmd/ld/pe.c @@ -49,6 +49,10 @@ static IMAGE_FILE_HEADER fh; static IMAGE_OPTIONAL_HEADER oh; static PE64_IMAGE_OPTIONAL_HEADER oh64; static IMAGE_SECTION_HEADER sh[16]; +static IMAGE_DATA_DIRECTORY* dd; + +#define set(n, v) (pe64 ? (oh64.n = v) : (oh.n = v)) +#define put(v) (pe64 ? vputl(v) : lputl(v)) typedef struct Imp Imp; struct Imp { @@ -106,18 +110,23 @@ addpesection(char *name, int sectsize, int filesize, Segment *s) void peinit(void) { + int32 l; + switch(thechar) { // 64-bit architectures case '6': pe64 = 1; - PEFILEHEADR = rnd(sizeof(dosstub)+sizeof(fh)+sizeof(oh64)+sizeof(sh), PEFILEALIGN); + l = sizeof(oh64); + dd = oh64.DataDirectory; break; // 32-bit architectures default: - PEFILEHEADR = rnd(sizeof(dosstub)+sizeof(fh)+sizeof(oh)+sizeof(sh), PEFILEALIGN); + l = sizeof(oh); + dd = oh.DataDirectory; break; } + PEFILEHEADR = rnd(sizeof(dosstub)+sizeof(fh)+l+sizeof(sh), PEFILEALIGN); PESECTHEADR = rnd(PEFILEHEADR, PESECTALIGN); nextsectoff = PESECTHEADR; nextfileoff = PEFILEHEADR; @@ -126,24 +135,20 @@ peinit(void) static void pewrite(void) { - int i, j; - seek(cout, 0, 0); ewrite(cout, dosstub, sizeof dosstub); strnput("PE", 4); - - for (i=0; inext) { d->thunkoff = cpos() - n; for(m = d->ms; m != nil; m = m->next) - pe64 ? vputl(m->off) : lputl(m->off); - pe64 ? vputl(0): lputl(0); + put(m->off); + put(0); } // add pe section and pad it at the end @@ -264,8 +269,8 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect) seek(cout, datsect->PointerToRawData + ftbase, 0); for(d = dr; d != nil; d = d->next) { for(m = d->ms; m != nil; m = m->next) - pe64 ? vputl(m->off) : lputl(m->off); - pe64 ? vputl(0): lputl(0); + put(m->off); + put(0); } cflush(); @@ -286,17 +291,10 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect) cflush(); // update data directory - if(pe64) { - oh64.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect->VirtualAddress; - oh64.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize; - oh64.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = dynamic->value - PEBASE; - oh64.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size; - } else { - oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect->VirtualAddress; - oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize; - oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = dynamic->value - PEBASE; - oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size; - } + dd[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect->VirtualAddress; + dd[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize; + dd[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = dynamic->value - PEBASE; + dd[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size; seek(cout, 0, 2); } @@ -340,7 +338,6 @@ addexports(vlong fileoff) IMAGE_SECTION_HEADER *sect; IMAGE_EXPORT_DIRECTORY e; int size, i, va, va_name, va_addr, va_na, v; - Sym *s; size = sizeof e + 10*nexport + strlen(outfile) + 1; for(i=0; iCharacteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ; va = sect->VirtualAddress; - oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = va; - oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect->VirtualSize; + dd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = va; + dd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect->VirtualSize; seek(cout, fileoff, 0); va_name = va + sizeof e + nexport*4; @@ -395,7 +392,6 @@ addexports(vlong fileoff) seek(cout, 0, 2); } - void dope(void) { @@ -463,7 +459,6 @@ addsymtable(void) cflush(); } - void asmbpe(void) { @@ -486,7 +481,7 @@ asmbpe(void) IMAGE_SCN_CNT_INITIALIZED_DATA| IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ; - d = addpesection(".data", segdata.len, pe64 ? segdata.len : segdata.filelen, &segdata); + d = addpesection(".data", segdata.len, segdata.filelen, &segdata); d->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA| IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE; @@ -503,67 +498,39 @@ asmbpe(void) fh.TimeDateStamp = time(0); fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED| IMAGE_FILE_EXECUTABLE_IMAGE|IMAGE_FILE_DEBUG_STRIPPED; - if (pe64) { fh.SizeOfOptionalHeader = sizeof(oh64); - oh64.Magic = 0x20b; // PE32+ - oh64.MajorLinkerVersion = 1; - oh64.MinorLinkerVersion = 0; - oh64.SizeOfCode = t->SizeOfRawData; - oh64.SizeOfInitializedData = d->SizeOfRawData; - oh64.SizeOfUninitializedData = 0; - oh64.AddressOfEntryPoint = entryvalue()-PEBASE; - oh64.BaseOfCode = t->VirtualAddress; - - oh64.ImageBase = PEBASE; - oh64.SectionAlignment = PESECTALIGN; - oh64.FileAlignment = PEFILEALIGN; - oh64.MajorOperatingSystemVersion = 4; - oh64.MinorOperatingSystemVersion = 0; - oh64.MajorImageVersion = 1; - oh64.MinorImageVersion = 0; - oh64.MajorSubsystemVersion = 4; - oh64.MinorSubsystemVersion = 0; - oh64.SizeOfImage = nextsectoff; - oh64.SizeOfHeaders = PEFILEHEADR; - oh64.Subsystem = 3; // WINDOWS_CUI - oh64.SizeOfStackReserve = 0x00200000; - oh64.SizeOfStackCommit = 0x00001000; - oh64.SizeOfHeapReserve = 0x00100000; - oh64.SizeOfHeapCommit = 0x00001000; - oh64.NumberOfRvaAndSizes = 16; + set(Magic, 0x20b); // PE32+ } else { fh.SizeOfOptionalHeader = sizeof(oh); fh.Characteristics |= IMAGE_FILE_32BIT_MACHINE; - oh.Magic = 0x10b; // PE32 - oh.MajorLinkerVersion = 1; - oh.MinorLinkerVersion = 0; - oh.SizeOfCode = t->SizeOfRawData; - oh.SizeOfInitializedData = d->SizeOfRawData; - oh.SizeOfUninitializedData = 0; - oh.AddressOfEntryPoint = entryvalue()-PEBASE; - oh.BaseOfCode = t->VirtualAddress; + set(Magic, 0x10b); // PE32 oh.BaseOfData = d->VirtualAddress; - - oh.ImageBase = PEBASE; - oh.SectionAlignment = PESECTALIGN; - oh.FileAlignment = PEFILEALIGN; - oh.MajorOperatingSystemVersion = 4; - oh.MinorOperatingSystemVersion = 0; - oh.MajorImageVersion = 1; - oh.MinorImageVersion = 0; - oh.MajorSubsystemVersion = 4; - oh.MinorSubsystemVersion = 0; - oh.SizeOfImage = nextsectoff; - oh.SizeOfHeaders = PEFILEHEADR; - oh.Subsystem = 3; // WINDOWS_CUI - oh.SizeOfStackReserve = 0x00200000; - oh.SizeOfStackCommit = 0x00001000; - oh.SizeOfHeapReserve = 0x00100000; - oh.SizeOfHeapCommit = 0x00001000; - oh.NumberOfRvaAndSizes = 16; } + set(MajorLinkerVersion, 1); + set(MinorLinkerVersion, 0); + set(SizeOfCode, t->SizeOfRawData); + set(SizeOfInitializedData, d->SizeOfRawData); + set(SizeOfUninitializedData, 0); + set(AddressOfEntryPoint, entryvalue()-PEBASE); + set(BaseOfCode, t->VirtualAddress); + set(ImageBase, PEBASE); + set(SectionAlignment, PESECTALIGN); + set(FileAlignment, PEFILEALIGN); + set(MajorOperatingSystemVersion, 4); + set(MinorOperatingSystemVersion, 0); + set(MajorImageVersion, 1); + set(MinorImageVersion, 0); + set(MajorSubsystemVersion, 4); + set(MinorSubsystemVersion, 0); + set(SizeOfImage, nextsectoff); + set(SizeOfHeaders, PEFILEHEADR); + set(Subsystem, 3); // WINDOWS_CUI + set(SizeOfStackReserve, 0x00200000); + set(SizeOfStackCommit, 0x00001000); + set(SizeOfHeapReserve, 0x00100000); + set(SizeOfHeapCommit, 0x00001000); + set(NumberOfRvaAndSizes, 16); pewrite(); } -