...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package main
20
21 import (
22 "bufio"
23 "flag"
24 "fmt"
25 "log"
26 "os"
27 "strconv"
28 "strings"
29
30 "cmd/internal/objfile"
31 )
32
33 func printUsage(w *os.File) {
34 fmt.Fprintf(w, "usage: addr2line binary\n")
35 fmt.Fprintf(w, "reads addresses from standard input and writes two lines for each:\n")
36 fmt.Fprintf(w, "\tfunction name\n")
37 fmt.Fprintf(w, "\tfile:line\n")
38 }
39
40 func usage() {
41 printUsage(os.Stderr)
42 os.Exit(2)
43 }
44
45 func main() {
46 log.SetFlags(0)
47 log.SetPrefix("addr2line: ")
48
49
50 if len(os.Args) > 1 && os.Args[1] == "--help" {
51 printUsage(os.Stdout)
52 os.Exit(0)
53 }
54
55 flag.Usage = usage
56 flag.Parse()
57 if flag.NArg() != 1 {
58 usage()
59 }
60
61 f, err := objfile.Open(flag.Arg(0))
62 if err != nil {
63 log.Fatal(err)
64 }
65 defer f.Close()
66
67 tab, err := f.PCLineTable()
68 if err != nil {
69 log.Fatalf("reading %s: %v", flag.Arg(0), err)
70 }
71
72 stdin := bufio.NewScanner(os.Stdin)
73 stdout := bufio.NewWriter(os.Stdout)
74
75 for stdin.Scan() {
76 p := stdin.Text()
77 if strings.Contains(p, ":") {
78
79
80
81
82 fmt.Fprintf(stdout, "!reverse translation not implemented\n")
83 continue
84 }
85 pc, _ := strconv.ParseUint(strings.TrimPrefix(p, "0x"), 16, 64)
86 file, line, fn := tab.PCToLine(pc)
87 name := "?"
88 if fn != nil {
89 name = fn.Name
90 } else {
91 file = "?"
92 line = 0
93 }
94 fmt.Fprintf(stdout, "%s\n%s:%d\n", name, file, line)
95 }
96 stdout.Flush()
97 }
98
View as plain text