mirror of
https://github.com/golang/go
synced 2024-11-25 04:07:55 -07:00
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
This commit is contained in:
parent
89cc4d7814
commit
d08df51366
@ -130,6 +130,7 @@ void ldobj1(Biobuf *f, char*, int64 len, char *pn);
|
|||||||
void ldobj(Biobuf*, char*, int64, char*, int);
|
void ldobj(Biobuf*, char*, int64, char*, int);
|
||||||
void ldelf(Biobuf*, char*, int64, char*);
|
void ldelf(Biobuf*, char*, int64, char*);
|
||||||
void ldmacho(Biobuf*, char*, int64, char*);
|
void ldmacho(Biobuf*, char*, int64, char*);
|
||||||
|
void ldpe(Biobuf*, char*, int64, char*);
|
||||||
void ldpkg(Biobuf*, char*, int64, char*, int);
|
void ldpkg(Biobuf*, char*, int64, char*, int);
|
||||||
void mark(Sym *s);
|
void mark(Sym *s);
|
||||||
void mkfwd(void);
|
void mkfwd(void);
|
||||||
|
151
src/cmd/ld/pe.c
151
src/cmd/ld/pe.c
@ -49,6 +49,10 @@ static IMAGE_FILE_HEADER fh;
|
|||||||
static IMAGE_OPTIONAL_HEADER oh;
|
static IMAGE_OPTIONAL_HEADER oh;
|
||||||
static PE64_IMAGE_OPTIONAL_HEADER oh64;
|
static PE64_IMAGE_OPTIONAL_HEADER oh64;
|
||||||
static IMAGE_SECTION_HEADER sh[16];
|
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;
|
typedef struct Imp Imp;
|
||||||
struct Imp {
|
struct Imp {
|
||||||
@ -106,18 +110,23 @@ addpesection(char *name, int sectsize, int filesize, Segment *s)
|
|||||||
void
|
void
|
||||||
peinit(void)
|
peinit(void)
|
||||||
{
|
{
|
||||||
|
int32 l;
|
||||||
|
|
||||||
switch(thechar) {
|
switch(thechar) {
|
||||||
// 64-bit architectures
|
// 64-bit architectures
|
||||||
case '6':
|
case '6':
|
||||||
pe64 = 1;
|
pe64 = 1;
|
||||||
PEFILEHEADR = rnd(sizeof(dosstub)+sizeof(fh)+sizeof(oh64)+sizeof(sh), PEFILEALIGN);
|
l = sizeof(oh64);
|
||||||
|
dd = oh64.DataDirectory;
|
||||||
break;
|
break;
|
||||||
// 32-bit architectures
|
// 32-bit architectures
|
||||||
default:
|
default:
|
||||||
PEFILEHEADR = rnd(sizeof(dosstub)+sizeof(fh)+sizeof(oh)+sizeof(sh), PEFILEALIGN);
|
l = sizeof(oh);
|
||||||
|
dd = oh.DataDirectory;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PEFILEHEADR = rnd(sizeof(dosstub)+sizeof(fh)+l+sizeof(sh), PEFILEALIGN);
|
||||||
PESECTHEADR = rnd(PEFILEHEADR, PESECTALIGN);
|
PESECTHEADR = rnd(PEFILEHEADR, PESECTALIGN);
|
||||||
nextsectoff = PESECTHEADR;
|
nextsectoff = PESECTHEADR;
|
||||||
nextfileoff = PEFILEHEADR;
|
nextfileoff = PEFILEHEADR;
|
||||||
@ -126,24 +135,20 @@ peinit(void)
|
|||||||
static void
|
static void
|
||||||
pewrite(void)
|
pewrite(void)
|
||||||
{
|
{
|
||||||
int i, j;
|
|
||||||
|
|
||||||
seek(cout, 0, 0);
|
seek(cout, 0, 0);
|
||||||
ewrite(cout, dosstub, sizeof dosstub);
|
ewrite(cout, dosstub, sizeof dosstub);
|
||||||
strnput("PE", 4);
|
strnput("PE", 4);
|
||||||
|
cflush();
|
||||||
for (i=0; i<sizeof(fh); i++)
|
// TODO: This code should not assume that the
|
||||||
cput(((char*)&fh)[i]);
|
// memory representation is little-endian or
|
||||||
if(pe64) {
|
// that the structs are packed identically to
|
||||||
for (i=0; i<sizeof(oh64); i++)
|
// their file representation.
|
||||||
cput(((char*)&oh64)[i]);
|
ewrite(cout, &fh, sizeof fh);
|
||||||
} else {
|
if(pe64)
|
||||||
for (i=0; i<sizeof(oh); i++)
|
ewrite(cout, &oh64, sizeof oh64);
|
||||||
cput(((char*)&oh)[i]);
|
else
|
||||||
}
|
ewrite(cout, &oh, sizeof oh);
|
||||||
for (i=0; i<nsect; i++)
|
ewrite(cout, &sh, nsect * sizeof sh[0]);
|
||||||
for (j=0; j<sizeof(sh[i]); j++)
|
|
||||||
cput(((char*)&sh[i])[j]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -247,8 +252,8 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
|
|||||||
for(d = dr; d != nil; d = d->next) {
|
for(d = dr; d != nil; d = d->next) {
|
||||||
d->thunkoff = cpos() - n;
|
d->thunkoff = cpos() - n;
|
||||||
for(m = d->ms; m != nil; m = m->next)
|
for(m = d->ms; m != nil; m = m->next)
|
||||||
pe64 ? vputl(m->off) : lputl(m->off);
|
put(m->off);
|
||||||
pe64 ? vputl(0): lputl(0);
|
put(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add pe section and pad it at the end
|
// 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);
|
seek(cout, datsect->PointerToRawData + ftbase, 0);
|
||||||
for(d = dr; d != nil; d = d->next) {
|
for(d = dr; d != nil; d = d->next) {
|
||||||
for(m = d->ms; m != nil; m = m->next)
|
for(m = d->ms; m != nil; m = m->next)
|
||||||
pe64 ? vputl(m->off) : lputl(m->off);
|
put(m->off);
|
||||||
pe64 ? vputl(0): lputl(0);
|
put(0);
|
||||||
}
|
}
|
||||||
cflush();
|
cflush();
|
||||||
|
|
||||||
@ -286,17 +291,10 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
|
|||||||
cflush();
|
cflush();
|
||||||
|
|
||||||
// update data directory
|
// update data directory
|
||||||
if(pe64) {
|
dd[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect->VirtualAddress;
|
||||||
oh64.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect->VirtualAddress;
|
dd[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize;
|
||||||
oh64.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize;
|
dd[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = dynamic->value - PEBASE;
|
||||||
oh64.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = dynamic->value - PEBASE;
|
dd[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
seek(cout, 0, 2);
|
seek(cout, 0, 2);
|
||||||
}
|
}
|
||||||
@ -340,7 +338,6 @@ addexports(vlong fileoff)
|
|||||||
IMAGE_SECTION_HEADER *sect;
|
IMAGE_SECTION_HEADER *sect;
|
||||||
IMAGE_EXPORT_DIRECTORY e;
|
IMAGE_EXPORT_DIRECTORY e;
|
||||||
int size, i, va, va_name, va_addr, va_na, v;
|
int size, i, va, va_name, va_addr, va_na, v;
|
||||||
Sym *s;
|
|
||||||
|
|
||||||
size = sizeof e + 10*nexport + strlen(outfile) + 1;
|
size = sizeof e + 10*nexport + strlen(outfile) + 1;
|
||||||
for(i=0; i<nexport; i++)
|
for(i=0; i<nexport; i++)
|
||||||
@ -352,8 +349,8 @@ addexports(vlong fileoff)
|
|||||||
sect = addpesection(".edata", size, size, 0);
|
sect = addpesection(".edata", size, size, 0);
|
||||||
sect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ;
|
sect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ;
|
||||||
va = sect->VirtualAddress;
|
va = sect->VirtualAddress;
|
||||||
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = va;
|
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = va;
|
||||||
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect->VirtualSize;
|
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect->VirtualSize;
|
||||||
|
|
||||||
seek(cout, fileoff, 0);
|
seek(cout, fileoff, 0);
|
||||||
va_name = va + sizeof e + nexport*4;
|
va_name = va + sizeof e + nexport*4;
|
||||||
@ -395,7 +392,6 @@ addexports(vlong fileoff)
|
|||||||
seek(cout, 0, 2);
|
seek(cout, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
dope(void)
|
dope(void)
|
||||||
{
|
{
|
||||||
@ -463,7 +459,6 @@ addsymtable(void)
|
|||||||
cflush();
|
cflush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
asmbpe(void)
|
asmbpe(void)
|
||||||
{
|
{
|
||||||
@ -486,7 +481,7 @@ asmbpe(void)
|
|||||||
IMAGE_SCN_CNT_INITIALIZED_DATA|
|
IMAGE_SCN_CNT_INITIALIZED_DATA|
|
||||||
IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ;
|
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|
|
d->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
|
||||||
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
|
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
|
||||||
|
|
||||||
@ -503,67 +498,39 @@ asmbpe(void)
|
|||||||
fh.TimeDateStamp = time(0);
|
fh.TimeDateStamp = time(0);
|
||||||
fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED|
|
fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED|
|
||||||
IMAGE_FILE_EXECUTABLE_IMAGE|IMAGE_FILE_DEBUG_STRIPPED;
|
IMAGE_FILE_EXECUTABLE_IMAGE|IMAGE_FILE_DEBUG_STRIPPED;
|
||||||
|
|
||||||
if (pe64) {
|
if (pe64) {
|
||||||
fh.SizeOfOptionalHeader = sizeof(oh64);
|
fh.SizeOfOptionalHeader = sizeof(oh64);
|
||||||
oh64.Magic = 0x20b; // PE32+
|
set(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;
|
|
||||||
} else {
|
} else {
|
||||||
fh.SizeOfOptionalHeader = sizeof(oh);
|
fh.SizeOfOptionalHeader = sizeof(oh);
|
||||||
fh.Characteristics |= IMAGE_FILE_32BIT_MACHINE;
|
fh.Characteristics |= IMAGE_FILE_32BIT_MACHINE;
|
||||||
oh.Magic = 0x10b; // PE32
|
set(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;
|
|
||||||
oh.BaseOfData = d->VirtualAddress;
|
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();
|
pewrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user