aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/debug
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-12-23 09:57:37 -0800
committerIan Lance Taylor <iant@golang.org>2020-12-30 15:13:24 -0800
commitcfcbb4227fb20191e04eb8d7766ae6202f526afd (patch)
treee2effea96f6f204451779f044415c2385e45042b /libgo/go/debug
parent0696141107d61483f38482b941549959a0d7f613 (diff)
downloadgcc-cfcbb4227fb20191e04eb8d7766ae6202f526afd.zip
gcc-cfcbb4227fb20191e04eb8d7766ae6202f526afd.tar.gz
gcc-cfcbb4227fb20191e04eb8d7766ae6202f526afd.tar.bz2
libgo: update to Go1.16beta1 release
This does not yet include support for the //go:embed directive added in this release. * Makefile.am (check-runtime): Don't create check-runtime-dir. (mostlyclean-local): Don't remove check-runtime-dir. (check-go-tool, check-vet): Copy in go.mod and modules.txt. (check-cgo-test, check-carchive-test): Add go.mod file. * Makefile.in: Regenerate. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/280172
Diffstat (limited to 'libgo/go/debug')
-rw-r--r--libgo/go/debug/dwarf/const.go12
-rw-r--r--libgo/go/debug/dwarf/dwarf5ranges_test.go41
-rw-r--r--libgo/go/debug/dwarf/entry.go354
-rw-r--r--libgo/go/debug/dwarf/entry_test.go142
-rw-r--r--libgo/go/debug/dwarf/line.go6
-rw-r--r--libgo/go/debug/dwarf/line_test.go8
-rw-r--r--libgo/go/debug/dwarf/open.go13
-rw-r--r--libgo/go/debug/dwarf/testdata/debug_rnglistsbin0 -> 23 bytes
-rw-r--r--libgo/go/debug/dwarf/testdata/line-clang-dwarf5.elfbin0 -> 18384 bytes
-rw-r--r--libgo/go/debug/dwarf/testdata/line-gcc-dwarf5.elfbin0 -> 18040 bytes
-rw-r--r--libgo/go/debug/elf/elf.go223
-rw-r--r--libgo/go/debug/elf/file.go82
-rw-r--r--libgo/go/debug/elf/file_test.go625
-rw-r--r--libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64bin0 -> 5696 bytes
-rw-r--r--libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64bin0 -> 7680 bytes
-rw-r--r--libgo/go/debug/elf/testdata/multiple-code-sections.c28
-rw-r--r--libgo/go/debug/gosym/pclntab.go221
-rw-r--r--libgo/go/debug/gosym/pclntab_test.go54
-rw-r--r--libgo/go/debug/pe/file_test.go13
19 files changed, 1309 insertions, 513 deletions
diff --git a/libgo/go/debug/dwarf/const.go b/libgo/go/debug/dwarf/const.go
index b11bf90..c607091 100644
--- a/libgo/go/debug/dwarf/const.go
+++ b/libgo/go/debug/dwarf/const.go
@@ -461,3 +461,15 @@ const (
utSplitCompile = 0x05
utSplitType = 0x06
)
+
+// Opcodes for DWARFv5 debug_rnglists section.
+const (
+ rleEndOfList = 0x0
+ rleBaseAddressx = 0x1
+ rleStartxEndx = 0x2
+ rleStartxLength = 0x3
+ rleOffsetPair = 0x4
+ rleBaseAddress = 0x5
+ rleStartEnd = 0x6
+ rleStartLength = 0x7
+)
diff --git a/libgo/go/debug/dwarf/dwarf5ranges_test.go b/libgo/go/debug/dwarf/dwarf5ranges_test.go
new file mode 100644
index 0000000..8bc50bc
--- /dev/null
+++ b/libgo/go/debug/dwarf/dwarf5ranges_test.go
@@ -0,0 +1,41 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dwarf
+
+import (
+ "encoding/binary"
+ "os"
+ "reflect"
+ "testing"
+)
+
+func TestDwarf5Ranges(t *testing.T) {
+ rngLists, err := os.ReadFile("testdata/debug_rnglists")
+ if err != nil {
+ t.Fatalf("could not read test data: %v", err)
+ }
+
+ d := &Data{}
+ d.order = binary.LittleEndian
+ if err := d.AddSection(".debug_rnglists", rngLists); err != nil {
+ t.Fatal(err)
+ }
+ u := &unit{
+ asize: 8,
+ vers: 5,
+ is64: true,
+ }
+ ret, err := d.dwarf5Ranges(u, nil, 0x5fbd, 0xc, [][2]uint64{})
+ if err != nil {
+ t.Fatalf("could not read rnglist: %v", err)
+ }
+ t.Logf("%#v", ret)
+
+ tgt := [][2]uint64{{0x0000000000006712, 0x000000000000679f}, {0x00000000000067af}, {0x00000000000067b3}}
+
+ if reflect.DeepEqual(ret, tgt) {
+ t.Errorf("expected %#v got %#x", tgt, ret)
+ }
+}
diff --git a/libgo/go/debug/dwarf/entry.go b/libgo/go/debug/dwarf/entry.go
index 01f2190..3fc73b8 100644
--- a/libgo/go/debug/dwarf/entry.go
+++ b/libgo/go/debug/dwarf/entry.go
@@ -423,6 +423,47 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
Children: a.children,
Field: make([]Field, len(a.field)),
}
+
+ // If we are currently parsing the compilation unit,
+ // we can't evaluate Addrx or Strx until we've seen the
+ // relevant base entry.
+ type delayed struct {
+ idx int
+ off uint64
+ fmt format
+ }
+ var delay []delayed
+
+ resolveStrx := func(strBase, off uint64) string {
+ off += strBase
+ if uint64(int(off)) != off {
+ b.error("DW_FORM_strx offset out of range")
+ }
+
+ b1 := makeBuf(b.dwarf, b.format, "str_offsets", 0, b.dwarf.strOffsets)
+ b1.skip(int(off))
+ is64, _ := b.format.dwarf64()
+ if is64 {
+ off = b1.uint64()
+ } else {
+ off = uint64(b1.uint32())
+ }
+ if b1.err != nil {
+ b.err = b1.err
+ return ""
+ }
+ if uint64(int(off)) != off {
+ b.error("DW_FORM_strx indirect offset out of range")
+ }
+ b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
+ b1.skip(int(off))
+ val := b1.string()
+ if b1.err != nil {
+ b.err = b1.err
+ }
+ return val
+ }
+
for i := range e.Field {
e.Field[i].Attr = a.field[i].attr
e.Field[i].Class = a.field[i].class
@@ -453,38 +494,31 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
case formAddrx4:
off = uint64(b.uint32())
}
- if len(b.dwarf.addr) == 0 {
+ if b.dwarf.addr == nil {
b.error("DW_FORM_addrx with no .debug_addr section")
}
if b.err != nil {
return nil
}
- addrsize := b.format.addrsize()
- if addrsize == 0 {
- b.error("unknown address size for DW_FORM_addrx")
- }
- off *= uint64(addrsize)
// We have to adjust by the offset of the
// compilation unit. This won't work if the
// program uses Reader.Seek to skip over the
// unit. Not much we can do about that.
+ var addrBase int64
if cu != nil {
- cuOff, ok := cu.Val(AttrAddrBase).(int64)
- if ok {
- off += uint64(cuOff)
- }
- }
-
- if uint64(int(off)) != off {
- b.error("DW_FORM_addrx offset out of range")
+ addrBase, _ = cu.Val(AttrAddrBase).(int64)
+ } else if a.tag == TagCompileUnit {
+ delay = append(delay, delayed{i, off, formAddrx})
+ break
}
- b1 := makeBuf(b.dwarf, b.format, "addr", 0, b.dwarf.addr)
- b1.skip(int(off))
- val = b1.addr()
- if b1.err != nil {
- b.err = b1.err
+ var err error
+ val, err = b.dwarf.debugAddr(b.format, uint64(addrBase), off)
+ if err != nil {
+ if b.err == nil {
+ b.err = err
+ }
return nil
}
@@ -621,38 +655,16 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
// compilation unit. This won't work if the
// program uses Reader.Seek to skip over the
// unit. Not much we can do about that.
+ var strBase int64
if cu != nil {
- cuOff, ok := cu.Val(AttrStrOffsetsBase).(int64)
- if ok {
- off += uint64(cuOff)
- }
+ strBase, _ = cu.Val(AttrStrOffsetsBase).(int64)
+ } else if a.tag == TagCompileUnit {
+ delay = append(delay, delayed{i, off, formStrx})
+ break
}
- if uint64(int(off)) != off {
- b.error("DW_FORM_strx offset out of range")
- }
+ val = resolveStrx(uint64(strBase), off)
- b1 := makeBuf(b.dwarf, b.format, "str_offsets", 0, b.dwarf.strOffsets)
- b1.skip(int(off))
- if is64 {
- off = b1.uint64()
- } else {
- off = uint64(b1.uint32())
- }
- if b1.err != nil {
- b.err = b1.err
- return nil
- }
- if uint64(int(off)) != off {
- b.error("DW_FORM_strx indirect offset out of range")
- }
- b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
- b1.skip(int(off))
- val = b1.string()
- if b1.err != nil {
- b.err = b1.err
- return nil
- }
case formStrpSup:
is64, known := b.format.dwarf64()
if !known {
@@ -699,11 +711,32 @@ func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry
case formRnglistx:
val = b.uint()
}
+
e.Field[i].Val = val
}
if b.err != nil {
return nil
}
+
+ for _, del := range delay {
+ switch del.fmt {
+ case formAddrx:
+ addrBase, _ := e.Val(AttrAddrBase).(int64)
+ val, err := b.dwarf.debugAddr(b.format, uint64(addrBase), del.off)
+ if err != nil {
+ b.err = err
+ return nil
+ }
+ e.Field[del.idx].Val = val
+ case formStrx:
+ strBase, _ := e.Val(AttrStrOffsetsBase).(int64)
+ e.Field[del.idx].Val = resolveStrx(uint64(strBase), del.off)
+ if b.err != nil {
+ return nil
+ }
+ }
+ }
+
return e
}
@@ -717,6 +750,7 @@ type Reader struct {
d *Data
err error
unit int
+ lastUnit bool // set if last entry returned by Next is TagCompileUnit/TagPartialUnit
lastChildren bool // .Children of last entry returned by Next
lastSibling Offset // .Val(AttrSibling) of last entry returned by Next
cu *Entry // current compilation unit
@@ -774,13 +808,18 @@ func (r *Reader) Seek(off Offset) {
// maybeNextUnit advances to the next unit if this one is finished.
func (r *Reader) maybeNextUnit() {
for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) {
- r.unit++
- u := &r.d.unit[r.unit]
- r.b = makeBuf(r.d, u, "info", u.off, u.data)
- r.cu = nil
+ r.nextUnit()
}
}
+// nextUnit advances to the next unit.
+func (r *Reader) nextUnit() {
+ r.unit++
+ u := &r.d.unit[r.unit]
+ r.b = makeBuf(r.d, u, "info", u.off, u.data)
+ r.cu = nil
+}
+
// Next reads the next entry from the encoded entry stream.
// It returns nil, nil when it reaches the end of the section.
// It returns an error if the current offset is invalid or the data at the
@@ -799,12 +838,14 @@ func (r *Reader) Next() (*Entry, error) {
r.err = r.b.err
return nil, r.err
}
+ r.lastUnit = false
if e != nil {
r.lastChildren = e.Children
if r.lastChildren {
r.lastSibling, _ = e.Val(AttrSibling).(Offset)
}
if e.Tag == TagCompileUnit || e.Tag == TagPartialUnit {
+ r.lastUnit = true
r.cu = e
}
} else {
@@ -830,6 +871,11 @@ func (r *Reader) SkipChildren() {
return
}
+ if r.lastUnit && r.unit+1 < len(r.d.unit) {
+ r.nextUnit()
+ return
+ }
+
for {
e, err := r.Next()
if err != nil || e == nil || e.Tag == 0 {
@@ -874,6 +920,7 @@ func (r *Reader) SeekPC(pc uint64) (*Entry, error) {
r.err = nil
r.lastChildren = false
r.unit = unit
+ r.cu = nil
u := &r.d.unit[unit]
r.b = makeBuf(r.d, u, "info", u.off, u.data)
e, err := r.Next()
@@ -922,53 +969,186 @@ func (d *Data) Ranges(e *Entry) ([][2]uint64, error) {
ret = append(ret, [2]uint64{low, high})
}
- ranges, rangesOK := e.Val(AttrRanges).(int64)
- if rangesOK && d.ranges != nil {
- // The initial base address is the lowpc attribute
- // of the enclosing compilation unit.
- // Although DWARF specifies the lowpc attribute,
- // comments in gdb/dwarf2read.c say that some versions
- // of GCC use the entrypc attribute, so we check that too.
- var cu *Entry
- if e.Tag == TagCompileUnit {
- cu = e
- } else {
- i := d.offsetToUnit(e.Offset)
- if i == -1 {
- return nil, errors.New("no unit for entry")
+ var u *unit
+ if uidx := d.offsetToUnit(e.Offset); uidx >= 0 && uidx < len(d.unit) {
+ u = &d.unit[uidx]
+ }
+
+ if u != nil && u.vers >= 5 && d.rngLists != nil {
+ // DWARF version 5 and later
+ field := e.AttrField(AttrRanges)
+ if field == nil {
+ return ret, nil
+ }
+ switch field.Class {
+ case ClassRangeListPtr:
+ ranges, rangesOK := field.Val.(int64)
+ if !rangesOK {
+ return ret, nil
}
- u := &d.unit[i]
- b := makeBuf(d, u, "info", u.off, u.data)
- cu = b.entry(nil, u.atable, u.base, u.vers)
- if b.err != nil {
- return nil, b.err
+ cu, base, err := d.baseAddressForEntry(e)
+ if err != nil {
+ return nil, err
}
+ return d.dwarf5Ranges(u, cu, base, ranges, ret)
+
+ case ClassRngList:
+ // TODO: support DW_FORM_rnglistx
+ return ret, nil
+
+ default:
+ return ret, nil
+ }
+ }
+
+ // DWARF version 2 through 4
+ ranges, rangesOK := e.Val(AttrRanges).(int64)
+ if rangesOK && d.ranges != nil {
+ _, base, err := d.baseAddressForEntry(e)
+ if err != nil {
+ return nil, err
}
+ return d.dwarf2Ranges(u, base, ranges, ret)
+ }
+
+ return ret, nil
+}
- var base uint64
- if cuEntry, cuEntryOK := cu.Val(AttrEntrypc).(uint64); cuEntryOK {
- base = cuEntry
- } else if cuLow, cuLowOK := cu.Val(AttrLowpc).(uint64); cuLowOK {
- base = cuLow
+// baseAddressForEntry returns the initial base address to be used when
+// looking up the range list of entry e.
+// DWARF specifies that this should be the lowpc attribute of the enclosing
+// compilation unit, however comments in gdb/dwarf2read.c say that some
+// versions of GCC use the entrypc attribute, so we check that too.
+func (d *Data) baseAddressForEntry(e *Entry) (*Entry, uint64, error) {
+ var cu *Entry
+ if e.Tag == TagCompileUnit {
+ cu = e
+ } else {
+ i := d.offsetToUnit(e.Offset)
+ if i == -1 {
+ return nil, 0, errors.New("no unit for entry")
+ }
+ u := &d.unit[i]
+ b := makeBuf(d, u, "info", u.off, u.data)
+ cu = b.entry(nil, u.atable, u.base, u.vers)
+ if b.err != nil {
+ return nil, 0, b.err
}
+ }
- u := &d.unit[d.offsetToUnit(e.Offset)]
- buf := makeBuf(d, u, "ranges", Offset(ranges), d.ranges[ranges:])
- for len(buf.data) > 0 {
- low = buf.addr()
- high = buf.addr()
+ if cuEntry, cuEntryOK := cu.Val(AttrEntrypc).(uint64); cuEntryOK {
+ return cu, cuEntry, nil
+ } else if cuLow, cuLowOK := cu.Val(AttrLowpc).(uint64); cuLowOK {
+ return cu, cuLow, nil
+ }
- if low == 0 && high == 0 {
- break
+ return cu, 0, nil
+}
+
+func (d *Data) dwarf2Ranges(u *unit, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
+ buf := makeBuf(d, u, "ranges", Offset(ranges), d.ranges[ranges:])
+ for len(buf.data) > 0 {
+ low := buf.addr()
+ high := buf.addr()
+
+ if low == 0 && high == 0 {
+ break
+ }
+
+ if low == ^uint64(0)>>uint((8-u.addrsize())*8) {
+ base = high
+ } else {
+ ret = append(ret, [2]uint64{base + low, base + high})
+ }
+ }
+
+ return ret, nil
+}
+
+// dwarf5Ranges interpets a debug_rnglists sequence, see DWARFv5 section
+// 2.17.3 (page 53).
+func (d *Data) dwarf5Ranges(u *unit, cu *Entry, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
+ var addrBase int64
+ if cu != nil {
+ addrBase, _ = cu.Val(AttrAddrBase).(int64)
+ }
+
+ buf := makeBuf(d, u, "rnglists", 0, d.rngLists)
+ buf.skip(int(ranges))
+ for {
+ opcode := buf.uint8()
+ switch opcode {
+ case rleEndOfList:
+ if buf.err != nil {
+ return nil, buf.err
+ }
+ return ret, nil
+
+ case rleBaseAddressx:
+ baseIdx := buf.uint()
+ var err error
+ base, err = d.debugAddr(u, uint64(addrBase), baseIdx)
+ if err != nil {
+ return nil, err
}
- if low == ^uint64(0)>>uint((8-u.addrsize())*8) {
- base = high
- } else {
- ret = append(ret, [2]uint64{base + low, base + high})
+ case rleStartxEndx:
+ startIdx := buf.uint()
+ endIdx := buf.uint()
+
+ start, err := d.debugAddr(u, uint64(addrBase), startIdx)
+ if err != nil {
+ return nil, err
+ }
+ end, err := d.debugAddr(u, uint64(addrBase), endIdx)
+ if err != nil {
+ return nil, err
+ }
+ ret = append(ret, [2]uint64{start, end})
+
+ case rleStartxLength:
+ startIdx := buf.uint()
+ len := buf.uint()
+ start, err := d.debugAddr(u, uint64(addrBase), startIdx)
+ if err != nil {
+ return nil, err
}
+ ret = append(ret, [2]uint64{start, start + len})
+
+ case rleOffsetPair:
+ off1 := buf.uint()
+ off2 := buf.uint()
+ ret = append(ret, [2]uint64{base + off1, base + off2})
+
+ case rleBaseAddress:
+ base = buf.addr()
+
+ case rleStartEnd:
+ start := buf.addr()
+ end := buf.addr()
+ ret = append(ret, [2]uint64{start, end})
+
+ case rleStartLength:
+ start := buf.addr()
+ len := buf.uint()
+ ret = append(ret, [2]uint64{start, start + len})
}
}
+}
- return ret, nil
+// debugAddr returns the address at idx in debug_addr
+func (d *Data) debugAddr(format dataFormat, addrBase, idx uint64) (uint64, error) {
+ off := idx*uint64(format.addrsize()) + addrBase
+
+ if uint64(int(off)) != off {
+ return 0, errors.New("offset out of range")
+ }
+
+ b := makeBuf(d, format, "addr", 0, d.addr)
+ b.skip(int(off))
+ val := b.addr()
+ if b.err != nil {
+ return 0, b.err
+ }
+ return val, nil
}
diff --git a/libgo/go/debug/dwarf/entry_test.go b/libgo/go/debug/dwarf/entry_test.go
index 4c9aad2..b54f8b4 100644
--- a/libgo/go/debug/dwarf/entry_test.go
+++ b/libgo/go/debug/dwarf/entry_test.go
@@ -7,6 +7,7 @@ package dwarf_test
import (
. "debug/dwarf"
"encoding/binary"
+ "path/filepath"
"reflect"
"testing"
)
@@ -54,6 +55,20 @@ func TestReaderSeek(t *testing.T) {
{0x400611, nil},
}
testRanges(t, "testdata/line-gcc.elf", want)
+
+ want = []wantRange{
+ {0x401122, [][2]uint64{{0x401122, 0x401166}}},
+ {0x401165, [][2]uint64{{0x401122, 0x401166}}},
+ {0x401166, [][2]uint64{{0x401166, 0x401179}}},
+ }
+ testRanges(t, "testdata/line-gcc-dwarf5.elf", want)
+
+ want = []wantRange{
+ {0x401130, [][2]uint64{{0x401130, 0x40117e}}},
+ {0x40117d, [][2]uint64{{0x401130, 0x40117e}}},
+ {0x40117e, nil},
+ }
+ testRanges(t, "testdata/line-clang-dwarf5.elf", want)
}
func TestRangesSection(t *testing.T) {
@@ -96,44 +111,72 @@ func testRanges(t *testing.T, name string, want []wantRange) {
}
func TestReaderRanges(t *testing.T) {
- d := elfData(t, "testdata/line-gcc.elf")
-
- subprograms := []struct {
+ type subprograms []struct {
name string
ranges [][2]uint64
+ }
+ tests := []struct {
+ filename string
+ subprograms subprograms
}{
- {"f1", [][2]uint64{{0x40059d, 0x4005e7}}},
- {"main", [][2]uint64{{0x4005e7, 0x400601}}},
- {"f2", [][2]uint64{{0x400601, 0x400611}}},
+ {
+ "testdata/line-gcc.elf",
+ subprograms{
+ {"f1", [][2]uint64{{0x40059d, 0x4005e7}}},
+ {"main", [][2]uint64{{0x4005e7, 0x400601}}},
+ {"f2", [][2]uint64{{0x400601, 0x400611}}},
+ },
+ },
+ {
+ "testdata/line-gcc-dwarf5.elf",
+ subprograms{
+ {"main", [][2]uint64{{0x401147, 0x401166}}},
+ {"f1", [][2]uint64{{0x401122, 0x401147}}},
+ {"f2", [][2]uint64{{0x401166, 0x401179}}},
+ },
+ },
+ {
+ "testdata/line-clang-dwarf5.elf",
+ subprograms{
+ {"main", [][2]uint64{{0x401130, 0x401144}}},
+ {"f1", [][2]uint64{{0x401150, 0x40117e}}},
+ {"f2", [][2]uint64{{0x401180, 0x401197}}},
+ },
+ },
}
- r := d.Reader()
- i := 0
- for entry, err := r.Next(); entry != nil && err == nil; entry, err = r.Next() {
- if entry.Tag != TagSubprogram {
- continue
- }
+ for _, test := range tests {
+ d := elfData(t, test.filename)
+ subprograms := test.subprograms
- if i > len(subprograms) {
- t.Fatalf("too many subprograms (expected at most %d)", i)
- }
+ r := d.Reader()
+ i := 0
+ for entry, err := r.Next(); entry != nil && err == nil; entry, err = r.Next() {
+ if entry.Tag != TagSubprogram {
+ continue
+ }
- if got := entry.Val(AttrName).(string); got != subprograms[i].name {
- t.Errorf("subprogram %d name is %s, expected %s", i, got, subprograms[i].name)
- }
- ranges, err := d.Ranges(entry)
- if err != nil {
- t.Errorf("subprogram %d: %v", i, err)
- continue
- }
- if !reflect.DeepEqual(ranges, subprograms[i].ranges) {
- t.Errorf("subprogram %d ranges are %x, expected %x", i, ranges, subprograms[i].ranges)
+ if i > len(subprograms) {
+ t.Fatalf("%s: too many subprograms (expected at most %d)", test.filename, i)
+ }
+
+ if got := entry.Val(AttrName).(string); got != subprograms[i].name {
+ t.Errorf("%s: subprogram %d name is %s, expected %s", test.filename, i, got, subprograms[i].name)
+ }
+ ranges, err := d.Ranges(entry)
+ if err != nil {
+ t.Errorf("%s: subprogram %d: %v", test.filename, i, err)
+ continue
+ }
+ if !reflect.DeepEqual(ranges, subprograms[i].ranges) {
+ t.Errorf("%s: subprogram %d ranges are %x, expected %x", test.filename, i, ranges, subprograms[i].ranges)
+ }
+ i++
}
- i++
- }
- if i < len(subprograms) {
- t.Errorf("saw only %d subprograms, expected %d", i, len(subprograms))
+ if i < len(subprograms) {
+ t.Errorf("%s: saw only %d subprograms, expected %d", test.filename, i, len(subprograms))
+ }
}
}
@@ -209,3 +252,44 @@ func Test64Bit(t *testing.T) {
}
}
}
+
+func TestUnitIteration(t *testing.T) {
+ // Iterate over all ELF test files we have and ensure that
+ // we get the same set of compilation units skipping (method 0)
+ // and not skipping (method 1) CU children.
+ files, err := filepath.Glob(filepath.Join("testdata", "*.elf"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, file := range files {
+ t.Run(file, func(t *testing.T) {
+ d := elfData(t, file)
+ var units [2][]interface{}
+ for method := range units {
+ for r := d.Reader(); ; {
+ ent, err := r.Next()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if ent == nil {
+ break
+ }
+ if ent.Tag == TagCompileUnit {
+ units[method] = append(units[method], ent.Val(AttrName))
+ }
+ if method == 0 {
+ if ent.Tag != TagCompileUnit {
+ t.Fatalf("found unexpected tag %v on top level", ent.Tag)
+ }
+ r.SkipChildren()
+ }
+ }
+ }
+ t.Logf("skipping CUs: %v", units[0])
+ t.Logf("not-skipping CUs: %v", units[1])
+ if !reflect.DeepEqual(units[0], units[1]) {
+ t.Fatal("set of CUs differ")
+ }
+ })
+ }
+}
diff --git a/libgo/go/debug/dwarf/line.go b/libgo/go/debug/dwarf/line.go
index 7692f05..c4937ca 100644
--- a/libgo/go/debug/dwarf/line.go
+++ b/libgo/go/debug/dwarf/line.go
@@ -814,7 +814,11 @@ func pathJoin(dirname, filename string) string {
// Drives are the same. Ignore drive on filename.
}
if !(strings.HasSuffix(dirname, "/") || strings.HasSuffix(dirname, `\`)) && dirname != "" {
- dirname += `\`
+ sep := `\`
+ if strings.HasPrefix(dirname, "/") {
+ sep = `/`
+ }
+ dirname += sep
}
return drive + dirname + filename
}
diff --git a/libgo/go/debug/dwarf/line_test.go b/libgo/go/debug/dwarf/line_test.go
index 1fd9b19..b13818e 100644
--- a/libgo/go/debug/dwarf/line_test.go
+++ b/libgo/go/debug/dwarf/line_test.go
@@ -341,6 +341,14 @@ var joinTests = []joinTest{
{`\\host\share\`, `foo\bar`, `\\host\share\foo\bar`},
{`//host/share/`, `foo/bar`, `//host/share/foo/bar`},
+ // Note: the Go compiler currently emits DWARF line table paths
+ // with '/' instead of '\' (see issues #19784, #36495). These
+ // tests are to cover cases that might come up for Windows Go
+ // binaries.
+ {`c:/workdir/go/src/x`, `y.go`, `c:/workdir/go/src/x/y.go`},
+ {`d:/some/thing/`, `b.go`, `d:/some/thing/b.go`},
+ {`e:\blah\`, `foo.c`, `e:\blah\foo.c`},
+
// The following are "best effort". We shouldn't see relative
// base directories in DWARF, but these test that pathJoin
// doesn't fail miserably if it sees one.
diff --git a/libgo/go/debug/dwarf/open.go b/libgo/go/debug/dwarf/open.go
index d6d4f78..b1a4d3a 100644
--- a/libgo/go/debug/dwarf/open.go
+++ b/libgo/go/debug/dwarf/open.go
@@ -7,7 +7,10 @@
// http://dwarfstd.org/doc/dwarf-2.0.0.pdf
package dwarf
-import "encoding/binary"
+import (
+ "encoding/binary"
+ "errors"
+)
// Data represents the DWARF debugging information
// loaded from an executable file (for example, an ELF or Mach-O executable).
@@ -26,6 +29,7 @@ type Data struct {
addr []byte
lineStr []byte
strOffsets []byte
+ rngLists []byte
// parsed data
abbrevCache map[uint64]abbrevTable
@@ -36,6 +40,8 @@ type Data struct {
unit []unit
}
+var errSegmentSelector = errors.New("non-zero segment_selector size not supported")
+
// New returns a new Data object initialized from the given parameters.
// Rather than calling this function directly, clients should typically use
// the DWARF method of the File type of the appropriate package debug/elf,
@@ -108,6 +114,7 @@ func (d *Data) AddTypes(name string, types []byte) error {
// so forth. This approach is used for new DWARF sections added in
// DWARF 5 and later.
func (d *Data) AddSection(name string, contents []byte) error {
+ var err error
switch name {
case ".debug_addr":
d.addr = contents
@@ -115,7 +122,9 @@ func (d *Data) AddSection(name string, contents []byte) error {
d.lineStr = contents
case ".debug_str_offsets":
d.strOffsets = contents
+ case ".debug_rnglists":
+ d.rngLists = contents
}
// Just ignore names that we don't yet support.
- return nil
+ return err
}
diff --git a/libgo/go/debug/dwarf/testdata/debug_rnglists b/libgo/go/debug/dwarf/testdata/debug_rnglists
new file mode 100644
index 0000000..985ec6c
--- /dev/null
+++ b/libgo/go/debug/dwarf/testdata/debug_rnglists
Binary files differ
diff --git a/libgo/go/debug/dwarf/testdata/line-clang-dwarf5.elf b/libgo/go/debug/dwarf/testdata/line-clang-dwarf5.elf
new file mode 100644
index 0000000..7b80c9c
--- /dev/null
+++ b/libgo/go/debug/dwarf/testdata/line-clang-dwarf5.elf
Binary files differ
diff --git a/libgo/go/debug/dwarf/testdata/line-gcc-dwarf5.elf b/libgo/go/debug/dwarf/testdata/line-gcc-dwarf5.elf
new file mode 100644
index 0000000..34ce17c
--- /dev/null
+++ b/libgo/go/debug/dwarf/testdata/line-gcc-dwarf5.elf
Binary files differ
diff --git a/libgo/go/debug/elf/elf.go b/libgo/go/debug/elf/elf.go
index 96a67ce..2b777ea 100644
--- a/libgo/go/debug/elf/elf.go
+++ b/libgo/go/debug/elf/elf.go
@@ -745,18 +745,51 @@ func (i CompressionType) GoString() string { return stringName(uint32(i), compre
type ProgType int
const (
- PT_NULL ProgType = 0 /* Unused entry. */
- PT_LOAD ProgType = 1 /* Loadable segment. */
- PT_DYNAMIC ProgType = 2 /* Dynamic linking information segment. */
- PT_INTERP ProgType = 3 /* Pathname of interpreter. */
- PT_NOTE ProgType = 4 /* Auxiliary information. */
- PT_SHLIB ProgType = 5 /* Reserved (not used). */
- PT_PHDR ProgType = 6 /* Location of program header itself. */
- PT_TLS ProgType = 7 /* Thread local storage segment */
- PT_LOOS ProgType = 0x60000000 /* First OS-specific. */
- PT_HIOS ProgType = 0x6fffffff /* Last OS-specific. */
- PT_LOPROC ProgType = 0x70000000 /* First processor-specific type. */
- PT_HIPROC ProgType = 0x7fffffff /* Last processor-specific type. */
+ PT_NULL ProgType = 0 /* Unused entry. */
+ PT_LOAD ProgType = 1 /* Loadable segment. */
+ PT_DYNAMIC ProgType = 2 /* Dynamic linking information segment. */
+ PT_INTERP ProgType = 3 /* Pathname of interpreter. */
+ PT_NOTE ProgType = 4 /* Auxiliary information. */
+ PT_SHLIB ProgType = 5 /* Reserved (not used). */
+ PT_PHDR ProgType = 6 /* Location of program header itself. */
+ PT_TLS ProgType = 7 /* Thread local storage segment */
+
+ PT_LOOS ProgType = 0x60000000 /* First OS-specific. */
+
+ PT_GNU_EH_FRAME ProgType = 0x6474e550 /* Frame unwind information */
+ PT_GNU_STACK ProgType = 0x6474e551 /* Stack flags */
+ PT_GNU_RELRO ProgType = 0x6474e552 /* Read only after relocs */
+ PT_GNU_PROPERTY ProgType = 0x6474e553 /* GNU property */
+ PT_GNU_MBIND_LO ProgType = 0x6474e555 /* Mbind segments start */
+ PT_GNU_MBIND_HI ProgType = 0x6474f554 /* Mbind segments finish */
+
+ PT_PAX_FLAGS ProgType = 0x65041580 /* PAX flags */
+
+ PT_OPENBSD_RANDOMIZE ProgType = 0x65a3dbe6 /* Random data */
+ PT_OPENBSD_WXNEEDED ProgType = 0x65a3dbe7 /* W^X violations */
+ PT_OPENBSD_BOOTDATA ProgType = 0x65a41be6 /* Boot arguments */
+
+ PT_SUNW_EH_FRAME ProgType = 0x6474e550 /* Frame unwind information */
+ PT_SUNWSTACK ProgType = 0x6ffffffb /* Stack segment */
+
+ PT_HIOS ProgType = 0x6fffffff /* Last OS-specific. */
+
+ PT_LOPROC ProgType = 0x70000000 /* First processor-specific type. */
+
+ PT_ARM_ARCHEXT ProgType = 0x70000000 /* Architecture compatibility */
+ PT_ARM_EXIDX ProgType = 0x70000001 /* Exception unwind tables */
+
+ PT_AARCH64_ARCHEXT ProgType = 0x70000000 /* Architecture compatibility */
+ PT_AARCH64_UNWIND ProgType = 0x70000001 /* Exception unwind tables */
+
+ PT_MIPS_REGINFO ProgType = 0x70000000 /* Register usage */
+ PT_MIPS_RTPROC ProgType = 0x70000001 /* Runtime procedures */
+ PT_MIPS_OPTIONS ProgType = 0x70000002 /* Options */
+ PT_MIPS_ABIFLAGS ProgType = 0x70000003 /* ABI flags */
+
+ PT_S390_PGSTE ProgType = 0x70000000 /* 4k page table size */
+
+ PT_HIPROC ProgType = 0x7fffffff /* Last processor-specific type. */
)
var ptStrings = []intName{
@@ -769,8 +802,19 @@ var ptStrings = []intName{
{6, "PT_PHDR"},
{7, "PT_TLS"},
{0x60000000, "PT_LOOS"},
+ {0x6474e550, "PT_GNU_EH_FRAME"},
+ {0x6474e551, "PT_GNU_STACK"},
+ {0x6474e552, "PT_GNU_RELRO"},
+ {0x6474e553, "PT_GNU_PROPERTY"},
+ {0x65041580, "PT_PAX_FLAGS"},
+ {0x65a3dbe6, "PT_OPENBSD_RANDOMIZE"},
+ {0x65a3dbe7, "PT_OPENBSD_WXNEEDED"},
+ {0x65a41be6, "PT_OPENBSD_BOOTDATA"},
+ {0x6ffffffb, "PT_SUNWSTACK"},
{0x6fffffff, "PT_HIOS"},
{0x70000000, "PT_LOPROC"},
+ // We don't list the processor-dependent ProgTypes,
+ // as the values overlap.
{0x7fffffff, "PT_HIPROC"},
}
@@ -837,15 +881,114 @@ const (
the interpretation of the d_un union
as follows: even == 'd_ptr', even == 'd_val'
or none */
- DT_PREINIT_ARRAY DynTag = 32 /* Address of the array of pointers to pre-initialization functions. */
- DT_PREINIT_ARRAYSZ DynTag = 33 /* Size in bytes of the array of pre-initialization functions. */
- DT_LOOS DynTag = 0x6000000d /* First OS-specific */
- DT_HIOS DynTag = 0x6ffff000 /* Last OS-specific */
- DT_VERSYM DynTag = 0x6ffffff0
- DT_VERNEED DynTag = 0x6ffffffe
- DT_VERNEEDNUM DynTag = 0x6fffffff
- DT_LOPROC DynTag = 0x70000000 /* First processor-specific type. */
- DT_HIPROC DynTag = 0x7fffffff /* Last processor-specific type. */
+ DT_PREINIT_ARRAY DynTag = 32 /* Address of the array of pointers to pre-initialization functions. */
+ DT_PREINIT_ARRAYSZ DynTag = 33 /* Size in bytes of the array of pre-initialization functions. */
+ DT_SYMTAB_SHNDX DynTag = 34 /* Address of SHT_SYMTAB_SHNDX section. */
+
+ DT_LOOS DynTag = 0x6000000d /* First OS-specific */
+ DT_HIOS DynTag = 0x6ffff000 /* Last OS-specific */
+
+ DT_VALRNGLO DynTag = 0x6ffffd00
+ DT_GNU_PRELINKED DynTag = 0x6ffffdf5
+ DT_GNU_CONFLICTSZ DynTag = 0x6ffffdf6
+ DT_GNU_LIBLISTSZ DynTag = 0x6ffffdf7
+ DT_CHECKSUM DynTag = 0x6ffffdf8
+ DT_PLTPADSZ DynTag = 0x6ffffdf9
+ DT_MOVEENT DynTag = 0x6ffffdfa
+ DT_MOVESZ DynTag = 0x6ffffdfb
+ DT_FEATURE DynTag = 0x6ffffdfc
+ DT_POSFLAG_1 DynTag = 0x6ffffdfd
+ DT_SYMINSZ DynTag = 0x6ffffdfe
+ DT_SYMINENT DynTag = 0x6ffffdff
+ DT_VALRNGHI DynTag = 0x6ffffdff
+
+ DT_ADDRRNGLO DynTag = 0x6ffffe00
+ DT_GNU_HASH DynTag = 0x6ffffef5
+ DT_TLSDESC_PLT DynTag = 0x6ffffef6
+ DT_TLSDESC_GOT DynTag = 0x6ffffef7
+ DT_GNU_CONFLICT DynTag = 0x6ffffef8
+ DT_GNU_LIBLIST DynTag = 0x6ffffef9
+ DT_CONFIG DynTag = 0x6ffffefa
+ DT_DEPAUDIT DynTag = 0x6ffffefb
+ DT_AUDIT DynTag = 0x6ffffefc
+ DT_PLTPAD DynTag = 0x6ffffefd
+ DT_MOVETAB DynTag = 0x6ffffefe
+ DT_SYMINFO DynTag = 0x6ffffeff
+ DT_ADDRRNGHI DynTag = 0x6ffffeff
+
+ DT_VERSYM DynTag = 0x6ffffff0
+ DT_RELACOUNT DynTag = 0x6ffffff9
+ DT_RELCOUNT DynTag = 0x6ffffffa
+ DT_FLAGS_1 DynTag = 0x6ffffffb
+ DT_VERDEF DynTag = 0x6ffffffc
+ DT_VERDEFNUM DynTag = 0x6ffffffd
+ DT_VERNEED DynTag = 0x6ffffffe
+ DT_VERNEEDNUM DynTag = 0x6fffffff
+
+ DT_LOPROC DynTag = 0x70000000 /* First processor-specific type. */
+
+ DT_MIPS_RLD_VERSION DynTag = 0x70000001
+ DT_MIPS_TIME_STAMP DynTag = 0x70000002
+ DT_MIPS_ICHECKSUM DynTag = 0x70000003
+ DT_MIPS_IVERSION DynTag = 0x70000004
+ DT_MIPS_FLAGS DynTag = 0x70000005
+ DT_MIPS_BASE_ADDRESS DynTag = 0x70000006
+ DT_MIPS_MSYM DynTag = 0x70000007
+ DT_MIPS_CONFLICT DynTag = 0x70000008
+ DT_MIPS_LIBLIST DynTag = 0x70000009
+ DT_MIPS_LOCAL_GOTNO DynTag = 0x7000000a
+ DT_MIPS_CONFLICTNO DynTag = 0x7000000b
+ DT_MIPS_LIBLISTNO DynTag = 0x70000010
+ DT_MIPS_SYMTABNO DynTag = 0x70000011
+ DT_MIPS_UNREFEXTNO DynTag = 0x70000012
+ DT_MIPS_GOTSYM DynTag = 0x70000013
+ DT_MIPS_HIPAGENO DynTag = 0x70000014
+ DT_MIPS_RLD_MAP DynTag = 0x70000016
+ DT_MIPS_DELTA_CLASS DynTag = 0x70000017
+ DT_MIPS_DELTA_CLASS_NO DynTag = 0x70000018
+ DT_MIPS_DELTA_INSTANCE DynTag = 0x70000019
+ DT_MIPS_DELTA_INSTANCE_NO DynTag = 0x7000001a
+ DT_MIPS_DELTA_RELOC DynTag = 0x7000001b
+ DT_MIPS_DELTA_RELOC_NO DynTag = 0x7000001c
+ DT_MIPS_DELTA_SYM DynTag = 0x7000001d
+ DT_MIPS_DELTA_SYM_NO DynTag = 0x7000001e
+ DT_MIPS_DELTA_CLASSSYM DynTag = 0x70000020
+ DT_MIPS_DELTA_CLASSSYM_NO DynTag = 0x70000021
+ DT_MIPS_CXX_FLAGS DynTag = 0x70000022
+ DT_MIPS_PIXIE_INIT DynTag = 0x70000023
+ DT_MIPS_SYMBOL_LIB DynTag = 0x70000024
+ DT_MIPS_LOCALPAGE_GOTIDX DynTag = 0x70000025
+ DT_MIPS_LOCAL_GOTIDX DynTag = 0x70000026
+ DT_MIPS_HIDDEN_GOTIDX DynTag = 0x70000027
+ DT_MIPS_PROTECTED_GOTIDX DynTag = 0x70000028
+ DT_MIPS_OPTIONS DynTag = 0x70000029
+ DT_MIPS_INTERFACE DynTag = 0x7000002a
+ DT_MIPS_DYNSTR_ALIGN DynTag = 0x7000002b
+ DT_MIPS_INTERFACE_SIZE DynTag = 0x7000002c
+ DT_MIPS_RLD_TEXT_RESOLVE_ADDR DynTag = 0x7000002d
+ DT_MIPS_PERF_SUFFIX DynTag = 0x7000002e
+ DT_MIPS_COMPACT_SIZE DynTag = 0x7000002f
+ DT_MIPS_GP_VALUE DynTag = 0x70000030
+ DT_MIPS_AUX_DYNAMIC DynTag = 0x70000031
+ DT_MIPS_PLTGOT DynTag = 0x70000032
+ DT_MIPS_RWPLT DynTag = 0x70000034
+ DT_MIPS_RLD_MAP_REL DynTag = 0x70000035
+
+ DT_PPC_GOT DynTag = 0x70000000
+ DT_PPC_OPT DynTag = 0x70000001
+
+ DT_PPC64_GLINK DynTag = 0x70000000
+ DT_PPC64_OPD DynTag = 0x70000001
+ DT_PPC64_OPDSZ DynTag = 0x70000002
+ DT_PPC64_OPT DynTag = 0x70000003
+
+ DT_SPARC_REGISTER DynTag = 0x70000001
+
+ DT_AUXILIARY DynTag = 0x7ffffffd
+ DT_USED DynTag = 0x7ffffffe
+ DT_FILTER DynTag = 0x7fffffff
+
+ DT_HIPROC DynTag = 0x7fffffff /* Last processor-specific type. */
)
var dtStrings = []intName{
@@ -883,13 +1026,49 @@ var dtStrings = []intName{
{32, "DT_ENCODING"},
{32, "DT_PREINIT_ARRAY"},
{33, "DT_PREINIT_ARRAYSZ"},
+ {34, "DT_SYMTAB_SHNDX"},
{0x6000000d, "DT_LOOS"},
{0x6ffff000, "DT_HIOS"},
+ {0x6ffffd00, "DT_VALRNGLO"},
+ {0x6ffffdf5, "DT_GNU_PRELINKED"},
+ {0x6ffffdf6, "DT_GNU_CONFLICTSZ"},
+ {0x6ffffdf7, "DT_GNU_LIBLISTSZ"},
+ {0x6ffffdf8, "DT_CHECKSUM"},
+ {0x6ffffdf9, "DT_PLTPADSZ"},
+ {0x6ffffdfa, "DT_MOVEENT"},
+ {0x6ffffdfb, "DT_MOVESZ"},
+ {0x6ffffdfc, "DT_FEATURE"},
+ {0x6ffffdfd, "DT_POSFLAG_1"},
+ {0x6ffffdfe, "DT_SYMINSZ"},
+ {0x6ffffdff, "DT_SYMINENT"},
+ {0x6ffffdff, "DT_VALRNGHI"},
+ {0x6ffffe00, "DT_ADDRRNGLO"},
+ {0x6ffffef5, "DT_GNU_HASH"},
+ {0x6ffffef6, "DT_TLSDESC_PLT"},
+ {0x6ffffef7, "DT_TLSDESC_GOT"},
+ {0x6ffffef8, "DT_GNU_CONFLICT"},
+ {0x6ffffef9, "DT_GNU_LIBLIST"},
+ {0x6ffffefa, "DT_CONFIG"},
+ {0x6ffffefb, "DT_DEPAUDIT"},
+ {0x6ffffefc, "DT_AUDIT"},
+ {0x6ffffefd, "DT_PLTPAD"},
+ {0x6ffffefe, "DT_MOVETAB"},
+ {0x6ffffeff, "DT_SYMINFO"},
+ {0x6ffffeff, "DT_ADDRRNGHI"},
{0x6ffffff0, "DT_VERSYM"},
+ {0x6ffffff9, "DT_RELACOUNT"},
+ {0x6ffffffa, "DT_RELCOUNT"},
+ {0x6ffffffb, "DT_FLAGS_1"},
+ {0x6ffffffc, "DT_VERDEF"},
+ {0x6ffffffd, "DT_VERDEFNUM"},
{0x6ffffffe, "DT_VERNEED"},
{0x6fffffff, "DT_VERNEEDNUM"},
{0x70000000, "DT_LOPROC"},
- {0x7fffffff, "DT_HIPROC"},
+ // We don't list the processor-dependent DynTags,
+ // as the values overlap.
+ {0x7ffffffd, "DT_AUXILIARY"},
+ {0x7ffffffe, "DT_USED"},
+ {0x7fffffff, "DT_FILTER"},
}
func (i DynTag) String() string { return stringName(uint32(i), dtStrings, false) }
diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go
index 48178d4..b409167 100644
--- a/libgo/go/debug/elf/file.go
+++ b/libgo/go/debug/elf/file.go
@@ -634,23 +634,14 @@ func (f *File) applyRelocations(dst []byte, rels []byte) error {
}
}
-// relocSymbolTargetOK decides whether we should try to apply a
+// canApplyRelocation reports whether we should try to apply a
// relocation to a DWARF data section, given a pointer to the symbol
-// targeted by the relocation. Most relocations in DWARF data tend to
-// be section-relative, but some target non-section symbols (for
-// example, low_PC attrs on subprogram or compilation unit DIEs that
-// target function symbols), and we need to include these as well.
-// Return value is a pair (X,Y) where X is a boolean indicating
-// whether the relocation is needed, and Y is the symbol value in the
-// case of a non-section relocation that needs to be applied.
-func relocSymbolTargetOK(sym *Symbol) (bool, uint64) {
- if ST_TYPE(sym.Info) == STT_SECTION {
- return true, 0
- }
- if sym.Section != SHN_UNDEF && sym.Section < SHN_LORESERVE {
- return true, sym.Value
- }
- return false, 0
+// targeted by the relocation.
+// Most relocations in DWARF data tend to be section-relative, but
+// some target non-section symbols (for example, low_PC attrs on
+// subprogram or compilation unit DIEs that target function symbols).
+func canApplyRelocation(sym *Symbol) bool {
+ return sym.Section != SHN_UNDEF && sym.Section < SHN_LORESERVE
}
func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
@@ -676,8 +667,7 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -690,13 +680,13 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := val + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_X86_64_32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -802,8 +792,7 @@ func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -816,13 +805,13 @@ func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := uint64(val) + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_AARCH64_ABS32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -853,8 +842,7 @@ func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -863,7 +851,7 @@ func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error {
if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -894,8 +882,7 @@ func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -904,13 +891,13 @@ func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := val + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_PPC64_ADDR32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -986,8 +973,7 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -996,13 +982,13 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := val + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_MIPS_32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -1033,8 +1019,7 @@ func (f *File) applyRelocationsRISCV(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -1043,7 +1028,7 @@ func (f *File) applyRelocationsRISCV(dst []byte, rels []byte) error {
if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -1074,8 +1059,7 @@ func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -1084,13 +1068,13 @@ func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := val + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_RISCV_32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -1121,8 +1105,7 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -1131,13 +1114,13 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := val + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_390_32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
@@ -1208,8 +1191,7 @@ func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
continue
}
sym := &symbols[symNo-1]
- needed, val := relocSymbolTargetOK(sym)
- if !needed {
+ if !canApplyRelocation(sym) {
continue
}
@@ -1218,13 +1200,13 @@ func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val64 := val + uint64(rela.Addend)
+ val64 := sym.Value + uint64(rela.Addend)
f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
case R_SPARC_32, R_SPARC_UA32:
if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
continue
}
- val32 := uint32(val) + uint32(rela.Addend)
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
}
}
diff --git a/libgo/go/debug/elf/file_test.go b/libgo/go/debug/elf/file_test.go
index b13d13e..4c6fdee 100644
--- a/libgo/go/debug/elf/file_test.go
+++ b/libgo/go/debug/elf/file_test.go
@@ -293,6 +293,7 @@ func decompress(gz string) (io.ReaderAt, error) {
type relocationTestEntry struct {
entryNumber int
entry *dwarf.Entry
+ pcRanges [][2]uint64
}
type relocationTest struct {
@@ -304,367 +305,481 @@ var relocationTests = []relocationTest{
{
"testdata/go-relocation-test-gcc441-x86-64.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x6}},
+ },
},
},
{
"testdata/go-relocation-test-gcc441-x86.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x5}},
+ },
},
},
{
"testdata/go-relocation-test-gcc424-x86-64.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x6}},
+ },
},
},
{
"testdata/go-relocation-test-gcc482-aarch64.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x24}},
+ },
},
},
{
"testdata/go-relocation-test-gcc492-arm.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x28}},
+ },
},
},
{
"testdata/go-relocation-test-clang-arm.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrStmtList, Val: int64(0x0), Class: dwarf.ClassLinePtr},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(48), Class: dwarf.ClassConstant},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrStmtList, Val: int64(0x0), Class: dwarf.ClassLinePtr},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x30), Class: dwarf.ClassConstant},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x30}},
+ },
},
},
{
"testdata/go-relocation-test-gcc5-ppc.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x44}},
+ },
},
},
{
"testdata/go-relocation-test-gcc482-ppc64le.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x24}},
+ },
},
},
{
"testdata/go-relocation-test-gcc492-mips64.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -g", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(100), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -g", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x64), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x64}},
+ },
},
},
{
"testdata/go-relocation-test-gcc531-s390x.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strong", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(58), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strong", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x3a), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x3a}},
+ },
},
},
{
"testdata/go-relocation-test-gcc620-sparc64.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(0x2c), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x2c), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x2c}},
+ },
},
},
{
"testdata/go-relocation-test-gcc492-mipsle.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -mel -march=mips2 -mtune=mips32 -mllsc -mno-shared -mabi=32 -g", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(0x58), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -mel -march=mips2 -mtune=mips32 -mllsc -mno-shared -mabi=32 -g", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x58), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x58}},
+ },
},
},
{
"testdata/go-relocation-test-gcc540-mips.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C11 5.4.0 20160609 -meb -mips32 -mtune=mips32r2 -mfpxx -mllsc -mno-shared -mabi=32 -g -gdwarf-2", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: uint64(0x5c), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C11 5.4.0 20160609 -meb -mips32 -mtune=mips32r2 -mfpxx -mllsc -mno-shared -mabi=32 -g -gdwarf-2", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: uint64(0x5c), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x5c}},
+ },
},
},
{
"testdata/go-relocation-test-gcc493-mips64le.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strong", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: int64(100), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strong", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: int64(0x64), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x64}},
+ },
},
},
{
"testdata/go-relocation-test-gcc720-riscv64.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "GNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrHighpc, Val: uint64(0x2c), Class: dwarf.ClassAddress},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrHighpc, Val: uint64(0x2c), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
},
- }},
+ pcRanges: [][2]uint64{{0x0, 0x2c}},
+ },
},
},
{
"testdata/go-relocation-test-clang-x86.obj",
[]relocationTestEntry{
- {0, &dwarf.Entry{
- Offset: 0xb,
- Tag: dwarf.TagCompileUnit,
- Children: true,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString},
- {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString},
- {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
- {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ },
},
- }},
+ },
},
},
{
"testdata/gcc-amd64-openbsd-debug-with-rela.obj",
[]relocationTestEntry{
- {203, &dwarf.Entry{
- Offset: 0xc62,
- Tag: dwarf.TagMember,
- Children: false,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString},
- {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
- {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc},
+ {
+ entryNumber: 203,
+ entry: &dwarf.Entry{
+ Offset: 0xc62,
+ Tag: dwarf.TagMember,
+ Children: false,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
+ {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc},
+ },
},
- }},
- {204, &dwarf.Entry{
- Offset: 0xc70,
- Tag: dwarf.TagMember,
- Children: false,
- Field: []dwarf.Field{
- {Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString},
- {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant},
- {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
- {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc},
+ },
+ {
+ entryNumber: 204,
+ entry: &dwarf.Entry{
+ Offset: 0xc70,
+ Tag: dwarf.TagMember,
+ Children: false,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference},
+ {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc},
+ },
},
- }},
+ },
+ },
+ },
+ {
+ "testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64",
+ []relocationTestEntry{
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fno-asynchronous-unwind-tables", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
+ },
+ pcRanges: [][2]uint64{
+ {0x765, 0x777},
+ {0x7e1, 0x7ec},
+ },
+ },
+ },
+ },
+ {
+ "testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64",
+ []relocationTestEntry{
+ {
+ entry: &dwarf.Entry{
+ Offset: 0xb,
+ Tag: dwarf.TagCompileUnit,
+ Children: true,
+ Field: []dwarf.Field{
+ {Attr: dwarf.AttrProducer, Val: "GNU C17 9.3.0 -mtune=generic -march=x86-64 -g -fno-asynchronous-unwind-tables", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant},
+ {Attr: dwarf.AttrName, Val: "multiple-code-sections.c", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString},
+ {Attr: dwarf.AttrRanges, Val: int64(0), Class: dwarf.ClassRangeListPtr},
+ {Attr: dwarf.AttrLowpc, Val: uint64(0), Class: dwarf.ClassAddress},
+ {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr},
+ },
+ },
+ pcRanges: [][2]uint64{
+ {0x765, 0x777},
+ {0x7e1, 0x7ec},
+ },
+ },
},
},
}
func TestDWARFRelocations(t *testing.T) {
- for i, test := range relocationTests {
- f, err := Open(test.file)
- if err != nil {
- t.Error(err)
- continue
- }
- dwarf, err := f.DWARF()
- if err != nil {
- t.Error(err)
- continue
- }
- for _, testEntry := range test.entries {
- reader := dwarf.Reader()
- for j := 0; j < testEntry.entryNumber; j++ {
- entry, err := reader.Next()
- if entry == nil || err != nil {
- t.Errorf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
- continue
- }
+ for _, test := range relocationTests {
+ test := test
+ t.Run(test.file, func(t *testing.T) {
+ t.Parallel()
+ f, err := Open(test.file)
+ if err != nil {
+ t.Fatal(err)
}
- entry, err := reader.Next()
+ dwarf, err := f.DWARF()
if err != nil {
- t.Error(err)
- continue
+ t.Fatal(err)
}
- if !reflect.DeepEqual(testEntry.entry, entry) {
- t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry)
- continue
+ reader := dwarf.Reader()
+ idx := 0
+ for _, testEntry := range test.entries {
+ if testEntry.entryNumber < idx {
+ t.Fatalf("internal test error: %d < %d", testEntry.entryNumber, idx)
+ }
+ for ; idx < testEntry.entryNumber; idx++ {
+ entry, err := reader.Next()
+ if entry == nil || err != nil {
+ t.Fatalf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
+ }
+ }
+ entry, err := reader.Next()
+ idx++
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(testEntry.entry, entry) {
+ t.Errorf("entry %d mismatch: got:%#v want:%#v", testEntry.entryNumber, entry, testEntry.entry)
+ }
+ pcRanges, err := dwarf.Ranges(entry)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(testEntry.pcRanges, pcRanges) {
+ t.Errorf("entry %d: PC range mismatch: got:%#v want:%#v", testEntry.entryNumber, pcRanges, testEntry.pcRanges)
+ }
}
- }
+ })
}
}
@@ -784,7 +899,7 @@ func TestCompressedSection(t *testing.T) {
func TestNoSectionOverlaps(t *testing.T) {
// Ensure cmd/link outputs sections without overlaps.
switch runtime.GOOS {
- case "aix", "android", "darwin", "js", "plan9", "windows":
+ case "aix", "android", "darwin", "ios", "js", "plan9", "windows":
t.Skipf("cmd/link doesn't produce ELF binaries on %s", runtime.GOOS)
}
_ = net.ResolveIPAddr // force dynamic linkage
diff --git a/libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64 b/libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64
new file mode 100644
index 0000000..c013f3e
--- /dev/null
+++ b/libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-no-rela-x86-64
Binary files differ
diff --git a/libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64 b/libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64
new file mode 100644
index 0000000..51e03aa
--- /dev/null
+++ b/libgo/go/debug/elf/testdata/go-relocation-test-gcc930-ranges-with-rela-x86-64
Binary files differ
diff --git a/libgo/go/debug/elf/testdata/multiple-code-sections.c b/libgo/go/debug/elf/testdata/multiple-code-sections.c
new file mode 100644
index 0000000..03b9d53
--- /dev/null
+++ b/libgo/go/debug/elf/testdata/multiple-code-sections.c
@@ -0,0 +1,28 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Build with:
+// gcc -g multiple-code-sections.c -Wl,--emit-relocs -Wl,--discard-none -Wl,-zmax-page-size=1 -fno-asynchronous-unwind-tables -o go-relocation-test-gcc930-ranges-with-rela-x86-64
+// gcc -g multiple-code-sections.c -Wl,-zmax-page-size=1 -fno-asynchronous-unwind-tables -o go-relocation-test-gcc930-ranges-no-rela-x86-64
+// Strip with:
+// strip --only-keep-debug \
+// --remove-section=.eh_frame \
+// --remove-section=.eh_frame_hdr \
+// --remove-section=.shstrtab \
+// --remove-section=.strtab \
+// --remove-section=.symtab \
+// --remove-section=.note.gnu.build-id \
+// --remove-section=.note.ABI-tag \
+// --remove-section=.dynamic \
+// --remove-section=.gnu.hash \
+// --remove-section=.interp \
+// --remove-section=.rodata
+__attribute__((section(".separate_section"))) // To get GCC to emit a DW_AT_ranges attribute for the CU.
+int func(void) {
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ return 0;
+}
diff --git a/libgo/go/debug/gosym/pclntab.go b/libgo/go/debug/gosym/pclntab.go
index 7e54a94..a72f984 100644
--- a/libgo/go/debug/gosym/pclntab.go
+++ b/libgo/go/debug/gosym/pclntab.go
@@ -14,6 +14,16 @@ import (
"sync"
)
+// version of the pclntab
+type version int
+
+const (
+ verUnknown version = iota
+ ver11
+ ver12
+ ver116
+)
+
// A LineTable is a data structure mapping program counters to line numbers.
//
// In Go 1.1 and earlier, each function (represented by a Func) had its own LineTable,
@@ -32,18 +42,30 @@ type LineTable struct {
PC uint64
Line int
- // Go 1.2 state
- mu sync.Mutex
- go12 int // is this in Go 1.2 format? -1 no, 0 unknown, 1 yes
- binary binary.ByteOrder
- quantum uint32
- ptrsize uint32
- functab []byte
- nfunctab uint32
- filetab []byte
- nfiletab uint32
- fileMap map[string]uint32
- strings map[uint32]string // interned substrings of Data, keyed by offset
+ // This mutex is used to keep parsing of pclntab synchronous.
+ mu sync.Mutex
+
+ // Contains the version of the pclntab section.
+ version version
+
+ // Go 1.2/1.16 state
+ binary binary.ByteOrder
+ quantum uint32
+ ptrsize uint32
+ funcnametab []byte
+ cutab []byte
+ funcdata []byte
+ functab []byte
+ nfunctab uint32
+ filetab []byte
+ pctab []byte // points to the pctables.
+ nfiletab uint32
+ funcNames map[uint32]string // cache the function names
+ strings map[uint32]string // interned substrings of Data, keyed by offset
+ // fileMap varies depending on the version of the object file.
+ // For ver12, it maps the name to the index in the file table.
+ // For ver116, it maps the name to the offset in filetab.
+ fileMap map[string]uint32
}
// NOTE(rsc): This is wrong for GOARCH=arm, which uses a quantum of 4,
@@ -124,7 +146,7 @@ func (t *LineTable) LineToPC(line int, maxpc uint64) uint64 {
// Text must be the start address of the
// corresponding text segment.
func NewLineTable(data []byte, text uint64) *LineTable {
- return &LineTable{Data: data, PC: text, Line: 0, strings: make(map[uint32]string)}
+ return &LineTable{Data: data, PC: text, Line: 0, funcNames: make(map[uint32]string), strings: make(map[uint32]string)}
}
// Go 1.2 symbol table format.
@@ -140,11 +162,12 @@ func NewLineTable(data []byte, text uint64) *LineTable {
// isGo12 reports whether this is a Go 1.2 (or later) symbol table.
func (t *LineTable) isGo12() bool {
- t.go12Init()
- return t.go12 == 1
+ t.parsePclnTab()
+ return t.version >= ver12
}
const go12magic = 0xfffffffb
+const go116magic = 0xfffffffa
// uintptr returns the pointer-sized value encoded at b.
// The pointer size is dictated by the table being read.
@@ -155,49 +178,86 @@ func (t *LineTable) uintptr(b []byte) uint64 {
return t.binary.Uint64(b)
}
-// go12init initializes the Go 1.2 metadata if t is a Go 1.2 symbol table.
-func (t *LineTable) go12Init() {
+// parsePclnTab parses the pclntab, setting the version.
+func (t *LineTable) parsePclnTab() {
t.mu.Lock()
defer t.mu.Unlock()
- if t.go12 != 0 {
+ if t.version != verUnknown {
return
}
+ // Note that during this function, setting the version is the last thing we do.
+ // If we set the version too early, and parsing failed (likely as a panic on
+ // slice lookups), we'd have a mistaken version.
+ //
+ // Error paths through this code will default the version to 1.1.
+ t.version = ver11
+
defer func() {
- // If we panic parsing, assume it's not a Go 1.2 symbol table.
+ // If we panic parsing, assume it's a Go 1.1 pclntab.
recover()
}()
// Check header: 4-byte magic, two zeros, pc quantum, pointer size.
- t.go12 = -1 // not Go 1.2 until proven otherwise
if len(t.Data) < 16 || t.Data[4] != 0 || t.Data[5] != 0 ||
(t.Data[6] != 1 && t.Data[6] != 2 && t.Data[6] != 4) || // pc quantum
(t.Data[7] != 4 && t.Data[7] != 8) { // pointer size
return
}
- switch uint32(go12magic) {
- case binary.LittleEndian.Uint32(t.Data):
- t.binary = binary.LittleEndian
- case binary.BigEndian.Uint32(t.Data):
- t.binary = binary.BigEndian
+ var possibleVersion version
+ leMagic := binary.LittleEndian.Uint32(t.Data)
+ beMagic := binary.BigEndian.Uint32(t.Data)
+ switch {
+ case leMagic == go12magic:
+ t.binary, possibleVersion = binary.LittleEndian, ver12
+ case beMagic == go12magic:
+ t.binary, possibleVersion = binary.BigEndian, ver12
+ case leMagic == go116magic:
+ t.binary, possibleVersion = binary.LittleEndian, ver116
+ case beMagic == go116magic:
+ t.binary, possibleVersion = binary.BigEndian, ver116
default:
return
}
+ // quantum and ptrSize are the same between 1.2 and 1.16
t.quantum = uint32(t.Data[6])
t.ptrsize = uint32(t.Data[7])
- t.nfunctab = uint32(t.uintptr(t.Data[8:]))
- t.functab = t.Data[8+t.ptrsize:]
- functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize
- fileoff := t.binary.Uint32(t.functab[functabsize:])
- t.functab = t.functab[:functabsize]
- t.filetab = t.Data[fileoff:]
- t.nfiletab = t.binary.Uint32(t.filetab)
- t.filetab = t.filetab[:t.nfiletab*4]
-
- t.go12 = 1 // so far so good
+ switch possibleVersion {
+ case ver116:
+ t.nfunctab = uint32(t.uintptr(t.Data[8:]))
+ t.nfiletab = uint32(t.uintptr(t.Data[8+t.ptrsize:]))
+ offset := t.uintptr(t.Data[8+2*t.ptrsize:])
+ t.funcnametab = t.Data[offset:]
+ offset = t.uintptr(t.Data[8+3*t.ptrsize:])
+ t.cutab = t.Data[offset:]
+ offset = t.uintptr(t.Data[8+4*t.ptrsize:])
+ t.filetab = t.Data[offset:]
+ offset = t.uintptr(t.Data[8+5*t.ptrsize:])
+ t.pctab = t.Data[offset:]
+ offset = t.uintptr(t.Data[8+6*t.ptrsize:])
+ t.funcdata = t.Data[offset:]
+ t.functab = t.Data[offset:]
+ functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize
+ t.functab = t.functab[:functabsize]
+ case ver12:
+ t.nfunctab = uint32(t.uintptr(t.Data[8:]))
+ t.funcdata = t.Data
+ t.funcnametab = t.Data
+ t.functab = t.Data[8+t.ptrsize:]
+ t.pctab = t.Data
+ functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize
+ fileoff := t.binary.Uint32(t.functab[functabsize:])
+ t.functab = t.functab[:functabsize]
+ t.filetab = t.Data[fileoff:]
+ t.nfiletab = t.binary.Uint32(t.filetab)
+ t.filetab = t.filetab[:t.nfiletab*4]
+ default:
+ panic("unreachable")
+ }
+ t.version = possibleVersion
}
// go12Funcs returns a slice of Funcs derived from the Go 1.2 pcln table.
@@ -213,13 +273,13 @@ func (t *LineTable) go12Funcs() []Func {
f := &funcs[i]
f.Entry = t.uintptr(t.functab[2*i*int(t.ptrsize):])
f.End = t.uintptr(t.functab[(2*i+2)*int(t.ptrsize):])
- info := t.Data[t.uintptr(t.functab[(2*i+1)*int(t.ptrsize):]):]
+ info := t.funcdata[t.uintptr(t.functab[(2*i+1)*int(t.ptrsize):]):]
f.LineTable = t
f.FrameSize = int(t.binary.Uint32(info[t.ptrsize+2*4:]))
f.Sym = &Sym{
Value: f.Entry,
Type: 'T',
- Name: t.string(t.binary.Uint32(info[t.ptrsize:])),
+ Name: t.funcName(t.binary.Uint32(info[t.ptrsize:])),
GoType: 0,
Func: f,
}
@@ -241,7 +301,7 @@ func (t *LineTable) findFunc(pc uint64) []byte {
m := nf / 2
fm := f[2*t.ptrsize*m:]
if t.uintptr(fm) <= pc && pc < t.uintptr(fm[2*t.ptrsize:]) {
- return t.Data[t.uintptr(fm[t.ptrsize:]):]
+ return t.funcdata[t.uintptr(fm[t.ptrsize:]):]
} else if pc < t.uintptr(fm) {
nf = m
} else {
@@ -268,17 +328,33 @@ func (t *LineTable) readvarint(pp *[]byte) uint32 {
return v
}
-// string returns a Go string found at off.
-func (t *LineTable) string(off uint32) string {
+// funcName returns the name of the function found at off.
+func (t *LineTable) funcName(off uint32) string {
+ if s, ok := t.funcNames[off]; ok {
+ return s
+ }
+ i := bytes.IndexByte(t.funcnametab[off:], 0)
+ s := string(t.funcnametab[off : off+uint32(i)])
+ t.funcNames[off] = s
+ return s
+}
+
+// stringFrom returns a Go string found at off from a position.
+func (t *LineTable) stringFrom(arr []byte, off uint32) string {
if s, ok := t.strings[off]; ok {
return s
}
- i := bytes.IndexByte(t.Data[off:], 0)
- s := string(t.Data[off : off+uint32(i)])
+ i := bytes.IndexByte(arr[off:], 0)
+ s := string(arr[off : off+uint32(i)])
t.strings[off] = s
return s
}
+// string returns a Go string found at off.
+func (t *LineTable) string(off uint32) string {
+ return t.stringFrom(t.funcdata, off)
+}
+
// step advances to the next pc, value pair in the encoded table.
func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool {
uvdelta := t.readvarint(p)
@@ -301,7 +377,7 @@ func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool {
// off is the offset to the beginning of the pc-value table,
// and entry is the start PC for the corresponding function.
func (t *LineTable) pcvalue(off uint32, entry, targetpc uint64) int32 {
- p := t.Data[off:]
+ p := t.pctab[off:]
val := int32(-1)
pc := entry
@@ -319,21 +395,25 @@ func (t *LineTable) pcvalue(off uint32, entry, targetpc uint64) int32 {
// to file number. Since most functions come from a single file, these
// are usually short and quick to scan. If a file match is found, then the
// code goes to the expense of looking for a simultaneous line number match.
-func (t *LineTable) findFileLine(entry uint64, filetab, linetab uint32, filenum, line int32) uint64 {
+func (t *LineTable) findFileLine(entry uint64, filetab, linetab uint32, filenum, line int32, cutab []byte) uint64 {
if filetab == 0 || linetab == 0 {
return 0
}
- fp := t.Data[filetab:]
- fl := t.Data[linetab:]
+ fp := t.pctab[filetab:]
+ fl := t.pctab[linetab:]
fileVal := int32(-1)
filePC := entry
lineVal := int32(-1)
linePC := entry
fileStartPC := filePC
for t.step(&fp, &filePC, &fileVal, filePC == entry) {
- if fileVal == filenum && fileStartPC < filePC {
- // fileVal is in effect starting at fileStartPC up to
+ fileIndex := fileVal
+ if t.version == ver116 {
+ fileIndex = int32(t.binary.Uint32(cutab[fileVal*4:]))
+ }
+ if fileIndex == filenum && fileStartPC < filePC {
+ // fileIndex is in effect starting at fileStartPC up to
// but not including filePC, and it's the file we want.
// Run the PC table looking for a matching line number
// or until we reach filePC.
@@ -388,13 +468,24 @@ func (t *LineTable) go12PCToFile(pc uint64) (file string) {
entry := t.uintptr(f)
filetab := t.binary.Uint32(f[t.ptrsize+4*4:])
fno := t.pcvalue(filetab, entry, pc)
- if fno <= 0 {
+ if t.version == ver12 {
+ if fno <= 0 {
+ return ""
+ }
+ return t.string(t.binary.Uint32(t.filetab[4*fno:]))
+ }
+ // Go ≥ 1.16
+ if fno < 0 { // 0 is valid for ≥ 1.16
return ""
}
- return t.string(t.binary.Uint32(t.filetab[4*fno:]))
+ cuoff := t.binary.Uint32(f[t.ptrsize+7*4:])
+ if fnoff := t.binary.Uint32(t.cutab[(cuoff+uint32(fno))*4:]); fnoff != ^uint32(0) {
+ return t.stringFrom(t.filetab, fnoff)
+ }
+ return ""
}
-// go12LineToPC maps a (file, line) pair to a program counter for the Go 1.2 pcln table.
+// go12LineToPC maps a (file, line) pair to a program counter for the Go 1.2/1.16 pcln table.
func (t *LineTable) go12LineToPC(file string, line int) (pc uint64) {
defer func() {
if recover() != nil {
@@ -403,20 +494,25 @@ func (t *LineTable) go12LineToPC(file string, line int) (pc uint64) {
}()
t.initFileMap()
- filenum := t.fileMap[file]
- if filenum == 0 {
+ filenum, ok := t.fileMap[file]
+ if !ok {
return 0
}
// Scan all functions.
// If this turns out to be a bottleneck, we could build a map[int32][]int32
// mapping file number to a list of functions with code from that file.
+ var cutab []byte
for i := uint32(0); i < t.nfunctab; i++ {
- f := t.Data[t.uintptr(t.functab[2*t.ptrsize*i+t.ptrsize:]):]
+ f := t.funcdata[t.uintptr(t.functab[2*t.ptrsize*i+t.ptrsize:]):]
entry := t.uintptr(f)
filetab := t.binary.Uint32(f[t.ptrsize+4*4:])
linetab := t.binary.Uint32(f[t.ptrsize+5*4:])
- pc := t.findFileLine(entry, filetab, linetab, int32(filenum), int32(line))
+ if t.version == ver116 {
+ cuoff := t.binary.Uint32(f[t.ptrsize+7*4:]) * 4
+ cutab = t.cutab[cuoff:]
+ }
+ pc := t.findFileLine(entry, filetab, linetab, int32(filenum), int32(line), cutab)
if pc != 0 {
return pc
}
@@ -434,9 +530,18 @@ func (t *LineTable) initFileMap() {
}
m := make(map[string]uint32)
- for i := uint32(1); i < t.nfiletab; i++ {
- s := t.string(t.binary.Uint32(t.filetab[4*i:]))
- m[s] = i
+ if t.version == ver12 {
+ for i := uint32(1); i < t.nfiletab; i++ {
+ s := t.string(t.binary.Uint32(t.filetab[4*i:]))
+ m[s] = i
+ }
+ } else {
+ var pos uint32
+ for i := uint32(0); i < t.nfiletab; i++ {
+ s := t.stringFrom(t.filetab, pos)
+ m[s] = pos
+ pos += uint32(len(s) + 1)
+ }
}
t.fileMap = m
}
diff --git a/libgo/go/debug/gosym/pclntab_test.go b/libgo/go/debug/gosym/pclntab_test.go
index 6baa53d..7347139 100644
--- a/libgo/go/debug/gosym/pclntab_test.go
+++ b/libgo/go/debug/gosym/pclntab_test.go
@@ -5,9 +5,11 @@
package gosym
import (
+ "bytes"
+ "compress/gzip"
"debug/elf"
"internal/testenv"
- "io/ioutil"
+ "io"
"os"
"os/exec"
"path/filepath"
@@ -28,7 +30,7 @@ func dotest(t *testing.T) {
t.Skipf("skipping on non-AMD64 system %s", runtime.GOARCH)
}
var err error
- pclineTempDir, err = ioutil.TempDir("", "pclinetest")
+ pclineTempDir, err = os.MkdirTemp("", "pclinetest")
if err != nil {
t.Fatal(err)
}
@@ -264,3 +266,51 @@ func TestPCLine(t *testing.T) {
off = pc + 1 - text.Addr
}
}
+
+// Test that we can parse a pclntab from 1.15.
+// The file was compiled in /tmp/hello.go:
+// [BEGIN]
+// package main
+//
+// func main() {
+// println("hello")
+// }
+// [END]
+func Test115PclnParsing(t *testing.T) {
+ zippedDat, err := os.ReadFile("testdata/pcln115.gz")
+ if err != nil {
+ t.Fatal(err)
+ }
+ var gzReader *gzip.Reader
+ gzReader, err = gzip.NewReader(bytes.NewBuffer(zippedDat))
+ if err != nil {
+ t.Fatal(err)
+ }
+ var dat []byte
+ dat, err = io.ReadAll(gzReader)
+ if err != nil {
+ t.Fatal(err)
+ }
+ const textStart = 0x1001000
+ pcln := NewLineTable(dat, textStart)
+ var tab *Table
+ tab, err = NewTable(nil, pcln)
+ if err != nil {
+ t.Fatal(err)
+ }
+ var f *Func
+ var pc uint64
+ pc, f, err = tab.LineToPC("/tmp/hello.go", 3)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if pcln.version != ver12 {
+ t.Fatal("Expected pcln to parse as an older version")
+ }
+ if pc != 0x105c280 {
+ t.Fatalf("expect pc = 0x105c280, got 0x%x", pc)
+ }
+ if f.Name != "main.main" {
+ t.Fatalf("expected to parse name as main.main, got %v", f.Name)
+ }
+}
diff --git a/libgo/go/debug/pe/file_test.go b/libgo/go/debug/pe/file_test.go
index d96cd30..58deff1 100644
--- a/libgo/go/debug/pe/file_test.go
+++ b/libgo/go/debug/pe/file_test.go
@@ -8,7 +8,6 @@ import (
"bytes"
"debug/dwarf"
"internal/testenv"
- "io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -354,7 +353,7 @@ func testDWARF(t *testing.T, linktype int) {
}
testenv.MustHaveGoRun(t)
- tmpdir, err := ioutil.TempDir("", "TestDWARF")
+ tmpdir, err := os.MkdirTemp("", "TestDWARF")
if err != nil {
t.Fatal(err)
}
@@ -473,7 +472,7 @@ func TestBSSHasZeros(t *testing.T) {
t.Skip("skipping test: gcc is missing")
}
- tmpdir, err := ioutil.TempDir("", "TestBSSHasZeros")
+ tmpdir, err := os.MkdirTemp("", "TestBSSHasZeros")
if err != nil {
t.Fatal(err)
}
@@ -492,7 +491,7 @@ main(void)
return 0;
}
`
- err = ioutil.WriteFile(srcpath, []byte(src), 0644)
+ err = os.WriteFile(srcpath, []byte(src), 0644)
if err != nil {
t.Fatal(err)
}
@@ -597,14 +596,14 @@ func TestBuildingWindowsGUI(t *testing.T) {
if runtime.GOOS != "windows" {
t.Skip("skipping windows only test")
}
- tmpdir, err := ioutil.TempDir("", "TestBuildingWindowsGUI")
+ tmpdir, err := os.MkdirTemp("", "TestBuildingWindowsGUI")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpdir)
src := filepath.Join(tmpdir, "a.go")
- err = ioutil.WriteFile(src, []byte(`package main; func main() {}`), 0644)
+ err = os.WriteFile(src, []byte(`package main; func main() {}`), 0644)
if err != nil {
t.Fatal(err)
}
@@ -684,7 +683,7 @@ func TestInvalidOptionalHeaderMagic(t *testing.T) {
func TestImportedSymbolsNoPanicMissingOptionalHeader(t *testing.T) {
// https://golang.org/issue/30250
// ImportedSymbols shouldn't panic if optional headers is missing
- data, err := ioutil.ReadFile("testdata/gcc-amd64-mingw-obj")
+ data, err := os.ReadFile("testdata/gcc-amd64-mingw-obj")
if err != nil {
t.Fatal(err)
}