URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [debug/] [gosym/] [pclntab_test.go] - Rev 747
Compare with Previous | Blame | View Log
// Copyright 2009 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 gosymimport ("debug/elf""os""runtime""testing")func dotest() bool {// For now, only works on ELF platforms.// TODO: convert to work with new go toolreturn false && runtime.GOOS == "linux" && runtime.GOARCH == "amd64"}func getTable(t *testing.T) *Table {f, tab := crack(os.Args[0], t)f.Close()return tab}func crack(file string, t *testing.T) (*elf.File, *Table) {// Open selff, err := elf.Open(file)if err != nil {t.Fatal(err)}return parse(file, f, t)}func parse(file string, f *elf.File, t *testing.T) (*elf.File, *Table) {symdat, err := f.Section(".gosymtab").Data()if err != nil {f.Close()t.Fatalf("reading %s gosymtab: %v", file, err)}pclndat, err := f.Section(".gopclntab").Data()if err != nil {f.Close()t.Fatalf("reading %s gopclntab: %v", file, err)}pcln := NewLineTable(pclndat, f.Section(".text").Addr)tab, err := NewTable(symdat, pcln)if err != nil {f.Close()t.Fatalf("parsing %s gosymtab: %v", file, err)}return f, tab}var goarch = os.Getenv("O")func TestLineFromAline(t *testing.T) {if !dotest() {return}tab := getTable(t)// Find the sym packagepkg := tab.LookupFunc("debug/gosym.TestLineFromAline").Objif pkg == nil {t.Fatalf("nil pkg")}// Walk every absolute line and ensure that we hit every// source line monotonicallylastline := make(map[string]int)final := -1for i := 0; i < 10000; i++ {path, line := pkg.lineFromAline(i)// Check for end of objectif path == "" {if final == -1 {final = i - 1}continue} else if final != -1 {t.Fatalf("reached end of package at absolute line %d, but absolute line %d mapped to %s:%d", final, i, path, line)}// It's okay to see files multiple times (e.g., sys.a)if line == 1 {lastline[path] = 1continue}// Check that the is the next line in pathll, ok := lastline[path]if !ok {t.Errorf("file %s starts on line %d", path, line)} else if line != ll+1 {t.Errorf("expected next line of file %s to be %d, got %d", path, ll+1, line)}lastline[path] = line}if final == -1 {t.Errorf("never reached end of object")}}func TestLineAline(t *testing.T) {if !dotest() {return}tab := getTable(t)for _, o := range tab.Files {// A source file can appear multiple times in a// object. alineFromLine will always return alines in// the first file, so track which lines we've seen.found := make(map[string]int)for i := 0; i < 1000; i++ {path, line := o.lineFromAline(i)if path == "" {break}// cgo files are full of 'Z' symbols, which we don't handleif len(path) > 4 && path[len(path)-4:] == ".cgo" {continue}if minline, ok := found[path]; path != "" && ok {if minline >= line {// We've already covered this filecontinue}}found[path] = linea, err := o.alineFromLine(path, line)if err != nil {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)} else if a != i {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)}}}}func TestPCLine(t *testing.T) {if !dotest() {return}f, tab := crack("_test/pclinetest", t)text := f.Section(".text")textdat, err := text.Data()if err != nil {t.Fatalf("reading .text: %v", err)}// Test PCToLinesym := tab.LookupFunc("linefrompc")wantLine := 0for pc := sym.Entry; pc < sym.End; pc++ {file, line, fn := tab.PCToLine(pc)off := pc - text.Addr // TODO(rsc): should not need off; bug in 8gwantLine += int(textdat[off])if fn == nil {t.Errorf("failed to get line of PC %#x", pc)} else if len(file) < 12 || file[len(file)-12:] != "pclinetest.s" || line != wantLine || fn != sym {t.Errorf("expected %s:%d (%s) at PC %#x, got %s:%d (%s)", "pclinetest.s", wantLine, sym.Name, pc, file, line, fn.Name)}}// Test LineToPCsym = tab.LookupFunc("pcfromline")lookupline := -1wantLine = 0off := uint64(0) // TODO(rsc): should not need off; bug in 8gfor pc := sym.Value; pc < sym.End; pc += 2 + uint64(textdat[off]) {file, line, fn := tab.PCToLine(pc)off = pc - text.AddrwantLine += int(textdat[off])if line != wantLine {t.Errorf("expected line %d at PC %#x in pcfromline, got %d", wantLine, pc, line)off = pc + 1 - text.Addrcontinue}if lookupline == -1 {lookupline = line}for ; lookupline <= line; lookupline++ {pc2, fn2, err := tab.LineToPC(file, lookupline)if lookupline != line {// Should be nothing on this lineif err == nil {t.Errorf("expected no PC at line %d, got %#x (%s)", lookupline, pc2, fn2.Name)}} else if err != nil {t.Errorf("failed to get PC of line %d: %s", lookupline, err)} else if pc != pc2 {t.Errorf("expected PC %#x (%s) at line %d, got PC %#x (%s)", pc, fn.Name, line, pc2, fn2.Name)}}off = pc + 1 - text.Addr}}
