summaryrefslogtreecommitdiff
path: root/src/cmd/ld/dwarf.c
diff options
context:
space:
mode:
authorMichael Stapelberg <michael@stapelberg.de>2013-03-23 11:28:53 +0100
committerMichael Stapelberg <michael@stapelberg.de>2013-03-23 11:28:53 +0100
commitb39e15dde5ec7b96c15da9faf4ab5892501c1aae (patch)
tree718cede1f6ca97d082c6c40b7dc3f4f6148253c0 /src/cmd/ld/dwarf.c
parent04b08da9af0c450d645ab7389d1467308cfc2db8 (diff)
downloadgolang-upstream/1.1_hg20130323.tar.gz
Imported Upstream version 1.1~hg20130323upstream/1.1_hg20130323
Diffstat (limited to 'src/cmd/ld/dwarf.c')
-rw-r--r--src/cmd/ld/dwarf.c294
1 files changed, 173 insertions, 121 deletions
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c
index d6a357e49..4bf788e64 100644
--- a/src/cmd/ld/dwarf.c
+++ b/src/cmd/ld/dwarf.c
@@ -41,9 +41,13 @@ static vlong arangeso;
static vlong arangessize;
static vlong gdbscripto;
static vlong gdbscriptsize;
+static vlong inforeloco;
+static vlong inforelocsize;
static char gdbscript[1024];
+static Sym *dsym;
+
/*
* Basic I/O
*/
@@ -150,6 +154,7 @@ enum
DW_ABRV_IFACETYPE,
DW_ABRV_MAPTYPE,
DW_ABRV_PTRTYPE,
+ DW_ABRV_BARE_PTRTYPE, // only for void*, no DW_AT_type attr to please gdb 6.
DW_ABRV_SLICETYPE,
DW_ABRV_STRINGTYPE,
DW_ABRV_STRUCTTYPE,
@@ -303,6 +308,12 @@ static struct DWAbbrev {
DW_AT_type, DW_FORM_ref_addr,
0, 0
},
+ /* BARE_PTRTYPE */
+ {
+ DW_TAG_pointer_type, DW_CHILDREN_no,
+ DW_AT_name, DW_FORM_string,
+ 0, 0
+ },
/* SLICETYPE */
{
@@ -485,26 +496,43 @@ mkindex(DWDie *die)
die->hash = mal(HASHSIZE * sizeof(DWDie*));
}
+static DWDie*
+walktypedef(DWDie *die)
+{
+ DWAttr *attr;
+
+ // Resolve typedef if present.
+ if (die->abbrev == DW_ABRV_TYPEDECL) {
+ for (attr = die->attr; attr; attr = attr->link) {
+ if (attr->atr == DW_AT_type && attr->cls == DW_CLS_REFERENCE && attr->data != nil) {
+ return (DWDie*)attr->data;
+ }
+ }
+ }
+ return die;
+}
+
// Find child by AT_name using hashtable if available or linear scan
// if not.
static DWDie*
find(DWDie *die, char* name)
{
- DWDie *a, *b;
+ DWDie *a, *b, *die2;
int h;
+top:
if (die->hash == nil) {
for (a = die->child; a != nil; a = a->link)
if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
return a;
- return nil;
+ goto notfound;
}
h = hashstr(name);
a = die->hash[h];
if (a == nil)
- return nil;
+ goto notfound;
if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
@@ -522,6 +550,14 @@ find(DWDie *die, char* name)
a = b;
b = b->hlink;
}
+
+notfound:
+ die2 = walktypedef(die);
+ if(die2 != die) {
+ die = die2;
+ goto top;
+ }
+
return nil;
}
@@ -531,7 +567,7 @@ find_or_diag(DWDie *die, char* name)
DWDie *r;
r = find(die, name);
if (r == nil) {
- diag("dwarf find: %s has no %s", getattr(die, DW_AT_name)->data, name);
+ diag("dwarf find: %s %p has no %s", getattr(die, DW_AT_name)->data, die, name);
errorexit();
}
return r;
@@ -548,14 +584,33 @@ newrefattr(DWDie *die, uint8 attr, DWDie* ref)
static int fwdcount;
static void
-putattr(int form, int cls, vlong value, char *data)
+putattr(int abbrev, int form, int cls, vlong value, char *data)
{
+ Reloc *r;
+
switch(form) {
case DW_FORM_addr: // address
addrput(value);
break;
case DW_FORM_block1: // block
+ if(cls == DW_CLS_ADDRESS) {
+ cput(1+PtrSize);
+ cput(DW_OP_addr);
+ if(linkmode == LinkExternal) {
+ r = addrel(dsym);
+ r->sym = (Sym*)data;
+ r->xsym = r->sym;
+ r->off = cpos() - infoo;
+ r->siz = PtrSize;
+ r->type = D_ADDR;
+ r->add = value - r->sym->value;
+ r->xadd = r->add;
+ value = r->add;
+ }
+ addrput(value);
+ break;
+ }
value &= 0xff;
cput(value);
while(value--)
@@ -615,13 +670,23 @@ putattr(int form, int cls, vlong value, char *data)
break;
case DW_FORM_ref_addr: // reference to a DIE in the .info section
+ // In DWARF 2 (which is what we claim to generate),
+ // the ref_addr is the same size as a normal address.
+ // In DWARF 3 it is always 32 bits, unless emitting a large
+ // (> 4 GB of debug info aka "64-bit") unit, which we don't implement.
if (data == nil) {
- diag("dwarf: null reference");
- LPUT(0); // invalid dwarf, gdb will complain.
+ diag("dwarf: null reference in %d", abbrev);
+ if(PtrSize == 8)
+ VPUT(0); // invalid dwarf, gdb will complain.
+ else
+ LPUT(0); // invalid dwarf, gdb will complain.
} else {
if (((DWDie*)data)->offs == 0)
fwdcount++;
- LPUT(((DWDie*)data)->offs);
+ if(PtrSize == 8)
+ VPUT(((DWDie*)data)->offs);
+ else
+ LPUT(((DWDie*)data)->offs);
}
break;
@@ -654,12 +719,12 @@ putattrs(int abbrev, DWAttr* attr)
for(af = abbrevs[abbrev].attr; af->attr; af++)
if (attrs[af->attr])
- putattr(af->form,
+ putattr(abbrev, af->form,
attrs[af->attr]->cls,
attrs[af->attr]->value,
attrs[af->attr]->data);
else
- putattr(af->form, 0, 0, 0);
+ putattr(abbrev, af->form, 0, 0, nil);
}
static void putdie(DWDie* die);
@@ -729,16 +794,9 @@ newmemberoffsetattr(DWDie *die, int32 offs)
// GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
// location expression that evals to a const.
static void
-newabslocexprattr(DWDie *die, vlong addr)
+newabslocexprattr(DWDie *die, vlong addr, Sym *sym)
{
- char block[10];
- int i;
-
- i = 0;
- block[i++] = DW_OP_constu;
- i += uleb128enc(addr, block+i);
- newattr(die, DW_AT_location, DW_CLS_BLOCK, i, mal(i));
- memmove(die->attr->data, block, i);
+ newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, (char*)sym);
}
@@ -766,6 +824,31 @@ lookup_or_diag(char *n)
return s;
}
+static void
+dotypedef(DWDie *parent, char *name, DWDie *def)
+{
+ DWDie *die;
+
+ // Only emit typedefs for real names.
+ if(strncmp(name, "map[", 4) == 0)
+ return;
+ if(strncmp(name, "struct {", 8) == 0)
+ return;
+ if(strncmp(name, "chan ", 5) == 0)
+ return;
+ if(*name == '[' || *name == '*')
+ return;
+ if(def == nil)
+ diag("dwarf: bad def in dotypedef");
+
+ // The typedef entry must be created after the def,
+ // so that future lookups will find the typedef instead
+ // of the real definition. This hooks the typedef into any
+ // circular definition loops, so that gdb can understand them.
+ die = newdie(parent, DW_ABRV_TYPEDECL, name);
+ newrefattr(die, DW_AT_type, def);
+}
+
// Define gotype, for composite ones recurse into constituents.
static DWDie*
defgotype(Sym *gotype)
@@ -840,6 +923,7 @@ defgotype(Sym *gotype)
case KindArray:
die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name);
+ dotypedef(&dwtypes, name, die);
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
s = decodetype_arrayelem(gotype);
newrefattr(die, DW_AT_type, defgotype(s));
@@ -857,6 +941,7 @@ defgotype(Sym *gotype)
case KindFunc:
die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name);
+ dotypedef(&dwtypes, name, die);
newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "void"));
nfields = decodetype_funcincount(gotype);
for (i = 0; i < nfields; i++) {
@@ -876,6 +961,7 @@ defgotype(Sym *gotype)
case KindInterface:
die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name);
+ dotypedef(&dwtypes, name, die);
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
nfields = decodetype_ifacemethodcount(gotype);
if (nfields == 0)
@@ -895,12 +981,14 @@ defgotype(Sym *gotype)
case KindPtr:
die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name);
+ dotypedef(&dwtypes, name, die);
s = decodetype_ptrelem(gotype);
newrefattr(die, DW_AT_type, defgotype(s));
break;
case KindSlice:
die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name);
+ dotypedef(&dwtypes, name, die);
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
s = decodetype_arrayelem(gotype);
newrefattr(die, DW_AT_internal_elem_type, defgotype(s));
@@ -913,6 +1001,7 @@ defgotype(Sym *gotype)
case KindStruct:
die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name);
+ dotypedef(&dwtypes, name, die);
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
nfields = decodetype_structfieldcount(gotype);
for (i = 0; i < nfields; i++) {
@@ -927,8 +1016,7 @@ defgotype(Sym *gotype)
break;
case KindUnsafePointer:
- die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name);
- newrefattr(die, DW_AT_type, find(&dwtypes, "void"));
+ die = newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, name);
break;
default:
@@ -998,7 +1086,7 @@ synthesizestringtypes(DWDie* die)
{
DWDie *prototype;
- prototype = defgotype(lookup_or_diag("type.runtime._string"));
+ prototype = walktypedef(defgotype(lookup_or_diag("type.runtime._string")));
if (prototype == nil)
return;
@@ -1014,7 +1102,7 @@ synthesizeslicetypes(DWDie *die)
{
DWDie *prototype, *elem;
- prototype = defgotype(lookup_or_diag("type.runtime.slice"));
+ prototype = walktypedef(defgotype(lookup_or_diag("type.runtime.slice")));
if (prototype == nil)
return;
@@ -1043,33 +1131,17 @@ mkinternaltypename(char *base, char *arg1, char *arg2)
}
-// synthesizemaptypes is way too closely married to runtime/hashmap.c
-enum {
- MaxValsize = 256 - 64
-};
-
static void
synthesizemaptypes(DWDie *die)
{
- DWDie *hash, *hash_subtable, *hash_entry,
- *dwh, *dwhs, *dwhe, *dwhash, *keytype, *valtype, *fld;
- int hashsize, keysize, valsize, datsize, valsize_in_hash, datavo;
- DWAttr *a;
+ DWDie *hash, *dwh, *keytype, *valtype;
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)
+ if (hash == nil)
return;
- dwhash = (DWDie*)getattr(find_or_diag(hash_entry, "hash"), DW_AT_type)->data;
- if (dwhash == nil)
- return;
-
- hashsize = getattr(dwhash, DW_AT_byte_size)->value;
-
for (; die != nil; die = die->link) {
if (die->abbrev != DW_ABRV_MAPTYPE)
continue;
@@ -1077,63 +1149,12 @@ synthesizemaptypes(DWDie *die)
keytype = (DWDie*) getattr(die, DW_AT_internal_key_type)->data;
valtype = (DWDie*) getattr(die, DW_AT_internal_val_type)->data;
- a = getattr(keytype, DW_AT_byte_size);
- keysize = a ? a->value : PtrSize; // We don't store size with Pointers
-
- a = getattr(valtype, DW_AT_byte_size);
- valsize = a ? a->value : PtrSize;
-
- // This is what happens in hash_init and makemap_c
- valsize_in_hash = valsize;
- if (valsize > MaxValsize)
- valsize_in_hash = PtrSize;
- datavo = keysize;
- if (valsize_in_hash >= PtrSize)
- datavo = rnd(keysize, PtrSize);
- datsize = datavo + valsize_in_hash;
- if (datsize < PtrSize)
- datsize = PtrSize;
- datsize = rnd(datsize, PtrSize);
-
- // Construct struct hash_entry<K,V>
- dwhe = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
- mkinternaltypename("hash_entry",
- getattr(keytype, DW_AT_name)->data,
- getattr(valtype, DW_AT_name)->data));
-
- 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);
- newrefattr(fld, DW_AT_type, valtype);
- newmemberoffsetattr(fld, hashsize + datavo);
- newattr(dwhe, DW_AT_byte_size, DW_CLS_CONSTANT, hashsize + datsize, nil);
-
- // Construct hash_subtable<hash_entry<K,V>>
- dwhs = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
- mkinternaltypename("hash_subtable",
- getattr(keytype, DW_AT_name)->data,
- getattr(valtype, DW_AT_name)->data));
- copychildren(dwhs, hash_subtable);
- substitutetype(dwhs, "last", defptrto(dwhe));
- substitutetype(dwhs, "entry", dwhe); // todo: []hash_entry with dynamic size
- newattr(dwhs, DW_AT_byte_size, DW_CLS_CONSTANT,
- getattr(hash_subtable, DW_AT_byte_size)->value, nil);
-
// Construct hash<K,V>
dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
mkinternaltypename("hash",
getattr(keytype, DW_AT_name)->data,
getattr(valtype, DW_AT_name)->data));
copychildren(dwh, hash);
- substitutetype(dwh, "st", defptrto(dwhs));
newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT,
getattr(hash, DW_AT_byte_size)->value, nil);
@@ -1149,9 +1170,9 @@ synthesizechantypes(DWDie *die)
DWAttr *a;
int elemsize, sudogsize;
- sudog = defgotype(lookup_or_diag("type.runtime.sudog"));
- waitq = defgotype(lookup_or_diag("type.runtime.waitq"));
- hchan = defgotype(lookup_or_diag("type.runtime.hchan"));
+ sudog = walktypedef(defgotype(lookup_or_diag("type.runtime.sudog")));
+ waitq = walktypedef(defgotype(lookup_or_diag("type.runtime.waitq")));
+ hchan = walktypedef(defgotype(lookup_or_diag("type.runtime.hchan")));
if (sudog == nil || waitq == nil || hchan == nil)
return;
@@ -1220,7 +1241,7 @@ defdwsymb(Sym* sym, char *s, int t, vlong v, vlong size, int ver, Sym *gotype)
case 'D':
case 'B':
dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s);
- newabslocexprattr(dv, v);
+ newabslocexprattr(dv, v, sym);
if (ver == 0)
newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0);
// fallthrough
@@ -1260,7 +1281,7 @@ dwarfaddfrag(int n, char *frag)
if (n >= ftabsize) {
s = ftabsize;
ftabsize = 1 + n + (n >> 2);
- ftab = realloc(ftab, ftabsize * sizeof(ftab[0]));
+ ftab = erealloc(ftab, ftabsize * sizeof(ftab[0]));
memset(ftab + s, 0, (ftabsize - s) * sizeof(ftab[0]));
}
@@ -1342,7 +1363,7 @@ addhistfile(char *zentry)
if (histfilesize == histfilecap) {
histfilecap = 2 * histfilecap + 2;
- histfile = realloc(histfile, histfilecap * sizeof(char*));
+ histfile = erealloc(histfile, histfilecap * sizeof(char*));
}
if (histfilesize == 0)
histfile[histfilesize++] = "<eof>";
@@ -1412,7 +1433,7 @@ checknesting(void)
includestacksize += 1;
includestacksize <<= 2;
// print("checknesting: growing to %d\n", includestacksize);
- includestack = realloc(includestack, includestacksize * sizeof *includestack);
+ includestack = erealloc(includestack, includestacksize * sizeof *includestack);
}
}
@@ -1581,12 +1602,12 @@ mkvarname(char* name, int da)
// flush previous compilation unit.
static void
-flushunit(DWDie *dwinfo, vlong pc, vlong unitstart, int32 header_length)
+flushunit(DWDie *dwinfo, vlong pc, Sym *pcsym, vlong unitstart, int32 header_length)
{
vlong here;
if (dwinfo != nil && pc != 0) {
- newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, 0);
+ newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc+1, (char*)pcsym);
}
if (unitstart >= 0) {
@@ -1597,7 +1618,7 @@ flushunit(DWDie *dwinfo, vlong pc, vlong unitstart, int32 header_length)
here = cpos();
cseek(unitstart);
LPUT(here - unitstart - sizeof(int32)); // unit_length
- WPUT(3); // dwarf version
+ WPUT(2); // dwarf version
LPUT(header_length); // header length starting here
cseek(here);
}
@@ -1607,7 +1628,7 @@ static void
writelines(void)
{
Prog *q;
- Sym *s;
+ Sym *s, *epcs;
Auto *a;
vlong unitstart, headerend, offs;
vlong pc, epc, lc, llc, lline;
@@ -1622,6 +1643,7 @@ writelines(void)
headerend = -1;
pc = 0;
epc = 0;
+ epcs = S;
lc = 1;
llc = 1;
currfile = -1;
@@ -1637,7 +1659,7 @@ writelines(void)
// we're entering a new compilation unit
if (inithist(s->autom)) {
- flushunit(dwinfo, epc, unitstart, headerend - unitstart - 10);
+ flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
unitstart = cpos();
if(debug['v'] > 1) {
@@ -1651,15 +1673,15 @@ writelines(void)
lang = guesslang(histfile[1]);
finddebugruntimepath();
- dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, strdup(histfile[1]));
+ dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, estrdup(histfile[1]));
newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT,lang, 0);
newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart - lineo, 0);
- newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s->text->pc, 0);
+ newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, s->text->pc, (char*)s);
// Write .debug_line Line Number Program Header (sec 6.2.4)
// Fields marked with (*) must be changed for 64-bit dwarf
LPUT(0); // unit_length (*), will be filled in by flushunit.
- WPUT(3); // dwarf version (appendix F)
+ WPUT(2); // dwarf version (appendix F)
LPUT(0); // header_length (*), filled in by flushunit.
// cpos == unitstart + 4 + 2 + 4
cput(1); // minimum_instruction_length
@@ -1683,6 +1705,7 @@ writelines(void)
pc = s->text->pc;
epc = pc;
+ epcs = s;
currfile = 1;
lc = 1;
llc = 1;
@@ -1701,9 +1724,9 @@ writelines(void)
}
dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s->name);
- newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s->value, 0);
+ newattr(dwfunc, DW_AT_low_pc, DW_CLS_ADDRESS, s->value, (char*)s);
epc = s->value + s->size;
- newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, 0);
+ newattr(dwfunc, DW_AT_high_pc, DW_CLS_ADDRESS, epc, (char*)s);
if (s->version == 0)
newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0);
@@ -1785,7 +1808,7 @@ writelines(void)
dwfunc->hash = nil;
}
- flushunit(dwinfo, epc, unitstart, headerend - unitstart - 10);
+ flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
linesize = cpos() - lineo;
}
@@ -1909,6 +1932,9 @@ writeinfo(void)
vlong unitstart, here;
fwdcount = 0;
+ if (dsym == S)
+ dsym = lookup(".dwarfinfo", 0);
+ dsym->nr = 0;
for (compunit = dwroot.child; compunit; compunit = compunit->link) {
unitstart = cpos();
@@ -1917,7 +1943,7 @@ writeinfo(void)
// Fields marked with (*) must be changed for 64-bit dwarf
// This must match COMPUNITHEADERSIZE above.
LPUT(0); // unit_length (*), will be filled in later.
- WPUT(3); // dwarf version (appendix F)
+ WPUT(2); // dwarf version (appendix F)
LPUT(0); // debug_abbrev_offset (*)
cput(PtrSize); // address_size
@@ -2057,6 +2083,27 @@ align(vlong size)
strnput("", rnd(size, PEFILEALIGN) - size);
}
+static vlong
+writeinforeloc(void)
+{
+ int i;
+ vlong start;
+ Reloc *r;
+
+ start = cpos();
+ for(r = dsym->r; r < dsym->r+dsym->nr; r++) {
+ if(iself)
+ i = elfreloc1(r, r->off);
+ else if(HEADTYPE == Hdarwin)
+ i = machoreloc1(r, r->off);
+ else
+ i = -1;
+ if(i < 0)
+ diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name);
+ }
+ return start;
+}
+
/*
* This is the main entry point for generating dwarf. After emitting
* the mandatory debug_abbrev section, it calls writelines() to set up
@@ -2085,8 +2132,7 @@ dwarfemitdebugsections(void)
// Some types that must exist to define other ones.
newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>");
newdie(&dwtypes, DW_ABRV_NULLTYPE, "void");
- newrefattr(newdie(&dwtypes, DW_ABRV_PTRTYPE, "unsafe.Pointer"),
- DW_AT_type, find(&dwtypes, "void"));
+ newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer");
die = newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr"); // needed for array size
newattr(die, DW_AT_encoding, DW_CLS_CONSTANT, DW_ATE_unsigned, 0);
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, PtrSize, 0);
@@ -2157,6 +2203,10 @@ dwarfemitdebugsections(void)
gdbscripto = writegdbscript();
gdbscriptsize = cpos() - gdbscripto;
align(gdbscriptsize);
+
+ inforeloco = writeinforeloc();
+ inforelocsize = cpos() - inforeloco;
+ align(inforelocsize);
}
/*
@@ -2298,42 +2348,44 @@ dwarfaddmachoheaders(void)
ms->fileoffset = fakestart;
ms->filesize = abbrevo-fakestart;
- msect = newMachoSect(ms, "__debug_abbrev");
+ msect = newMachoSect(ms, "__debug_abbrev", "__DWARF");
msect->off = abbrevo;
msect->size = abbrevsize;
ms->filesize += msect->size;
- msect = newMachoSect(ms, "__debug_line");
+ msect = newMachoSect(ms, "__debug_line", "__DWARF");
msect->off = lineo;
msect->size = linesize;
ms->filesize += msect->size;
- msect = newMachoSect(ms, "__debug_frame");
+ msect = newMachoSect(ms, "__debug_frame", "__DWARF");
msect->off = frameo;
msect->size = framesize;
ms->filesize += msect->size;
- msect = newMachoSect(ms, "__debug_info");
+ msect = newMachoSect(ms, "__debug_info", "__DWARF");
msect->off = infoo;
msect->size = infosize;
+ msect->reloc = inforeloco;
+ msect->nreloc = inforelocsize / 8;
ms->filesize += msect->size;
if (pubnamessize > 0) {
- msect = newMachoSect(ms, "__debug_pubnames");
+ msect = newMachoSect(ms, "__debug_pubnames", "__DWARF");
msect->off = pubnameso;
msect->size = pubnamessize;
ms->filesize += msect->size;
}
if (pubtypessize > 0) {
- msect = newMachoSect(ms, "__debug_pubtypes");
+ msect = newMachoSect(ms, "__debug_pubtypes", "__DWARF");
msect->off = pubtypeso;
msect->size = pubtypessize;
ms->filesize += msect->size;
}
if (arangessize > 0) {
- msect = newMachoSect(ms, "__debug_aranges");
+ msect = newMachoSect(ms, "__debug_aranges", "__DWARF");
msect->off = arangeso;
msect->size = arangessize;
ms->filesize += msect->size;
@@ -2341,7 +2393,7 @@ dwarfaddmachoheaders(void)
// TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
if (gdbscriptsize > 0) {
- msect = newMachoSect(ms, "__debug_gdb_scripts");
+ msect = newMachoSect(ms, "__debug_gdb_scripts", "__DWARF");
msect->off = gdbscripto;
msect->size = gdbscriptsize;
ms->filesize += msect->size;