1
2
3
4
5
6
7
8
9
10
11
12 package main
13
14 import (
15 "debug/dwarf"
16 "debug/elf"
17 "debug/macho"
18 "debug/pe"
19 "fmt"
20 "os"
21 "strings"
22 )
23
24 func usage() {
25 fmt.Fprintf(os.Stderr, "checkdwarf executable-or-library DIE-suffix\n")
26 }
27
28 type dwarfer interface {
29 DWARF() (*dwarf.Data, error)
30 }
31
32 func openElf(path string) dwarfer {
33 exe, err := elf.Open(path)
34 if err != nil {
35 return nil
36 }
37 return exe
38 }
39
40 func openMacho(path string) dwarfer {
41 exe, err := macho.Open(path)
42 if err != nil {
43 return nil
44 }
45 return exe
46 }
47
48 func openPE(path string) dwarfer {
49 exe, err := pe.Open(path)
50 if err != nil {
51 return nil
52 }
53 return exe
54 }
55
56 func main() {
57 if len(os.Args) != 3 {
58 usage()
59 }
60
61 exePath := os.Args[1]
62 dieSuffix := os.Args[2]
63
64 var exe dwarfer
65
66 for _, openfn := range []func(string) dwarfer{openMacho, openPE, openElf} {
67 exe = openfn(exePath)
68 if exe != nil {
69 break
70 }
71 }
72
73 if exe == nil {
74 fmt.Fprintf(os.Stderr, "could not open %s\n", exePath)
75 os.Exit(1)
76 }
77
78 data, err := exe.DWARF()
79 if err != nil {
80 fmt.Fprintf(os.Stderr, "%s: error opening DWARF: %v\n", exePath, err)
81 os.Exit(1)
82 }
83
84 rdr := data.Reader()
85 for {
86 e, err := rdr.Next()
87 if err != nil {
88 fmt.Fprintf(os.Stderr, "%s: error reading DWARF: %v\n", exePath, err)
89 os.Exit(1)
90 }
91 if e == nil {
92 break
93 }
94 name, hasname := e.Val(dwarf.AttrName).(string)
95 if !hasname {
96 continue
97 }
98 if strings.HasSuffix(name, dieSuffix) {
99
100 os.Exit(0)
101 }
102 }
103
104 fmt.Fprintf(os.Stderr, "%s: no entry with a name ending in %q was found\n", exePath, dieSuffix)
105 os.Exit(1)
106 }
107
View as plain text