github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/cmd/objdump/macho.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 Mach-O executables (OS X).
     6  
     7  package main
     8  
     9  import (
    10  	"debug/macho"
    11  	"os"
    12  	"sort"
    13  )
    14  
    15  func machoSymbols(f *os.File) (syms []Sym, goarch string) {
    16  	p, err := macho.NewFile(f)
    17  	if err != nil {
    18  		errorf("parsing %s: %v", f.Name(), err)
    19  		return
    20  	}
    21  
    22  	if p.Symtab == nil {
    23  		errorf("%s: no symbol table", f.Name())
    24  		return
    25  	}
    26  
    27  	switch p.Cpu {
    28  	case macho.Cpu386:
    29  		goarch = "386"
    30  	case macho.CpuAmd64:
    31  		goarch = "amd64"
    32  	case macho.CpuArm:
    33  		goarch = "arm"
    34  	}
    35  
    36  	// Build sorted list of addresses of all symbols.
    37  	// We infer the size of a symbol by looking at where the next symbol begins.
    38  	var addrs []uint64
    39  	for _, s := range p.Symtab.Syms {
    40  		addrs = append(addrs, s.Value)
    41  	}
    42  	sort.Sort(uint64s(addrs))
    43  
    44  	for _, s := range p.Symtab.Syms {
    45  		sym := Sym{Name: s.Name, Addr: s.Value, Code: '?'}
    46  		i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
    47  		if i < len(addrs) {
    48  			sym.Size = int64(addrs[i] - s.Value)
    49  		}
    50  		if s.Sect == 0 {
    51  			sym.Code = 'U'
    52  		} else if int(s.Sect) <= len(p.Sections) {
    53  			sect := p.Sections[s.Sect-1]
    54  			switch sect.Seg {
    55  			case "__TEXT":
    56  				sym.Code = 'R'
    57  			case "__DATA":
    58  				sym.Code = 'D'
    59  			}
    60  			switch sect.Seg + " " + sect.Name {
    61  			case "__TEXT __text":
    62  				sym.Code = 'T'
    63  			case "__DATA __bss", "__DATA __noptrbss":
    64  				sym.Code = 'B'
    65  			}
    66  		}
    67  		syms = append(syms, sym)
    68  	}
    69  
    70  	return
    71  }
    72  
    73  type uint64s []uint64
    74  
    75  func (x uint64s) Len() int           { return len(x) }
    76  func (x uint64s) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
    77  func (x uint64s) Less(i, j int) bool { return x[i] < x[j] }