summaryrefslogtreecommitdiff
path: root/src/cmd/ld/dwarf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/ld/dwarf.c')
-rw-r--r--src/cmd/ld/dwarf.c112
1 files changed, 68 insertions, 44 deletions
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c
index 98b068008..50b42183e 100644
--- a/src/cmd/ld/dwarf.c
+++ b/src/cmd/ld/dwarf.c
@@ -529,8 +529,10 @@ find_or_diag(DWDie *die, char* name)
{
DWDie *r;
r = find(die, name);
- if (r == nil)
+ if (r == nil) {
diag("dwarf find: %s has no %s", getattr(die, DW_AT_name)->data, name);
+ errorexit();
+ }
return r;
}
@@ -613,7 +615,7 @@ putattr(int form, int cls, vlong value, char *data)
case DW_FORM_ref_addr: // reference to a DIE in the .info section
if (data == nil) {
- diag("null dwarf reference");
+ diag("dwarf: null reference");
LPUT(0); // invalid dwarf, gdb will complain.
} else {
if (((DWDie*)data)->offs == 0)
@@ -631,7 +633,7 @@ putattr(int form, int cls, vlong value, char *data)
case DW_FORM_strp: // string
case DW_FORM_indirect: // (see Section 7.5.3)
default:
- diag("Unsupported atribute form %d / class %d", form, cls);
+ diag("dwarf: unsupported attribute form %d / class %d", form, cls);
errorexit();
}
}
@@ -823,7 +825,7 @@ decode_inuxi(uchar* p, int sz)
inuxi = inuxi8;
break;
default:
- diag("decode inuxi %d", sz);
+ diag("dwarf: decode inuxi %d", sz);
errorexit();
}
for (i = 0; i < sz; i++)
@@ -1013,7 +1015,7 @@ defgotype(Sym *gotype)
return find_or_diag(&dwtypes, "<unspecified>");
if (strncmp("type.", gotype->name, 5) != 0) {
- diag("Type name doesn't start with \".type\": %s", gotype->name);
+ diag("dwarf: type name doesn't start with \".type\": %s", gotype->name);
return find_or_diag(&dwtypes, "<unspecified>");
}
name = gotype->name + 5; // could also decode from Type.string
@@ -1164,7 +1166,7 @@ defgotype(Sym *gotype)
break;
default:
- diag("definition of unknown kind %d: %s", kind, gotype->name);
+ diag("dwarf: definition of unknown kind %d: %s", kind, gotype->name);
die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name);
newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "<unspecified>"));
}
@@ -1346,7 +1348,7 @@ synthesizemaptypes(DWDie *die)
valtype = defptrto(valtype);
newrefattr(fld, DW_AT_type, valtype);
newmemberoffsetattr(fld, hashsize + datavo);
- newattr(dwhe, DW_AT_byte_size, DW_CLS_CONSTANT, hashsize + datsize, NULL);
+ 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,
@@ -1357,7 +1359,7 @@ synthesizemaptypes(DWDie *die)
substitutetype(dwhs, "end", 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, NULL);
+ getattr(hash_subtable, DW_AT_byte_size)->value, nil);
// Construct hash<K,V>
dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
@@ -1367,7 +1369,7 @@ synthesizemaptypes(DWDie *die)
copychildren(dwh, hash);
substitutetype(dwh, "st", defptrto(dwhs));
newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT,
- getattr(hash, DW_AT_byte_size)->value, NULL);
+ getattr(hash, DW_AT_byte_size)->value, nil);
newrefattr(die, DW_AT_type, defptrto(dwh));
}
@@ -1399,30 +1401,30 @@ synthesizechantypes(DWDie *die)
// sudog<T>
dws = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
mkinternaltypename("sudog",
- getattr(elemtype, DW_AT_name)->data, NULL));
+ getattr(elemtype, DW_AT_name)->data, nil));
copychildren(dws, sudog);
substitutetype(dws, "elem", elemtype);
newattr(dws, DW_AT_byte_size, DW_CLS_CONSTANT,
- sudogsize + (elemsize > 8 ? elemsize - 8 : 0), NULL);
+ sudogsize + (elemsize > 8 ? elemsize - 8 : 0), nil);
// waitq<T>
dww = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
- mkinternaltypename("waitq", getattr(elemtype, DW_AT_name)->data, NULL));
+ mkinternaltypename("waitq", getattr(elemtype, DW_AT_name)->data, nil));
copychildren(dww, waitq);
substitutetype(dww, "first", defptrto(dws));
substitutetype(dww, "last", defptrto(dws));
newattr(dww, DW_AT_byte_size, DW_CLS_CONSTANT,
- getattr(waitq, DW_AT_byte_size)->value, NULL);
+ getattr(waitq, DW_AT_byte_size)->value, nil);
// hchan<T>
dwh = newdie(&dwtypes, DW_ABRV_STRUCTTYPE,
- mkinternaltypename("hchan", getattr(elemtype, DW_AT_name)->data, NULL));
+ mkinternaltypename("hchan", getattr(elemtype, DW_AT_name)->data, nil));
copychildren(dwh, hchan);
substitutetype(dwh, "recvq", dww);
substitutetype(dwh, "sendq", dww);
substitutetype(dwh, "free", defptrto(dws));
newattr(dwh, DW_AT_byte_size, DW_CLS_CONSTANT,
- getattr(hchan, DW_AT_byte_size)->value, NULL);
+ getattr(hchan, DW_AT_byte_size)->value, nil);
newrefattr(die, DW_AT_type, defptrto(dwh));
}
@@ -1434,6 +1436,7 @@ defdwsymb(Sym* sym, char *s, int t, vlong v, vlong size, int ver, Sym *gotype)
{
DWDie *dv, *dt;
+ USED(size);
if (strncmp(s, "go.string.", 10) == 0)
return;
@@ -1513,12 +1516,12 @@ decodez(char *s)
ss = s + 1; // first is 0
while((o = ((uint8)ss[0] << 8) | (uint8)ss[1]) != 0) {
if (o < 0 || o >= ftabsize) {
- diag("corrupt z entry");
+ diag("dwarf: corrupt z entry");
return 0;
}
f = ftab[o];
if (f == nil) {
- diag("corrupt z entry");
+ diag("dwarf: corrupt z entry");
return 0;
}
len += strlen(f) + 1; // for the '/'
@@ -1590,7 +1593,7 @@ addhistfile(char *zentry)
// if the histfile stack contains ..../runtime/runtime_defs.go
// use that to set gdbscript
static void
-finddebugruntimepath()
+finddebugruntimepath(void)
{
int i, l;
char *c;
@@ -1630,11 +1633,11 @@ checknesting(void)
int i;
if (includetop < 0) {
- diag("corrupt z stack");
+ diag("dwarf: corrupt z stack");
errorexit();
}
if (includetop >= nelem(includestack)) {
- diag("nesting too deep");
+ diag("dwarf: nesting too deep");
for (i = 0; i < nelem(includestack); i++)
diag("\t%s", histfile[includestack[i].file]);
errorexit();
@@ -1660,7 +1663,7 @@ inithist(Auto *a)
// We have a new history. They are guaranteed to come completely
// at the beginning of the compilation unit.
if (a->aoffset != 1) {
- diag("stray 'z' with offset %d", a->aoffset);
+ diag("dwarf: stray 'z' with offset %d", a->aoffset);
return 0;
}
@@ -1801,7 +1804,7 @@ mkvarname(char* name, int da)
// flush previous compilation unit.
static void
-flushunit(DWDie *dwinfo, vlong pc, vlong unitstart)
+flushunit(DWDie *dwinfo, vlong pc, vlong unitstart, int32 header_length)
{
vlong here;
@@ -1817,7 +1820,9 @@ flushunit(DWDie *dwinfo, vlong pc, vlong unitstart)
here = cpos();
seek(cout, unitstart, 0);
- LPUT(here - unitstart - sizeof(int32));
+ LPUT(here - unitstart - sizeof(int32)); // unit_length
+ WPUT(3); // dwarf version
+ LPUT(header_length); // header lenght starting here
cflush();
seek(cout, here, 0);
}
@@ -1829,7 +1834,7 @@ writelines(void)
Prog *q;
Sym *s;
Auto *a;
- vlong unitstart, offs;
+ vlong unitstart, headerend, offs;
vlong pc, epc, lc, llc, lline;
int currfile;
int i, lang, da, dt;
@@ -1839,7 +1844,9 @@ writelines(void)
char *n, *nn;
unitstart = -1;
- epc = pc = 0;
+ headerend = -1;
+ pc = 0;
+ epc = 0;
lc = 1;
llc = 1;
currfile = -1;
@@ -1855,7 +1862,7 @@ writelines(void)
// we're entering a new compilation unit
if (inithist(s->autom)) {
- flushunit(dwinfo, epc, unitstart);
+ flushunit(dwinfo, epc, unitstart, headerend - unitstart - 10);
unitstart = cpos();
if(debug['v'] > 1) {
@@ -1876,10 +1883,10 @@ writelines(void)
// 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 later.
+ LPUT(0); // unit_length (*), will be filled in by flushunit.
WPUT(3); // dwarf version (appendix F)
- LPUT(11); // header_length (*), starting here.
-
+ LPUT(0); // header_length (*), filled in by flushunit.
+ // cpos == unitstart + 4 + 2 + 4
cput(1); // minimum_instruction_length
cput(1); // default_is_stmt
cput(LINE_BASE); // line_base
@@ -1890,18 +1897,17 @@ writelines(void)
cput(1); // standard_opcode_lengths[3]
cput(1); // standard_opcode_lengths[4]
cput(0); // include_directories (empty)
- cput(0); // file_names (empty) (emitted by DW_LNE's below)
- // header_length ends here.
for (i=1; i < histfilesize; i++) {
- cput(0); // start extended opcode
- uleb128put(1 + strlen(histfile[i]) + 4);
- cput(DW_LNE_define_file);
strnput(histfile[i], strlen(histfile[i]) + 4);
// 4 zeros: the string termination + 3 fields.
}
- epc = pc = s->text->pc;
+ cput(0); // terminate file_names.
+ headerend = cpos();
+
+ pc = s->text->pc;
+ epc = pc;
currfile = 1;
lc = 1;
llc = 1;
@@ -1915,7 +1921,7 @@ writelines(void)
continue;
if (unitstart < 0) {
- diag("reachable code before seeing any history: %P", s->text);
+ diag("dwarf: reachable code before seeing any history: %P", s->text);
continue;
}
@@ -1932,7 +1938,7 @@ writelines(void)
for(q = s->text; q != P; q = q->link) {
lh = searchhist(q->line);
if (lh == nil) {
- diag("corrupt history or bad absolute line: %P", q);
+ diag("dwarf: corrupt history or bad absolute line: %P", q);
continue;
}
@@ -1990,7 +1996,7 @@ writelines(void)
newrefattr(dwvar, DW_AT_type, defgotype(a->gotype));
// push dwvar down dwfunc->child to preserve order
- newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, NULL);
+ newattr(dwvar, DW_AT_internal_location, DW_CLS_CONSTANT, offs, nil);
dwfunc->child = dwvar->link; // take dwvar out from the top of the list
for (dws = &dwfunc->child; *dws != nil; dws = &(*dws)->link)
if (offs > getattr(*dws, DW_AT_internal_location)->value)
@@ -2004,7 +2010,7 @@ writelines(void)
dwfunc->hash = nil;
}
- flushunit(dwinfo, epc, unitstart);
+ flushunit(dwinfo, epc, unitstart, headerend - unitstart - 10);
linesize = cpos() - lineo;
}
@@ -2066,7 +2072,7 @@ writeframes(void)
// 4 is to exclude the length field.
pad = CIERESERVE + frameo + 4 - cpos();
if (pad < 0) {
- diag("CIERESERVE too small by %lld bytes.", -pad);
+ diag("dwarf: CIERESERVE too small by %lld bytes.", -pad);
errorexit();
}
strnput("", pad);
@@ -2296,6 +2302,9 @@ dwarfemitdebugsections(void)
vlong infoe;
DWDie* die;
+ if(debug['w']) // disable dwarf
+ return;
+
// For diagnostic messages.
newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, strlen("dwtypes"), "dwtypes");
@@ -2340,7 +2349,11 @@ dwarfemitdebugsections(void)
infoo = cpos();
writeinfo();
- gdbscripto = arangeso = pubtypeso = pubnameso = infoe = cpos();
+ infoe = cpos();
+ pubnameso = infoe;
+ pubtypeso = infoe;
+ arangeso = infoe;
+ gdbscripto = infoe;
if (fwdcount > 0) {
if (debug['v'])
@@ -2348,11 +2361,11 @@ dwarfemitdebugsections(void)
seek(cout, infoo, 0);
writeinfo();
if (fwdcount > 0) {
- diag("unresolved references after first dwarf info pass");
+ diag("dwarf: unresolved references after first dwarf info pass");
errorexit();
}
if (infoe != cpos()) {
- diag("inconsistent second dwarf info pass");
+ diag("dwarf: inconsistent second dwarf info pass");
errorexit();
}
}
@@ -2401,6 +2414,9 @@ vlong elfstrdbg[NElfStrDbg];
void
dwarfaddshstrings(Sym *shstrtab)
{
+ if(debug['w']) // disable dwarf
+ return;
+
elfstrdbg[ElfStrDebugAbbrev] = addstring(shstrtab, ".debug_abbrev");
elfstrdbg[ElfStrDebugAranges] = addstring(shstrtab, ".debug_aranges");
elfstrdbg[ElfStrDebugFrame] = addstring(shstrtab, ".debug_frame");
@@ -2420,6 +2436,9 @@ dwarfaddelfheaders(void)
{
ElfShdr *sh;
+ if(debug['w']) // disable dwarf
+ return;
+
sh = newElfShdr(elfstrdbg[ElfStrDebugAbbrev]);
sh->type = SHT_PROGBITS;
sh->off = abbrevo;
@@ -2488,6 +2507,9 @@ dwarfaddmachoheaders(void)
vlong fakestart;
int nsect;
+ if(debug['w']) // disable dwarf
+ return;
+
// Zero vsize segments won't be loaded in memory, even so they
// have to be page aligned in the file.
fakestart = abbrevo & ~0xfff;
@@ -2562,7 +2584,9 @@ dwarfaddmachoheaders(void)
void
dwarfaddpeheaders(void)
{
- dwarfemitdebugsections();
+ if(debug['w']) // disable dwarf
+ return;
+
newPEDWARFSection(".debug_abbrev", abbrevsize);
newPEDWARFSection(".debug_line", linesize);
newPEDWARFSection(".debug_frame", framesize);