aboutsummaryrefslogtreecommitdiff
path: root/src/debug/elf
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2015-12-01 22:55:28 -0500
committerAustin Clements <austin@google.com>2015-12-03 20:53:04 +0000
commite1544d3bb68d56ebf43cc8828e3dce18fd5ef442 (patch)
tree243cedefafec4e8420a23416b316547609e29a5b /src/debug/elf
parent606d9a7e18c951bb64ea460597894558ff3808c1 (diff)
downloadgo-e1544d3bb68d56ebf43cc8828e3dce18fd5ef442.tar.xz
dwbug/elf: support old-style compressed DWARF
GCC and LLVM support zlib-compressing DWARF debug sections (and there's some evidence that this may be happening by default in some circumstances now). Add support for reading compressed DWARF sections. Since ELF relocations apply to the decompressed data, decompression is done before applying relocations. Since relcations are applied by debug/elf, decompression must also be handled there. Note that this is different from compressed ELF sections, which is a more general mechanism used by very recent versions of GCC. Updates #11773. Change-Id: I3f4bf1b04d0802cc1e8fcb7c2a5fcf6c467c5089 Reviewed-on: https://go-review.googlesource.com/17340 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
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