summaryrefslogtreecommitdiff
path: root/src/cmd/ld/dwarf.c
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-02-14 13:23:51 +0100
committerOndřej Surý <ondrej@sury.org>2011-02-14 13:23:51 +0100
commit758ff64c69e34965f8af5b2d6ffd65e8d7ab2150 (patch)
tree6d6b34f8c678862fe9b56c945a7b63f68502c245 /src/cmd/ld/dwarf.c
parent3e45412327a2654a77944249962b3652e6142299 (diff)
downloadgolang-upstream/2011-02-01.1.tar.gz
Imported Upstream version 2011-02-01.1upstream/2011-02-01.1
Diffstat (limited to 'src/cmd/ld/dwarf.c')
-rw-r--r--src/cmd/ld/dwarf.c176
1 files changed, 116 insertions, 60 deletions
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c
index 506c6e5db..5df3515f5 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.
@@ -453,19 +454,6 @@ getattr(DWDie *die, uint8 attr)
return nil;
}
-static void
-delattr(DWDie *die, uint8 attr)
-{
- DWAttr **a;
-
- a = &die->attr;
- while (*a != nil)
- if ((*a)->atr == attr)
- *a = (*a)->link;
- else
- a = &((*a)->link);
-}
-
// Every DIE has at least a DW_AT_name attribute (but it will only be
// written out if it is listed in the abbrev). If its parent is
// keeping an index, the new DIE will be inserted there.
@@ -768,10 +756,8 @@ enum {
KindUint32,
KindUint64,
KindUintptr,
- KindFloat,
KindFloat32,
KindFloat64,
- KindComplex,
KindComplex64,
KindComplex128,
KindArray,
@@ -799,6 +785,17 @@ decode_reloc(Sym *s, int32 off)
return nil;
}
+static Sym*
+decode_reloc_sym(Sym *s, int32 off)
+{
+ Reloc *r;
+
+ r = decode_reloc(s,off);
+ if (r == nil)
+ return nil;
+ return r->sym;
+}
+
static uvlong
decode_inuxi(uchar* p, int sz)
{
@@ -852,7 +849,7 @@ decodetype_size(Sym *s)
static Sym*
decodetype_arrayelem(Sym *s)
{
- return decode_reloc(s, 5*PtrSize + 8)->sym; // 0x1c / 0x30
+ return decode_reloc_sym(s, 5*PtrSize + 8); // 0x1c / 0x30
}
static vlong
@@ -865,26 +862,26 @@ decodetype_arraylen(Sym *s)
static Sym*
decodetype_ptrelem(Sym *s)
{
- return decode_reloc(s, 5*PtrSize + 8)->sym; // 0x1c / 0x30
+ return decode_reloc_sym(s, 5*PtrSize + 8); // 0x1c / 0x30
}
// Type.MapType.key, elem
static Sym*
decodetype_mapkey(Sym *s)
{
- return decode_reloc(s, 5*PtrSize + 8)->sym; // 0x1c / 0x30
+ return decode_reloc_sym(s, 5*PtrSize + 8); // 0x1c / 0x30
}
static Sym*
decodetype_mapvalue(Sym *s)
{
- return decode_reloc(s, 6*PtrSize + 8)->sym; // 0x20 / 0x38
+ return decode_reloc_sym(s, 6*PtrSize + 8); // 0x20 / 0x38
}
// Type.ChanType.elem
static Sym*
decodetype_chanelem(Sym *s)
{
- return decode_reloc(s, 5*PtrSize + 8)->sym; // 0x1c / 0x30
+ return decode_reloc_sym(s, 5*PtrSize + 8); // 0x1c / 0x30
}
// Type.FuncType.dotdotdot
@@ -913,7 +910,9 @@ decodetype_funcintype(Sym *s, int i)
Reloc *r;
r = decode_reloc(s, 6*PtrSize + 8);
- return decode_reloc(r->sym, r->add + i * PtrSize)->sym;
+ if (r == nil)
+ return nil;
+ return decode_reloc_sym(r->sym, r->add + i * PtrSize);
}
static Sym*
@@ -922,7 +921,9 @@ decodetype_funcouttype(Sym *s, int i)
Reloc *r;
r = decode_reloc(s, 7*PtrSize + 16);
- return decode_reloc(r->sym, r->add + i * PtrSize)->sym;
+ if (r == nil)
+ return nil;
+ return decode_reloc_sym(r->sym, r->add + i * PtrSize);
}
// Type.StructType.fields.Slice::len
@@ -936,21 +937,20 @@ decodetype_structfieldcount(Sym *s)
static char*
decodetype_structfieldname(Sym *s, int i)
{
- Reloc* r;
-
- r = decode_reloc(s, 6*PtrSize + 0x10 + i*5*PtrSize); // go.string."foo" 0x28 / 0x40
- if (r == nil) // embedded structs have a nil name.
+ // go.string."foo" 0x28 / 0x40
+ s = decode_reloc_sym(s, 6*PtrSize + 0x10 + i*5*PtrSize);
+ if (s == nil) // embedded structs have a nil name.
return nil;
- r = decode_reloc(r->sym, 0); // string."foo"
- if (r == nil) // shouldn't happen.
+ s = decode_reloc_sym(s, 0); // string."foo"
+ if (s == nil) // shouldn't happen.
return nil;
- return (char*)r->sym->p; // the c-string
+ return (char*)s->p; // the c-string
}
static Sym*
decodetype_structfieldtype(Sym *s, int i)
{
- return decode_reloc(s, 8*PtrSize + 0x10 + i*5*PtrSize)->sym; // 0x30 / 0x50
+ return decode_reloc_sym(s, 8*PtrSize + 0x10 + i*5*PtrSize); // 0x30 / 0x50
}
static vlong
@@ -977,6 +977,20 @@ enum {
static DWDie* defptrto(DWDie *dwtype); // below
+// Lookup predefined types
+static Sym*
+lookup_or_diag(char *n)
+{
+ Sym *s;
+
+ s = lookup(n, 0);
+ if (s->size == 0) {
+ diag("dwarf: missing type: %s", n);
+ errorexit();
+ }
+ return s;
+}
+
// Define gotype, for composite ones recurse into constituents.
static DWDie*
defgotype(Sym *gotype)
@@ -995,7 +1009,7 @@ defgotype(Sym *gotype)
diag("Type name doesn't start with \".type\": %s", gotype->name);
return find_or_diag(&dwtypes, "<unspecified>");
}
- name = gotype->name + 5; // Altenatively decode from Type.string
+ name = gotype->name + 5; // could also decode from Type.string
die = find(&dwtypes, name);
if (die != nil)
@@ -1049,7 +1063,6 @@ defgotype(Sym *gotype)
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
break;
- case KindFloat:
case KindFloat32:
case KindFloat64:
die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
@@ -1057,7 +1070,6 @@ defgotype(Sym *gotype)
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
break;
- case KindComplex:
case KindComplex64:
case KindComplex128:
die = newdie(&dwtypes, DW_ABRV_BASETYPE, name);
@@ -1107,9 +1119,9 @@ defgotype(Sym *gotype)
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
nfields = decodetype_ifacemethodcount(gotype);
if (nfields == 0)
- s = lookup("type.runtime.eface", 0);
+ s = lookup_or_diag("type.runtime.eface");
else
- s = lookup("type.runtime.iface", 0);
+ s = lookup_or_diag("type.runtime.iface");
newrefattr(die, DW_AT_type, defgotype(s));
break;
@@ -1226,7 +1238,7 @@ synthesizestringtypes(DWDie* die)
{
DWDie *prototype;
- prototype = defgotype(lookup("type.runtime.string_", 0));
+ prototype = defgotype(lookup_or_diag("type.runtime._string"));
if (prototype == nil)
return;
@@ -1242,7 +1254,7 @@ synthesizeslicetypes(DWDie *die)
{
DWDie *prototype, *elem;
- prototype = defgotype(lookup("type.runtime.slice",0));
+ prototype = defgotype(lookup_or_diag("type.runtime.slice"));
if (prototype == nil)
return;
@@ -1281,22 +1293,22 @@ synthesizemaptypes(DWDie *die)
{
DWDie *hash, *hash_subtable, *hash_entry,
- *dwh, *dwhs, *dwhe, *keytype, *valtype, *fld;
+ *dwh, *dwhs, *dwhe, *dwhash, *keytype, *valtype, *fld;
int hashsize, keysize, valsize, datsize, valsize_in_hash, datavo;
DWAttr *a;
- hash = defgotype(lookup("type.runtime.hash",0));
- hash_subtable = defgotype(lookup("type.runtime.hash_subtable",0));
- hash_entry = defgotype(lookup("type.runtime.hash_entry",0));
+ hash = defgotype(lookup_or_diag("type.runtime.hmap"));
+ hash_subtable = defgotype(lookup_or_diag("type.runtime.hash_subtable"));
+ hash_entry = defgotype(lookup_or_diag("type.runtime.hash_entry"));
if (hash == nil || hash_subtable == nil || hash_entry == nil)
return;
- dwh = (DWDie*)getattr(find_or_diag(hash_entry, "hash"), DW_AT_type)->data;
- if (dwh == nil)
+ dwhash = (DWDie*)getattr(find_or_diag(hash_entry, "hash"), DW_AT_type)->data;
+ if (dwhash == nil)
return;
- hashsize = getattr(dwh, DW_AT_byte_size)->value;
+ hashsize = getattr(dwhash, DW_AT_byte_size)->value;
for (; die != nil; die = die->link) {
if (die->abbrev != DW_ABRV_MAPTYPE)
@@ -1328,13 +1340,19 @@ synthesizemaptypes(DWDie *die)
mkinternaltypename("hash_entry",
getattr(keytype, DW_AT_name)->data,
getattr(valtype, DW_AT_name)->data));
- copychildren(dwhe, hash_entry);
- substitutetype(dwhe, "key", keytype);
+
+ fld = newdie(dwhe, DW_ABRV_STRUCTFIELD, "hash");
+ newrefattr(fld, DW_AT_type, dwhash);
+ newmemberoffsetattr(fld, 0);
+
+ fld = newdie(dwhe, DW_ABRV_STRUCTFIELD, "key");
+ newrefattr(fld, DW_AT_type, keytype);
+ newmemberoffsetattr(fld, hashsize);
+
+ fld = newdie(dwhe, DW_ABRV_STRUCTFIELD, "val");
if (valsize > MaxValsize)
valtype = defptrto(valtype);
- substitutetype(dwhe, "val", valtype);
- fld = find_or_diag(dwhe, "val");
- delattr(fld, DW_AT_data_member_location);
+ newrefattr(fld, DW_AT_type, valtype);
newmemberoffsetattr(fld, hashsize + datavo);
newattr(dwhe, DW_AT_byte_size, DW_CLS_CONSTANT, hashsize + datsize, NULL);
@@ -1371,10 +1389,10 @@ synthesizechantypes(DWDie *die)
DWAttr *a;
int elemsize, linksize, sudogsize;
- sudog = defgotype(lookup("type.runtime.sudoG",0));
- waitq = defgotype(lookup("type.runtime.waitQ",0));
- link = defgotype(lookup("type.runtime.link",0));
- hchan = defgotype(lookup("type.runtime.hChan",0));
+ sudog = defgotype(lookup_or_diag("type.runtime.sudog"));
+ waitq = defgotype(lookup_or_diag("type.runtime.waitq"));
+ link = defgotype(lookup_or_diag("type.runtime.link"));
+ hchan = defgotype(lookup_or_diag("type.runtime.hchan"));
if (sudog == nil || waitq == nil || link == nil || hchan == nil)
return;
@@ -2281,6 +2299,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
@@ -2313,15 +2338,18 @@ dwarfemitdebugsections(void)
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, PtrSize, 0);
// Needed by the prettyprinter code for interface inspection.
- defgotype(lookup("type.runtime.commonType",0));
- defgotype(lookup("type.runtime.InterfaceType",0));
- defgotype(lookup("type.runtime.itab",0));
+ defgotype(lookup_or_diag("type.runtime.commonType"));
+ defgotype(lookup_or_diag("type.runtime.InterfaceType"));
+ defgotype(lookup_or_diag("type.runtime.itab"));
genasmsym(defdwsymb);
writeabbrev();
+ align(abbrevsize);
writelines();
+ align(linesize);
writeframes();
+ align(framesize);
synthesizestringtypes(dwtypes.child);
synthesizeslicetypes(dwtypes.child);
@@ -2354,16 +2382,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);
}
/*
@@ -2545,3 +2580,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);
+}