summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2017-10-20 18:34:36 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2017-10-20 18:34:36 +0000
commit41bce6cb4e8e3736e0c180ee37a3d843c540e6cc (patch)
treebf968276f6a08a26ec3cea8784d0f5ba5c4f8420
parent9f23bd8e3d9ac18958de53f5fb3cd76471b0ce45 (diff)
downloadgcc-41bce6cb4e8e3736e0c180ee37a3d843c540e6cc.tar.gz
debug/dwarf: support 64-bit DWARF in byte order check
Also fix 64-bit DWARF to read a 64-bit abbrev offset in the compilation unit. This is a backport of https://golang.org/cl/71171, which will be in the Go 1.10 release, to the gofrontend copy. Doing it now because AIX is pretty much the only system that uses 64-bit DWARF. Reviewed-on: https://go-review.googlesource.com/72250 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@253955 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--libgo/go/debug/dwarf/entry.go4
-rw-r--r--libgo/go/debug/dwarf/entry_test.go60
-rw-r--r--libgo/go/debug/dwarf/open.go17
-rw-r--r--libgo/go/debug/dwarf/typeunit.go11
-rw-r--r--libgo/go/debug/dwarf/unit.go11
6 files changed, 88 insertions, 17 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 418e1274fdf..8b1846d07c4 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-44132970e4b6c1186036bf8eda8982fb6e905d6f
+a409ac2c78899e638a014c97891925bec93cb3ad
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/libgo/go/debug/dwarf/entry.go b/libgo/go/debug/dwarf/entry.go
index 80bf14cb22f..ffa61c28d15 100644
--- a/libgo/go/debug/dwarf/entry.go
+++ b/libgo/go/debug/dwarf/entry.go
@@ -33,13 +33,13 @@ type abbrevTable map[uint32]abbrev
// ParseAbbrev returns the abbreviation table that starts at byte off
// in the .debug_abbrev section.
-func (d *Data) parseAbbrev(off uint32, vers int) (abbrevTable, error) {
+func (d *Data) parseAbbrev(off uint64, vers int) (abbrevTable, error) {
if m, ok := d.abbrevCache[off]; ok {
return m, nil
}
data := d.abbrev
- if off > uint32(len(data)) {
+ if off > uint64(len(data)) {
data = nil
} else {
data = data[off:]
diff --git a/libgo/go/debug/dwarf/entry_test.go b/libgo/go/debug/dwarf/entry_test.go
index 58a5d570be5..58f3023d296 100644
--- a/libgo/go/debug/dwarf/entry_test.go
+++ b/libgo/go/debug/dwarf/entry_test.go
@@ -135,3 +135,63 @@ func TestReaderRanges(t *testing.T) {
t.Errorf("saw only %d subprograms, expected %d", i, len(subprograms))
}
}
+
+func Test64Bit(t *testing.T) {
+ // I don't know how to generate a 64-bit DWARF debug
+ // compilation unit except by using XCOFF, so this is
+ // hand-written.
+ tests := []struct {
+ name string
+ info []byte
+ }{
+ {
+ "32-bit little",
+ []byte{0x30, 0, 0, 0, // comp unit length
+ 4, 0, // DWARF version 4
+ 0, 0, 0, 0, // abbrev offset
+ 8, // address size
+ 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ {
+ "64-bit little",
+ []byte{0xff, 0xff, 0xff, 0xff, // 64-bit DWARF
+ 0x30, 0, 0, 0, 0, 0, 0, 0, // comp unit length
+ 4, 0, // DWARF version 4
+ 0, 0, 0, 0, 0, 0, 0, 0, // abbrev offset
+ 8, // address size
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ {
+ "64-bit big",
+ []byte{0xff, 0xff, 0xff, 0xff, // 64-bit DWARF
+ 0, 0, 0, 0, 0, 0, 0, 0x30, // comp unit length
+ 0, 4, // DWARF version 4
+ 0, 0, 0, 0, 0, 0, 0, 0, // abbrev offset
+ 8, // address size
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+ },
+ }
+
+ for _, test := range tests {
+ _, err := New(nil, nil, nil, test.info, nil, nil, nil, nil)
+ if err != nil {
+ t.Errorf("%s: %v", test.name, err)
+ }
+ }
+}
diff --git a/libgo/go/debug/dwarf/open.go b/libgo/go/debug/dwarf/open.go
index 253a43cf579..938186998ff 100644
--- a/libgo/go/debug/dwarf/open.go
+++ b/libgo/go/debug/dwarf/open.go
@@ -23,7 +23,7 @@ type Data struct {
str []byte
// parsed data
- abbrevCache map[uint32]abbrevTable
+ abbrevCache map[uint64]abbrevTable
order binary.ByteOrder
typeCache map[Offset]Type
typeSigs map[uint64]*typeUnit
@@ -48,17 +48,26 @@ func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Dat
pubnames: pubnames,
ranges: ranges,
str: str,
- abbrevCache: make(map[uint32]abbrevTable),
+ abbrevCache: make(map[uint64]abbrevTable),
typeCache: make(map[Offset]Type),
typeSigs: make(map[uint64]*typeUnit),
}
// Sniff .debug_info to figure out byte order.
- // bytes 4:6 are the version, a tiny 16-bit number (1, 2, 3).
+ // 32-bit DWARF: 4 byte length, 2 byte version.
+ // 64-bit DWARf: 4 bytes of 0xff, 8 byte length, 2 byte version.
if len(d.info) < 6 {
return nil, DecodeError{"info", Offset(len(d.info)), "too short"}
}
- x, y := d.info[4], d.info[5]
+ offset := 4
+ if d.info[0] == 0xff && d.info[1] == 0xff && d.info[2] == 0xff && d.info[3] == 0xff {
+ if len(d.info) < 14 {
+ return nil, DecodeError{"info", Offset(len(d.info)), "too short"}
+ }
+ offset = 12
+ }
+ // Fetch the version, a tiny 16-bit number (1, 2, 3, 4, 5).
+ x, y := d.info[offset], d.info[offset+1]
switch {
case x == 0 && y == 0:
return nil, DecodeError{"info", 4, "unsupported version 0"}
diff --git a/libgo/go/debug/dwarf/typeunit.go b/libgo/go/debug/dwarf/typeunit.go
index 652e02d9172..76b357ce28b 100644
--- a/libgo/go/debug/dwarf/typeunit.go
+++ b/libgo/go/debug/dwarf/typeunit.go
@@ -38,16 +38,11 @@ func (d *Data) parseTypes(name string, types []byte) error {
b.error("unsupported DWARF version " + strconv.Itoa(vers))
return b.err
}
- var ao uint32
+ var ao uint64
if !dwarf64 {
- ao = b.uint32()
+ ao = uint64(b.uint32())
} else {
- ao64 := b.uint64()
- if ao64 != uint64(uint32(ao64)) {
- b.error("type unit abbrev offset overflow")
- return b.err
- }
- ao = uint32(ao64)
+ ao = b.uint64()
}
atable, err := d.parseAbbrev(ao, vers)
if err != nil {
diff --git a/libgo/go/debug/dwarf/unit.go b/libgo/go/debug/dwarf/unit.go
index e45aed7ad1d..98024ca1f84 100644
--- a/libgo/go/debug/dwarf/unit.go
+++ b/libgo/go/debug/dwarf/unit.go
@@ -61,13 +61,20 @@ func (d *Data) parseUnits() ([]unit, error) {
u.base = b.off
var n Offset
n, u.is64 = b.unitLength()
+ dataOff := b.off
vers := b.uint16()
if vers != 2 && vers != 3 && vers != 4 {
b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
break
}
u.vers = int(vers)
- atable, err := d.parseAbbrev(b.uint32(), u.vers)
+ var abbrevOff uint64
+ if u.is64 {
+ abbrevOff = b.uint64()
+ } else {
+ abbrevOff = uint64(b.uint32())
+ }
+ atable, err := d.parseAbbrev(abbrevOff, u.vers)
if err != nil {
if b.err == nil {
b.err = err
@@ -77,7 +84,7 @@ func (d *Data) parseUnits() ([]unit, error) {
u.atable = atable
u.asize = int(b.uint8())
u.off = b.off
- u.data = b.bytes(int(n - (2 + 4 + 1)))
+ u.data = b.bytes(int(n - (b.off - dataOff)))
}
if b.err != nil {
return nil, b.err