Commit f1751e7d authored by Wei Guangjing's avatar Wei Guangjing Committed by Russ Cox

8l: emit DWARF in Windows PE.

R=rsc, lvd, brainman, Joe Poirier
CC=golang-dev
https://golang.org/cl/2124041
parent 1aa2d887
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "../ld/dwarf_defs.h" #include "../ld/dwarf_defs.h"
#include "../ld/elf.h" #include "../ld/elf.h"
#include "../ld/macho.h" #include "../ld/macho.h"
#include "../ld/pe.h"
/* /*
* Offsets and sizes of the debug_* sections in the cout file. * Offsets and sizes of the debug_* sections in the cout file.
...@@ -2277,6 +2278,13 @@ writegdbscript(void) ...@@ -2277,6 +2278,13 @@ writegdbscript(void)
return sectionstart; return sectionstart;
} }
static void
align(vlong size)
{
if((thechar == '6' || thechar == '8') && HEADTYPE == 10) // Only Windows PE need section align.
strnput("", rnd(size, PEFILEALIGN) - size);
}
/* /*
* This is the main entry point for generating dwarf. After emitting * This is the main entry point for generating dwarf. After emitting
* the mandatory debug_abbrev section, it calls writelines() to set up * the mandatory debug_abbrev section, it calls writelines() to set up
...@@ -2316,8 +2324,11 @@ dwarfemitdebugsections(void) ...@@ -2316,8 +2324,11 @@ dwarfemitdebugsections(void)
genasmsym(defdwsymb); genasmsym(defdwsymb);
writeabbrev(); writeabbrev();
align(abbrevsize);
writelines(); writelines();
align(linesize);
writeframes(); writeframes();
align(framesize);
synthesizestringtypes(dwtypes.child); synthesizestringtypes(dwtypes.child);
synthesizeslicetypes(dwtypes.child); synthesizeslicetypes(dwtypes.child);
...@@ -2350,16 +2361,23 @@ dwarfemitdebugsections(void) ...@@ -2350,16 +2361,23 @@ dwarfemitdebugsections(void)
} }
} }
infosize = infoe - infoo; infosize = infoe - infoo;
align(infosize);
pubnameso = writepub(ispubname); pubnameso = writepub(ispubname);
pubnamessize = cpos() - pubnameso;
align(pubnamessize);
pubtypeso = writepub(ispubtype); pubtypeso = writepub(ispubtype);
pubtypessize = cpos() - pubtypeso;
align(pubtypessize);
arangeso = writearanges(); arangeso = writearanges();
gdbscripto = writegdbscript(); arangessize = cpos() - arangeso;
align(arangessize);
pubnamessize = pubtypeso - pubnameso; gdbscripto = writegdbscript();
pubtypessize = arangeso - pubtypeso;
arangessize = gdbscripto - arangeso;
gdbscriptsize = cpos() - gdbscripto; gdbscriptsize = cpos() - gdbscripto;
align(gdbscriptsize);
} }
/* /*
...@@ -2541,3 +2559,24 @@ dwarfaddmachoheaders(void) ...@@ -2541,3 +2559,24 @@ dwarfaddmachoheaders(void)
ms->filesize += msect->size; ms->filesize += msect->size;
} }
} }
/*
* Windows PE
*/
void
dwarfaddpeheaders(void)
{
dwarfemitdebugsections();
newPEDWARFSection(".debug_abbrev", abbrevsize);
newPEDWARFSection(".debug_line", linesize);
newPEDWARFSection(".debug_frame", framesize);
newPEDWARFSection(".debug_info", infosize);
if (pubnamessize > 0)
newPEDWARFSection(".debug_pubnames", pubnamessize);
if (pubtypessize > 0)
newPEDWARFSection(".debug_pubtypes", pubtypessize);
if (arangessize > 0)
newPEDWARFSection(".debug_aranges", arangessize);
if (gdbscriptsize > 0)
newPEDWARFSection(".debug_gdb_scripts", gdbscriptsize);
}
...@@ -27,3 +27,4 @@ void dwarfaddshstrings(Sym *shstrtab); ...@@ -27,3 +27,4 @@ void dwarfaddshstrings(Sym *shstrtab);
*/ */
void dwarfaddelfheaders(void); void dwarfaddelfheaders(void);
void dwarfaddmachoheaders(void); void dwarfaddmachoheaders(void);
void dwarfaddpeheaders(void);
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "l.h" #include "l.h"
#include "../ld/lib.h" #include "../ld/lib.h"
#include "../ld/pe.h" #include "../ld/pe.h"
#include "../ld/dwarf.h"
// DOS stub that prints out // DOS stub that prints out
// "This program cannot be run in DOS mode." // "This program cannot be run in DOS mode."
...@@ -33,6 +34,9 @@ static char dosstub[] = ...@@ -33,6 +34,9 @@ static char dosstub[] =
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
static char symnames[256];
static int nextsymoff;
int32 PESECTHEADR; int32 PESECTHEADR;
int32 PEFILEHEADR; int32 PEFILEHEADR;
...@@ -307,6 +311,60 @@ dope(void) ...@@ -307,6 +311,60 @@ dope(void)
initdynimport(); initdynimport();
} }
/*
* 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
* the string table.
* reference: pecoff_v8.docx Page 24.
* <http://www.microsoft.com/whdc/system/platform/firmware/PECOFFdwn.mspx>
*/
IMAGE_SECTION_HEADER*
newPEDWARFSection(char *name, vlong size)
{
IMAGE_SECTION_HEADER *h;
char s[8];
if(nextsymoff+strlen(name)+1 > sizeof(symnames)) {
diag("pe string table is full");
errorexit();
}
strcpy(&symnames[nextsymoff], name);
sprint(s, "/%d\0", nextsymoff+4);
nextsymoff += strlen(name);
symnames[nextsymoff] = 0;
nextsymoff ++;
h = addpesection(s, size, size, 0);
h->Characteristics = IMAGE_SCN_MEM_READ|
IMAGE_SCN_MEM_DISCARDABLE;
return h;
}
static void
addsymtable(void)
{
IMAGE_SECTION_HEADER *h;
int i, size;
if(nextsymoff == 0)
return;
size = nextsymoff + 4;
h = addpesection(".symtab", size, size, 0);
h->Characteristics = IMAGE_SCN_MEM_READ|
IMAGE_SCN_MEM_DISCARDABLE;
fh.PointerToSymbolTable = cpos();
fh.NumberOfSymbols = 0;
// put symbol string table
lputl(size);
for (i=0; i<nextsymoff; i++)
cput(symnames[i]);
strnput("", h->SizeOfRawData - size);
cflush();
}
void void
asmbpe(void) asmbpe(void)
{ {
...@@ -334,7 +392,12 @@ asmbpe(void) ...@@ -334,7 +392,12 @@ asmbpe(void)
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE; IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE;
addimports(nextfileoff, d); addimports(nextfileoff, d);
if(!debug['s'])
dwarfaddpeheaders();
addsymtable();
fh.NumberOfSections = nsect; fh.NumberOfSections = nsect;
fh.TimeDateStamp = time(0); fh.TimeDateStamp = time(0);
fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED| fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED|
...@@ -402,3 +465,4 @@ asmbpe(void) ...@@ -402,3 +465,4 @@ asmbpe(void)
pewrite(); pewrite();
} }
...@@ -99,6 +99,7 @@ enum { ...@@ -99,6 +99,7 @@ enum {
IMAGE_SCN_MEM_EXECUTE = 0x20000000, IMAGE_SCN_MEM_EXECUTE = 0x20000000,
IMAGE_SCN_MEM_READ = 0x40000000, IMAGE_SCN_MEM_READ = 0x40000000,
IMAGE_SCN_MEM_WRITE = 0x80000000, IMAGE_SCN_MEM_WRITE = 0x80000000,
IMAGE_SCN_MEM_DISCARDABLE = 0x2000000,
IMAGE_DIRECTORY_ENTRY_EXPORT = 0, IMAGE_DIRECTORY_ENTRY_EXPORT = 0,
IMAGE_DIRECTORY_ENTRY_IMPORT = 1, IMAGE_DIRECTORY_ENTRY_IMPORT = 1,
...@@ -122,6 +123,8 @@ void peinit(void); ...@@ -122,6 +123,8 @@ void peinit(void);
void asmbpe(void); void asmbpe(void);
void dope(void); void dope(void);
IMAGE_SECTION_HEADER* newPEDWARFSection(char *name, vlong size);
// X64 // X64
typedef struct { typedef struct {
uint16 Magic; uint16 Magic;
......
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