mirror of
https://github.com/golang/go
synced 2024-11-24 21:10:04 -07:00
8l: pe changes
Dll names and function names padded to even size. Refactoring of imports writing code. R=rsc CC=golang-dev https://golang.org/cl/3804042
This commit is contained in:
parent
ff25900bb6
commit
48d2de7eb9
159
src/cmd/ld/pe.c
159
src/cmd/ld/pe.c
@ -48,21 +48,20 @@ static IMAGE_SECTION_HEADER sh[16];
|
|||||||
typedef struct Imp Imp;
|
typedef struct Imp Imp;
|
||||||
struct Imp {
|
struct Imp {
|
||||||
Sym* s;
|
Sym* s;
|
||||||
long va;
|
uvlong off;
|
||||||
long vb;
|
|
||||||
Imp* next;
|
Imp* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Dll Dll;
|
typedef struct Dll Dll;
|
||||||
struct Dll {
|
struct Dll {
|
||||||
char* name;
|
char* name;
|
||||||
int count;
|
uvlong nameoff;
|
||||||
|
uvlong thunkoff;
|
||||||
Imp* ms;
|
Imp* ms;
|
||||||
Dll* next;
|
Dll* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Dll* dr;
|
static Dll* dr;
|
||||||
static int ndll, nimp, nsize;
|
|
||||||
|
|
||||||
static IMAGE_SECTION_HEADER*
|
static IMAGE_SECTION_HEADER*
|
||||||
addpesection(char *name, int sectsize, int filesize, Segment *s)
|
addpesection(char *name, int sectsize, int filesize, Segment *s)
|
||||||
@ -136,9 +135,15 @@ pewrite(void)
|
|||||||
static void
|
static void
|
||||||
strput(char *s)
|
strput(char *s)
|
||||||
{
|
{
|
||||||
while(*s)
|
int n;
|
||||||
|
|
||||||
|
for(n=0; *s; n++)
|
||||||
cput(*s++);
|
cput(*s++);
|
||||||
cput('\0');
|
cput('\0');
|
||||||
|
n++;
|
||||||
|
// string must be padded to even size
|
||||||
|
if(n%2)
|
||||||
|
cput('\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
static Dll*
|
static Dll*
|
||||||
@ -146,50 +151,33 @@ initdynimport(void)
|
|||||||
{
|
{
|
||||||
Imp *m;
|
Imp *m;
|
||||||
Dll *d;
|
Dll *d;
|
||||||
Sym *s;
|
Sym *s, *dynamic;
|
||||||
int i;
|
int i;
|
||||||
Sym *dynamic;
|
|
||||||
|
|
||||||
dr = nil;
|
dr = nil;
|
||||||
ndll = 0;
|
|
||||||
nimp = 0;
|
|
||||||
nsize = 0;
|
|
||||||
|
|
||||||
for(i=0; i<NHASH; i++)
|
for(i=0; i<NHASH; i++)
|
||||||
for(s = hash[i]; s != S; s = s->hash) {
|
for(s = hash[i]; s != S; s = s->hash) {
|
||||||
if(!s->reachable || !s->dynimpname)
|
if(!s->reachable || !s->dynimpname)
|
||||||
continue;
|
continue;
|
||||||
nimp++;
|
|
||||||
for(d = dr; d != nil; d = d->next) {
|
for(d = dr; d != nil; d = d->next) {
|
||||||
if(strcmp(d->name,s->dynimplib) == 0) {
|
if(strcmp(d->name,s->dynimplib) == 0) {
|
||||||
m = mal(sizeof *m);
|
m = mal(sizeof *m);
|
||||||
m->s = s;
|
|
||||||
m->next = d->ms;
|
|
||||||
d->ms = m;
|
|
||||||
d->count++;
|
|
||||||
nsize += strlen(s->dynimpname)+2+1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(d == nil) {
|
if(d == nil) {
|
||||||
d = mal(sizeof *d);
|
d = mal(sizeof *d);
|
||||||
d->name = s->dynimplib;
|
d->name = s->dynimplib;
|
||||||
d->count = 1;
|
|
||||||
d->next = dr;
|
d->next = dr;
|
||||||
dr = d;
|
dr = d;
|
||||||
m = mal(sizeof *m);
|
m = mal(sizeof *m);
|
||||||
m->s = s;
|
|
||||||
m->next = 0;
|
|
||||||
d->ms = m;
|
|
||||||
ndll++;
|
|
||||||
nsize += strlen(s->dynimpname)+2+1;
|
|
||||||
nsize += strlen(s->dynimplib)+1;
|
|
||||||
}
|
}
|
||||||
|
m->s = s;
|
||||||
|
m->next = d->ms;
|
||||||
|
d->ms = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsize += 20*ndll + 20;
|
|
||||||
nsize += 4*nimp + 4*ndll;
|
|
||||||
|
|
||||||
dynamic = lookup(".windynamic", 0);
|
dynamic = lookup(".windynamic", 0);
|
||||||
dynamic->reachable = 1;
|
dynamic->reachable = 1;
|
||||||
dynamic->type = SWINDOWS;
|
dynamic->type = SWINDOWS;
|
||||||
@ -211,83 +199,84 @@ static void
|
|||||||
addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
|
addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
|
||||||
{
|
{
|
||||||
IMAGE_SECTION_HEADER *isect;
|
IMAGE_SECTION_HEADER *isect;
|
||||||
uint32 va;
|
uvlong n, oftbase, ftbase;
|
||||||
int noff, aoff, o, last_fn, last_name_off, iat_off;
|
|
||||||
Imp *m;
|
Imp *m;
|
||||||
Dll *d;
|
Dll *d;
|
||||||
Sym* dynamic;
|
Sym* dynamic;
|
||||||
|
|
||||||
isect = addpesection(".idata", nsize, nsize, 0);
|
dynamic = lookup(".windynamic", 0);
|
||||||
|
|
||||||
|
// skip import descriptor table (will write it later)
|
||||||
|
n = 0;
|
||||||
|
for(d = dr; d != nil; d = d->next)
|
||||||
|
n++;
|
||||||
|
seek(cout, fileoff + sizeof(IMAGE_IMPORT_DESCRIPTOR) * (n + 1), 0);
|
||||||
|
|
||||||
|
// write dll names
|
||||||
|
for(d = dr; d != nil; d = d->next) {
|
||||||
|
d->nameoff = cpos() - fileoff;
|
||||||
|
strput(d->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write function names
|
||||||
|
for(d = dr; d != nil; d = d->next) {
|
||||||
|
for(m = d->ms; m != nil; m = m->next) {
|
||||||
|
m->off = nextsectoff + cpos() - fileoff;
|
||||||
|
wputl(0); // hint
|
||||||
|
strput(m->s->dynimpname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write OriginalFirstThunks
|
||||||
|
oftbase = cpos() - fileoff;
|
||||||
|
n = cpos();
|
||||||
|
for(d = dr; d != nil; d = d->next) {
|
||||||
|
d->thunkoff = cpos() - n;
|
||||||
|
for(m = d->ms; m != nil; m = m->next)
|
||||||
|
lputl(m->off);
|
||||||
|
lputl(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add pe section and pad it at the end
|
||||||
|
n = cpos() - fileoff;
|
||||||
|
isect = addpesection(".idata", n, n, 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;
|
||||||
va = isect->VirtualAddress;
|
strnput("", isect->SizeOfRawData - n);
|
||||||
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = va;
|
cflush();
|
||||||
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize;
|
|
||||||
|
|
||||||
seek(cout, fileoff, 0);
|
// write FirstThunks (allocated in .data section)
|
||||||
|
ftbase = dynamic->value - datsect->VirtualAddress - PEBASE;
|
||||||
dynamic = lookup(".windynamic", 0);
|
seek(cout, datsect->PointerToRawData + ftbase, 0);
|
||||||
iat_off = dynamic->value - PEBASE; // FirstThunk allocated in .data
|
|
||||||
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = iat_off;
|
|
||||||
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size;
|
|
||||||
|
|
||||||
noff = va + 20*ndll + 20;
|
|
||||||
aoff = noff + 4*nimp + 4*ndll;
|
|
||||||
last_fn = 0;
|
|
||||||
last_name_off = aoff;
|
|
||||||
for(d = dr; d != nil; d = d->next) {
|
for(d = dr; d != nil; d = d->next) {
|
||||||
lputl(noff);
|
for(m = d->ms; m != nil; m = m->next)
|
||||||
|
lputl(m->off);
|
||||||
|
lputl(0);
|
||||||
|
}
|
||||||
|
cflush();
|
||||||
|
|
||||||
|
// finally write import descriptor table
|
||||||
|
seek(cout, fileoff, 0);
|
||||||
|
for(d = dr; d != nil; d = d->next) {
|
||||||
|
lputl(isect->VirtualAddress + oftbase + d->thunkoff);
|
||||||
lputl(0);
|
lputl(0);
|
||||||
lputl(0);
|
lputl(0);
|
||||||
lputl(last_name_off);
|
lputl(isect->VirtualAddress + d->nameoff);
|
||||||
lputl(iat_off);
|
lputl(datsect->VirtualAddress + ftbase + d->thunkoff);
|
||||||
last_fn = d->count;
|
|
||||||
noff += 4*last_fn + 4;
|
|
||||||
aoff += 4*last_fn + 4;
|
|
||||||
iat_off += 4*last_fn + 4;
|
|
||||||
last_name_off += strlen(d->name)+1;
|
|
||||||
}
|
}
|
||||||
lputl(0); //end
|
lputl(0); //end
|
||||||
lputl(0);
|
lputl(0);
|
||||||
lputl(0);
|
lputl(0);
|
||||||
lputl(0);
|
lputl(0);
|
||||||
lputl(0);
|
lputl(0);
|
||||||
|
|
||||||
// put OriginalFirstThunk
|
|
||||||
o = last_name_off;
|
|
||||||
for(d = dr; d != nil; d = d->next) {
|
|
||||||
for(m = d->ms; m != nil; m = m->next) {
|
|
||||||
lputl(o);
|
|
||||||
o += 2 + strlen(m->s->dynimpname) + 1;
|
|
||||||
}
|
|
||||||
lputl(0);
|
|
||||||
}
|
|
||||||
// put names
|
|
||||||
for(d = dr; d != nil; d = d->next) {
|
|
||||||
strput(d->name);
|
|
||||||
}
|
|
||||||
// put hint+name
|
|
||||||
for(d = dr; d != nil; d = d->next) {
|
|
||||||
for(m = d->ms; m != nil; m = m->next) {
|
|
||||||
wputl(0);
|
|
||||||
strput(m->s->dynimpname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
strnput("", isect->SizeOfRawData - nsize);
|
|
||||||
cflush();
|
cflush();
|
||||||
|
|
||||||
|
// update data directory
|
||||||
|
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;
|
||||||
|
|
||||||
// put FirstThunk
|
|
||||||
o = last_name_off;
|
|
||||||
seek(cout, datsect->PointerToRawData + dynamic->value - PEBASE - datsect->VirtualAddress, 0);
|
|
||||||
for(d = dr; d != nil; d = d->next) {
|
|
||||||
for(m = d->ms; m != nil; m = m->next) {
|
|
||||||
lputl(o);
|
|
||||||
o += 2 + strlen(m->s->dynimpname) + 1;
|
|
||||||
}
|
|
||||||
lputl(0);
|
|
||||||
}
|
|
||||||
cflush();
|
|
||||||
seek(cout, 0, 2);
|
seek(cout, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user