File: additions_test.go

package info (click to toggle)
golang-golang-x-vuln 1.0.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,400 kB
  • sloc: sh: 161; asm: 40; makefile: 7
file content (110 lines) | stat: -rw-r--r-- 2,516 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gosym

import (
	"debug/elf"
	"runtime"
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
)

func TestFuncSymName(t *testing.T) {
	for _, test := range []struct {
		v    string
		want string
	}{
		{"go1.15", ""},
		{"go1.18", funcSymNameGo119Lower},
		{"go1.19", funcSymNameGo119Lower},
		{"devel go1.19", funcSymNameGo119Lower},
		{"go1.19-pre4", funcSymNameGo119Lower},
		{"go1.20", funcSymNameGo120},
		{"devel bd56cb90a72e6725e", funcSymNameGo120},
		{"go1.21", funcSymNameGo120},
		{"unknown version", funcSymNameGo120},
	} {
		if got := FuncSymName(test.v); got != test.want {
			t.Errorf("got %s; want %s", got, test.want)
		}
	}
}

func TestInlineTree(t *testing.T) {
	t.Skip("to temporarily resolve #61511")
	pclinetestBinary, cleanup := dotest(t)
	defer cleanup()

	f, err := elf.Open(pclinetestBinary)
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()
	pclndat, err := f.Section(".gopclntab").Data()
	if err != nil {
		t.Fatalf("reading %s gopclntab: %v", pclinetestBinary, err)
	}

	// The test binaries will be compiled with the same Go version
	// used to run the tests.
	goFunc := lookupSymbol(f, FuncSymName(runtime.Version()))
	if goFunc == nil {
		t.Fatal("couldn't find go.func.*")
	}
	prog := progContaining(f, goFunc.Value)
	if prog == nil {
		t.Fatal("couldn't find go.func.* Prog")
	}
	pcln := NewLineTable(pclndat, f.Section(".text").Addr)
	s := f.Section(".gosymtab")
	if s == nil {
		t.Fatal("no .gosymtab section")
	}
	d, err := s.Data()
	if err != nil {
		t.Fatal(err)
	}
	tab, err := NewTable(d, pcln)
	if err != nil {
		t.Fatal(err)
	}

	fun := tab.LookupFunc("main.main")
	got, err := pcln.InlineTree(fun, goFunc.Value, prog.Vaddr, prog.ReaderAt)
	if err != nil {
		t.Fatal(err)
	}
	want := []InlinedCall{
		{FuncID: 0, Name: "main.inline1"},
		{FuncID: 0, Name: "main.inline2"},
	}
	if !cmp.Equal(got, want, cmpopts.IgnoreFields(InlinedCall{}, "ParentPC")) {
		t.Errorf("got\n%+v\nwant\n%+v", got, want)
	}
}

func progContaining(f *elf.File, addr uint64) *elf.Prog {
	for _, p := range f.Progs {
		if addr >= p.Vaddr && addr < p.Vaddr+p.Filesz {
			return p
		}
	}
	return nil
}

func lookupSymbol(f *elf.File, name string) *elf.Symbol {
	syms, err := f.Symbols()
	if err != nil {
		return nil
	}
	for _, s := range syms {
		if s.Name == name {
			return &s
		}
	}
	return nil
}