github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/cmd/internal/objfile/objfile.go (about) 1 // Copyright 2014 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 objfile implements portable access to OS-specific executable files. 6 package objfile 7 8 import ( 9 "debug/dwarf" 10 "debug/gosym" 11 "fmt" 12 "os" 13 "sort" 14 ) 15 16 type rawFile interface { 17 symbols() (syms []Sym, err error) 18 pcln() (textStart uint64, symtab, pclntab []byte, err error) 19 text() (textStart uint64, text []byte, err error) 20 goarch() string 21 dwarf() (*dwarf.Data, error) 22 } 23 24 // A File is an opened executable file. 25 type File struct { 26 r *os.File 27 raw rawFile 28 } 29 30 // A Sym is a symbol defined in an executable file. 31 type Sym struct { 32 Name string // symbol name 33 Addr uint64 // virtual address of symbol 34 Size int64 // size in bytes 35 Code rune // nm code (T for text, D for data, and so on) 36 Type string // XXX? 37 } 38 39 var openers = []func(*os.File) (rawFile, error){ 40 openElf, 41 openGoobj, 42 openMacho, 43 openPE, 44 openPlan9, 45 } 46 47 // Open opens the named file. 48 // The caller must call f.Close when the file is no longer needed. 49 func Open(name string) (*File, error) { 50 r, err := os.Open(name) 51 if err != nil { 52 return nil, err 53 } 54 for _, try := range openers { 55 if raw, err := try(r); err == nil { 56 return &File{r, raw}, nil 57 } 58 } 59 r.Close() 60 return nil, fmt.Errorf("open %s: unrecognized object file", name) 61 } 62 63 func (f *File) Close() error { 64 return f.r.Close() 65 } 66 67 func (f *File) Symbols() ([]Sym, error) { 68 syms, err := f.raw.symbols() 69 if err != nil { 70 return nil, err 71 } 72 sort.Sort(byAddr(syms)) 73 return syms, nil 74 } 75 76 type byAddr []Sym 77 78 func (x byAddr) Less(i, j int) bool { return x[i].Addr < x[j].Addr } 79 func (x byAddr) Len() int { return len(x) } 80 func (x byAddr) Swap(i, j int) { x[i], x[j] = x[j], x[i] } 81 82 func (f *File) PCLineTable() (*gosym.Table, error) { 83 textStart, symtab, pclntab, err := f.raw.pcln() 84 if err != nil { 85 return nil, err 86 } 87 return gosym.NewTable(symtab, gosym.NewLineTable(pclntab, textStart)) 88 } 89 90 func (f *File) Text() (uint64, []byte, error) { 91 return f.raw.text() 92 } 93 94 func (f *File) GOARCH() string { 95 return f.raw.goarch() 96 } 97 98 // DWARF returns DWARF debug data for the file, if any. 99 // This is for cmd/pprof to locate cgo functions. 100 func (f *File) DWARF() (*dwarf.Data, error) { 101 return f.raw.dwarf() 102 }