aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Brainman <alex.brainman@gmail.com>2010-02-10 00:47:52 -0800
committerRuss Cox <rsc@golang.org>2010-02-10 00:47:52 -0800
commit3b1a71862e0db013ec1b2c1cb55212e9611e8885 (patch)
treee38f5f1f32101747687b959ebfabac98594115c5
parent1ca39fb1fdce4d9371d5b95829234490ff9f8327 (diff)
downloadgo-3b1a71862e0db013ec1b2c1cb55212e9611e8885.tar.gz
go-3b1a71862e0db013ec1b2c1cb55212e9611e8885.zip
8l: pe executable building code changed to include import table for kernel32.dll functions
Fixes #586. R=rsc CC=golang-dev https://golang.org/cl/203060
-rw-r--r--src/cmd/ld/pe.c74
-rw-r--r--src/cmd/ld/pe.h25
2 files changed, 99 insertions, 0 deletions
diff --git a/src/cmd/ld/pe.c b/src/cmd/ld/pe.c
index 3a3099d044..15bd7b70d6 100644
--- a/src/cmd/ld/pe.c
+++ b/src/cmd/ld/pe.c
@@ -95,6 +95,78 @@ dope(void)
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
}
+static void
+strput(char *s)
+{
+ while(*s)
+ cput(*s++);
+ cput('\0');
+}
+
+static void
+add_import_table(void)
+{
+ IMAGE_IMPORT_DESCRIPTOR ds[2], *d;
+ char *dllname = "kernel32.dll";
+ struct {
+ char *name;
+ uint32 thunk;
+ } *f, fs[] = {
+ { "GetProcAddress", 0 },
+ { "LoadLibraryExA", 0 },
+ { 0, 0 }
+ };
+
+ uint32 size = 0;
+ memset(ds, 0, sizeof(ds));
+ size += sizeof(ds);
+ ds[0].Name = size;
+ size += strlen(dllname) + 1;
+ for(f=fs; f->name; f++) {
+ f->thunk = size;
+ size += sizeof(uint16) + strlen(f->name) + 1;
+ }
+ ds[0].FirstThunk = size;
+ for(f=fs; f->name; f++)
+ size += sizeof(fs[0].thunk);
+
+ IMAGE_SECTION_HEADER *isect;
+ isect = new_section(".idata", size, 0);
+ isect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|
+ IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
+
+ uint32 va = isect->VirtualAddress;
+ oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = va;
+ oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize;
+
+ ds[0].Name += va;
+ ds[0].FirstThunk += va;
+ for(f=fs; f->name; f++)
+ f->thunk += va;
+
+ vlong off = seek(cout, 0, 1);
+ seek(cout, 0, 2);
+ for(d=ds; ; d++) {
+ lputl(d->OriginalFirstThunk);
+ lputl(d->TimeDateStamp);
+ lputl(d->ForwarderChain);
+ lputl(d->Name);
+ lputl(d->FirstThunk);
+ if(!d->Name)
+ break;
+ }
+ strput(dllname);
+ for(f=fs; f->name; f++) {
+ wputl(0);
+ strput(f->name);
+ }
+ for(f=fs; f->name; f++)
+ lputl(f->thunk);
+ strnput("", isect->SizeOfRawData - size);
+ cflush();
+ seek(cout, off, 0);
+}
+
void
asmbpe(void)
{
@@ -117,6 +189,8 @@ asmbpe(void)
IMAGE_SCN_CNT_INITIALIZED_DATA;
}
+ add_import_table();
+
fh.NumberOfSections = nsect;
fh.TimeDateStamp = time(0);
fh.SizeOfOptionalHeader = sizeof(oh);
diff --git a/src/cmd/ld/pe.h b/src/cmd/ld/pe.h
index e7e2f9f08b..b64dd97c07 100644
--- a/src/cmd/ld/pe.h
+++ b/src/cmd/ld/pe.h
@@ -64,6 +64,14 @@ typedef struct {
uint32 Characteristics;
} IMAGE_SECTION_HEADER;
+typedef struct {
+ uint32 OriginalFirstThunk;
+ uint32 TimeDateStamp;
+ uint32 ForwarderChain;
+ uint32 Name;
+ uint32 FirstThunk;
+} IMAGE_IMPORT_DESCRIPTOR;
+
#define PERESERVE 0x400
#define PEALIGN 0x200
#define PEBASE 0x00400000
@@ -84,6 +92,23 @@ enum {
IMAGE_SCN_MEM_EXECUTE = 0x20000000,
IMAGE_SCN_MEM_READ = 0x40000000,
IMAGE_SCN_MEM_WRITE = 0x80000000,
+
+ IMAGE_DIRECTORY_ENTRY_EXPORT = 0,
+ IMAGE_DIRECTORY_ENTRY_IMPORT = 1,
+ IMAGE_DIRECTORY_ENTRY_RESOURCE = 2,
+ IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3,
+ IMAGE_DIRECTORY_ENTRY_SECURITY = 4,
+ IMAGE_DIRECTORY_ENTRY_BASERELOC = 5,
+ IMAGE_DIRECTORY_ENTRY_DEBUG = 6,
+ IMAGE_DIRECTORY_ENTRY_COPYRIGHT = 7,
+ IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7,
+ IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8,
+ IMAGE_DIRECTORY_ENTRY_TLS = 9,
+ IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10,
+ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11,
+ IMAGE_DIRECTORY_ENTRY_IAT = 12,
+ IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13,
+ IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14,
};
void peinit(void);