]> Cypherpunks repositories - gostls13.git/commitdiff
debug/dwarf: check for DWARFv4 AttrDataBitOffset value
authorJoe Sylve <joe.sylve@gmail.com>
Thu, 2 Sep 2021 19:09:15 +0000 (19:09 +0000)
committerThan McIntosh <thanm@google.com>
Thu, 2 Sep 2021 19:56:24 +0000 (19:56 +0000)
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>

src/debug/dwarf/testdata/typedef.c
src/debug/dwarf/testdata/typedef.macho4 [new file with mode: 0644]
src/debug/dwarf/type.go
src/debug/dwarf/type_test.go

index 4780a0b2bad80e94b7fec5e6d187faceb8b370cc..3e7e008621e832d81af45f1e77f8d1fcdc645d44 100644 (file)
@@ -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
new file mode 100644 (file)
index 0000000..093ff37
Binary files /dev/null and b/src/debug/dwarf/testdata/typedef.macho4 differ
index eb5a666ed38d3bcaf1cc42a0b54c5e28ef63453a..2e5a605174c378f29ab89acad9a28240555f133a 100644 (file)
@@ -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)
 
index fda03fdbb09cf22230a006747a2a80e000f11898..431d0853e0546d0361dc627d6920e25065a37bcd 100644 (file)
@@ -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()
+               }
+       }
+}