From: Wei Guangjing Date: Thu, 20 Jan 2011 16:28:30 +0000 (-0500) Subject: 8l: emit DWARF in Windows PE. X-Git-Tag: weekly.2011-02-01~123 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=f1751e7de5c842deecd6f8c96f85f8269e5776cc;p=gostls13.git 8l: emit DWARF in Windows PE. R=rsc, lvd, brainman, Joe Poirier CC=golang-dev https://golang.org/cl/2124041 --- diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c index 4683f806fa..b724a98f5d 100644 --- a/src/cmd/ld/dwarf.c +++ b/src/cmd/ld/dwarf.c @@ -19,6 +19,7 @@ #include "../ld/dwarf_defs.h" #include "../ld/elf.h" #include "../ld/macho.h" +#include "../ld/pe.h" /* * Offsets and sizes of the debug_* sections in the cout file. @@ -2277,6 +2278,13 @@ writegdbscript(void) 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 * the mandatory debug_abbrev section, it calls writelines() to set up @@ -2316,8 +2324,11 @@ dwarfemitdebugsections(void) genasmsym(defdwsymb); writeabbrev(); + align(abbrevsize); writelines(); + align(linesize); writeframes(); + align(framesize); synthesizestringtypes(dwtypes.child); synthesizeslicetypes(dwtypes.child); @@ -2350,16 +2361,23 @@ dwarfemitdebugsections(void) } } infosize = infoe - infoo; + align(infosize); pubnameso = writepub(ispubname); + pubnamessize = cpos() - pubnameso; + align(pubnamessize); + pubtypeso = writepub(ispubtype); + pubtypessize = cpos() - pubtypeso; + align(pubtypessize); + arangeso = writearanges(); - gdbscripto = writegdbscript(); + arangessize = cpos() - arangeso; + align(arangessize); - pubnamessize = pubtypeso - pubnameso; - pubtypessize = arangeso - pubtypeso; - arangessize = gdbscripto - arangeso; + gdbscripto = writegdbscript(); gdbscriptsize = cpos() - gdbscripto; + align(gdbscriptsize); } /* @@ -2541,3 +2559,24 @@ dwarfaddmachoheaders(void) 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); +} diff --git a/src/cmd/ld/dwarf.h b/src/cmd/ld/dwarf.h index 7881213c21..f0df2f9b1e 100644 --- a/src/cmd/ld/dwarf.h +++ b/src/cmd/ld/dwarf.h @@ -27,3 +27,4 @@ void dwarfaddshstrings(Sym *shstrtab); */ void dwarfaddelfheaders(void); void dwarfaddmachoheaders(void); +void dwarfaddpeheaders(void); diff --git a/src/cmd/ld/pe.c b/src/cmd/ld/pe.c index 7ce6767a2f..860910e345 100644 --- a/src/cmd/ld/pe.c +++ b/src/cmd/ld/pe.c @@ -10,6 +10,7 @@ #include "l.h" #include "../ld/lib.h" #include "../ld/pe.h" +#include "../ld/dwarf.h" // DOS stub that prints out // "This program cannot be run in DOS mode." @@ -33,6 +34,9 @@ static char dosstub[] = 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static char symnames[256]; +static int nextsymoff; + int32 PESECTHEADR; int32 PEFILEHEADR; @@ -307,6 +311,60 @@ dope(void) 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. + * + */ +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; iSizeOfRawData - size); + cflush(); +} + + void asmbpe(void) { @@ -334,7 +392,12 @@ asmbpe(void) IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE; addimports(nextfileoff, d); + + if(!debug['s']) + dwarfaddpeheaders(); + addsymtable(); + fh.NumberOfSections = nsect; fh.TimeDateStamp = time(0); fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED| @@ -402,3 +465,4 @@ asmbpe(void) pewrite(); } + diff --git a/src/cmd/ld/pe.h b/src/cmd/ld/pe.h index 7c19630f41..6fb37c37dc 100644 --- a/src/cmd/ld/pe.h +++ b/src/cmd/ld/pe.h @@ -99,6 +99,7 @@ enum { IMAGE_SCN_MEM_EXECUTE = 0x20000000, IMAGE_SCN_MEM_READ = 0x40000000, IMAGE_SCN_MEM_WRITE = 0x80000000, + IMAGE_SCN_MEM_DISCARDABLE = 0x2000000, IMAGE_DIRECTORY_ENTRY_EXPORT = 0, IMAGE_DIRECTORY_ENTRY_IMPORT = 1, @@ -122,6 +123,8 @@ void peinit(void); void asmbpe(void); void dope(void); +IMAGE_SECTION_HEADER* newPEDWARFSection(char *name, vlong size); + // X64 typedef struct { uint16 Magic;