aboutsummaryrefslogtreecommitdiff
path: root/src/debug/elf
diff options
context:
space:
mode:
Diffstat (limited to 'src/debug/elf')
-rw-r--r--src/debug/elf/file.go29
-rw-r--r--src/debug/elf/file_test.go28
-rw-r--r--src/debug/elf/testdata/zdebug-test-gcc484-x86-64.objbin0 -> 3216 bytes
3 files changed, 54 insertions, 3 deletions
diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go
index 3e766afe15..a42bde94f8 100644
--- a/src/debug/elf/file.go
+++ b/src/debug/elf/file.go
@@ -7,6 +7,7 @@ package elf
import (
"bytes"
+ "compress/zlib"
"debug/dwarf"
"encoding/binary"
"errors"
@@ -863,6 +864,22 @@ func (f *File) DWARF() (*dwarf.Data, error) {
return nil, err
}
+ if len(b) >= 12 && string(b[:4]) == "ZLIB" {
+ dlen := binary.BigEndian.Uint64(b[4:12])
+ dbuf := make([]byte, dlen)
+ r, err := zlib.NewReader(bytes.NewBuffer(b[12:]))
+ if err != nil {
+ return nil, err
+ }
+ if _, err := io.ReadFull(r, dbuf); err != nil {
+ return nil, err
+ }
+ if err := r.Close(); err != nil {
+ return nil, err
+ }
+ b = dbuf
+ }
+
for _, r := range f.Sections {
if r.Type != SHT_RELA && r.Type != SHT_REL {
continue
@@ -887,17 +904,23 @@ func (f *File) DWARF() (*dwarf.Data, error) {
// Don't bother loading others.
var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil}
for i, s := range f.Sections {
- if !strings.HasPrefix(s.Name, ".debug_") {
+ suffix := ""
+ switch {
+ case strings.HasPrefix(s.Name, ".debug_"):
+ suffix = s.Name[7:]
+ case strings.HasPrefix(s.Name, ".zdebug_"):
+ suffix = s.Name[8:]
+ default:
continue
}
- if _, ok := dat[s.Name[7:]]; !ok {
+ if _, ok := dat[suffix]; !ok {
continue
}
b, err := sectionData(i, s)
if err != nil {
return nil, err
}
- dat[s.Name[7:]] = b
+ dat[suffix] = b
}
d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], dat["line"], nil, nil, dat["str"])
diff --git a/src/debug/elf/file_test.go b/src/debug/elf/file_test.go
index cd1a4577af..6864b6df79 100644
--- a/src/debug/elf/file_test.go
+++ b/src/debug/elf/file_test.go
@@ -514,6 +514,34 @@ func TestDWARFRelocations(t *testing.T) {
}
}
+func TestCompressedDWARF(t *testing.T) {
+ // Test file built with GCC 4.8.4 and as 2.24 using:
+ // gcc -Wa,--compress-debug-sections -g -c -o zdebug-test-gcc484-x86-64.obj hello.c
+ f, err := Open("testdata/zdebug-test-gcc484-x86-64.obj")
+ if err != nil {
+ t.Fatal(err)
+ }
+ dwarf, err := f.DWARF()
+ if err != nil {
+ t.Fatal(err)
+ }
+ reader := dwarf.Reader()
+ n := 0
+ for {
+ entry, err := reader.Next()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if entry == nil {
+ break
+ }
+ n++
+ }
+ if n != 18 {
+ t.Fatalf("want %d DWARF entries, got %d", 18, n)
+ }
+}
+
func TestNoSectionOverlaps(t *testing.T) {
// Ensure 6l outputs sections without overlaps.
if runtime.GOOS != "linux" && runtime.GOOS != "freebsd" {
diff --git a/src/debug/elf/testdata/zdebug-test-gcc484-x86-64.obj b/src/debug/elf/testdata/zdebug-test-gcc484-x86-64.obj
new file mode 100644
index 0000000000..a595a01df4
--- /dev/null
+++ b/src/debug/elf/testdata/zdebug-test-gcc484-x86-64.obj
Binary files differ