Source file src/pkg/cmd/internal/objfile/objfile.go
1
2
3
4
5
6 package objfile
7
8 import (
9 "debug/dwarf"
10 "debug/gosym"
11 "fmt"
12 "io"
13 "os"
14 "sort"
15 )
16
17 type rawFile interface {
18 symbols() (syms []Sym, err error)
19 pcln() (textStart uint64, symtab, pclntab []byte, err error)
20 text() (textStart uint64, text []byte, err error)
21 goarch() string
22 loadAddress() (uint64, error)
23 dwarf() (*dwarf.Data, error)
24 }
25
26
27 type File struct {
28 r *os.File
29 entries []*Entry
30 }
31
32 type Entry struct {
33 name string
34 raw rawFile
35 }
36
37
38 type Sym struct {
39 Name string
40 Addr uint64
41 Size int64
42 Code rune
43 Type string
44 Relocs []Reloc
45 }
46
47 type Reloc struct {
48 Addr uint64
49 Size uint64
50 Stringer RelocStringer
51 }
52
53 type RelocStringer interface {
54
55
56 String(insnOffset uint64) string
57 }
58
59 var openers = []func(io.ReaderAt) (rawFile, error){
60 openElf,
61 openMacho,
62 openPE,
63 openPlan9,
64 openXcoff,
65 }
66
67
68
69 func Open(name string) (*File, error) {
70 r, err := os.Open(name)
71 if err != nil {
72 return nil, err
73 }
74 if f, err := openGoFile(r); err == nil {
75 return f, nil
76 }
77 for _, try := range openers {
78 if raw, err := try(r); err == nil {
79 return &File{r, []*Entry{&Entry{raw: raw}}}, nil
80 }
81 }
82 r.Close()
83 return nil, fmt.Errorf("open %s: unrecognized object file", name)
84 }
85
86 func (f *File) Close() error {
87 return f.r.Close()
88 }
89
90 func (f *File) Entries() []*Entry {
91 return f.entries
92 }
93
94 func (f *File) Symbols() ([]Sym, error) {
95 return f.entries[0].Symbols()
96 }
97
98 func (f *File) PCLineTable() (Liner, error) {
99 return f.entries[0].PCLineTable()
100 }
101
102 func (f *File) Text() (uint64, []byte, error) {
103 return f.entries[0].Text()
104 }
105
106 func (f *File) GOARCH() string {
107 return f.entries[0].GOARCH()
108 }
109
110 func (f *File) LoadAddress() (uint64, error) {
111 return f.entries[0].LoadAddress()
112 }
113
114 func (f *File) DWARF() (*dwarf.Data, error) {
115 return f.entries[0].DWARF()
116 }
117
118 func (f *File) Disasm() (*Disasm, error) {
119 return f.entries[0].Disasm()
120 }
121
122 func (e *Entry) Name() string {
123 return e.name
124 }
125
126 func (e *Entry) Symbols() ([]Sym, error) {
127 syms, err := e.raw.symbols()
128 if err != nil {
129 return nil, err
130 }
131 sort.Sort(byAddr(syms))
132 return syms, nil
133 }
134
135 type byAddr []Sym
136
137 func (x byAddr) Less(i, j int) bool { return x[i].Addr < x[j].Addr }
138 func (x byAddr) Len() int { return len(x) }
139 func (x byAddr) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
140
141 func (e *Entry) PCLineTable() (Liner, error) {
142
143
144 if pcln, ok := e.raw.(Liner); ok {
145 return pcln, nil
146 }
147
148 textStart, symtab, pclntab, err := e.raw.pcln()
149 if err != nil {
150 return nil, err
151 }
152 return gosym.NewTable(symtab, gosym.NewLineTable(pclntab, textStart))
153 }
154
155 func (e *Entry) Text() (uint64, []byte, error) {
156 return e.raw.text()
157 }
158
159 func (e *Entry) GOARCH() string {
160 return e.raw.goarch()
161 }
162
163
164
165
166 func (e *Entry) LoadAddress() (uint64, error) {
167 return e.raw.loadAddress()
168 }
169
170
171
172 func (e *Entry) DWARF() (*dwarf.Data, error) {
173 return e.raw.dwarf()
174 }
175
View as plain text