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