mirror of
https://github.com/golang/go
synced 2024-11-26 00:57:56 -07:00
8l : add dynimport to import table in Windows PE, initial make cgo dll work.
R=rsc, brainman, Joe Poirier, mattn CC=golang-dev https://golang.org/cl/2166041
This commit is contained in:
parent
836643400c
commit
70deac67cf
@ -820,6 +820,7 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
|
|||||||
case SDATA:
|
case SDATA:
|
||||||
case SELFDATA:
|
case SELFDATA:
|
||||||
case SMACHO:
|
case SMACHO:
|
||||||
|
case SWINDOWS:
|
||||||
if(!s->reachable)
|
if(!s->reachable)
|
||||||
continue;
|
continue;
|
||||||
put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
|
put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
|
||||||
|
@ -168,6 +168,7 @@ enum
|
|||||||
SRODATA,
|
SRODATA,
|
||||||
SDATA,
|
SDATA,
|
||||||
SMACHO, /* Mach-O __nl_symbol_ptr */
|
SMACHO, /* Mach-O __nl_symbol_ptr */
|
||||||
|
SWINDOWS,
|
||||||
SBSS,
|
SBSS,
|
||||||
|
|
||||||
SXREF,
|
SXREF,
|
||||||
|
@ -320,6 +320,8 @@ main(int argc, char *argv[])
|
|||||||
doelf();
|
doelf();
|
||||||
if(HEADTYPE == 6)
|
if(HEADTYPE == 6)
|
||||||
domacho();
|
domacho();
|
||||||
|
if(HEADTYPE == 10)
|
||||||
|
dope();
|
||||||
dostkoff();
|
dostkoff();
|
||||||
if(debug['p'])
|
if(debug['p'])
|
||||||
if(debug['1'])
|
if(debug['1'])
|
||||||
|
205
src/cmd/ld/pe.c
205
src/cmd/ld/pe.c
@ -45,6 +45,25 @@ 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];
|
||||||
|
|
||||||
|
typedef struct Imp Imp;
|
||||||
|
struct Imp {
|
||||||
|
Sym* s;
|
||||||
|
long va;
|
||||||
|
long vb;
|
||||||
|
Imp* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Dll Dll;
|
||||||
|
struct Dll {
|
||||||
|
char* name;
|
||||||
|
int count;
|
||||||
|
Imp* ms;
|
||||||
|
Dll* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
@ -122,66 +141,160 @@ strput(char *s)
|
|||||||
cput('\0');
|
cput('\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static Dll*
|
||||||
addimports(vlong fileoff)
|
initdynimport(void)
|
||||||
{
|
{
|
||||||
IMAGE_IMPORT_DESCRIPTOR ds[2], *d;
|
Imp *m;
|
||||||
char *dllname = "kernel32.dll";
|
Dll *d;
|
||||||
struct {
|
Sym *s;
|
||||||
char *name;
|
int i;
|
||||||
uint32 thunk;
|
Sym *dynamic;
|
||||||
} *f, fs[] = {
|
|
||||||
{ "GetProcAddress", 0 },
|
|
||||||
{ "LoadLibraryExA", 0 },
|
|
||||||
{ 0, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32 size = 0;
|
dr = nil;
|
||||||
memset(ds, 0, sizeof(ds));
|
ndll = 0;
|
||||||
size += sizeof(ds);
|
nimp = 0;
|
||||||
ds[0].Name = size;
|
nsize = 0;
|
||||||
size += strlen(dllname) + 1;
|
|
||||||
for(f=fs; f->name; f++) {
|
for(i=0; i<NHASH; i++)
|
||||||
f->thunk = size;
|
for(s = hash[i]; s != S; s = s->hash) {
|
||||||
size += sizeof(uint16) + strlen(f->name) + 1;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ds[0].FirstThunk = size;
|
|
||||||
for(f=fs; f->name; f++)
|
|
||||||
size += sizeof(fs[0].thunk);
|
|
||||||
|
|
||||||
|
nsize += 20*ndll + 20;
|
||||||
|
nsize += 4*nimp + 4*ndll;
|
||||||
|
|
||||||
|
dynamic = lookup(".windynamic", 0);
|
||||||
|
dynamic->reachable = 1;
|
||||||
|
dynamic->type = SWINDOWS;
|
||||||
|
for(d = dr; d != nil; d = d->next) {
|
||||||
|
for(m = d->ms; m != nil; m = m->next) {
|
||||||
|
m->s->type = SWINDOWS | SSUB;
|
||||||
|
m->s->sub = dynamic->sub;
|
||||||
|
dynamic->sub = m->s;
|
||||||
|
m->s->value = dynamic->size;
|
||||||
|
dynamic->size += 4;
|
||||||
|
}
|
||||||
|
dynamic->size += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
|
||||||
|
{
|
||||||
IMAGE_SECTION_HEADER *isect;
|
IMAGE_SECTION_HEADER *isect;
|
||||||
isect = addpesection(".idata", size, size, 0);
|
uint32 va;
|
||||||
|
int noff, aoff, o, last_fn, last_name_off, iat_off;
|
||||||
|
Imp *m;
|
||||||
|
Dll *d;
|
||||||
|
Sym* dynamic;
|
||||||
|
|
||||||
|
isect = addpesection(".idata", nsize, nsize, 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;
|
||||||
uint32 va = isect->VirtualAddress;
|
|
||||||
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = va;
|
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = va;
|
||||||
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = isect->VirtualSize;
|
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;
|
|
||||||
|
|
||||||
seek(cout, fileoff, 0);
|
seek(cout, fileoff, 0);
|
||||||
for(d=ds; ; d++) {
|
|
||||||
lputl(d->OriginalFirstThunk);
|
dynamic = lookup(".windynamic", 0);
|
||||||
lputl(d->TimeDateStamp);
|
iat_off = dynamic->value - PEBASE; // FirstThunk allocated in .data
|
||||||
lputl(d->ForwarderChain);
|
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = iat_off;
|
||||||
lputl(d->Name);
|
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = dynamic->size;
|
||||||
lputl(d->FirstThunk);
|
|
||||||
if(!d->Name)
|
noff = va + 20*ndll + 20;
|
||||||
break;
|
aoff = noff + 4*nimp + 4*ndll;
|
||||||
|
last_fn = 0;
|
||||||
|
last_name_off = aoff;
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
strput(dllname);
|
lputl(0); //end
|
||||||
for(f=fs; f->name; f++) {
|
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);
|
wputl(0);
|
||||||
strput(f->name);
|
strput(m->s->dynimpname);
|
||||||
}
|
}
|
||||||
for(f=fs; f->name; f++)
|
}
|
||||||
lputl(f->thunk);
|
|
||||||
strnput("", isect->SizeOfRawData - size);
|
strnput("", isect->SizeOfRawData - nsize);
|
||||||
cflush();
|
cflush();
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dope(void)
|
||||||
|
{
|
||||||
|
initdynimport();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -210,7 +323,7 @@ asmbpe(void)
|
|||||||
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;
|
||||||
|
|
||||||
addimports(nextfileoff);
|
addimports(nextfileoff, d);
|
||||||
|
|
||||||
fh.NumberOfSections = nsect;
|
fh.NumberOfSections = nsect;
|
||||||
fh.TimeDateStamp = time(0);
|
fh.TimeDateStamp = time(0);
|
||||||
|
@ -120,3 +120,5 @@ enum {
|
|||||||
|
|
||||||
void peinit(void);
|
void peinit(void);
|
||||||
void asmbpe(void);
|
void asmbpe(void);
|
||||||
|
void dope(void);
|
||||||
|
|
||||||
|
@ -4,14 +4,6 @@
|
|||||||
|
|
||||||
#include "386/asm.h"
|
#include "386/asm.h"
|
||||||
|
|
||||||
TEXT runtime·get_kernel_module(SB),7,$0
|
|
||||||
MOVL 0x30(FS), AX // get PEB
|
|
||||||
MOVL 0x0c(AX), AX // get PEB_LDR_DATA
|
|
||||||
MOVL 0x1c(AX), AX // get init order module list
|
|
||||||
MOVL (AX), AX // get next entry (kernel module)
|
|
||||||
MOVL 0x08(AX), AX // get base of module
|
|
||||||
RET
|
|
||||||
|
|
||||||
// void *stdcall_raw(void *fn, int32 count, uintptr *args)
|
// void *stdcall_raw(void *fn, int32 count, uintptr *args)
|
||||||
TEXT runtime·stdcall_raw(SB),7,$4
|
TEXT runtime·stdcall_raw(SB),7,$4
|
||||||
// Copy arguments from stack.
|
// Copy arguments from stack.
|
||||||
|
@ -25,6 +25,11 @@ abort(int8 *name)
|
|||||||
runtime·throw(name);
|
runtime·throw(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma dynimport runtime·VirtualAlloc VirtualAlloc "kernel32.dll"
|
||||||
|
#pragma dynimport runtime·VirtualFree VirtualFree "kernel32.dll"
|
||||||
|
void *runtime·VirtualAlloc;
|
||||||
|
void *runtime·VirtualFree;
|
||||||
|
|
||||||
void*
|
void*
|
||||||
runtime·SysAlloc(uintptr n)
|
runtime·SysAlloc(uintptr n)
|
||||||
{
|
{
|
||||||
|
@ -2,16 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// The following function allows one to dynamically
|
|
||||||
// resolve DLL function names.
|
|
||||||
// The arguments are strings.
|
|
||||||
void *runtime·get_proc_addr(void *library, void *name);
|
|
||||||
|
|
||||||
extern void *runtime·VirtualAlloc;
|
|
||||||
extern void *runtime·VirtualFree;
|
|
||||||
extern void *runtime·LoadLibraryEx;
|
extern void *runtime·LoadLibraryEx;
|
||||||
extern void *runtime·GetProcAddress;
|
extern void *runtime·GetProcAddress;
|
||||||
extern void *runtime·GetLastError;
|
|
||||||
|
|
||||||
#define runtime·goargs runtime·windows_goargs
|
#define runtime·goargs runtime·windows_goargs
|
||||||
void runtime·windows_goargs(void);
|
void runtime·windows_goargs(void);
|
||||||
|
@ -5,7 +5,15 @@
|
|||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
extern void *runtime·get_kernel_module(void);
|
#pragma dynimport runtime·LoadLibraryEx LoadLibraryExA "kernel32.dll"
|
||||||
|
#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
|
||||||
|
#pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll"
|
||||||
|
#pragma dynimport runtime·ExitProcess ExitProcess "kernel32.dll"
|
||||||
|
#pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
|
||||||
|
#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
|
||||||
|
#pragma dynimport runtime·WriteFile WriteFile "kernel32.dll"
|
||||||
|
#pragma dynimport runtime·GetLastError GetLastError "kernel32.dll"
|
||||||
|
#pragma dynimport runtime·SetLastError SetLastError "kernel32.dll"
|
||||||
|
|
||||||
// Also referenced by external packages
|
// Also referenced by external packages
|
||||||
void *runtime·CloseHandle;
|
void *runtime·CloseHandle;
|
||||||
@ -13,71 +21,37 @@ void *runtime·ExitProcess;
|
|||||||
void *runtime·GetStdHandle;
|
void *runtime·GetStdHandle;
|
||||||
void *runtime·SetEvent;
|
void *runtime·SetEvent;
|
||||||
void *runtime·WriteFile;
|
void *runtime·WriteFile;
|
||||||
void *runtime·VirtualAlloc;
|
|
||||||
void *runtime·VirtualFree;
|
|
||||||
void *runtime·LoadLibraryEx;
|
void *runtime·LoadLibraryEx;
|
||||||
void *runtime·GetProcAddress;
|
void *runtime·GetProcAddress;
|
||||||
void *runtime·GetLastError;
|
void *runtime·GetLastError;
|
||||||
void *runtime·SetLastError;
|
void *runtime·SetLastError;
|
||||||
|
|
||||||
static void *CreateEvent;
|
#pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
|
||||||
static void *CreateThread;
|
#pragma dynimport runtime·CreateThread CreateThread "kernel32.dll"
|
||||||
static void *WaitForSingleObject;
|
#pragma dynimport runtime·GetModuleHandle GetModuleHandleA "kernel32.dll"
|
||||||
|
#pragma dynimport runtime·WaitForSingleObject WaitForSingleObject "kernel32.dll"
|
||||||
|
|
||||||
static void*
|
void *runtime·CreateEvent;
|
||||||
get_proc_addr2(byte *base, byte *name)
|
void *runtime·CreateThread;
|
||||||
{
|
void *runtime·GetModuleHandle;
|
||||||
byte *pe_header, *exports;
|
void *runtime·WaitForSingleObject;
|
||||||
uint32 entries, *addr, *names, i;
|
|
||||||
uint16 *ordinals;
|
|
||||||
|
|
||||||
pe_header = base+*(uint32*)(base+0x3c);
|
|
||||||
exports = base+*(uint32*)(pe_header+0x78);
|
|
||||||
entries = *(uint32*)(exports+0x18);
|
|
||||||
addr = (uint32*)(base+*(uint32*)(exports+0x1c));
|
|
||||||
names = (uint32*)(base+*(uint32*)(exports+0x20));
|
|
||||||
ordinals = (uint16*)(base+*(uint32*)(exports+0x24));
|
|
||||||
for(i=0; i<entries; i++) {
|
|
||||||
byte *s = base+names[i];
|
|
||||||
if(runtime·strcmp(name, s) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(i == entries)
|
|
||||||
return 0;
|
|
||||||
return base+addr[ordinals[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
runtime·osinit(void)
|
runtime·osinit(void)
|
||||||
{
|
{
|
||||||
void *base;
|
|
||||||
|
|
||||||
base = runtime·get_kernel_module();
|
|
||||||
runtime·GetProcAddress = get_proc_addr2(base, (byte*)"GetProcAddress");
|
|
||||||
runtime·LoadLibraryEx = get_proc_addr2(base, (byte*)"LoadLibraryExA");
|
|
||||||
runtime·CloseHandle = runtime·get_proc_addr("kernel32.dll", "CloseHandle");
|
|
||||||
CreateEvent = runtime·get_proc_addr("kernel32.dll", "CreateEventA");
|
|
||||||
CreateThread = runtime·get_proc_addr("kernel32.dll", "CreateThread");
|
|
||||||
runtime·ExitProcess = runtime·get_proc_addr("kernel32.dll", "ExitProcess");
|
|
||||||
runtime·GetStdHandle = runtime·get_proc_addr("kernel32.dll", "GetStdHandle");
|
|
||||||
runtime·SetEvent = runtime·get_proc_addr("kernel32.dll", "SetEvent");
|
|
||||||
runtime·VirtualAlloc = runtime·get_proc_addr("kernel32.dll", "VirtualAlloc");
|
|
||||||
runtime·VirtualFree = runtime·get_proc_addr("kernel32.dll", "VirtualFree");
|
|
||||||
WaitForSingleObject = runtime·get_proc_addr("kernel32.dll", "WaitForSingleObject");
|
|
||||||
runtime·WriteFile = runtime·get_proc_addr("kernel32.dll", "WriteFile");
|
|
||||||
runtime·GetLastError = runtime·get_proc_addr("kernel32.dll", "GetLastError");
|
|
||||||
runtime·SetLastError = runtime·get_proc_addr("kernel32.dll", "SetLastError");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The arguments are strings.
|
#pragma dynimport runtime·GetCommandLine GetCommandLineW "kernel32.dll"
|
||||||
void*
|
#pragma dynimport runtime·CommandLineToArgv CommandLineToArgvW "shell32.dll"
|
||||||
runtime·get_proc_addr(void *library, void *name)
|
#pragma dynimport runtime·GetEnvironmentStrings GetEnvironmentStringsW "kernel32.dll"
|
||||||
{
|
#pragma dynimport runtime·FreeEnvironmentStrings FreeEnvironmentStringsW "kernel32.dll"
|
||||||
void *base;
|
#pragma dynimport runtime·LocalFree LocalFree "kernel32.dll"
|
||||||
|
|
||||||
base = runtime·stdcall(runtime·LoadLibraryEx, 3, library, 0, 0);
|
void *runtime·GetCommandLine;
|
||||||
return runtime·stdcall(runtime·GetProcAddress, 2, base, name);
|
void *runtime·CommandLineToArgv;
|
||||||
}
|
void *runtime·GetEnvironmentStrings;
|
||||||
|
void *runtime·FreeEnvironmentStrings;
|
||||||
|
void *runtime·LocalFree;
|
||||||
|
|
||||||
void
|
void
|
||||||
runtime·windows_goargs(void)
|
runtime·windows_goargs(void)
|
||||||
@ -85,22 +59,15 @@ runtime·windows_goargs(void)
|
|||||||
extern Slice os·Args;
|
extern Slice os·Args;
|
||||||
extern Slice os·Envs;
|
extern Slice os·Envs;
|
||||||
|
|
||||||
void *gcl, *clta, *ges, *fes, *lf;
|
|
||||||
uint16 *cmd, *env, **argv;
|
uint16 *cmd, *env, **argv;
|
||||||
String *gargv;
|
String *gargv;
|
||||||
String *genvv;
|
String *genvv;
|
||||||
int32 i, argc, envc;
|
int32 i, argc, envc;
|
||||||
uint16 *envp;
|
uint16 *envp;
|
||||||
|
|
||||||
gcl = runtime·get_proc_addr("kernel32.dll", "GetCommandLineW");
|
cmd = runtime·stdcall(runtime·GetCommandLine, 0);
|
||||||
clta = runtime·get_proc_addr("shell32.dll", "CommandLineToArgvW");
|
env = runtime·stdcall(runtime·GetEnvironmentStrings, 0);
|
||||||
ges = runtime·get_proc_addr("kernel32.dll", "GetEnvironmentStringsW");
|
argv = runtime·stdcall(runtime·CommandLineToArgv, 2, cmd, &argc);
|
||||||
lf = runtime·get_proc_addr("kernel32.dll", "LocalFree");
|
|
||||||
fes = runtime·get_proc_addr("kernel32.dll", "FreeEnvironmentStringsW");
|
|
||||||
|
|
||||||
cmd = runtime·stdcall(gcl, 0);
|
|
||||||
env = runtime·stdcall(ges, 0);
|
|
||||||
argv = runtime·stdcall(clta, 2, cmd, &argc);
|
|
||||||
|
|
||||||
envc = 0;
|
envc = 0;
|
||||||
for(envp=env; *envp; envc++)
|
for(envp=env; *envp; envc++)
|
||||||
@ -124,8 +91,8 @@ runtime·windows_goargs(void)
|
|||||||
os·Envs.len = envc;
|
os·Envs.len = envc;
|
||||||
os·Envs.cap = envc;
|
os·Envs.cap = envc;
|
||||||
|
|
||||||
runtime·stdcall(lf, 1, argv);
|
runtime·stdcall(runtime·LocalFree, 1, argv);
|
||||||
runtime·stdcall(fes, 1, env);
|
runtime·stdcall(runtime·FreeEnvironmentStrings, 1, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -161,7 +128,7 @@ initevent(void **pevent)
|
|||||||
{
|
{
|
||||||
void *event;
|
void *event;
|
||||||
|
|
||||||
event = runtime·stdcall(CreateEvent, 4, 0, 0, 0, 0);
|
event = runtime·stdcall(runtime·CreateEvent, 4, 0, 0, 0, 0);
|
||||||
if(!runtime·casp(pevent, 0, event)) {
|
if(!runtime·casp(pevent, 0, event)) {
|
||||||
// Someone else filled it in. Use theirs.
|
// Someone else filled it in. Use theirs.
|
||||||
runtime·stdcall(runtime·CloseHandle, 1, event);
|
runtime·stdcall(runtime·CloseHandle, 1, event);
|
||||||
@ -176,7 +143,7 @@ eventlock(Lock *l)
|
|||||||
initevent(&l->event);
|
initevent(&l->event);
|
||||||
|
|
||||||
if(runtime·xadd(&l->key, 1) > 1) // someone else has it; wait
|
if(runtime·xadd(&l->key, 1) > 1) // someone else has it; wait
|
||||||
runtime·stdcall(WaitForSingleObject, 2, l->event, -1);
|
runtime·stdcall(runtime·WaitForSingleObject, 2, l->event, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -237,7 +204,7 @@ runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
|
|||||||
USED(g); // assuming g = m->g0
|
USED(g); // assuming g = m->g0
|
||||||
USED(fn); // assuming fn = mstart
|
USED(fn); // assuming fn = mstart
|
||||||
|
|
||||||
runtime·stdcall(CreateThread, 6, 0, 0, runtime·tstart_stdcall, m, 0, 0);
|
runtime·stdcall(runtime·CreateThread, 6, 0, 0, runtime·tstart_stdcall, m, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called to initialize a new m (including the bootstrap m).
|
// Called to initialize a new m (including the bootstrap m).
|
||||||
|
Loading…
Reference in New Issue
Block a user