mirror of
https://github.com/golang/go
synced 2024-11-22 00:44:39 -07:00
ld: remove cseekend and redo pe writing
Simplify code and add more checks. Fixes #2105. R=rsc CC=golang-dev https://golang.org/cl/4794060
This commit is contained in:
parent
5a52c6ad29
commit
fa249cae38
@ -1415,9 +1415,3 @@ cwrite(void *buf, int n)
|
|||||||
}
|
}
|
||||||
coutpos += n;
|
coutpos += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
cseekend(void)
|
|
||||||
{
|
|
||||||
seek(cout, 0, 2);
|
|
||||||
}
|
|
||||||
|
@ -302,7 +302,6 @@ EXTERN char* cbpmax;
|
|||||||
void cflush(void);
|
void cflush(void);
|
||||||
vlong cpos(void);
|
vlong cpos(void);
|
||||||
void cseek(vlong);
|
void cseek(vlong);
|
||||||
void cseekend(void);
|
|
||||||
void cwrite(void*, int);
|
void cwrite(void*, int);
|
||||||
void importcycles(void);
|
void importcycles(void);
|
||||||
int Zconv(Fmt*);
|
int Zconv(Fmt*);
|
||||||
|
@ -76,7 +76,7 @@ static Sym *dexport[1024];
|
|||||||
static int nexport;
|
static int nexport;
|
||||||
|
|
||||||
static IMAGE_SECTION_HEADER*
|
static IMAGE_SECTION_HEADER*
|
||||||
addpesection(char *name, int sectsize, int filesize, Segment *s)
|
addpesection(char *name, int sectsize, int filesize)
|
||||||
{
|
{
|
||||||
IMAGE_SECTION_HEADER *h;
|
IMAGE_SECTION_HEADER *h;
|
||||||
|
|
||||||
@ -94,18 +94,30 @@ addpesection(char *name, int sectsize, int filesize, Segment *s)
|
|||||||
h->SizeOfRawData = rnd(filesize, PEFILEALIGN);
|
h->SizeOfRawData = rnd(filesize, PEFILEALIGN);
|
||||||
nextfileoff += h->SizeOfRawData;
|
nextfileoff += h->SizeOfRawData;
|
||||||
}
|
}
|
||||||
if(s) {
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
chksectoff(IMAGE_SECTION_HEADER *h, vlong off)
|
||||||
|
{
|
||||||
|
if(off != h->PointerToRawData) {
|
||||||
|
diag("%s.PointerToRawData = %#llux, want %#llux", h->Name, (vlong)h->PointerToRawData, off);
|
||||||
|
errorexit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
chksectseg(IMAGE_SECTION_HEADER *h, Segment *s)
|
||||||
|
{
|
||||||
if(s->vaddr-PEBASE != h->VirtualAddress) {
|
if(s->vaddr-PEBASE != h->VirtualAddress) {
|
||||||
diag("%s.VirtualAddress = %#llux, want %#llux", name, (vlong)h->VirtualAddress, (vlong)(s->vaddr-PEBASE));
|
diag("%s.VirtualAddress = %#llux, want %#llux", h->Name, (vlong)h->VirtualAddress, (vlong)(s->vaddr-PEBASE));
|
||||||
errorexit();
|
errorexit();
|
||||||
}
|
}
|
||||||
if(s->fileoff != h->PointerToRawData) {
|
if(s->fileoff != h->PointerToRawData) {
|
||||||
diag("%s.PointerToRawData = %#llux, want %#llux", name, (vlong)h->PointerToRawData, (vlong)(s->fileoff));
|
diag("%s.PointerToRawData = %#llux, want %#llux", h->Name, (vlong)h->PointerToRawData, (vlong)(s->fileoff));
|
||||||
errorexit();
|
errorexit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return h;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
peinit(void)
|
peinit(void)
|
||||||
@ -138,7 +150,6 @@ pewrite(void)
|
|||||||
cseek(0);
|
cseek(0);
|
||||||
cwrite(dosstub, sizeof dosstub);
|
cwrite(dosstub, sizeof dosstub);
|
||||||
strnput("PE", 4);
|
strnput("PE", 4);
|
||||||
cflush();
|
|
||||||
// TODO: This code should not assume that the
|
// TODO: This code should not assume that the
|
||||||
// memory representation is little-endian or
|
// memory representation is little-endian or
|
||||||
// that the structs are packed identically to
|
// that the structs are packed identically to
|
||||||
@ -213,39 +224,41 @@ initdynimport(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
|
addimports(IMAGE_SECTION_HEADER *datsect)
|
||||||
{
|
{
|
||||||
IMAGE_SECTION_HEADER *isect;
|
IMAGE_SECTION_HEADER *isect;
|
||||||
uvlong n, oftbase, ftbase;
|
uvlong n, oftbase, ftbase;
|
||||||
|
vlong startoff, endoff;
|
||||||
Imp *m;
|
Imp *m;
|
||||||
Dll *d;
|
Dll *d;
|
||||||
Sym* dynamic;
|
Sym* dynamic;
|
||||||
|
|
||||||
|
startoff = cpos();
|
||||||
dynamic = lookup(".windynamic", 0);
|
dynamic = lookup(".windynamic", 0);
|
||||||
|
|
||||||
// skip import descriptor table (will write it later)
|
// skip import descriptor table (will write it later)
|
||||||
n = 0;
|
n = 0;
|
||||||
for(d = dr; d != nil; d = d->next)
|
for(d = dr; d != nil; d = d->next)
|
||||||
n++;
|
n++;
|
||||||
cseek(fileoff + sizeof(IMAGE_IMPORT_DESCRIPTOR) * (n + 1));
|
cseek(startoff + sizeof(IMAGE_IMPORT_DESCRIPTOR) * (n + 1));
|
||||||
|
|
||||||
// write dll names
|
// write dll names
|
||||||
for(d = dr; d != nil; d = d->next) {
|
for(d = dr; d != nil; d = d->next) {
|
||||||
d->nameoff = cpos() - fileoff;
|
d->nameoff = cpos() - startoff;
|
||||||
strput(d->name);
|
strput(d->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// write function names
|
// write function names
|
||||||
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) {
|
||||||
m->off = nextsectoff + cpos() - fileoff;
|
m->off = nextsectoff + cpos() - startoff;
|
||||||
wputl(0); // hint
|
wputl(0); // hint
|
||||||
strput(m->s->dynimpname);
|
strput(m->s->dynimpname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write OriginalFirstThunks
|
// write OriginalFirstThunks
|
||||||
oftbase = cpos() - fileoff;
|
oftbase = cpos() - startoff;
|
||||||
n = cpos();
|
n = cpos();
|
||||||
for(d = dr; d != nil; d = d->next) {
|
for(d = dr; d != nil; d = d->next) {
|
||||||
d->thunkoff = cpos() - n;
|
d->thunkoff = cpos() - n;
|
||||||
@ -255,12 +268,13 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add pe section and pad it at the end
|
// add pe section and pad it at the end
|
||||||
n = cpos() - fileoff;
|
n = cpos() - startoff;
|
||||||
isect = addpesection(".idata", n, n, 0);
|
isect = addpesection(".idata", n, n);
|
||||||
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;
|
||||||
|
chksectoff(isect, startoff);
|
||||||
strnput("", isect->SizeOfRawData - n);
|
strnput("", isect->SizeOfRawData - n);
|
||||||
cflush();
|
endoff = cpos();
|
||||||
|
|
||||||
// write FirstThunks (allocated in .data section)
|
// write FirstThunks (allocated in .data section)
|
||||||
ftbase = dynamic->value - datsect->VirtualAddress - PEBASE;
|
ftbase = dynamic->value - datsect->VirtualAddress - PEBASE;
|
||||||
@ -270,10 +284,9 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
|
|||||||
put(m->off);
|
put(m->off);
|
||||||
put(0);
|
put(0);
|
||||||
}
|
}
|
||||||
cflush();
|
|
||||||
|
|
||||||
// finally write import descriptor table
|
// finally write import descriptor table
|
||||||
cseek(fileoff);
|
cseek(startoff);
|
||||||
for(d = dr; d != nil; d = d->next) {
|
for(d = dr; d != nil; d = d->next) {
|
||||||
lputl(isect->VirtualAddress + oftbase + d->thunkoff);
|
lputl(isect->VirtualAddress + oftbase + d->thunkoff);
|
||||||
lputl(0);
|
lputl(0);
|
||||||
@ -286,7 +299,6 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
|
|||||||
lputl(0);
|
lputl(0);
|
||||||
lputl(0);
|
lputl(0);
|
||||||
lputl(0);
|
lputl(0);
|
||||||
cflush();
|
|
||||||
|
|
||||||
// update data directory
|
// update data directory
|
||||||
dd[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect->VirtualAddress;
|
dd[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect->VirtualAddress;
|
||||||
@ -294,7 +306,7 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
|
|||||||
dd[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = dynamic->value - PEBASE;
|
dd[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = dynamic->value - PEBASE;
|
||||||
dd[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size;
|
dd[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size;
|
||||||
|
|
||||||
cseekend();
|
cseek(endoff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -329,7 +341,7 @@ initdynexport(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
addexports(vlong fileoff)
|
addexports(void)
|
||||||
{
|
{
|
||||||
IMAGE_SECTION_HEADER *sect;
|
IMAGE_SECTION_HEADER *sect;
|
||||||
IMAGE_EXPORT_DIRECTORY e;
|
IMAGE_EXPORT_DIRECTORY e;
|
||||||
@ -342,13 +354,13 @@ addexports(vlong fileoff)
|
|||||||
if (nexport == 0)
|
if (nexport == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sect = addpesection(".edata", size, size, 0);
|
sect = addpesection(".edata", size, size);
|
||||||
sect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ;
|
sect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ;
|
||||||
|
chksectoff(sect, cpos());
|
||||||
va = sect->VirtualAddress;
|
va = sect->VirtualAddress;
|
||||||
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = va;
|
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = va;
|
||||||
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect->VirtualSize;
|
dd[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect->VirtualSize;
|
||||||
|
|
||||||
cseek(fileoff);
|
|
||||||
va_name = va + sizeof e + nexport*4;
|
va_name = va + sizeof e + nexport*4;
|
||||||
va_addr = va + sizeof e;
|
va_addr = va + sizeof e;
|
||||||
va_na = va + sizeof e + nexport*8;
|
va_na = va + sizeof e + nexport*8;
|
||||||
@ -383,9 +395,6 @@ addexports(vlong fileoff)
|
|||||||
for(i=0; i<nexport; i++)
|
for(i=0; i<nexport; i++)
|
||||||
strnput(dexport[i]->dynimpname, strlen(dexport[i]->dynimpname)+1);
|
strnput(dexport[i]->dynimpname, strlen(dexport[i]->dynimpname)+1);
|
||||||
strnput("", sect->SizeOfRawData - size);
|
strnput("", sect->SizeOfRawData - size);
|
||||||
cflush();
|
|
||||||
|
|
||||||
cseekend();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -428,7 +437,7 @@ newPEDWARFSection(char *name, vlong size)
|
|||||||
nextsymoff += strlen(name);
|
nextsymoff += strlen(name);
|
||||||
symnames[nextsymoff] = 0;
|
symnames[nextsymoff] = 0;
|
||||||
nextsymoff ++;
|
nextsymoff ++;
|
||||||
h = addpesection(s, size, size, 0);
|
h = addpesection(s, size, size);
|
||||||
h->Characteristics = IMAGE_SCN_MEM_READ|
|
h->Characteristics = IMAGE_SCN_MEM_READ|
|
||||||
IMAGE_SCN_MEM_DISCARDABLE;
|
IMAGE_SCN_MEM_DISCARDABLE;
|
||||||
|
|
||||||
@ -445,9 +454,10 @@ addsymtable(void)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
size = nextsymoff + 4;
|
size = nextsymoff + 4;
|
||||||
h = addpesection(".symtab", size, size, 0);
|
h = addpesection(".symtab", size, size);
|
||||||
h->Characteristics = IMAGE_SCN_MEM_READ|
|
h->Characteristics = IMAGE_SCN_MEM_READ|
|
||||||
IMAGE_SCN_MEM_DISCARDABLE;
|
IMAGE_SCN_MEM_DISCARDABLE;
|
||||||
|
chksectoff(h, cpos());
|
||||||
fh.PointerToSymbolTable = cpos();
|
fh.PointerToSymbolTable = cpos();
|
||||||
fh.NumberOfSymbols = 0;
|
fh.NumberOfSymbols = 0;
|
||||||
// put symbol string table
|
// put symbol string table
|
||||||
@ -455,7 +465,6 @@ addsymtable(void)
|
|||||||
for (i=0; i<nextsymoff; i++)
|
for (i=0; i<nextsymoff; i++)
|
||||||
cput(symnames[i]);
|
cput(symnames[i]);
|
||||||
strnput("", h->SizeOfRawData - size);
|
strnput("", h->SizeOfRawData - size);
|
||||||
cflush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -478,9 +487,10 @@ addpersrc(void)
|
|||||||
if(rsrcsym == nil)
|
if(rsrcsym == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
h = addpesection(".rsrc", rsrcsym->size, rsrcsym->size, 0);
|
h = addpesection(".rsrc", rsrcsym->size, rsrcsym->size);
|
||||||
h->Characteristics = IMAGE_SCN_MEM_READ|
|
h->Characteristics = IMAGE_SCN_MEM_READ|
|
||||||
IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA;
|
IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA;
|
||||||
|
chksectoff(h, cpos());
|
||||||
// relocation
|
// relocation
|
||||||
for(r=rsrcsym->r; r<rsrcsym->r+rsrcsym->nr; r++) {
|
for(r=rsrcsym->r; r<rsrcsym->r+rsrcsym->nr; r++) {
|
||||||
p = rsrcsym->p + r->off;
|
p = rsrcsym->p + r->off;
|
||||||
@ -493,7 +503,6 @@ addpersrc(void)
|
|||||||
}
|
}
|
||||||
cwrite(rsrcsym->p, rsrcsym->size);
|
cwrite(rsrcsym->p, rsrcsym->size);
|
||||||
strnput("", h->SizeOfRawData - rsrcsym->size);
|
strnput("", h->SizeOfRawData - rsrcsym->size);
|
||||||
cflush();
|
|
||||||
|
|
||||||
// update data directory
|
// update data directory
|
||||||
dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = h->VirtualAddress;
|
dd[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = h->VirtualAddress;
|
||||||
@ -517,24 +526,24 @@ asmbpe(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = addpesection(".text", segtext.len, segtext.len, &segtext);
|
t = addpesection(".text", segtext.len, segtext.len);
|
||||||
t->Characteristics = IMAGE_SCN_CNT_CODE|
|
t->Characteristics = IMAGE_SCN_CNT_CODE|
|
||||||
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;
|
||||||
|
chksectseg(t, &segtext);
|
||||||
|
|
||||||
d = addpesection(".data", segdata.len, segdata.filelen, &segdata);
|
d = addpesection(".data", segdata.len, segdata.filelen);
|
||||||
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;
|
||||||
|
chksectseg(d, &segdata);
|
||||||
|
|
||||||
if(!debug['s'])
|
if(!debug['s'])
|
||||||
dwarfaddpeheaders();
|
dwarfaddpeheaders();
|
||||||
|
|
||||||
addimports(nextfileoff, d);
|
cseek(nextfileoff);
|
||||||
|
addimports(d);
|
||||||
addexports(nextfileoff);
|
addexports();
|
||||||
|
|
||||||
addsymtable();
|
addsymtable();
|
||||||
|
|
||||||
addpersrc();
|
addpersrc();
|
||||||
|
|
||||||
fh.NumberOfSections = nsect;
|
fh.NumberOfSections = nsect;
|
||||||
|
Loading…
Reference in New Issue
Block a user