]> Cypherpunks.ru repositories - gostls13.git/commitdiff
debug/elf: support zstd compression
authorIan Lance Taylor <iant@golang.org>
Fri, 3 Mar 2023 22:29:44 +0000 (14:29 -0800)
committerGopher Robot <gobot@golang.org>
Tue, 18 Apr 2023 20:34:36 +0000 (20:34 +0000)
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>
api/next/55107.txt [new file with mode: 0644]
src/cmd/dist/buildtool.go
src/debug/dwarf/entry_test.go
src/debug/dwarf/line_test.go
src/debug/dwarf/testdata/line-gcc-zstd.elf [new file with mode: 0644]
src/debug/elf/elf.go
src/debug/elf/elf_test.go
src/debug/elf/file.go
src/go/build/deps_test.go

diff --git a/api/next/55107.txt b/api/next/55107.txt
new file mode 100644 (file)
index 0000000..234f030
--- /dev/null
@@ -0,0 +1,2 @@
+pkg debug/elf, const COMPRESS_ZSTD = 2 #55107
+pkg debug/elf, const COMPRESS_ZSTD CompressionType #55107
index 3a455b9677486190ffd7e255203533d1ea95cac5..e06991d726ef78291ab9f1ebec50f246b26c991e 100644 (file)
@@ -78,6 +78,7 @@ var bootstrapDirs = []string{
        "internal/types/errors",
        "internal/unsafeheader",
        "internal/xcoff",
+       "internal/zstd",
        "math/big",
        "math/bits",
        "sort",
index 4e96dbfc1d56409ff49691dd6ab5423d7fe29150..1ce1c98f60a6ada121daadbbf33c08abfa56fd5f 100644 (file)
@@ -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 {
index 163fc3bbb99bb6da25e08233e1247c6a54e6be13..e947d99ebb872f16d495e7dc66f77bc88992e079 100644 (file)
@@ -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 (file)
index 0000000..45cbe72
Binary files /dev/null and b/src/debug/dwarf/testdata/line-gcc-zstd.elf differ
index ccb7e5a893cae33e72bab01fcb121ea7f6ef8bd0..8b064bd880667e17c1b9ead74dcf7a7cbbac835b 100644 (file)
@@ -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"},
index 623a4147a75c2eccd3e34b5591b32c245b807097..0350d530502b2e8919fa78fb17470c3dc8178348 100644 (file)
@@ -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) {
index 04737e6b2f42bfc1655ab06838506f1825461af3..7485337905fb090512c3d11abb5244b34def503e 100644 (file)
@@ -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 {
index 24ad2def85c46e22f39553af9c5e6b8272267d0c..4415b92a29593def5a7e5e1edea648f0d93addd8 100644 (file)
@@ -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