aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/6l/asm.c3
-rw-r--r--src/cmd/6l/l.h2
-rw-r--r--src/cmd/8l/Makefile5
-rw-r--r--src/cmd/8l/asm.c20
-rw-r--r--src/cmd/8l/l.h1
-rw-r--r--src/cmd/8l/obj.c2
-rw-r--r--src/cmd/ld/dwarf.c864
7 files changed, 481 insertions, 416 deletions
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c
index db11f14efb..af615e6938 100644
--- a/src/cmd/6l/asm.c
+++ b/src/cmd/6l/asm.c
@@ -641,8 +641,7 @@ asmb(void)
dwarfemitdebugsections();
}
- } else
- if(dlm){
+ } else if(dlm){
seek(cout, HEADR+textsize+datsize, 0);
asmdyn();
cflush();
diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h
index 9a77658c3d..a8428865a7 100644
--- a/src/cmd/6l/l.h
+++ b/src/cmd/6l/l.h
@@ -394,9 +394,9 @@ Prog* brchain(Prog*);
Prog* brloop(Prog*);
void buildop(void);
void cflush(void);
-vlong cpos(void);
void ckoff(Sym*, int32);
Prog* copyp(Prog*);
+vlong cpos(void);
double cputime(void);
void datblk(int32, int32);
void deadcode(void);
diff --git a/src/cmd/8l/Makefile b/src/cmd/8l/Makefile
index 2b509b3613..49064ca6a6 100644
--- a/src/cmd/8l/Makefile
+++ b/src/cmd/8l/Makefile
@@ -9,8 +9,10 @@ TARG=8l
OFILES=\
asm.$O\
+ dwarf.$O\
elf.$O\
enam.$O\
+ go.$O\
lib.$O\
list.$O\
macho.$O\
@@ -19,11 +21,12 @@ OFILES=\
pass.$O\
pe.$O\
span.$O\
- go.$O\
+
HFILES=\
l.h\
../8l/8.out.h\
+ ../ld/dwarf.h\
../ld/elf.h\
../ld/macho.h\
../ld/pe.h\
diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c
index a7f894aa28..277fba37ab 100644
--- a/src/cmd/8l/asm.c
+++ b/src/cmd/8l/asm.c
@@ -31,6 +31,7 @@
#include "l.h"
#include "../ld/lib.h"
#include "../ld/elf.h"
+#include "../ld/dwarf.h"
#include "../ld/macho.h"
#include "../ld/pe.h"
@@ -293,6 +294,7 @@ doelf(void)
elfstr[ElfStrGosymcounts] = addstring(shstrtab, ".gosymcounts");
elfstr[ElfStrGosymtab] = addstring(shstrtab, ".gosymtab");
elfstr[ElfStrGopclntab] = addstring(shstrtab, ".gopclntab");
+ dwarfaddshstrings(shstrtab);
}
elfstr[ElfStrShstrtab] = addstring(shstrtab, ".shstrtab");
@@ -649,8 +651,13 @@ asmb(void)
lputl(symsize);
lputl(lcsize);
cflush();
- }
- else if(dlm){
+ if(!debug['s']) {
+ seek(cout, symo+8+symsize+lcsize, 0);
+ if(debug['v'])
+ Bprint(&bso, "%5.2f dwarf\n", cputime());
+ dwarfemitdebugsections();
+ }
+ } else if(dlm){
seek(cout, HEADR+textsize+datsize, 0);
asmdyn();
cflush();
@@ -1042,6 +1049,8 @@ asmb(void)
sh->size = w;
sh->addralign = 1;
sh->addr = symdatva + 8 + symsize;
+
+ dwarfaddheaders();
}
sh = newElfShstrtab(elfstr[ElfStrShstrtab]);
@@ -1118,6 +1127,13 @@ cflush(void)
cbc = sizeof(buf.cbuf);
}
+/* Current position in file */
+vlong
+cpos(void)
+{
+ return seek(cout, 0, 1) + sizeof(buf.cbuf) - cbc;
+}
+
void
datblk(int32 s, int32 n)
{
diff --git a/src/cmd/8l/l.h b/src/cmd/8l/l.h
index 6473cc5013..32ead12efb 100644
--- a/src/cmd/8l/l.h
+++ b/src/cmd/8l/l.h
@@ -345,6 +345,7 @@ Prog* brloop(Prog*);
void cflush(void);
void ckoff(Sym*, int32);
Prog* copyp(Prog*);
+vlong cpos(void);
double cputime(void);
void datblk(int32, int32);
void diag(char*, ...);
diff --git a/src/cmd/8l/obj.c b/src/cmd/8l/obj.c
index 9067e94707..241b4d6b7f 100644
--- a/src/cmd/8l/obj.c
+++ b/src/cmd/8l/obj.c
@@ -33,6 +33,7 @@
#include "../ld/lib.h"
#include "../ld/elf.h"
#include "../ld/macho.h"
+#include "../ld/dwarf.h"
#include "../ld/pe.h"
#include <ar.h>
@@ -604,6 +605,7 @@ loop:
histfrogp++;
} else
collapsefrog(s);
+ dwarfaddfrag(s->value, s->name);
}
goto loop;
}
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c
index d14fddb50f..e889ef739b 100644
--- a/src/cmd/ld/dwarf.c
+++ b/src/cmd/ld/dwarf.c
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-#include "l.h"
-#include "lib.h"
-#include "../ld/dwarf.h"
-#include "../ld/dwarf_defs.h"
-#include "../ld/elf.h"
+#include "l.h"
+#include "lib.h"
+#include "../ld/dwarf.h"
+#include "../ld/dwarf_defs.h"
+#include "../ld/elf.h"
/*
* Offsets and sizes of the .debug_* sections in the cout file.
@@ -37,8 +37,9 @@ struct DWAttrForm {
// index into the abbrevs table below.
enum
{
- DW_ABRV_NULL,
- DW_ABRV_COMPUNIT,
+ DW_ABRV_NULL,
+ DW_ABRV_COMPUNIT,
+ DW_ABRV_FUNCTION,
DW_NABRV
};
@@ -48,18 +49,26 @@ struct DWAbbrev {
uint8 children;
DWAttrForm attr[30];
} abbrevs[DW_NABRV] = {
- /* The mandatory DW_ABRV_NULL entry. */
- { 0 },
+ /* The mandatory DW_ABRV_NULL entry. */
+ { 0 },
/* COMPUNIT */
{
DW_TAG_compile_unit, DW_CHILDREN_yes,
- DW_AT_name, DW_FORM_string,
- DW_AT_language, DW_FORM_data1,
- DW_AT_low_pc, DW_FORM_addr,
- DW_AT_high_pc, DW_FORM_addr,
- DW_AT_stmt_list, DW_FORM_data4,
- 0, 0
- },
+ DW_AT_name, DW_FORM_string,
+ DW_AT_language, DW_FORM_data1,
+ DW_AT_low_pc, DW_FORM_addr,
+ DW_AT_high_pc, DW_FORM_addr,
+ DW_AT_stmt_list, DW_FORM_data4,
+ 0, 0
+ },
+ /* FUNCTION */
+ {
+ DW_TAG_subprogram, DW_CHILDREN_no,
+ DW_AT_name, DW_FORM_string,
+ DW_AT_low_pc, DW_FORM_addr,
+ DW_AT_high_pc, DW_FORM_addr,
+ 0, 0
+ },
};
/*
@@ -72,19 +81,19 @@ struct DWAbbrev {
typedef struct DWAttr DWAttr;
struct DWAttr {
- DWAttr *link;
- uint8 atr; // DW_AT_
- uint8 cls; // DW_CLS_
- vlong value;
- char *data;
+ DWAttr *link;
+ uint8 atr; // DW_AT_
+ uint8 cls; // DW_CLS_
+ vlong value;
+ char *data;
};
typedef struct DWDie DWDie;
struct DWDie {
- int abbrev;
- DWDie *link;
- DWDie *child;
- DWAttr *attr;
+ int abbrev;
+ DWDie *link;
+ DWDie *child;
+ DWAttr *attr;
};
// top level compilation unit DIE's
@@ -93,33 +102,45 @@ static DWDie *dwinfo;
static DWDie*
newdie(DWDie *link, int abbrev)
{
- DWDie *die;
+ DWDie *die;
- die = mal(sizeof *die);
- die->abbrev = abbrev;
- die->link = link;
- return die;
+ die = mal(sizeof *die);
+ die->abbrev = abbrev;
+ die->link = link;
+ return die;
}
static DWAttr*
newattr(DWDie *die, uint8 attr, int cls, vlong value, char *data)
{
- DWAttr *a;
+ DWAttr *a;
+
+ a = mal(sizeof *a);
+ a->link = die->attr;
+ die->attr = a;
+ a->atr = attr;
+ a->cls = cls;
+ a->value = value;
+ a->data = data;
+ return a;
+}
- a = mal(sizeof *a);
- a->link = die->attr;
- die->attr = a;
- a->atr = attr;
- a->cls = cls;
- a->value = value;
- a->data = data;
- return a;
+static void addrput(vlong addr)
+{
+ switch(PtrSize) {
+ case 4:
+ LPUT(addr);
+ break;
+ case 8:
+ VPUT(addr);
+ break;
+ }
}
static void
uleb128put(uvlong v)
{
- uint8 c;
+ uint8 c;
do {
c = v & 0x7f;
@@ -132,116 +153,116 @@ uleb128put(uvlong v)
static void
sleb128put(vlong v)
{
- uint8 c, s;
+ uint8 c, s;
- do {
- c = v & 0x7f;
- s = c & 0x40;
- v >>= 7;
- if ((v != -1 || !s) && (v != 0 || s))
- c |= 0x80;
- cput(c);
- } while(c & 0x80);
+ do {
+ c = v & 0x7f;
+ s = c & 0x40;
+ v >>= 7;
+ if ((v != -1 || !s) && (v != 0 || s))
+ c |= 0x80;
+ cput(c);
+ } while(c & 0x80);
};
static void
putattr(int form, int cls, vlong value, char *data)
{
- switch(form) {
- case DW_FORM_addr: // address
- VPUT(value);
- break;
+ switch(form) {
+ case DW_FORM_addr: // address
+ addrput(value);
+ break;
- case DW_FORM_block1: // block
- value &= 0xff;
- cput(value);
- while(value--)
- cput(*data++);
- break;
+ case DW_FORM_block1: // block
+ value &= 0xff;
+ cput(value);
+ while(value--)
+ cput(*data++);
+ break;
- case DW_FORM_block2: // block
- value &= 0xffff;
- WPUT(value);
- while(value--)
- cput(*data++);
- break;
+ case DW_FORM_block2: // block
+ value &= 0xffff;
+ WPUT(value);
+ while(value--)
+ cput(*data++);
+ break;
- case DW_FORM_block4: // block
- value &= 0xffffffff;
- LPUT(value);
- while(value--)
- cput(*data++);
- break;
+ case DW_FORM_block4: // block
+ value &= 0xffffffff;
+ LPUT(value);
+ while(value--)
+ cput(*data++);
+ break;
- case DW_FORM_block: // block
- uleb128put(value);
- while(value--)
- cput(*data++);
- break;
+ case DW_FORM_block: // block
+ uleb128put(value);
+ while(value--)
+ cput(*data++);
+ break;
- case DW_FORM_data1: // constant
- cput(value);
- break;
+ case DW_FORM_data1: // constant
+ cput(value);
+ break;
- case DW_FORM_data2: // constant
- WPUT(value);
- break;
+ case DW_FORM_data2: // constant
+ WPUT(value);
+ break;
- case DW_FORM_data4: // constant, lineptr, loclistptr, macptr, rangelistptr
- LPUT(value);
- break;
+ case DW_FORM_data4: // constant, lineptr, loclistptr, macptr, rangelistptr
+ LPUT(value);
+ break;
- case DW_FORM_data8: // constant, lineptr, loclistptr, macptr, rangelistptr
- VPUT(value);
- break;
+ case DW_FORM_data8: // constant, lineptr, loclistptr, macptr, rangelistptr
+ VPUT(value);
+ break;
- case DW_FORM_sdata: // constant
- sleb128put(value);
- break;
+ case DW_FORM_sdata: // constant
+ sleb128put(value);
+ break;
- case DW_FORM_udata: // constant
- uleb128put(value);
- break;
+ case DW_FORM_udata: // constant
+ uleb128put(value);
+ break;
- case DW_FORM_string: // string
- strnput(data, value+1);
- break;
+ case DW_FORM_string: // string
+ strnput(data, value+1);
+ break;
- case DW_FORM_flag: // flag
- cput(value?1:0);
- break;
+ case DW_FORM_flag: // flag
+ cput(value?1:0);
+ break;
- case DW_FORM_strp: // string
- case DW_FORM_ref_addr: // reference
- case DW_FORM_ref1: // reference
- case DW_FORM_ref2: // reference
- case DW_FORM_ref4: // reference
- case DW_FORM_ref8: // reference
- case DW_FORM_ref_udata: // reference
- case DW_FORM_indirect: // (see Section 7.5.3)
- default:
- diag("Unsupported atribute form %d / class %d", form, cls);
- errorexit();
- }
+ case DW_FORM_strp: // string
+ case DW_FORM_ref_addr: // reference
+ case DW_FORM_ref1: // reference
+ case DW_FORM_ref2: // reference
+ case DW_FORM_ref4: // reference
+ case DW_FORM_ref8: // reference
+ case DW_FORM_ref_udata: // reference
+ case DW_FORM_indirect: // (see Section 7.5.3)
+ default:
+ diag("Unsupported atribute form %d / class %d", form, cls);
+ errorexit();
+ }
}
static void
putattrs(int abbrev, DWAttr* attr)
{
- DWAttr *attrs[DW_AT_recursive + 1];
- DWAttrForm* af;
+ DWAttr *attrs[DW_AT_recursive + 1];
+ DWAttrForm* af;
- memset(attrs, 0, sizeof attrs);
- for( ; attr; attr = attr->link)
- attrs[attr->atr] = attr;
- for(af = abbrevs[abbrev].attr; af->attr; af++)
- if (attrs[af->attr])
- putattr(af->form,
- attrs[af->attr]->cls,
- attrs[af->attr]->value,
- attrs[af->attr]->data);
- else
- putattr(af->form, 0, 0, 0);
+ memset(attrs, 0, sizeof attrs);
+ for( ; attr; attr = attr->link)
+ attrs[attr->atr] = attr;
+ for(af = abbrevs[abbrev].attr; af->attr; af++)
+ if (attrs[af->attr])
+ putattr(af->form,
+ attrs[af->attr]->cls,
+ attrs[af->attr]->value,
+ attrs[af->attr]->data);
+ else
+ putattr(af->form, 0, 0, 0);
}
static void putdie(DWDie* die);
@@ -249,35 +270,46 @@ static void putdie(DWDie* die);
static void
putdies(DWDie* die)
{
- for(; die; die = die->link)
- putdie(die);
+ for(; die; die = die->link)
+ putdie(die);
}
static void
putdie(DWDie* die)
{
- uleb128put(die->abbrev);
- putattrs(die->abbrev, die->attr);
- if (abbrevs[die->abbrev].children) {
- putdies(die->child);
- cput(0);
- }
+ uleb128put(die->abbrev);
+ putattrs(die->abbrev, die->attr);
+ if (abbrevs[die->abbrev].children) {
+ putdies(die->child);
+ cput(0);
+ }
}
static void
reverselist(DWDie** list)
{
- DWDie *curr, * prev;
+ DWDie *curr, * prev;
- curr = *list;
- prev = 0;
- while(curr) {
- DWDie* next = curr->link;
- curr->link = prev;
- prev = curr;
- curr = next;
- }
- *list = prev;
+ curr = *list;
+ prev = 0;
+ while(curr) {
+ DWDie* next = curr->link;
+ curr->link = prev;
+ prev = curr;
+ curr = next;
+ }
+ *list = prev;
+}
+
+static void
+reversetree(DWDie** list)
+{
+ DWDie *die;
+
+ reverselist(list);
+ if (*list != nil && abbrevs[(*list)->abbrev].children)
+ for (die = *list; die != nil; die = die->link)
+ reversetree(&die->child);
}
/*
@@ -290,7 +322,7 @@ static int ftabsize;
void
dwarfaddfrag(int n, char *frag)
{
- int s;
+ int s;
if (n >= ftabsize) {
s = ftabsize;
@@ -308,19 +340,19 @@ dwarfaddfrag(int n, char *frag)
static char *
decodez(char *s)
{
- int len, o;
- char *ss, *f;
- char *r, *rb, *re;
+ int len, o;
+ char *ss, *f;
+ char *r, *rb, *re;
len = 0;
ss = s + 1; // first is 0
- while((o = ((uint8)ss[0] << 8) | (uint8)ss[1]) != 0) {
+ while((o = ((uint8)ss[0] << 8) | (uint8)ss[1]) != 0) {
if (o < 0 || o >= ftabsize) {
diag("corrupt z entry");
return 0;
}
f = ftab[o];
- if (!f) {
+ if (f == nil) {
diag("corrupt z entry");
return 0;
}
@@ -351,60 +383,60 @@ decodez(char *s)
* The line history itself
*/
-static char **histfile; // [0] holds the empty string.
+static char **histfile; // [0] holds the empty string.
static int histfilesize;
static int histfilecap;
static void
clearhistfile(void)
{
- int i;
+ int i;
- // [0] holds the empty string.
- for (i = 1; i < histfilesize; i++)
- free(histfile[i]);
- histfilesize = 0;
+ // [0] holds the empty string.
+ for (i = 1; i < histfilesize; i++)
+ free(histfile[i]);
+ histfilesize = 0;
}
static int
addhistfile(char *zentry)
{
- char *fname;
+ char *fname;
- if (histfilesize == histfilecap) {
- histfilecap = 2 * histfilecap + 2;
- histfile = realloc(histfile, histfilecap * sizeof(char*));
- }
- if (histfilesize == 0)
- histfile[histfilesize++] = "<eof>";
+ if (histfilesize == histfilecap) {
+ histfilecap = 2 * histfilecap + 2;
+ histfile = realloc(histfile, histfilecap * sizeof(char*));
+ }
+ if (histfilesize == 0)
+ histfile[histfilesize++] = "<eof>";
- fname = decodez(zentry);
- if (fname == 0)
- return -1;
- // Don't fill with duplicates (check only top one).
- if (strcmp(fname, histfile[histfilesize-1]) == 0) {
- free(fname);
- return histfilesize - 1;
- }
- histfile[histfilesize++] = fname;
- return histfilesize - 1;
+ fname = decodez(zentry);
+ if (fname == 0)
+ return -1;
+ // Don't fill with duplicates (check only top one).
+ if (strcmp(fname, histfile[histfilesize-1]) == 0) {
+ free(fname);
+ return histfilesize - 1;
+ }
+ histfile[histfilesize++] = fname;
+ return histfilesize - 1;
}
// Go's runtime C sources are sane, and Go sources nest only 1 level,
// so 16 should be plenty.
static struct {
- int file;
- vlong line;
+ int file;
+ vlong line;
} includestack[16];
static int includetop;
static vlong absline;
typedef struct Linehist Linehist;
struct Linehist {
- Linehist *link;
- vlong absline;
- vlong line;
- int file;
+ Linehist *link;
+ vlong absline;
+ vlong line;
+ int file;
};
static Linehist *linehist;
@@ -412,101 +444,101 @@ static Linehist *linehist;
static void
checknesting(void)
{
- int i;
+ int i;
- if (includetop < 0) {
- diag("corrupt z stack");
- errorexit();
- }
- if (includetop >= nelem(includestack)) {
- diag("nesting too deep");
- for (i = 0; i < nelem(includestack); i++)
- diag("\t%s", histfile[includestack[i].file]);
- errorexit();
- }
+ if (includetop < 0) {
+ diag("corrupt z stack");
+ errorexit();
+ }
+ if (includetop >= nelem(includestack)) {
+ diag("nesting too deep");
+ for (i = 0; i < nelem(includestack); i++)
+ diag("\t%s", histfile[includestack[i].file]);
+ errorexit();
+ }
}
/* find z and Z entries in the Auto list (of a Prog), and reset the history stack */
static char *
inithist(Auto *a)
{
- char *unitname;
- Linehist *lh;
+ char *unitname;
+ Linehist *lh;
for (; a; a = a->link)
if (a->type == D_FILE)
- break;
- if (a==nil)
- return 0;
+ break;
+ if (a==nil)
+ return 0;
- // 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);
- return 0;
- }
+ // 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);
+ return 0;
+ }
- unitname = decodez(a->asym->name);
+ unitname = decodez(a->asym->name);
- // Clear the history.
- clearhistfile();
- includetop = 0;
- includestack[includetop].file = 0;
- includestack[includetop].line = -1;
- absline = 0;
- while (linehist != nil) {
- lh = linehist->link;
- free(linehist);
- linehist = lh;
- }
+ // Clear the history.
+ clearhistfile();
+ includetop = 0;
+ includestack[includetop].file = 0;
+ includestack[includetop].line = -1;
+ absline = 0;
+ while (linehist != nil) {
+ lh = linehist->link;
+ free(linehist);
+ linehist = lh;
+ }
- // Construct the new one.
- for (; a; a = a->link) {
- if (a->type == D_FILE) { // 'z'
- int f = addhistfile(a->asym->name);
- if (f < 0) { // pop file
- includetop--;
- checknesting();
- } else if(f != includestack[includetop].file) { // pushed a new file
- includestack[includetop].line += a->aoffset - absline;
- includetop++;
- checknesting();
- includestack[includetop].file = f;
- includestack[includetop].line = 1;
+ // Construct the new one.
+ for (; a; a = a->link) {
+ if (a->type == D_FILE) { // 'z'
+ int f = addhistfile(a->asym->name);
+ if (f < 0) { // pop file
+ includetop--;
+ checknesting();
+ } else if(f != includestack[includetop].file) { // pushed a new file
+ includestack[includetop].line += a->aoffset - absline;
+ includetop++;
+ checknesting();
+ includestack[includetop].file = f;
+ includestack[includetop].line = 1;
- }
- absline = a->aoffset;
- } else if (a->type == D_FILE1) { // 'Z'
- // We could just fixup the current
- // linehist->line, but there doesn't appear to
- // be a guarantee that every 'Z' is preceded
- // by it's own 'z', so do the safe thing and
- // update the stack and push a new Linehist
- // entry
- includestack[includetop].line = a->aoffset;
- } else
- continue;
- if (linehist == 0 || linehist->absline != absline) {
- Linehist* lh = malloc(sizeof *lh);
- lh->link = linehist;
- lh->absline = absline;
- linehist = lh;
- }
- linehist->file = includestack[includetop].file;
- linehist->line = includestack[includetop].line;
- }
- return unitname;
+ }
+ absline = a->aoffset;
+ } else if (a->type == D_FILE1) { // 'Z'
+ // We could just fixup the current
+ // linehist->line, but there doesn't appear to
+ // be a guarantee that every 'Z' is preceded
+ // by it's own 'z', so do the safe thing and
+ // update the stack and push a new Linehist
+ // entry
+ includestack[includetop].line = a->aoffset;
+ } else
+ continue;
+ if (linehist == 0 || linehist->absline != absline) {
+ Linehist* lh = malloc(sizeof *lh);
+ lh->link = linehist;
+ lh->absline = absline;
+ linehist = lh;
+ }
+ linehist->file = includestack[includetop].file;
+ linehist->line = includestack[includetop].line;
+ }
+ return unitname;
}
static Linehist *
searchhist(vlong absline)
{
- Linehist *lh;
+ Linehist *lh;
- for (lh = linehist; lh; lh = lh->link)
- if (lh->absline <= absline)
- break;
- return lh;
+ for (lh = linehist; lh; lh = lh->link)
+ if (lh->absline <= absline)
+ break;
+ return lh;
}
static void
@@ -516,7 +548,7 @@ writeabbrev(void)
abbrevo = cpos();
for (i = 1; i < DW_NABRV; i++) {
- // See section 7.5.3
+ // See section 7.5.3
uleb128put(i);
uleb128put(abbrevs[i].tag);
cput(abbrevs[i].children);
@@ -526,7 +558,7 @@ writeabbrev(void)
strnput((char *) abbrevs[i].attr,
(n + 1) * sizeof(DWAttrForm));
}
- cput(0);
+ cput(0);
abbrevsize = cpos() - abbrevo;
}
@@ -534,10 +566,10 @@ writeabbrev(void)
static int
guesslang(char *s)
{
- if(strlen(s) >= 3 && strcmp(s+strlen(s)-3, ".go") == 0)
- return DW_LANG_Go;
+ if(strlen(s) >= 3 && strcmp(s+strlen(s)-3, ".go") == 0)
+ return DW_LANG_Go;
- return DW_LANG_C;
+ return DW_LANG_C;
}
/*
@@ -546,30 +578,30 @@ guesslang(char *s)
*/
enum {
- LINE_BASE = -1,
- LINE_RANGE = 4,
- OPCODE_BASE = 5
+ LINE_BASE = -1,
+ LINE_RANGE = 4,
+ OPCODE_BASE = 5
};
static void
putpclcdelta(vlong delta_pc, vlong delta_lc)
{
- if (LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE) {
- vlong opcode = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc);
- if (OPCODE_BASE <= opcode && opcode < 256) {
- cput(opcode);
- return;
- }
- }
+ if (LINE_BASE <= delta_lc && delta_lc < LINE_BASE+LINE_RANGE) {
+ vlong opcode = OPCODE_BASE + (delta_lc - LINE_BASE) + (LINE_RANGE * delta_pc);
+ if (OPCODE_BASE <= opcode && opcode < 256) {
+ cput(opcode);
+ return;
+ }
+ }
- if (delta_pc) {
- cput(DW_LNS_advance_pc);
- sleb128put(delta_pc);
- }
+ if (delta_pc) {
+ cput(DW_LNS_advance_pc);
+ sleb128put(delta_pc);
+ }
- cput(DW_LNS_advance_line);
- sleb128put(delta_lc);
- cput(DW_LNS_copy);
+ cput(DW_LNS_advance_line);
+ sleb128put(delta_lc);
+ cput(DW_LNS_copy);
}
@@ -581,132 +613,143 @@ putpclcdelta(vlong delta_pc, vlong delta_lc)
static void
flushunit(vlong pc, vlong unitstart)
{
- vlong here;
+ vlong here;
- if (dwinfo != 0 && pc != 0) {
- newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc, 0);
- }
+ if (dwinfo != 0 && pc != 0) {
+ newattr(dwinfo, DW_AT_high_pc, DW_CLS_ADDRESS, pc, 0);
+ }
- if (unitstart >= 0) {
- cput(0); // start extended opcode
- uleb128put(1);
- cput(DW_LNE_end_sequence);
- cflush();
+ if (unitstart >= 0) {
+ cput(0); // start extended opcode
+ uleb128put(1);
+ cput(DW_LNE_end_sequence);
+ cflush();
- here = cpos();
- seek(cout, unitstart, 0);
- LPUT(here - unitstart - sizeof(int32));
- cflush();
- seek(cout, here, 0);
- }
+ here = cpos();
+ seek(cout, unitstart, 0);
+ LPUT(here - unitstart - sizeof(int32));
+ cflush();
+ seek(cout, here, 0);
+ }
}
static void
writelines(void)
{
- Prog *p, *q;
- Sym *s;
- char *unitname;
- vlong unitstart;
- vlong pc, lc, llc, lline;
- int currfile;
- int i;
- Linehist *lh;
+ Prog *p, *q;
+ Sym *s;
+ char *unitname;
+ vlong unitstart;
+ vlong pc, lc, llc, lline;
+ int currfile;
+ int i;
+ Linehist *lh;
- unitstart = -1;
- pc = 0;
- lc = 1;
- llc = 1;
- currfile = -1;
- lineo = cpos();
+ unitstart = -1;
+ pc = 0;
+ lc = 1;
+ llc = 1;
+ currfile = -1;
+ lineo = cpos();
- for (p = textp; p != P; p = p->pcond) {
+ for (p = textp; p != P; p = p->pcond) {
s = p->from.sym;
if (s == nil || s->type != STEXT) {
- diag("->pcond was supposed to loop over STEXT: %P", p);
- continue;
- }
+ diag("->pcond was supposed to loop over STEXT: %P", p);
+ continue;
+ }
+
+ // Look for history stack. If we find one,
+ // we're entering a new compilation unit
+ if ((unitname = inithist(p->to.autom)) != 0) {
+ flushunit(pc, unitstart);
+ unitstart = cpos();
+ if(debug['v'] > 1) {
+ print("dwarf writelines found %s\n", unitname);
+ Linehist* lh;
+ for (lh = linehist; lh; lh = lh->link)
+ print("\t%8lld: [%4lld]%s\n",
+ lh->absline, lh->line, histfile[lh->file]);
+ }
+ dwinfo = newdie(dwinfo, DW_ABRV_COMPUNIT);
+ newattr(dwinfo, DW_AT_name, DW_CLS_STRING, strlen(unitname), unitname);
+ newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT, guesslang(unitname), 0);
+ newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart - lineo, 0);
+ newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, p->pc, 0);
+ // 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.
+ WPUT(3); // version
+ LPUT(11); // header_length (*)
+ cput(1); // minimum_instruction_length
+ cput(1); // default_is_stmt
+ cput(LINE_BASE); // line_base
+ cput(LINE_RANGE); // line_range
+ cput(OPCODE_BASE); // opcode_base (we only use 1..4)
+ cput(0); // standard_opcode_lengths[1]
+ cput(1); // standard_opcode_lengths[2]
+ 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)
+ 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.
+ }
- // Look for history stack. If we find one,
- // we're entering a new compilation unit
- if ((unitname = inithist(p->to.autom)) != 0) {
- flushunit(pc, unitstart);
- unitstart = cpos();
- if(debug['v'] > 1) {
- print("dwarf writelines found %s\n", unitname);
- Linehist* lh;
- for (lh = linehist; lh; lh = lh->link)
- print("\t%8lld: [%4lld]%s\n",
- lh->absline, lh->line, histfile[lh->file]);
- }
- dwinfo = newdie(dwinfo, DW_ABRV_COMPUNIT);
- newattr(dwinfo, DW_AT_name, DW_CLS_STRING, strlen(unitname), unitname);
- newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT, guesslang(unitname), 0);
- newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart - lineo, 0);
- newattr(dwinfo, DW_AT_low_pc, DW_CLS_ADDRESS, p->pc, 0);
- // 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.
- WPUT(3); // version
- LPUT(11); // header_length (*)
- cput(1); // minimum_instruction_length
- cput(1); // default_is_stmt
- cput(LINE_BASE); // line_base
- cput(LINE_RANGE); // line_range
- cput(OPCODE_BASE); // opcode_base (we only use 1..4)
- cput(0); // standard_opcode_lengths[1]
- cput(1); // standard_opcode_lengths[2]
- 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)
- 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.
- }
- pc = p->pc;
- currfile = 1;
- lc = 1;
- llc = 1;
- cput(0); // start extended opcode
- uleb128put(1 + sizeof pc);
- cput(DW_LNE_set_address);
- VPUT(pc);
- }
- if (!p->from.sym->reachable)
- continue;
- if (unitstart < 0) {
- diag("Reachable code before seeing any history: %P", p);
- continue;
- }
- for(q = p; q != P && (q == p || q->as != ATEXT); q = q->link) {
- lh = searchhist(q->line);
- if (!lh) {
- diag("corrupt history or bad absolute line: %P", q);
- continue;
- }
- lline = lh->line + q->line - lh->absline;
- if (debug['v'] > 1)
- print("%6llux %s[%lld] %P\n", q->pc, histfile[lh->file], lline, q);
- // Only emit a line program statement if line has changed.
- if (q->line == lc)
- continue;
- if (currfile != lh->file) {
- currfile = lh->file;
- cput(DW_LNS_set_file);
- uleb128put(currfile);
- }
- putpclcdelta(q->pc - pc, lline - llc);
- pc = q->pc;
- lc = q->line;
- llc = lline;
- }
- }
- flushunit(pc, unitstart);
- linesize = cpos() - lineo;
+ pc = p->pc;
+ currfile = 1;
+ lc = 1;
+ llc = 1;
+
+ cput(0); // start extended opcode
+ uleb128put(1 + PtrSize);
+ cput(DW_LNE_set_address);
+ addrput(pc);
+ }
+ if (!p->from.sym->reachable)
+ continue;
+ if (unitstart < 0) {
+ diag("reachable code before seeing any history: %P", p);
+ continue;
+ }
+
+ dwinfo->child = newdie(dwinfo->child, DW_ABRV_FUNCTION);
+ newattr(dwinfo->child, DW_AT_name, DW_CLS_STRING, strlen(s->name), s->name);
+ newattr(dwinfo->child, DW_AT_low_pc, DW_CLS_ADDRESS, p->pc, 0);
+ if (debug['v'] > 1)
+ print("frame offset: %d\n", p->to.offset);
+// newattr(dwinfo->child, DW_AT_return_addr, DW_CLS_BLOCK, p->to.offset, 0);
+
+ for(q = p; q != P && (q == p || q->as != ATEXT); q = q->link) {
+ lh = searchhist(q->line);
+ if (lh == nil) {
+ diag("corrupt history or bad absolute line: %P", q);
+ continue;
+ }
+ lline = lh->line + q->line - lh->absline;
+ if (debug['v'] > 1)
+ print("%6llux %s[%lld] %P\n", q->pc, histfile[lh->file], lline, q);
+ // Only emit a line program statement if line has changed.
+ if (q->line == lc)
+ continue;
+ if (currfile != lh->file) {
+ currfile = lh->file;
+ cput(DW_LNS_set_file);
+ uleb128put(currfile);
+ }
+ putpclcdelta(q->pc - pc, lline - llc);
+ pc = q->pc;
+ lc = q->line;
+ llc = lline;
+ }
+ newattr(dwinfo->child, DW_AT_high_pc, DW_CLS_ADDRESS, pc, 0);
+ }
+ flushunit(pc, unitstart);
+ linesize = cpos() - lineo;
}
/*
@@ -715,41 +758,42 @@ writelines(void)
static void
writeinfo(void)
{
- DWDie *compunit;
- vlong unitstart;
+ DWDie *compunit;
+ vlong unitstart;
- reverselist(&dwinfo);
+ reversetree(&dwinfo);
- infoo = cpos();
+ infoo = cpos();
- for (compunit = dwinfo; compunit; compunit = compunit->link) {
- unitstart = cpos();
+ for (compunit = dwinfo; compunit; compunit = compunit->link) {
+ unitstart = cpos();
- // Write .debug_info Compilation Unit Header (sec 7.5.1)
- // Fields marked with (*) must be changed for 64-bit dwarf
- LPUT(0); // unit_length (*), will be filled in later.
- WPUT(3); // version
- LPUT(0); // debug_abbrev_offset (*)
- cput(8); // address_size
+ // Write .debug_info Compilation Unit Header (sec 7.5.1)
+ // Fields marked with (*) must be changed for 64-bit dwarf
+ LPUT(0); // unit_length (*), will be filled in later.
+ WPUT(3); // version
+ LPUT(0); // debug_abbrev_offset (*)
+ cput(PtrSize); // address_size
- putdie(compunit);
+ putdie(compunit);
- cflush();
- vlong here = cpos();
- seek(cout, unitstart, 0);
- LPUT(here - unitstart - sizeof(int32));
- cflush();
- seek(cout, here, 0);
- }
+ cflush();
+ vlong here = cpos();
+ seek(cout, unitstart, 0);
+ LPUT(here - unitstart - sizeof(int32));
+ cflush();
+ seek(cout, here, 0);
+ }
- cflush();
- infosize = cpos() - infoo;
+ cflush();
+ infosize = cpos() - infoo;
}
/*
* Elf sections.
*/
-enum {
+enum
+{
ElfStrDebugAbbrev,
ElfStrDebugAranges,
ElfStrDebugFrame,