diff options
| author | Austin Clements <austin@google.com> | 2015-12-01 22:55:28 -0500 |
|---|---|---|
| committer | Austin Clements <austin@google.com> | 2015-12-03 20:53:04 +0000 |
| commit | e1544d3bb68d56ebf43cc8828e3dce18fd5ef442 (patch) | |
| tree | 243cedefafec4e8420a23416b316547609e29a5b /src/debug | |
| parent | 606d9a7e18c951bb64ea460597894558ff3808c1 (diff) | |
| download | go-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')
| -rw-r--r-- | src/debug/elf/file.go | 29 | ||||
| -rw-r--r-- | src/debug/elf/file_test.go | 28 | ||||
| -rw-r--r-- | src/debug/elf/testdata/zdebug-test-gcc484-x86-64.obj | bin | 0 -> 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 Binary files differnew file mode 100644 index 0000000000..a595a01df4 --- /dev/null +++ b/src/debug/elf/testdata/zdebug-test-gcc484-x86-64.obj |
