Commit 9da7abd2 authored by Than McIntosh's avatar Than McIntosh

debug/dwarf: better handling for DW_FORM_indirect

Fix a buglet in abbrev processing related to DW_FORM_indirect. When
reading an abbrev entry if we encounter an attribute with form
DW_FORM_indirect, leave the class as ClassUnknown, then when the
abbrev is walked during the reading of the DIE fill in the class based
on the value read at that point (code for handling DW_FORM_indirect
seems to be already partially in place in the DIE reader).

Updates #33488.

Change-Id: I9dc89abf5cc8d7ea96824c0011bef979de0540bf
Reviewed-on: https://go-review.googlesource.com/c/go/+/190158
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarDavid Chase <drchase@google.com>
parent 9f89edcd
...@@ -160,6 +160,9 @@ func formToClass(form format, attr Attr, vers int, b *buf) Class { ...@@ -160,6 +160,9 @@ func formToClass(form format, attr Attr, vers int, b *buf) Class {
b.error("cannot determine class of unknown attribute form") b.error("cannot determine class of unknown attribute form")
return 0 return 0
case formIndirect:
return ClassUnknown
case formAddr, formAddrx, formAddrx1, formAddrx2, formAddrx3, formAddrx4: case formAddr, formAddrx, formAddrx1, formAddrx2, formAddrx3, formAddrx4:
return ClassAddress return ClassAddress
...@@ -402,7 +405,7 @@ type Offset uint32 ...@@ -402,7 +405,7 @@ type Offset uint32
// Entry reads a single entry from buf, decoding // Entry reads a single entry from buf, decoding
// according to the given abbreviation table. // according to the given abbreviation table.
func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset) *Entry { func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry {
off := b.off off := b.off
id := uint32(b.uint()) id := uint32(b.uint())
if id == 0 { if id == 0 {
...@@ -425,6 +428,7 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset) *Entry { ...@@ -425,6 +428,7 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset) *Entry {
fmt := a.field[i].fmt fmt := a.field[i].fmt
if fmt == formIndirect { if fmt == formIndirect {
fmt = format(b.uint()) fmt = format(b.uint())
e.Field[i].Class = formToClass(fmt, a.field[i].attr, vers, b)
} }
var val interface{} var val interface{}
switch fmt { switch fmt {
...@@ -784,7 +788,7 @@ func (r *Reader) Next() (*Entry, error) { ...@@ -784,7 +788,7 @@ func (r *Reader) Next() (*Entry, error) {
return nil, nil return nil, nil
} }
u := &r.d.unit[r.unit] u := &r.d.unit[r.unit]
e := r.b.entry(r.cu, u.atable, u.base) e := r.b.entry(r.cu, u.atable, u.base, u.vers)
if r.b.err != nil { if r.b.err != nil {
r.err = r.b.err r.err = r.b.err
return nil, r.err return nil, r.err
...@@ -929,7 +933,7 @@ func (d *Data) Ranges(e *Entry) ([][2]uint64, error) { ...@@ -929,7 +933,7 @@ func (d *Data) Ranges(e *Entry) ([][2]uint64, error) {
} }
u := &d.unit[i] u := &d.unit[i]
b := makeBuf(d, u, "info", u.off, u.data) b := makeBuf(d, u, "info", u.off, u.data)
cu = b.entry(nil, u.atable, u.base) cu = b.entry(nil, u.atable, u.base, u.vers)
if b.err != nil { if b.err != nil {
return nil, b.err return nil, b.err
} }
......
...@@ -137,7 +137,7 @@ func (tur *typeUnitReader) Next() (*Entry, error) { ...@@ -137,7 +137,7 @@ func (tur *typeUnitReader) Next() (*Entry, error) {
if len(tur.tu.data) == 0 { if len(tur.tu.data) == 0 {
return nil, nil return nil, nil
} }
e := tur.b.entry(nil, tur.tu.atable, tur.tu.base) e := tur.b.entry(nil, tur.tu.atable, tur.tu.base, tur.tu.vers)
if tur.b.err != nil { if tur.b.err != nil {
tur.err = tur.b.err tur.err = tur.b.err
return nil, tur.err return nil, tur.err
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment