aboutsummaryrefslogtreecommitdiff
path: root/src/debug
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2023-03-03 14:29:44 -0800
committerGopher Robot <gobot@golang.org>2023-04-18 20:34:36 +0000
commit48a1dcb92778a349e13bcb8be10a40047f0cf7d1 (patch)
tree6e708f1dab53c571657621cfd925d2d4f1431fb1 /src/debug
parent73ee0fcf375c12e52997870125dbbac7aad96284 (diff)
downloadgo-48a1dcb92778a349e13bcb8be10a40047f0cf7d1.tar.xz
debug/elf: support zstd compression
Test cases added to debug/dwarf because that is where it matters in practice. The new test binary line-gcc-zstd.elf built with gcc -g -no-pie -Wl,--compress-debug-sections=zstd line[12].c using gcc (Debian 12.2.0-10) 12.2.0 with a development version of the GNU binutils. Fixes #55107 Change-Id: I48507c96902e1f83a174e5647b5cc403d965b52b Reviewed-on: https://go-review.googlesource.com/c/go/+/473256 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Run-TryBot: Ian Lance Taylor <iant@google.com> Run-TryBot: Ian Lance Taylor <iant@golang.org> Auto-Submit: Ian Lance Taylor <iant@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'src/debug')
-rw-r--r--src/debug/dwarf/entry_test.go15
-rw-r--r--src/debug/dwarf/line_test.go46
-rw-r--r--src/debug/dwarf/testdata/line-gcc-zstd.elfbin0 -> 17168 bytes
-rw-r--r--src/debug/elf/elf.go2
-rw-r--r--src/debug/elf/elf_test.go2
-rw-r--r--src/debug/elf/file.go5
6 files changed, 67 insertions, 3 deletions
diff --git a/src/debug/dwarf/entry_test.go b/src/debug/dwarf/entry_test.go
index 4e96dbfc1d..1ce1c98f60 100644
--- a/src/debug/dwarf/entry_test.go
+++ b/src/debug/dwarf/entry_test.go
@@ -69,6 +69,12 @@ func TestReaderSeek(t *testing.T) {
{0x40117e, nil},
}
testRanges(t, "testdata/line-clang-dwarf5.elf", want)
+
+ want = []wantRange{
+ {0x401126, [][2]uint64{{0x401126, 0x40116a}}},
+ {0x40116a, [][2]uint64{{0x40116a, 0x401180}}},
+ }
+ testRanges(t, "testdata/line-gcc-zstd.elf", want)
}
func TestRangesSection(t *testing.T) {
@@ -156,6 +162,15 @@ func TestReaderRanges(t *testing.T) {
{"f2", [][2]uint64{{0x401180, 0x401197}}},
},
},
+ {
+ "testdata/line-gcc-zstd.elf",
+ subprograms{
+ {"f2", nil},
+ {"main", [][2]uint64{{0x40114b, 0x40116a}}},
+ {"f1", [][2]uint64{{0x401126, 0x40114b}}},
+ {"f2", [][2]uint64{{0x40116a, 0x401180}}},
+ },
+ },
}
for _, test := range tests {
diff --git a/src/debug/dwarf/line_test.go b/src/debug/dwarf/line_test.go
index 163fc3bbb9..e947d99ebb 100644
--- a/src/debug/dwarf/line_test.go
+++ b/src/debug/dwarf/line_test.go
@@ -48,6 +48,44 @@ func TestLineELFGCC(t *testing.T) {
testLineTable(t, want, files, elfData(t, "testdata/line-gcc.elf"))
}
+func TestLineELFGCCZstd(t *testing.T) {
+ // Generated by:
+ // # gcc --version | head -n1
+ // gcc (Debian 12.2.0-10) 12.2.0
+ // # gcc -g -no-pie -Wl,--compress-debug-sections=zstd line*.c
+
+ zfile1H := &LineFile{Name: "/home/iant/go/src/debug/dwarf/testdata/line1.h"}
+ zfile1C := &LineFile{Name: "/home/iant/go/src/debug/dwarf/testdata/line1.c"}
+ zfile2C := &LineFile{Name: "/home/iant/go/src/debug/dwarf/testdata/line2.c"}
+
+ // Line table based on readelf --debug-dump=rawline,decodedline
+ want := []LineEntry{
+ {Address: 0x401126, File: zfile1H, Line: 2, Column: 1, IsStmt: true},
+ {Address: 0x40112a, File: zfile1H, Line: 5, Column: 8, IsStmt: true},
+ {Address: 0x401131, File: zfile1H, Line: 5, Column: 2, IsStmt: true},
+ {Address: 0x401133, File: zfile1H, Line: 6, Column: 10, IsStmt: true, Discriminator: 3},
+ {Address: 0x40113d, File: zfile1H, Line: 5, Column: 22, IsStmt: true, Discriminator: 3},
+ {Address: 0x401141, File: zfile1H, Line: 5, Column: 15, IsStmt: true, Discriminator: 1},
+ {Address: 0x401147, File: zfile1H, Line: 7, Column: 1, IsStmt: true},
+ {Address: 0x40114b, File: zfile1C, Line: 6, Column: 1, IsStmt: true},
+ {Address: 0x40114f, File: zfile1C, Line: 7, Column: 2, IsStmt: true},
+ {Address: 0x401159, File: zfile1C, Line: 8, Column: 2, IsStmt: true},
+ {Address: 0x401168, File: zfile1C, Line: 9, Column: 1, IsStmt: true},
+ {Address: 0x40116a, EndSequence: true},
+
+ {Address: 0x40116a, File: zfile2C, Line: 4, Column: 1, IsStmt: true},
+ {Address: 0x40116e, File: zfile2C, Line: 5, Column: 2, IsStmt: true},
+ {Address: 0x40117d, File: zfile2C, Line: 6, Column: 1, IsStmt: true},
+ {Address: 0x401180, EndSequence: true},
+ }
+ files := [][]*LineFile{
+ {zfile1C, zfile1H, zfile1C},
+ {zfile2C, zfile2C},
+ }
+
+ testLineTable(t, want, files, elfData(t, "testdata/line-gcc-zstd.elf"))
+}
+
func TestLineGCCWindows(t *testing.T) {
// Generated by:
// > gcc --version
@@ -277,7 +315,7 @@ func testLineTable(t *testing.T, want []LineEntry, files [][]*LineFile, d *Data)
}
// Compare line tables.
- if !compareLines(got, want) {
+ if !compareLines(t, got, want) {
t.Log("Line tables do not match. Got:")
dumpLines(t, got)
t.Log("Want:")
@@ -312,8 +350,10 @@ func dumpFiles(t *testing.T, files []*LineFile) {
}
}
-func compareLines(a, b []LineEntry) bool {
+func compareLines(t *testing.T, a, b []LineEntry) bool {
+ t.Helper()
if len(a) != len(b) {
+ t.Errorf("len(a) == %d, len(b) == %d", len(a), len(b))
return false
}
@@ -326,11 +366,13 @@ func compareLines(a, b []LineEntry) bool {
continue
}
if al.File.Name != bl.File.Name {
+ t.Errorf("%d: name %v != name %v", i, al.File.Name, bl.File.Name)
return false
}
al.File = nil
bl.File = nil
if al != bl {
+ t.Errorf("%d: %#v != %#v", i, al, bl)
return false
}
}
diff --git a/src/debug/dwarf/testdata/line-gcc-zstd.elf b/src/debug/dwarf/testdata/line-gcc-zstd.elf
new file mode 100644
index 0000000000..45cbe72039
--- /dev/null
+++ b/src/debug/dwarf/testdata/line-gcc-zstd.elf
Binary files differ
diff --git a/src/debug/elf/elf.go b/src/debug/elf/elf.go
index ccb7e5a893..8b064bd880 100644
--- a/src/debug/elf/elf.go
+++ b/src/debug/elf/elf.go
@@ -728,6 +728,7 @@ type CompressionType int
const (
COMPRESS_ZLIB CompressionType = 1 /* ZLIB compression. */
+ COMPRESS_ZSTD CompressionType = 2 /* ZSTD compression. */
COMPRESS_LOOS CompressionType = 0x60000000 /* First OS-specific. */
COMPRESS_HIOS CompressionType = 0x6fffffff /* Last OS-specific. */
COMPRESS_LOPROC CompressionType = 0x70000000 /* First processor-specific type. */
@@ -736,6 +737,7 @@ const (
var compressionStrings = []intName{
{1, "COMPRESS_ZLIB"},
+ {2, "COMPRESS_ZSTD"},
{0x60000000, "COMPRESS_LOOS"},
{0x6fffffff, "COMPRESS_HIOS"},
{0x70000000, "COMPRESS_LOPROC"},
diff --git a/src/debug/elf/elf_test.go b/src/debug/elf/elf_test.go
index 623a4147a7..0350d53050 100644
--- a/src/debug/elf/elf_test.go
+++ b/src/debug/elf/elf_test.go
@@ -38,7 +38,7 @@ var nameTests = []nameTest{
{R_SPARC_GOT22, "R_SPARC_GOT22"},
{ET_LOOS + 5, "ET_LOOS+5"},
{ProgFlag(0x50), "0x50"},
- {COMPRESS_ZLIB + 1, "COMPRESS_ZLIB+1"},
+ {COMPRESS_ZLIB + 2, "COMPRESS_ZSTD+1"},
}
func TestNames(t *testing.T) {
diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go
index 04737e6b2f..7485337905 100644
--- a/src/debug/elf/file.go
+++ b/src/debug/elf/file.go
@@ -23,6 +23,7 @@ import (
"errors"
"fmt"
"internal/saferio"
+ "internal/zstd"
"io"
"os"
"strings"
@@ -164,6 +165,10 @@ func (s *Section) Open() io.ReadSeeker {
switch s.compressionType {
case COMPRESS_ZLIB:
zrd = zlib.NewReader
+ case COMPRESS_ZSTD:
+ zrd = func(r io.Reader) (io.ReadCloser, error) {
+ return io.NopCloser(zstd.NewReader(r)), nil
+ }
}
if zrd == nil {