mirror of
https://github.com/golang/go
synced 2024-11-22 06:24:38 -07:00
8l: pe generation fixes
Restore ability to have different file and section alignment in generated pe file. Stop generating .bss pe section, it is part of .data now. Some code refactoring. R=rsc, vcc CC=golang-dev https://golang.org/cl/2731041
This commit is contained in:
parent
ce98044523
commit
8f8f625cb1
@ -397,10 +397,14 @@ asmb(void)
|
|||||||
symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(segdata.filelen, INITRND)+machlink;
|
symo = rnd(HEADR+segtext.filelen, INITRND)+rnd(segdata.filelen, INITRND)+machlink;
|
||||||
break;
|
break;
|
||||||
Elfsym:
|
Elfsym:
|
||||||
case 10:
|
|
||||||
symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
|
symo = rnd(HEADR+segtext.filelen, INITRND)+segdata.filelen;
|
||||||
symo = rnd(symo, INITRND);
|
symo = rnd(symo, INITRND);
|
||||||
break;
|
break;
|
||||||
|
case 10:
|
||||||
|
// TODO(brainman): not sure what symo meant to be, but it is not used for Windows PE for now anyway
|
||||||
|
symo = rnd(HEADR+segtext.filelen, PEFILEALIGN)+segdata.filelen;
|
||||||
|
symo = rnd(symo, PEFILEALIGN);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if(HEADTYPE != 10 && !debug['s']) {
|
if(HEADTYPE != 10 && !debug['s']) {
|
||||||
seek(cout, symo, 0);
|
seek(cout, symo, 0);
|
||||||
|
@ -265,13 +265,13 @@ main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
case 10: /* PE executable */
|
case 10: /* PE executable */
|
||||||
peinit();
|
peinit();
|
||||||
HEADR = PERESERVE;
|
HEADR = PEFILEHEADR;
|
||||||
if(INITTEXT == -1)
|
if(INITTEXT == -1)
|
||||||
INITTEXT = PEBASE+0x1000;
|
INITTEXT = PEBASE+PESECTHEADR;
|
||||||
if(INITDAT == -1)
|
if(INITDAT == -1)
|
||||||
INITDAT = 0;
|
INITDAT = 0;
|
||||||
if(INITRND == -1)
|
if(INITRND == -1)
|
||||||
INITRND = 4096;
|
INITRND = PESECTALIGN;
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
tlsoffset = 0;
|
tlsoffset = 0;
|
||||||
@ -332,8 +332,6 @@ main(int argc, char *argv[])
|
|||||||
dodata();
|
dodata();
|
||||||
address();
|
address();
|
||||||
reloc();
|
reloc();
|
||||||
if(HEADTYPE == 10)
|
|
||||||
dope();
|
|
||||||
asmb();
|
asmb();
|
||||||
undef();
|
undef();
|
||||||
if(debug['v']) {
|
if(debug['v']) {
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "l.h"
|
#include "l.h"
|
||||||
#include "../ld/lib.h"
|
#include "../ld/lib.h"
|
||||||
#include "../ld/elf.h"
|
#include "../ld/elf.h"
|
||||||
|
#include "../ld/pe.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* divide-and-conquer list-link
|
* divide-and-conquer list-link
|
||||||
@ -736,6 +737,8 @@ address(void)
|
|||||||
segdata.rwx = 06;
|
segdata.rwx = 06;
|
||||||
segdata.vaddr = va;
|
segdata.vaddr = va;
|
||||||
segdata.fileoff = va - segtext.vaddr + segtext.fileoff;
|
segdata.fileoff = va - segtext.vaddr + segtext.fileoff;
|
||||||
|
if(thechar == '8' && HEADTYPE == 10) // Windows PE
|
||||||
|
segdata.fileoff = segtext.fileoff + rnd(segtext.len, PEFILEALIGN);
|
||||||
for(s=segdata.sect; s != nil; s=s->next) {
|
for(s=segdata.sect; s != nil; s=s->next) {
|
||||||
s->vaddr = va;
|
s->vaddr = va;
|
||||||
va += s->len;
|
va += s->len;
|
||||||
|
100
src/cmd/ld/pe.c
100
src/cmd/ld/pe.c
@ -33,18 +33,20 @@ static char dosstub[] =
|
|||||||
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int32 PESECTHEADR;
|
||||||
|
int32 PEFILEHEADR;
|
||||||
|
|
||||||
static int pe64;
|
static int pe64;
|
||||||
static int nsect;
|
static int nsect;
|
||||||
static int sect_virt_begin;
|
static int nextsectoff;
|
||||||
static int sect_raw_begin = PERESERVE;
|
static int nextfileoff;
|
||||||
|
|
||||||
static IMAGE_FILE_HEADER fh;
|
static IMAGE_FILE_HEADER fh;
|
||||||
static IMAGE_OPTIONAL_HEADER oh;
|
static IMAGE_OPTIONAL_HEADER oh;
|
||||||
static IMAGE_SECTION_HEADER sh[16];
|
static IMAGE_SECTION_HEADER sh[16];
|
||||||
static IMAGE_SECTION_HEADER *textsect, *datsect, *bsssect;
|
|
||||||
|
|
||||||
static IMAGE_SECTION_HEADER*
|
static IMAGE_SECTION_HEADER*
|
||||||
new_section(char *name, int size, int noraw)
|
addpesection(char *name, int sectsize, int filesize, Segment *s)
|
||||||
{
|
{
|
||||||
IMAGE_SECTION_HEADER *h;
|
IMAGE_SECTION_HEADER *h;
|
||||||
|
|
||||||
@ -54,15 +56,23 @@ new_section(char *name, int size, int noraw)
|
|||||||
}
|
}
|
||||||
h = &sh[nsect++];
|
h = &sh[nsect++];
|
||||||
strncpy((char*)h->Name, name, sizeof(h->Name));
|
strncpy((char*)h->Name, name, sizeof(h->Name));
|
||||||
h->VirtualSize = size;
|
h->VirtualSize = sectsize;
|
||||||
if(!sect_virt_begin)
|
h->VirtualAddress = nextsectoff;
|
||||||
sect_virt_begin = 0x1000;
|
nextsectoff = rnd(nextsectoff+sectsize, PESECTALIGN);
|
||||||
h->VirtualAddress = sect_virt_begin;
|
h->PointerToRawData = nextfileoff;
|
||||||
sect_virt_begin = rnd(sect_virt_begin+size, 0x1000);
|
if(filesize > 0) {
|
||||||
if(!noraw) {
|
h->SizeOfRawData = rnd(filesize, PEFILEALIGN);
|
||||||
h->SizeOfRawData = rnd(size, PEALIGN);
|
nextfileoff += h->SizeOfRawData;
|
||||||
h->PointerToRawData = sect_raw_begin;
|
}
|
||||||
sect_raw_begin += h->SizeOfRawData;
|
if(s) {
|
||||||
|
if(s->vaddr-PEBASE != h->VirtualAddress) {
|
||||||
|
diag("%s.VirtualAddress = %#llux, want %#llux", name, (vlong)h->VirtualAddress, (vlong)(s->vaddr-PEBASE));
|
||||||
|
errorexit();
|
||||||
|
}
|
||||||
|
if(s->fileoff != h->PointerToRawData) {
|
||||||
|
diag("%s.PointerToRawData = %#llux, want %#llux", name, (vlong)h->PointerToRawData, (vlong)(s->fileoff));
|
||||||
|
errorexit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
@ -79,6 +89,11 @@ peinit(void)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PEFILEHEADR = rnd(sizeof(dosstub)+sizeof(fh)+sizeof(oh)+sizeof(sh), PEFILEALIGN);
|
||||||
|
PESECTHEADR = rnd(PEFILEHEADR, PESECTALIGN);
|
||||||
|
nextsectoff = PESECTHEADR;
|
||||||
|
nextfileoff = PEFILEHEADR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -97,26 +112,6 @@ pewrite(void)
|
|||||||
for (i=0; i<nsect; i++)
|
for (i=0; i<nsect; i++)
|
||||||
for (j=0; j<sizeof(sh[i]); j++)
|
for (j=0; j<sizeof(sh[i]); j++)
|
||||||
cput(((char*)&sh[i])[j]);
|
cput(((char*)&sh[i])[j]);
|
||||||
strnput("", PERESERVE-0x400);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
dope(void)
|
|
||||||
{
|
|
||||||
textsect = new_section(".text", segtext.len, 0);
|
|
||||||
textsect->Characteristics = IMAGE_SCN_CNT_CODE|
|
|
||||||
IMAGE_SCN_CNT_INITIALIZED_DATA|
|
|
||||||
IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ;
|
|
||||||
|
|
||||||
datsect = new_section(".data", segdata.filelen, 0);
|
|
||||||
datsect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
|
|
||||||
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
|
|
||||||
if(segdata.vaddr != PEBASE+datsect->VirtualAddress)
|
|
||||||
diag("segdata.vaddr = %#llux, want %#llux", (vlong)segdata.vaddr, (vlong)(PEBASE+datsect->VirtualAddress));
|
|
||||||
|
|
||||||
bsssect = new_section(".bss", segdata.len - segdata.filelen, 1);
|
|
||||||
bsssect->Characteristics = IMAGE_SCN_CNT_UNINITIALIZED_DATA|
|
|
||||||
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -128,7 +123,7 @@ strput(char *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_import_table(void)
|
addimports(vlong fileoff)
|
||||||
{
|
{
|
||||||
IMAGE_IMPORT_DESCRIPTOR ds[2], *d;
|
IMAGE_IMPORT_DESCRIPTOR ds[2], *d;
|
||||||
char *dllname = "kernel32.dll";
|
char *dllname = "kernel32.dll";
|
||||||
@ -155,7 +150,7 @@ add_import_table(void)
|
|||||||
size += sizeof(fs[0].thunk);
|
size += sizeof(fs[0].thunk);
|
||||||
|
|
||||||
IMAGE_SECTION_HEADER *isect;
|
IMAGE_SECTION_HEADER *isect;
|
||||||
isect = new_section(".idata", size, 0);
|
isect = addpesection(".idata", size, size, 0);
|
||||||
isect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
|
isect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
|
||||||
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
|
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
|
||||||
|
|
||||||
@ -168,7 +163,7 @@ add_import_table(void)
|
|||||||
for(f=fs; f->name; f++)
|
for(f=fs; f->name; f++)
|
||||||
f->thunk += va;
|
f->thunk += va;
|
||||||
|
|
||||||
seek(cout, 0, 2);
|
seek(cout, fileoff, 0);
|
||||||
for(d=ds; ; d++) {
|
for(d=ds; ; d++) {
|
||||||
lputl(d->OriginalFirstThunk);
|
lputl(d->OriginalFirstThunk);
|
||||||
lputl(d->TimeDateStamp);
|
lputl(d->TimeDateStamp);
|
||||||
@ -192,7 +187,7 @@ add_import_table(void)
|
|||||||
void
|
void
|
||||||
asmbpe(void)
|
asmbpe(void)
|
||||||
{
|
{
|
||||||
vlong eof;
|
IMAGE_SECTION_HEADER *t, *d;
|
||||||
|
|
||||||
switch(thechar) {
|
switch(thechar) {
|
||||||
default:
|
default:
|
||||||
@ -206,11 +201,16 @@ asmbpe(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the end of file is INITRND-aligned.
|
t = addpesection(".text", segtext.len, segtext.len, &segtext);
|
||||||
eof = seek(cout, 0, 2);
|
t->Characteristics = IMAGE_SCN_CNT_CODE|
|
||||||
strnput("", rnd(eof, INITRND) - eof);
|
IMAGE_SCN_CNT_INITIALIZED_DATA|
|
||||||
|
IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ;
|
||||||
|
|
||||||
add_import_table();
|
d = addpesection(".data", segdata.len, segdata.filelen, &segdata);
|
||||||
|
d->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
|
||||||
|
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
|
||||||
|
|
||||||
|
addimports(nextfileoff);
|
||||||
|
|
||||||
fh.NumberOfSections = nsect;
|
fh.NumberOfSections = nsect;
|
||||||
fh.TimeDateStamp = time(0);
|
fh.TimeDateStamp = time(0);
|
||||||
@ -223,24 +223,24 @@ asmbpe(void)
|
|||||||
oh.Magic = 0x10b; // PE32
|
oh.Magic = 0x10b; // PE32
|
||||||
oh.MajorLinkerVersion = 1;
|
oh.MajorLinkerVersion = 1;
|
||||||
oh.MinorLinkerVersion = 0;
|
oh.MinorLinkerVersion = 0;
|
||||||
oh.SizeOfCode = textsect->SizeOfRawData;
|
oh.SizeOfCode = t->SizeOfRawData;
|
||||||
oh.SizeOfInitializedData = datsect->SizeOfRawData;
|
oh.SizeOfInitializedData = d->SizeOfRawData;
|
||||||
oh.SizeOfUninitializedData = bsssect->SizeOfRawData;
|
oh.SizeOfUninitializedData = 0;
|
||||||
oh.AddressOfEntryPoint = entryvalue()-PEBASE;
|
oh.AddressOfEntryPoint = entryvalue()-PEBASE;
|
||||||
oh.BaseOfCode = textsect->VirtualAddress;
|
oh.BaseOfCode = t->VirtualAddress;
|
||||||
oh.BaseOfData = datsect->VirtualAddress;
|
oh.BaseOfData = d->VirtualAddress;
|
||||||
|
|
||||||
oh.ImageBase = PEBASE;
|
oh.ImageBase = PEBASE;
|
||||||
oh.SectionAlignment = 0x00001000;
|
oh.SectionAlignment = PESECTALIGN;
|
||||||
oh.FileAlignment = PEALIGN;
|
oh.FileAlignment = PEFILEALIGN;
|
||||||
oh.MajorOperatingSystemVersion = 4;
|
oh.MajorOperatingSystemVersion = 4;
|
||||||
oh.MinorOperatingSystemVersion = 0;
|
oh.MinorOperatingSystemVersion = 0;
|
||||||
oh.MajorImageVersion = 1;
|
oh.MajorImageVersion = 1;
|
||||||
oh.MinorImageVersion = 0;
|
oh.MinorImageVersion = 0;
|
||||||
oh.MajorSubsystemVersion = 4;
|
oh.MajorSubsystemVersion = 4;
|
||||||
oh.MinorSubsystemVersion = 0;
|
oh.MinorSubsystemVersion = 0;
|
||||||
oh.SizeOfImage = sect_virt_begin;
|
oh.SizeOfImage = nextsectoff;
|
||||||
oh.SizeOfHeaders = PERESERVE;
|
oh.SizeOfHeaders = PEFILEHEADR;
|
||||||
oh.Subsystem = 3; // WINDOWS_CUI
|
oh.Subsystem = 3; // WINDOWS_CUI
|
||||||
oh.SizeOfStackReserve = 0x00200000;
|
oh.SizeOfStackReserve = 0x00200000;
|
||||||
oh.SizeOfStackCommit = 0x00001000;
|
oh.SizeOfStackCommit = 0x00001000;
|
||||||
|
@ -72,9 +72,16 @@ typedef struct {
|
|||||||
uint32 FirstThunk;
|
uint32 FirstThunk;
|
||||||
} IMAGE_IMPORT_DESCRIPTOR;
|
} IMAGE_IMPORT_DESCRIPTOR;
|
||||||
|
|
||||||
#define PERESERVE 0x1000
|
|
||||||
#define PEALIGN 0x1000
|
|
||||||
#define PEBASE 0x00400000
|
#define PEBASE 0x00400000
|
||||||
|
// SectionAlignment must be greater than or equal to FileAlignment.
|
||||||
|
// The default is the page size for the architecture.
|
||||||
|
#define PESECTALIGN 0x1000
|
||||||
|
// FileAlignment should be a power of 2 between 512 and 64 K, inclusive.
|
||||||
|
// The default is 512. If the SectionAlignment is less than
|
||||||
|
// the architecture's page size, then FileAlignment must match SectionAlignment.
|
||||||
|
#define PEFILEALIGN (2<<8)
|
||||||
|
extern int32 PESECTHEADR;
|
||||||
|
extern int32 PEFILEHEADR;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
IMAGE_FILE_MACHINE_I386 = 0x14c,
|
IMAGE_FILE_MACHINE_I386 = 0x14c,
|
||||||
@ -112,5 +119,4 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void peinit(void);
|
void peinit(void);
|
||||||
void dope(void);
|
|
||||||
void asmbpe(void);
|
void asmbpe(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user