mirror of
https://github.com/golang/go
synced 2024-11-22 02:54:39 -07:00
8l: add PE dynexport
R=rsc, brainman, mattn CC=golang-dev https://golang.org/cl/4022043
This commit is contained in:
parent
354219951e
commit
a3120f67ca
@ -520,7 +520,7 @@ adddynsym(Sym *s)
|
||||
adduint8(d, 0); // section
|
||||
adduint16(d, 0); // desc
|
||||
adduint32(d, 0); // value
|
||||
} else {
|
||||
} else if(HEADTYPE != 10) {
|
||||
diag("adddynsym: unsupported binary format");
|
||||
}
|
||||
}
|
||||
@ -540,7 +540,7 @@ adddynlib(char *lib)
|
||||
elfwritedynent(lookup(".dynamic", 0), DT_NEEDED, addstring(s, lib));
|
||||
} else if(HEADTYPE == 6) { // Mach-O
|
||||
machoadddynlib(lib);
|
||||
} else {
|
||||
} else if(HEADTYPE != 10) {
|
||||
diag("adddynlib: unsupported binary format");
|
||||
}
|
||||
}
|
||||
|
103
src/cmd/ld/pe.c
103
src/cmd/ld/pe.c
@ -68,6 +68,9 @@ struct Dll {
|
||||
|
||||
static Dll* dr;
|
||||
|
||||
static Sym *dexport[1024];
|
||||
static int nexport;
|
||||
|
||||
static IMAGE_SECTION_HEADER*
|
||||
addpesection(char *name, int sectsize, int filesize, Segment *s)
|
||||
{
|
||||
@ -169,7 +172,7 @@ initdynimport(void)
|
||||
|
||||
for(i=0; i<NHASH; i++)
|
||||
for(s = hash[i]; s != S; s = s->hash) {
|
||||
if(!s->reachable || !s->dynimpname)
|
||||
if(!s->reachable || !s->dynimpname || s->dynexport)
|
||||
continue;
|
||||
for(d = dr; d != nil; d = d->next) {
|
||||
if(strcmp(d->name,s->dynimplib) == 0) {
|
||||
@ -298,6 +301,101 @@ addimports(vlong fileoff, IMAGE_SECTION_HEADER *datsect)
|
||||
seek(cout, 0, 2);
|
||||
}
|
||||
|
||||
static int
|
||||
scmp(const void *p1, const void *p2)
|
||||
{
|
||||
Sym *s1, *s2;
|
||||
|
||||
s1 = *(Sym**)p1;
|
||||
s2 = *(Sym**)p2;
|
||||
return strcmp(s1->dynimpname, s2->dynimpname);
|
||||
}
|
||||
|
||||
static void
|
||||
initdynexport(void)
|
||||
{
|
||||
int i;
|
||||
Sym *s;
|
||||
|
||||
nexport = 0;
|
||||
for(i=0; i<NHASH; i++)
|
||||
for(s = hash[i]; s != S; s = s->hash) {
|
||||
if(!s->reachable || !s->dynimpname || !s->dynexport)
|
||||
continue;
|
||||
if(nexport+1 > sizeof(dexport)/sizeof(dexport[0])) {
|
||||
diag("pe dynexport table is full");
|
||||
errorexit();
|
||||
}
|
||||
|
||||
dexport[nexport] = s;
|
||||
nexport++;
|
||||
}
|
||||
|
||||
qsort(dexport, nexport, sizeof dexport[0], scmp);
|
||||
}
|
||||
|
||||
void
|
||||
addexports(vlong fileoff)
|
||||
{
|
||||
IMAGE_SECTION_HEADER *sect;
|
||||
IMAGE_EXPORT_DIRECTORY e;
|
||||
int size, i, va, va_name, va_addr, va_na, v;
|
||||
Sym *s;
|
||||
|
||||
size = sizeof e + 10*nexport + strlen(outfile) + 1;
|
||||
for(i=0; i<nexport; i++)
|
||||
size += strlen(dexport[i]->dynimpname) + 1;
|
||||
|
||||
if (nexport == 0)
|
||||
return;
|
||||
|
||||
sect = addpesection(".edata", size, size, 0);
|
||||
sect->Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ;
|
||||
va = sect->VirtualAddress;
|
||||
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = va;
|
||||
oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect->VirtualSize;
|
||||
|
||||
seek(cout, fileoff, 0);
|
||||
va_name = va + sizeof e + nexport*4;
|
||||
va_addr = va + sizeof e;
|
||||
va_na = va + sizeof e + nexport*8;
|
||||
|
||||
e.Characteristics = 0;
|
||||
e.MajorVersion = 0;
|
||||
e.MinorVersion = 0;
|
||||
e.NumberOfFunctions = nexport;
|
||||
e.NumberOfNames = nexport;
|
||||
e.Name = va + sizeof e + nexport*10; // Program names.
|
||||
e.Base = 1;
|
||||
e.AddressOfFunctions = va_addr;
|
||||
e.AddressOfNames = va_name;
|
||||
e.AddressOfNameOrdinals = va_na;
|
||||
// put IMAGE_EXPORT_DIRECTORY
|
||||
for (i=0; i<sizeof(e); i++)
|
||||
cput(((char*)&e)[i]);
|
||||
// put EXPORT Address Table
|
||||
for(i=0; i<nexport; i++)
|
||||
lputl(dexport[i]->value - PEBASE);
|
||||
// put EXPORT Name Pointer Table
|
||||
v = e.Name + strlen(outfile)+1;
|
||||
for(i=0; i<nexport; i++) {
|
||||
lputl(v);
|
||||
v += strlen(dexport[i]->dynimpname)+1;
|
||||
}
|
||||
// put EXPORT Ordinal Table
|
||||
for(i=0; i<nexport; i++)
|
||||
wputl(i);
|
||||
// put Names
|
||||
strnput(outfile, strlen(outfile)+1);
|
||||
for(i=0; i<nexport; i++)
|
||||
strnput(dexport[i]->dynimpname, strlen(dexport[i]->dynimpname)+1);
|
||||
strnput("", sect->SizeOfRawData - size);
|
||||
cflush();
|
||||
|
||||
seek(cout, 0, 2);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dope(void)
|
||||
{
|
||||
@ -309,6 +407,7 @@ dope(void)
|
||||
rel->type = SELFDATA;
|
||||
|
||||
initdynimport();
|
||||
initdynexport();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -393,6 +492,8 @@ asmbpe(void)
|
||||
|
||||
addimports(nextfileoff, d);
|
||||
|
||||
addexports(nextfileoff);
|
||||
|
||||
if(!debug['s'])
|
||||
dwarfaddpeheaders();
|
||||
|
||||
|
@ -72,6 +72,20 @@ typedef struct {
|
||||
uint32 FirstThunk;
|
||||
} IMAGE_IMPORT_DESCRIPTOR;
|
||||
|
||||
typedef struct _IMAGE_EXPORT_DIRECTORY {
|
||||
uint32 Characteristics;
|
||||
uint32 TimeDateStamp;
|
||||
uint16 MajorVersion;
|
||||
uint16 MinorVersion;
|
||||
uint32 Name;
|
||||
uint32 Base;
|
||||
uint32 NumberOfFunctions;
|
||||
uint32 NumberOfNames;
|
||||
uint32 AddressOfFunctions;
|
||||
uint32 AddressOfNames;
|
||||
uint32 AddressOfNameOrdinals;
|
||||
} IMAGE_EXPORT_DIRECTORY;
|
||||
|
||||
#define PEBASE 0x00400000
|
||||
// SectionAlignment must be greater than or equal to FileAlignment.
|
||||
// The default is the page size for the architecture.
|
||||
|
Loading…
Reference in New Issue
Block a user