diff options
author | Joe Sylve <joe.sylve@gmail.com> | 2021-09-02 19:09:15 +0000 |
---|---|---|
committer | Than McIntosh <thanm@google.com> | 2021-09-02 19:56:24 +0000 |
commit | 065f3808156c92d957fc1ad2a2a37e147ee628f4 (patch) | |
tree | c204b01ef5ffbeaabba69b0c1d6de2a956ef38f5 /src/debug | |
parent | a8aa6cfa6d41a1be17bf8d35c490f693935f81ac (diff) | |
download | go-065f3808156c92d957fc1ad2a2a37e147ee628f4.tar.gz go-065f3808156c92d957fc1ad2a2a37e147ee628f4.zip |
debug/dwarf: check for DWARFv4 AttrDataBitOffset value
AttrBitOffset is deprecated (but reserved) in DWARFv4. This fix adds
logic to check the new AttrDataBitOffset attribute if AttrBitOffset
attribute is not present.
Fixes #46784
Change-Id: I7406dcaa4c98e95df72361fd4462c39e6be8879d
GitHub-Last-Rev: 5aa10d04910a09538320b4de8fbd8a1f5fd8c17d
GitHub-Pull-Request: golang/go#46790
Reviewed-on: https://go-review.googlesource.com/c/go/+/328709
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/debug')
-rw-r--r-- | src/debug/dwarf/testdata/typedef.c | 1 | ||||
-rw-r--r-- | src/debug/dwarf/testdata/typedef.macho4 | bin | 0 -> 6220 bytes | |||
-rw-r--r-- | src/debug/dwarf/type.go | 9 | ||||
-rw-r--r-- | src/debug/dwarf/type_test.go | 51 |
4 files changed, 59 insertions, 2 deletions
diff --git a/src/debug/dwarf/testdata/typedef.c b/src/debug/dwarf/testdata/typedef.c index 4780a0b2ba..3e7e008621 100644 --- a/src/debug/dwarf/testdata/typedef.c +++ b/src/debug/dwarf/testdata/typedef.c @@ -8,6 +8,7 @@ gcc -gdwarf-2 -m64 -c typedef.c && gcc -gdwarf-2 -m64 -o typedef.elf typedef.o OS X Mach-O: gcc -gdwarf-2 -m64 -c typedef.c -o typedef.macho +gcc -gdwarf-4 -m64 -c typedef.c -o typedef.macho4 */ #include <complex.h> diff --git a/src/debug/dwarf/testdata/typedef.macho4 b/src/debug/dwarf/testdata/typedef.macho4 Binary files differnew file mode 100644 index 0000000000..093ff37ea1 --- /dev/null +++ b/src/debug/dwarf/testdata/typedef.macho4 diff --git a/src/debug/dwarf/type.go b/src/debug/dwarf/type.go index eb5a666ed3..2e5a605174 100644 --- a/src/debug/dwarf/type.go +++ b/src/debug/dwarf/type.go @@ -516,7 +516,10 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off }).Basic() t.Name = name t.BitSize, _ = e.Val(AttrBitSize).(int64) - t.BitOffset, _ = e.Val(AttrBitOffset).(int64) + haveBitOffset := false + if t.BitOffset, haveBitOffset = e.Val(AttrBitOffset).(int64); !haveBitOffset { + t.BitOffset, _ = e.Val(AttrDataBitOffset).(int64) + } case TagClassType, TagStructType, TagUnionType: // Structure, union, or class type. (DWARF v2 ยง5.5) @@ -578,7 +581,9 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off haveBitOffset := false f.Name, _ = kid.Val(AttrName).(string) f.ByteSize, _ = kid.Val(AttrByteSize).(int64) - f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64) + if f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64); !haveBitOffset { + f.BitOffset, haveBitOffset = kid.Val(AttrDataBitOffset).(int64) + } f.BitSize, _ = kid.Val(AttrBitSize).(int64) t.Field = append(t.Field, f) diff --git a/src/debug/dwarf/type_test.go b/src/debug/dwarf/type_test.go index fda03fdbb0..431d0853e0 100644 --- a/src/debug/dwarf/type_test.go +++ b/src/debug/dwarf/type_test.go @@ -228,3 +228,54 @@ func TestUnsupportedTypes(t *testing.T) { } } } + +func TestBitOffsetsELF(t *testing.T) { testBitOffsets(t, elfData(t, "testdata/typedef.elf")) } + +func TestBitOffsetsMachO(t *testing.T) { + testBitOffsets(t, machoData(t, "testdata/typedef.macho")) +} + +func TestBitOffsetsMachO4(t *testing.T) { + testBitOffsets(t, machoData(t, "testdata/typedef.macho4")) +} + +func TestBitOffsetsELFDwarf4(t *testing.T) { + testBitOffsets(t, elfData(t, "testdata/typedef.elf4")) +} + +func testBitOffsets(t *testing.T, d *Data) { + r := d.Reader() + for { + e, err := r.Next() + if err != nil { + t.Fatal("r.Next:", err) + } + if e == nil { + break + } + + if e.Tag == TagStructType { + typ, err := d.Type(e.Offset) + if err != nil { + t.Fatal("d.Type:", err) + } + + t1 := typ.(*StructType) + + for _, field := range t1.Field { + // We're only testing for bitfields + if field.BitSize == 0 { + continue + } + + // Ensure BitOffset is not zero + if field.BitOffset == 0 { + t.Errorf("bit offset of field %s in %s %s is not set", field.Name, t1.Kind, t1.StructName) + } + } + } + if e.Tag != TagCompileUnit { + r.SkipChildren() + } + } +} |