mirror of
https://github.com/golang/go
synced 2024-11-23 07:50:05 -07:00
cmd/ld: fix bad merge
CL 7504044 accidentally reverted part of CL 7891044 and 7552045, this CL bring those part back. R=golang-dev TBR=rsc CC=golang-dev https://golang.org/cl/7950045
This commit is contained in:
parent
ec8caf696a
commit
f74b4d3de3
@ -41,9 +41,13 @@ static vlong arangeso;
|
|||||||
static vlong arangessize;
|
static vlong arangessize;
|
||||||
static vlong gdbscripto;
|
static vlong gdbscripto;
|
||||||
static vlong gdbscriptsize;
|
static vlong gdbscriptsize;
|
||||||
|
static vlong inforeloco;
|
||||||
|
static vlong inforelocsize;
|
||||||
|
|
||||||
static char gdbscript[1024];
|
static char gdbscript[1024];
|
||||||
|
|
||||||
|
static Sym *dsym;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Basic I/O
|
* Basic I/O
|
||||||
*/
|
*/
|
||||||
@ -485,26 +489,43 @@ mkindex(DWDie *die)
|
|||||||
die->hash = mal(HASHSIZE * sizeof(DWDie*));
|
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
|
// Find child by AT_name using hashtable if available or linear scan
|
||||||
// if not.
|
// if not.
|
||||||
static DWDie*
|
static DWDie*
|
||||||
find(DWDie *die, char* name)
|
find(DWDie *die, char* name)
|
||||||
{
|
{
|
||||||
DWDie *a, *b;
|
DWDie *a, *b, *die2;
|
||||||
int h;
|
int h;
|
||||||
|
|
||||||
|
top:
|
||||||
if (die->hash == nil) {
|
if (die->hash == nil) {
|
||||||
for (a = die->child; a != nil; a = a->link)
|
for (a = die->child; a != nil; a = a->link)
|
||||||
if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
|
if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
|
||||||
return a;
|
return a;
|
||||||
return nil;
|
goto notfound;
|
||||||
}
|
}
|
||||||
|
|
||||||
h = hashstr(name);
|
h = hashstr(name);
|
||||||
a = die->hash[h];
|
a = die->hash[h];
|
||||||
|
|
||||||
if (a == nil)
|
if (a == nil)
|
||||||
return nil;
|
goto notfound;
|
||||||
|
|
||||||
|
|
||||||
if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
|
if (strcmp(name, getattr(a, DW_AT_name)->data) == 0)
|
||||||
@ -522,6 +543,14 @@ find(DWDie *die, char* name)
|
|||||||
a = b;
|
a = b;
|
||||||
b = b->hlink;
|
b = b->hlink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
notfound:
|
||||||
|
die2 = walktypedef(die);
|
||||||
|
if(die2 != die) {
|
||||||
|
die = die2;
|
||||||
|
goto top;
|
||||||
|
}
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,7 +560,7 @@ find_or_diag(DWDie *die, char* name)
|
|||||||
DWDie *r;
|
DWDie *r;
|
||||||
r = find(die, name);
|
r = find(die, name);
|
||||||
if (r == nil) {
|
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();
|
errorexit();
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
@ -548,14 +577,33 @@ newrefattr(DWDie *die, uint8 attr, DWDie* ref)
|
|||||||
static int fwdcount;
|
static int fwdcount;
|
||||||
|
|
||||||
static void
|
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) {
|
switch(form) {
|
||||||
case DW_FORM_addr: // address
|
case DW_FORM_addr: // address
|
||||||
addrput(value);
|
addrput(value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_block1: // block
|
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;
|
value &= 0xff;
|
||||||
cput(value);
|
cput(value);
|
||||||
while(value--)
|
while(value--)
|
||||||
@ -615,13 +663,23 @@ putattr(int form, int cls, vlong value, char *data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_FORM_ref_addr: // reference to a DIE in the .info section
|
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) {
|
if (data == nil) {
|
||||||
diag("dwarf: null reference");
|
diag("dwarf: null reference in %d", abbrev);
|
||||||
LPUT(0); // invalid dwarf, gdb will complain.
|
if(PtrSize == 8)
|
||||||
|
VPUT(0); // invalid dwarf, gdb will complain.
|
||||||
|
else
|
||||||
|
LPUT(0); // invalid dwarf, gdb will complain.
|
||||||
} else {
|
} else {
|
||||||
if (((DWDie*)data)->offs == 0)
|
if (((DWDie*)data)->offs == 0)
|
||||||
fwdcount++;
|
fwdcount++;
|
||||||
LPUT(((DWDie*)data)->offs);
|
if(PtrSize == 8)
|
||||||
|
VPUT(((DWDie*)data)->offs);
|
||||||
|
else
|
||||||
|
LPUT(((DWDie*)data)->offs);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -654,12 +712,12 @@ putattrs(int abbrev, DWAttr* attr)
|
|||||||
|
|
||||||
for(af = abbrevs[abbrev].attr; af->attr; af++)
|
for(af = abbrevs[abbrev].attr; af->attr; af++)
|
||||||
if (attrs[af->attr])
|
if (attrs[af->attr])
|
||||||
putattr(af->form,
|
putattr(abbrev, af->form,
|
||||||
attrs[af->attr]->cls,
|
attrs[af->attr]->cls,
|
||||||
attrs[af->attr]->value,
|
attrs[af->attr]->value,
|
||||||
attrs[af->attr]->data);
|
attrs[af->attr]->data);
|
||||||
else
|
else
|
||||||
putattr(af->form, 0, 0, 0);
|
putattr(abbrev, af->form, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void putdie(DWDie* die);
|
static void putdie(DWDie* die);
|
||||||
@ -729,16 +787,9 @@ newmemberoffsetattr(DWDie *die, int32 offs)
|
|||||||
// GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
|
// GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
|
||||||
// location expression that evals to a const.
|
// location expression that evals to a const.
|
||||||
static void
|
static void
|
||||||
newabslocexprattr(DWDie *die, vlong addr)
|
newabslocexprattr(DWDie *die, vlong addr, Sym *sym)
|
||||||
{
|
{
|
||||||
char block[10];
|
newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, (char*)sym);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -766,6 +817,31 @@ lookup_or_diag(char *n)
|
|||||||
return s;
|
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.
|
// Define gotype, for composite ones recurse into constituents.
|
||||||
static DWDie*
|
static DWDie*
|
||||||
defgotype(Sym *gotype)
|
defgotype(Sym *gotype)
|
||||||
@ -840,6 +916,7 @@ defgotype(Sym *gotype)
|
|||||||
|
|
||||||
case KindArray:
|
case KindArray:
|
||||||
die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name);
|
die = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, name);
|
||||||
|
dotypedef(&dwtypes, name, die);
|
||||||
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
|
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
|
||||||
s = decodetype_arrayelem(gotype);
|
s = decodetype_arrayelem(gotype);
|
||||||
newrefattr(die, DW_AT_type, defgotype(s));
|
newrefattr(die, DW_AT_type, defgotype(s));
|
||||||
@ -857,6 +934,7 @@ defgotype(Sym *gotype)
|
|||||||
|
|
||||||
case KindFunc:
|
case KindFunc:
|
||||||
die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name);
|
die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name);
|
||||||
|
dotypedef(&dwtypes, name, die);
|
||||||
newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "void"));
|
newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "void"));
|
||||||
nfields = decodetype_funcincount(gotype);
|
nfields = decodetype_funcincount(gotype);
|
||||||
for (i = 0; i < nfields; i++) {
|
for (i = 0; i < nfields; i++) {
|
||||||
@ -876,6 +954,7 @@ defgotype(Sym *gotype)
|
|||||||
|
|
||||||
case KindInterface:
|
case KindInterface:
|
||||||
die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name);
|
die = newdie(&dwtypes, DW_ABRV_IFACETYPE, name);
|
||||||
|
dotypedef(&dwtypes, name, die);
|
||||||
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
|
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
|
||||||
nfields = decodetype_ifacemethodcount(gotype);
|
nfields = decodetype_ifacemethodcount(gotype);
|
||||||
if (nfields == 0)
|
if (nfields == 0)
|
||||||
@ -895,12 +974,14 @@ defgotype(Sym *gotype)
|
|||||||
|
|
||||||
case KindPtr:
|
case KindPtr:
|
||||||
die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name);
|
die = newdie(&dwtypes, DW_ABRV_PTRTYPE, name);
|
||||||
|
dotypedef(&dwtypes, name, die);
|
||||||
s = decodetype_ptrelem(gotype);
|
s = decodetype_ptrelem(gotype);
|
||||||
newrefattr(die, DW_AT_type, defgotype(s));
|
newrefattr(die, DW_AT_type, defgotype(s));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KindSlice:
|
case KindSlice:
|
||||||
die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name);
|
die = newdie(&dwtypes, DW_ABRV_SLICETYPE, name);
|
||||||
|
dotypedef(&dwtypes, name, die);
|
||||||
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
|
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
|
||||||
s = decodetype_arrayelem(gotype);
|
s = decodetype_arrayelem(gotype);
|
||||||
newrefattr(die, DW_AT_internal_elem_type, defgotype(s));
|
newrefattr(die, DW_AT_internal_elem_type, defgotype(s));
|
||||||
@ -913,6 +994,7 @@ defgotype(Sym *gotype)
|
|||||||
|
|
||||||
case KindStruct:
|
case KindStruct:
|
||||||
die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name);
|
die = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, name);
|
||||||
|
dotypedef(&dwtypes, name, die);
|
||||||
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
|
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
|
||||||
nfields = decodetype_structfieldcount(gotype);
|
nfields = decodetype_structfieldcount(gotype);
|
||||||
for (i = 0; i < nfields; i++) {
|
for (i = 0; i < nfields; i++) {
|
||||||
@ -998,7 +1080,7 @@ synthesizestringtypes(DWDie* die)
|
|||||||
{
|
{
|
||||||
DWDie *prototype;
|
DWDie *prototype;
|
||||||
|
|
||||||
prototype = defgotype(lookup_or_diag("type.runtime._string"));
|
prototype = walktypedef(defgotype(lookup_or_diag("type.runtime._string")));
|
||||||
if (prototype == nil)
|
if (prototype == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1014,7 +1096,7 @@ synthesizeslicetypes(DWDie *die)
|
|||||||
{
|
{
|
||||||
DWDie *prototype, *elem;
|
DWDie *prototype, *elem;
|
||||||
|
|
||||||
prototype = defgotype(lookup_or_diag("type.runtime.slice"));
|
prototype = walktypedef(defgotype(lookup_or_diag("type.runtime.slice")));
|
||||||
if (prototype == nil)
|
if (prototype == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1082,9 +1164,9 @@ synthesizechantypes(DWDie *die)
|
|||||||
DWAttr *a;
|
DWAttr *a;
|
||||||
int elemsize, sudogsize;
|
int elemsize, sudogsize;
|
||||||
|
|
||||||
sudog = defgotype(lookup_or_diag("type.runtime.sudog"));
|
sudog = walktypedef(defgotype(lookup_or_diag("type.runtime.sudog")));
|
||||||
waitq = defgotype(lookup_or_diag("type.runtime.waitq"));
|
waitq = walktypedef(defgotype(lookup_or_diag("type.runtime.waitq")));
|
||||||
hchan = defgotype(lookup_or_diag("type.runtime.hchan"));
|
hchan = walktypedef(defgotype(lookup_or_diag("type.runtime.hchan")));
|
||||||
if (sudog == nil || waitq == nil || hchan == nil)
|
if (sudog == nil || waitq == nil || hchan == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1153,7 +1235,7 @@ defdwsymb(Sym* sym, char *s, int t, vlong v, vlong size, int ver, Sym *gotype)
|
|||||||
case 'D':
|
case 'D':
|
||||||
case 'B':
|
case 'B':
|
||||||
dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s);
|
dv = newdie(&dwglobals, DW_ABRV_VARIABLE, s);
|
||||||
newabslocexprattr(dv, v);
|
newabslocexprattr(dv, v, sym);
|
||||||
if (ver == 0)
|
if (ver == 0)
|
||||||
newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0);
|
newattr(dv, DW_AT_external, DW_CLS_FLAG, 1, 0);
|
||||||
// fallthrough
|
// fallthrough
|
||||||
@ -1514,12 +1596,12 @@ mkvarname(char* name, int da)
|
|||||||
|
|
||||||
// flush previous compilation unit.
|
// flush previous compilation unit.
|
||||||
static void
|
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;
|
vlong here;
|
||||||
|
|
||||||
if (dwinfo != nil && pc != 0) {
|
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) {
|
if (unitstart >= 0) {
|
||||||
@ -1530,7 +1612,7 @@ flushunit(DWDie *dwinfo, vlong pc, vlong unitstart, int32 header_length)
|
|||||||
here = cpos();
|
here = cpos();
|
||||||
cseek(unitstart);
|
cseek(unitstart);
|
||||||
LPUT(here - unitstart - sizeof(int32)); // unit_length
|
LPUT(here - unitstart - sizeof(int32)); // unit_length
|
||||||
WPUT(3); // dwarf version
|
WPUT(2); // dwarf version
|
||||||
LPUT(header_length); // header length starting here
|
LPUT(header_length); // header length starting here
|
||||||
cseek(here);
|
cseek(here);
|
||||||
}
|
}
|
||||||
@ -1540,7 +1622,7 @@ static void
|
|||||||
writelines(void)
|
writelines(void)
|
||||||
{
|
{
|
||||||
Prog *q;
|
Prog *q;
|
||||||
Sym *s;
|
Sym *s, *epcs;
|
||||||
Auto *a;
|
Auto *a;
|
||||||
vlong unitstart, headerend, offs;
|
vlong unitstart, headerend, offs;
|
||||||
vlong pc, epc, lc, llc, lline;
|
vlong pc, epc, lc, llc, lline;
|
||||||
@ -1555,6 +1637,7 @@ writelines(void)
|
|||||||
headerend = -1;
|
headerend = -1;
|
||||||
pc = 0;
|
pc = 0;
|
||||||
epc = 0;
|
epc = 0;
|
||||||
|
epcs = S;
|
||||||
lc = 1;
|
lc = 1;
|
||||||
llc = 1;
|
llc = 1;
|
||||||
currfile = -1;
|
currfile = -1;
|
||||||
@ -1570,7 +1653,7 @@ writelines(void)
|
|||||||
// we're entering a new compilation unit
|
// we're entering a new compilation unit
|
||||||
|
|
||||||
if (inithist(s->autom)) {
|
if (inithist(s->autom)) {
|
||||||
flushunit(dwinfo, epc, unitstart, headerend - unitstart - 10);
|
flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
|
||||||
unitstart = cpos();
|
unitstart = cpos();
|
||||||
|
|
||||||
if(debug['v'] > 1) {
|
if(debug['v'] > 1) {
|
||||||
@ -1587,12 +1670,12 @@ writelines(void)
|
|||||||
dwinfo = newdie(&dwroot, DW_ABRV_COMPUNIT, estrdup(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_language, DW_CLS_CONSTANT,lang, 0);
|
||||||
newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart - lineo, 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)
|
// Write .debug_line Line Number Program Header (sec 6.2.4)
|
||||||
// Fields marked with (*) must be changed for 64-bit dwarf
|
// Fields marked with (*) must be changed for 64-bit dwarf
|
||||||
LPUT(0); // unit_length (*), will be filled in by flushunit.
|
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.
|
LPUT(0); // header_length (*), filled in by flushunit.
|
||||||
// cpos == unitstart + 4 + 2 + 4
|
// cpos == unitstart + 4 + 2 + 4
|
||||||
cput(1); // minimum_instruction_length
|
cput(1); // minimum_instruction_length
|
||||||
@ -1616,6 +1699,7 @@ writelines(void)
|
|||||||
|
|
||||||
pc = s->text->pc;
|
pc = s->text->pc;
|
||||||
epc = pc;
|
epc = pc;
|
||||||
|
epcs = s;
|
||||||
currfile = 1;
|
currfile = 1;
|
||||||
lc = 1;
|
lc = 1;
|
||||||
llc = 1;
|
llc = 1;
|
||||||
@ -1634,9 +1718,9 @@ writelines(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dwfunc = newdie(dwinfo, DW_ABRV_FUNCTION, s->name);
|
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;
|
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)
|
if (s->version == 0)
|
||||||
newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0);
|
newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0);
|
||||||
|
|
||||||
@ -1718,7 +1802,7 @@ writelines(void)
|
|||||||
dwfunc->hash = nil;
|
dwfunc->hash = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
flushunit(dwinfo, epc, unitstart, headerend - unitstart - 10);
|
flushunit(dwinfo, epc, epcs, unitstart, headerend - unitstart - 10);
|
||||||
linesize = cpos() - lineo;
|
linesize = cpos() - lineo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1842,6 +1926,9 @@ writeinfo(void)
|
|||||||
vlong unitstart, here;
|
vlong unitstart, here;
|
||||||
|
|
||||||
fwdcount = 0;
|
fwdcount = 0;
|
||||||
|
if (dsym == S)
|
||||||
|
dsym = lookup(".dwarfinfo", 0);
|
||||||
|
dsym->nr = 0;
|
||||||
|
|
||||||
for (compunit = dwroot.child; compunit; compunit = compunit->link) {
|
for (compunit = dwroot.child; compunit; compunit = compunit->link) {
|
||||||
unitstart = cpos();
|
unitstart = cpos();
|
||||||
@ -1850,7 +1937,7 @@ writeinfo(void)
|
|||||||
// Fields marked with (*) must be changed for 64-bit dwarf
|
// Fields marked with (*) must be changed for 64-bit dwarf
|
||||||
// This must match COMPUNITHEADERSIZE above.
|
// This must match COMPUNITHEADERSIZE above.
|
||||||
LPUT(0); // unit_length (*), will be filled in later.
|
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 (*)
|
LPUT(0); // debug_abbrev_offset (*)
|
||||||
cput(PtrSize); // address_size
|
cput(PtrSize); // address_size
|
||||||
|
|
||||||
@ -1990,6 +2077,27 @@ align(vlong size)
|
|||||||
strnput("", rnd(size, PEFILEALIGN) - 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
|
* This is the main entry point for generating dwarf. After emitting
|
||||||
* the mandatory debug_abbrev section, it calls writelines() to set up
|
* the mandatory debug_abbrev section, it calls writelines() to set up
|
||||||
@ -2090,6 +2198,10 @@ dwarfemitdebugsections(void)
|
|||||||
gdbscripto = writegdbscript();
|
gdbscripto = writegdbscript();
|
||||||
gdbscriptsize = cpos() - gdbscripto;
|
gdbscriptsize = cpos() - gdbscripto;
|
||||||
align(gdbscriptsize);
|
align(gdbscriptsize);
|
||||||
|
|
||||||
|
inforeloco = writeinforeloc();
|
||||||
|
inforelocsize = cpos() - inforeloco;
|
||||||
|
align(inforelocsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2249,6 +2361,8 @@ dwarfaddmachoheaders(void)
|
|||||||
msect = newMachoSect(ms, "__debug_info", "__DWARF");
|
msect = newMachoSect(ms, "__debug_info", "__DWARF");
|
||||||
msect->off = infoo;
|
msect->off = infoo;
|
||||||
msect->size = infosize;
|
msect->size = infosize;
|
||||||
|
msect->reloc = inforeloco;
|
||||||
|
msect->nreloc = inforelocsize / 8;
|
||||||
ms->filesize += msect->size;
|
ms->filesize += msect->size;
|
||||||
|
|
||||||
if (pubnamessize > 0) {
|
if (pubnamessize > 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user