OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [debug/] [gosym/] [pclntab_test.go] - Blame information for rev 801

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 The Go Authors.  All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
package gosym
6
 
7
import (
8
        "debug/elf"
9
        "os"
10
        "runtime"
11
        "testing"
12
)
13
 
14
func dotest() bool {
15
        // For now, only works on ELF platforms.
16
        // TODO: convert to work with new go tool
17
        return false && runtime.GOOS == "linux" && runtime.GOARCH == "amd64"
18
}
19
 
20
func getTable(t *testing.T) *Table {
21
        f, tab := crack(os.Args[0], t)
22
        f.Close()
23
        return tab
24
}
25
 
26
func crack(file string, t *testing.T) (*elf.File, *Table) {
27
        // Open self
28
        f, err := elf.Open(file)
29
        if err != nil {
30
                t.Fatal(err)
31
        }
32
        return parse(file, f, t)
33
}
34
 
35
func parse(file string, f *elf.File, t *testing.T) (*elf.File, *Table) {
36
        symdat, err := f.Section(".gosymtab").Data()
37
        if err != nil {
38
                f.Close()
39
                t.Fatalf("reading %s gosymtab: %v", file, err)
40
        }
41
        pclndat, err := f.Section(".gopclntab").Data()
42
        if err != nil {
43
                f.Close()
44
                t.Fatalf("reading %s gopclntab: %v", file, err)
45
        }
46
 
47
        pcln := NewLineTable(pclndat, f.Section(".text").Addr)
48
        tab, err := NewTable(symdat, pcln)
49
        if err != nil {
50
                f.Close()
51
                t.Fatalf("parsing %s gosymtab: %v", file, err)
52
        }
53
 
54
        return f, tab
55
}
56
 
57
var goarch = os.Getenv("O")
58
 
59
func TestLineFromAline(t *testing.T) {
60
        if !dotest() {
61
                return
62
        }
63
 
64
        tab := getTable(t)
65
 
66
        // Find the sym package
67
        pkg := tab.LookupFunc("debug/gosym.TestLineFromAline").Obj
68
        if pkg == nil {
69
                t.Fatalf("nil pkg")
70
        }
71
 
72
        // Walk every absolute line and ensure that we hit every
73
        // source line monotonically
74
        lastline := make(map[string]int)
75
        final := -1
76
        for i := 0; i < 10000; i++ {
77
                path, line := pkg.lineFromAline(i)
78
                // Check for end of object
79
                if path == "" {
80
                        if final == -1 {
81
                                final = i - 1
82
                        }
83
                        continue
84
                } else if final != -1 {
85
                        t.Fatalf("reached end of package at absolute line %d, but absolute line %d mapped to %s:%d", final, i, path, line)
86
                }
87
                // It's okay to see files multiple times (e.g., sys.a)
88
                if line == 1 {
89
                        lastline[path] = 1
90
                        continue
91
                }
92
                // Check that the is the next line in path
93
                ll, ok := lastline[path]
94
                if !ok {
95
                        t.Errorf("file %s starts on line %d", path, line)
96
                } else if line != ll+1 {
97
                        t.Errorf("expected next line of file %s to be %d, got %d", path, ll+1, line)
98
                }
99
                lastline[path] = line
100
        }
101
        if final == -1 {
102
                t.Errorf("never reached end of object")
103
        }
104
}
105
 
106
func TestLineAline(t *testing.T) {
107
        if !dotest() {
108
                return
109
        }
110
 
111
        tab := getTable(t)
112
 
113
        for _, o := range tab.Files {
114
                // A source file can appear multiple times in a
115
                // object.  alineFromLine will always return alines in
116
                // the first file, so track which lines we've seen.
117
                found := make(map[string]int)
118
                for i := 0; i < 1000; i++ {
119
                        path, line := o.lineFromAline(i)
120
                        if path == "" {
121
                                break
122
                        }
123
 
124
                        // cgo files are full of 'Z' symbols, which we don't handle
125
                        if len(path) > 4 && path[len(path)-4:] == ".cgo" {
126
                                continue
127
                        }
128
 
129
                        if minline, ok := found[path]; path != "" && ok {
130
                                if minline >= line {
131
                                        // We've already covered this file
132
                                        continue
133
                                }
134
                        }
135
                        found[path] = line
136
 
137
                        a, err := o.alineFromLine(path, line)
138
                        if err != nil {
139
                                t.Errorf("absolute line %d in object %s maps to %s:%d, but mapping that back gives error %s", i, o.Paths[0].Name, path, line, err)
140
                        } else if a != i {
141
                                t.Errorf("absolute line %d in object %s maps to %s:%d, which maps back to absolute line %d\n", i, o.Paths[0].Name, path, line, a)
142
                        }
143
                }
144
        }
145
}
146
 
147
func TestPCLine(t *testing.T) {
148
        if !dotest() {
149
                return
150
        }
151
 
152
        f, tab := crack("_test/pclinetest", t)
153
        text := f.Section(".text")
154
        textdat, err := text.Data()
155
        if err != nil {
156
                t.Fatalf("reading .text: %v", err)
157
        }
158
 
159
        // Test PCToLine
160
        sym := tab.LookupFunc("linefrompc")
161
        wantLine := 0
162
        for pc := sym.Entry; pc < sym.End; pc++ {
163
                file, line, fn := tab.PCToLine(pc)
164
                off := pc - text.Addr // TODO(rsc): should not need off; bug in 8g
165
                wantLine += int(textdat[off])
166
                if fn == nil {
167
                        t.Errorf("failed to get line of PC %#x", pc)
168
                } else if len(file) < 12 || file[len(file)-12:] != "pclinetest.s" || line != wantLine || fn != sym {
169
                        t.Errorf("expected %s:%d (%s) at PC %#x, got %s:%d (%s)", "pclinetest.s", wantLine, sym.Name, pc, file, line, fn.Name)
170
                }
171
        }
172
 
173
        // Test LineToPC
174
        sym = tab.LookupFunc("pcfromline")
175
        lookupline := -1
176
        wantLine = 0
177
        off := uint64(0) // TODO(rsc): should not need off; bug in 8g
178
        for pc := sym.Value; pc < sym.End; pc += 2 + uint64(textdat[off]) {
179
                file, line, fn := tab.PCToLine(pc)
180
                off = pc - text.Addr
181
                wantLine += int(textdat[off])
182
                if line != wantLine {
183
                        t.Errorf("expected line %d at PC %#x in pcfromline, got %d", wantLine, pc, line)
184
                        off = pc + 1 - text.Addr
185
                        continue
186
                }
187
                if lookupline == -1 {
188
                        lookupline = line
189
                }
190
                for ; lookupline <= line; lookupline++ {
191
                        pc2, fn2, err := tab.LineToPC(file, lookupline)
192
                        if lookupline != line {
193
                                // Should be nothing on this line
194
                                if err == nil {
195
                                        t.Errorf("expected no PC at line %d, got %#x (%s)", lookupline, pc2, fn2.Name)
196
                                }
197
                        } else if err != nil {
198
                                t.Errorf("failed to get PC of line %d: %s", lookupline, err)
199
                        } else if pc != pc2 {
200
                                t.Errorf("expected PC %#x (%s) at line %d, got PC %#x (%s)", pc, fn.Name, line, pc2, fn2.Name)
201
                        }
202
                }
203
                off = pc + 1 - text.Addr
204
        }
205
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.