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  }