github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/cmd/nm/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 main
     8  
     9  import (
    10  	"debug/elf"
    11  	"os"
    12  )
    13  
    14  func elfSymbols(f *os.File) []Sym {
    15  	p, err := elf.NewFile(f)
    16  	if err != nil {
    17  		errorf("parsing %s: %v", f.Name(), err)
    18  		return nil
    19  	}
    20  
    21  	elfSyms, err := p.Symbols()
    22  	if err != nil {
    23  		errorf("parsing %s: %v", f.Name(), err)
    24  		return nil
    25  	}
    26  
    27  	var syms []Sym
    28  	for _, s := range elfSyms {
    29  		sym := Sym{Addr: s.Value, Name: s.Name, Size: int64(s.Size), Code: '?'}
    30  		switch s.Section {
    31  		case elf.SHN_UNDEF:
    32  			sym.Code = 'U'
    33  		case elf.SHN_COMMON:
    34  			sym.Code = 'B'
    35  		default:
    36  			i := int(s.Section)
    37  			if i < 0 || i >= len(p.Sections) {
    38  				break
    39  			}
    40  			sect := p.Sections[i]
    41  			switch sect.Flags & (elf.SHF_WRITE | elf.SHF_ALLOC | elf.SHF_EXECINSTR) {
    42  			case elf.SHF_ALLOC | elf.SHF_EXECINSTR:
    43  				sym.Code = 'T'
    44  			case elf.SHF_ALLOC:
    45  				sym.Code = 'R'
    46  			case elf.SHF_ALLOC | elf.SHF_WRITE:
    47  				sym.Code = 'D'
    48  			}
    49  		}
    50  		if elf.ST_BIND(s.Info) == elf.STB_LOCAL {
    51  			sym.Code += 'a' - 'A'
    52  		}
    53  		syms = append(syms, sym)
    54  	}
    55  
    56  	return syms
    57  }