Commit fce4f048 authored by Alex Brainman's avatar Alex Brainman Committed by Russ Cox

cmd/ld: populate pe symbol table with Go symbols

Fixes #6936

LGTM=rsc
R=golang-codereviews, bradfitz, rsc
CC=golang-codereviews
https://golang.org/cl/87770048
parent 06dc4e78
...@@ -32,15 +32,11 @@ static char dosstub[] = ...@@ -32,15 +32,11 @@ static char dosstub[] =
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
// Note: currently only up to 8 chars plus \0.
static char *symlabels[] = {
"symtab", "esymtab", "pclntab", "epclntab"
};
static LSym *rsrcsym; static LSym *rsrcsym;
static char symnames[256]; static char* strtbl;
static int nextsymoff; static int strtblnextoff;
static int strtblsize;
int32 PESECTHEADR; int32 PESECTHEADR;
int32 PEFILEHEADR; int32 PEFILEHEADR;
...@@ -50,6 +46,7 @@ static int nsect; ...@@ -50,6 +46,7 @@ static int nsect;
static int nextsectoff; static int nextsectoff;
static int nextfileoff; static int nextfileoff;
static int textsect; static int textsect;
static int datasect;
static IMAGE_FILE_HEADER fh; static IMAGE_FILE_HEADER fh;
static IMAGE_OPTIONAL_HEADER oh; static IMAGE_OPTIONAL_HEADER oh;
...@@ -81,6 +78,17 @@ static Dll* dr; ...@@ -81,6 +78,17 @@ static Dll* dr;
static LSym *dexport[1024]; static LSym *dexport[1024];
static int nexport; static int nexport;
typedef struct COFFSym COFFSym;
struct COFFSym
{
LSym* sym;
int strtbloff;
int sect;
};
static COFFSym* coffsym;
static int ncoffsym;
static IMAGE_SECTION_HEADER* static IMAGE_SECTION_HEADER*
addpesection(char *name, int sectsize, int filesize) addpesection(char *name, int sectsize, int filesize)
{ {
...@@ -421,6 +429,24 @@ dope(void) ...@@ -421,6 +429,24 @@ dope(void)
initdynexport(); initdynexport();
} }
static int
strtbladd(char *name)
{
int newsize, thisoff;
newsize = strtblnextoff + strlen(name) + 1;
if(newsize > strtblsize) {
strtblsize = 2 * (newsize + (1<<18));
strtbl = realloc(strtbl, strtblsize);
}
thisoff = strtblnextoff+4; // first string starts at offset=4
strcpy(&strtbl[strtblnextoff], name);
strtblnextoff += strlen(name);
strtbl[strtblnextoff] = 0;
strtblnextoff++;
return thisoff;
}
/* /*
* For more than 8 characters section names, name contains a slash (/) that is * For more than 8 characters section names, name contains a slash (/) that is
* followed by an ASCII representation of a decimal number that is an offset into * followed by an ASCII representation of a decimal number that is an offset into
...@@ -433,20 +459,13 @@ newPEDWARFSection(char *name, vlong size) ...@@ -433,20 +459,13 @@ newPEDWARFSection(char *name, vlong size)
{ {
IMAGE_SECTION_HEADER *h; IMAGE_SECTION_HEADER *h;
char s[8]; char s[8];
int off;
if(size == 0) if(size == 0)
return nil; return nil;
if(nextsymoff+strlen(name)+1 > sizeof(symnames)) { off = strtbladd(name);
diag("pe string table is full"); sprint(s, "/%d\0", off);
errorexit();
}
strcpy(&symnames[nextsymoff], name);
sprint(s, "/%d\0", nextsymoff+4);
nextsymoff += strlen(name);
symnames[nextsymoff] = 0;
nextsymoff ++;
h = addpesection(s, size, size); h = addpesection(s, size, size);
h->Characteristics = IMAGE_SCN_MEM_READ| h->Characteristics = IMAGE_SCN_MEM_READ|
IMAGE_SCN_MEM_DISCARDABLE; IMAGE_SCN_MEM_DISCARDABLE;
...@@ -454,36 +473,84 @@ newPEDWARFSection(char *name, vlong size) ...@@ -454,36 +473,84 @@ newPEDWARFSection(char *name, vlong size)
return h; return h;
} }
static void
addsym(LSym *s, char *name, int type, vlong addr, vlong size, int ver, LSym *gotype)
{
USED(name);
USED(addr);
USED(size);
USED(ver);
USED(gotype);
if(s == nil)
return;
if(s->sect == nil)
return;
switch(type) {
default:
return;
case 'D':
case 'B':
case 'T':
break;
}
if(coffsym) {
coffsym[ncoffsym].sym = s;
if(strlen(s->name) > 8)
coffsym[ncoffsym].strtbloff = strtbladd(s->name);
if(type == 'T')
coffsym[ncoffsym].sect = textsect;
else
coffsym[ncoffsym].sect = datasect;
}
ncoffsym++;
}
static void static void
addsymtable(void) addsymtable(void)
{ {
IMAGE_SECTION_HEADER *h; IMAGE_SECTION_HEADER *h;
int i, size; int i, size;
LSym *s; COFFSym *s;
fh.NumberOfSymbols = sizeof(symlabels)/sizeof(symlabels[0]); if(!debug['s']) {
size = nextsymoff + 4 + 18*fh.NumberOfSymbols; genasmsym(addsym);
coffsym = mal(ncoffsym * sizeof coffsym[0]);
ncoffsym = 0;
genasmsym(addsym);
}
size = strtblnextoff + 4 + 18*ncoffsym;
h = addpesection(".symtab", size, size); h = addpesection(".symtab", size, size);
h->Characteristics = IMAGE_SCN_MEM_READ| h->Characteristics = IMAGE_SCN_MEM_READ|
IMAGE_SCN_MEM_DISCARDABLE; IMAGE_SCN_MEM_DISCARDABLE;
chksectoff(h, cpos()); chksectoff(h, cpos());
fh.PointerToSymbolTable = cpos(); fh.PointerToSymbolTable = cpos();
fh.NumberOfSymbols = ncoffsym;
// put COFF symbol table // put COFF symbol table
for (i=0; i<fh.NumberOfSymbols; i++) { for (i=0; i<ncoffsym; i++) {
s = linkrlookup(ctxt, symlabels[i], 0); s = &coffsym[i];
strnput(s->name, 8); if(s->strtbloff == 0)
lputl(datoff(s->value)); strnput(s->sym->name, 8);
wputl(textsect); else {
lputl(0);
lputl(s->strtbloff);
}
lputl(datoff(s->sym->value));
wputl(s->sect);
wputl(0x0308); // "array of structs" wputl(0x0308); // "array of structs"
cput(2); // storage class: external cput(2); // storage class: external
cput(0); // no aux entries cput(0); // no aux entries
} }
// put COFF string table // put COFF string table
lputl(nextsymoff + 4); lputl(strtblnextoff + 4);
for (i=0; i<nextsymoff; i++) for (i=0; i<strtblnextoff; i++)
cput(symnames[i]); cput(strtbl[i]);
strnput("", h->SizeOfRawData - size); strnput("", h->SizeOfRawData - size);
} }
...@@ -557,6 +624,7 @@ asmbpe(void) ...@@ -557,6 +624,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;
chksectseg(d, &segdata); chksectseg(d, &segdata);
datasect = nsect;
if(!debug['s']) if(!debug['s'])
dwarfaddpeheaders(); dwarfaddpeheaders();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment