}).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)
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)
}
}
}
+
+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()
+ }
+ }
+}