aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Brainman <alex.brainman@gmail.com>2011-01-19 15:10:01 -0500
committerRuss Cox <rsc@golang.org>2011-01-19 15:10:01 -0500
commit48d2de7eb9a4ed30faf29abebbbbb205b308cb33 (patch)
tree9bd2063e1112a1d341336d70026c93584fc89629
parentff25900bb660722d3496e7afafbdb9e3454271b6 (diff)
downloadgo-48d2de7eb9a4ed30faf29abebbbbb205b308cb33.tar.gz
go-48d2de7eb9a4ed30faf29abebbbbb205b308cb33.zip
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
-rw-r--r--src/cmd/ld/pe.c151
1 files changed, 70 insertions, 81 deletions
diff --git a/src/cmd/ld/pe.c b/src/cmd/ld/pe.c
index 82c6941f25..661d307185 100644
--- a/src/cmd/ld/pe.c
+++ b/src/cmd/ld/pe.c
@@ -48,21 +48,20 @@ static IMAGE_SECTION_HEADER sh[16];
typedef struct Imp Imp;
struct Imp {
Sym* s;
- long va;
- long vb;
+ uvlong off;
Imp* next;
};
typedef struct Dll Dll;
struct Dll {
char* name;
- int count;
+ uvlong nameoff;
+ uvlong thunkoff;
Imp* ms;
Dll* next;
};
static Dll* dr;
-static int ndll, nimp, nsize;
static IMAGE_SECTION_HEADER*
addpesection(char *name, int sectsize, int filesize, Segment *s)
@@ -136,9 +135,15 @@ pewrite(void)
static void
strput(char *s)
{
- while(*s)
+ int n;
+
+ for(n=0; *s; n++)
cput(*s++);
cput('\0');
+ n++;
+ // string must be padded to even size
+ if(n%2)
+ cput('\0');
}
static Dll*
@@ -146,50 +151,33 @@ initdynimport(void)
{
Imp *m;
Dll *d;
- Sym *s;
+ Sym *s, *dynamic;
int i;
- Sym *dynamic;
dr = nil;
- ndll = 0;
- nimp = 0;
- nsize = 0;
for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->hash) {
if(!s->reachable || !s->dynimpname)
continue;
- nimp++;
for(d = dr; d != nil; d = d->next) {
if(strcmp(d->name,s->dynimplib) == 0) {
m = mal(sizeof *m);
- m->s = s;
- m->next = d->ms;
- d->ms = m;
- d->count++;
- nsize += strlen(s->dynimpname)+2+1;
break;
}
}
if(d == nil) {
d = mal(sizeof *d);
d->name = s->dynimplib;
- d->count = 1;
d->next = dr;
dr = d;
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->reachable = 1;
dynamic->type = SWINDOWS;
@@ -211,83 +199,84 @@ static void
addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
{
IMAGE_SECTION_HEADER *isect;
- uint32 va;
- int noff, aoff, o, last_fn, last_name_off, iat_off;
+ uvlong n, oftbase, ftbase;
Imp *m;
Dll *d;
Sym* dynamic;
- isect = addpesection(".idata", nsize, nsize, 0);
- isect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
- IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
- va = isect->VirtualAddress;
- oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = va;
- oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize;
-
- seek(cout, fileoff, 0);
-
dynamic = lookup(".windynamic", 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;
+ // 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) {
- lputl(noff);
- lputl(0);
- lputl(0);
- lputl(last_name_off);
- lputl(iat_off);
- 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;
+ d->nameoff = cpos() - fileoff;
+ strput(d->name);
}
- lputl(0); //end
- lputl(0);
- lputl(0);
- lputl(0);
- lputl(0);
-
- // put OriginalFirstThunk
- o = last_name_off;
+
+ // write function names
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;
+ m->off = nextsectoff + cpos() - fileoff;
+ wputl(0); // hint
+ strput(m->s->dynimpname);
}
- lputl(0);
}
- // put names
+
+ // write OriginalFirstThunks
+ oftbase = cpos() - fileoff;
+ n = cpos();
for(d = dr; d != nil; d = d->next) {
- strput(d->name);
+ d->thunkoff = cpos() - n;
+ for(m = d->ms; m != nil; m = m->next)
+ lputl(m->off);
+ lputl(0);
}
- // put hint+name
+
+ // 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|
+ IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
+ strnput("", isect->SizeOfRawData - n);
+ cflush();
+
+ // write FirstThunks (allocated in .data section)
+ ftbase = dynamic->value - datsect->VirtualAddress - PEBASE;
+ seek(cout, datsect->PointerToRawData + ftbase, 0);
for(d = dr; d != nil; d = d->next) {
- for(m = d->ms; m != nil; m = m->next) {
- wputl(0);
- strput(m->s->dynimpname);
- }
+ for(m = d->ms; m != nil; m = m->next)
+ lputl(m->off);
+ lputl(0);
}
-
- strnput("", isect->SizeOfRawData - nsize);
cflush();
- // put FirstThunk
- o = last_name_off;
- seek(cout, datsect->PointerToRawData + dynamic->value - PEBASE - datsect->VirtualAddress, 0);
+ // finally write import descriptor table
+ seek(cout, fileoff, 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(isect->VirtualAddress + oftbase + d->thunkoff);
+ lputl(0);
lputl(0);
+ lputl(isect->VirtualAddress + d->nameoff);
+ lputl(datsect->VirtualAddress + ftbase + d->thunkoff);
}
+ lputl(0); //end
+ lputl(0);
+ lputl(0);
+ lputl(0);
+ lputl(0);
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;
+
seek(cout, 0, 2);
}