From 48a1dcb92778a349e13bcb8be10a40047f0cf7d1 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 3 Mar 2023 14:29:44 -0800 Subject: [PATCH] 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 Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor Run-TryBot: Ian Lance Taylor Auto-Submit: Ian Lance Taylor Reviewed-by: Than McIntosh --- api/next/55107.txt | 2 + src/cmd/dist/buildtool.go | 1 + src/debug/dwarf/entry_test.go | 15 +++++++ src/debug/dwarf/line_test.go | 46 ++++++++++++++++++++- src/debug/dwarf/testdata/line-gcc-zstd.elf | Bin 0 -> 17168 bytes src/debug/elf/elf.go | 2 + src/debug/elf/elf_test.go | 2 +- src/debug/elf/file.go | 5 +++ src/go/build/deps_test.go | 2 +- 9 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 api/next/55107.txt create mode 100644 src/debug/dwarf/testdata/line-gcc-zstd.elf diff --git a/api/next/55107.txt b/api/next/55107.txt new file mode 100644 index 0000000000..234f030ffd --- /dev/null +++ b/api/next/55107.txt @@ -0,0 +1,2 @@ +pkg debug/elf, const COMPRESS_ZSTD = 2 #55107 +pkg debug/elf, const COMPRESS_ZSTD CompressionType #55107 diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go index 3a455b9677..e06991d726 100644 --- a/src/cmd/dist/buildtool.go +++ b/src/cmd/dist/buildtool.go @@ -78,6 +78,7 @@ var bootstrapDirs = []string{ "internal/types/errors", "internal/unsafeheader", "internal/xcoff", + "internal/zstd", "math/big", "math/bits", "sort", 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 0000000000000000000000000000000000000000..45cbe720397419fe11d47b1ae811b4d84f317d60 GIT binary patch literal 17168 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 S!rZ=Z{L?&sw+^5a+1~-Mr2_2$ literal 0 HcmV?d00001 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 { diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go index 24ad2def85..4415b92a29 100644 --- a/src/go/build/deps_test.go +++ b/src/go/build/deps_test.go @@ -251,7 +251,7 @@ var depsRules = ` < index/suffixarray; # executable parsing - FMT, encoding/binary, compress/zlib, internal/saferio + FMT, encoding/binary, compress/zlib, internal/saferio, internal/zstd < runtime/debug < debug/dwarf < debug/elf, debug/gosym, debug/macho, debug/pe, debug/plan9obj, internal/xcoff -- 2.48.1