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