github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/cmd/internal/objfile/elf.go (about) 1 // Copyright 2013 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 // Parsing of ELF executables (Linux, FreeBSD, and so on). 6 7 package objfile 8 9 import ( 10 "debug/elf" 11 "os" 12 ) 13 14 type elfFile struct { 15 elf *elf.File 16 } 17 18 func openElf(r *os.File) (rawFile, error) { 19 f, err := elf.NewFile(r) 20 if err != nil { 21 return nil, err 22 } 23 return &elfFile{f}, nil 24 } 25 26 func (f *elfFile) symbols() ([]Sym, error) { 27 elfSyms, err := f.elf.Symbols() 28 if err != nil { 29 return nil, err 30 } 31 32 var syms []Sym 33 for _, s := range elfSyms { 34 sym := Sym{Addr: s.Value, Name: s.Name, Size: int64(s.Size), Code: '?'} 35 switch s.Section { 36 case elf.SHN_UNDEF: 37 sym.Code = 'U' 38 case elf.SHN_COMMON: 39 sym.Code = 'B' 40 default: 41 i := int(s.Section) 42 if i < 0 || i >= len(f.elf.Sections) { 43 break 44 } 45 sect := f.elf.Sections[i] 46 switch sect.Flags & (elf.SHF_WRITE | elf.SHF_ALLOC | elf.SHF_EXECINSTR) { 47 case elf.SHF_ALLOC | elf.SHF_EXECINSTR: 48 sym.Code = 'T' 49 case elf.SHF_ALLOC: 50 sym.Code = 'R' 51 case elf.SHF_ALLOC | elf.SHF_WRITE: 52 sym.Code = 'D' 53 } 54 } 55 if elf.ST_BIND(s.Info) == elf.STB_LOCAL { 56 sym.Code += 'a' - 'A' 57 } 58 syms = append(syms, sym) 59 } 60 61 return syms, nil 62 } 63 64 func (f *elfFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) { 65 if sect := f.elf.Section(".text"); sect != nil { 66 textStart = sect.Addr 67 } 68 if sect := f.elf.Section(".gosymtab"); sect != nil { 69 if symtab, err = sect.Data(); err != nil { 70 return 0, nil, nil, err 71 } 72 } 73 if sect := f.elf.Section(".gopclntab"); sect != nil { 74 if pclntab, err = sect.Data(); err != nil { 75 return 0, nil, nil, err 76 } 77 } 78 return textStart, symtab, pclntab, nil 79 }