github.com/peggyl/go@v0.0.0-20151008231540-ae315999c2d5/src/cmd/newlink/auto.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 // Automatic symbol generation. 6 7 // TODO(rsc): Handle go.typelink, go.track symbols. 8 // TODO(rsc): Do not handle $f64. and $f32. symbols. Instead, generate those 9 // from the compiler and assemblers as dupok data, and then remove autoData below. 10 package main 11 12 import ( 13 "cmd/internal/goobj" 14 "strconv" 15 "strings" 16 ) 17 18 // linkerDefined lists the symbols supplied by other parts of the linker 19 // (runtime.go and layout.go). 20 var linkerDefined = map[string]bool{ 21 "runtime.bss": true, 22 "runtime.data": true, 23 "runtime.ebss": true, 24 "runtime.edata": true, 25 "runtime.efunctab": true, 26 "runtime.end": true, 27 "runtime.enoptrbss": true, 28 "runtime.enoptrdata": true, 29 "runtime.erodata": true, 30 "runtime.etext": true, 31 "runtime.etypelink": true, 32 "runtime.functab": true, 33 "runtime.gcbss": true, 34 "runtime.gcdata": true, 35 "runtime.noptrbss": true, 36 "runtime.noptrdata": true, 37 "runtime.pclntab": true, 38 "runtime.rodata": true, 39 "runtime.text": true, 40 "runtime.typelink": true, 41 } 42 43 // isAuto reports whether sym is an automatically-generated data or constant symbol. 44 func (p *Prog) isAuto(sym goobj.SymID) bool { 45 return strings.HasPrefix(sym.Name, "go.weak.") || 46 strings.HasPrefix(sym.Name, "$f64.") || 47 strings.HasPrefix(sym.Name, "$f32.") || 48 linkerDefined[sym.Name] 49 } 50 51 // autoData defines the automatically generated data symbols needed by p. 52 func (p *Prog) autoData() { 53 for sym := range p.Missing { 54 switch { 55 // Floating-point constants that need to be loaded from memory are 56 // written as $f64.{16 hex digits} or $f32.{8 hex digits}; the hex digits 57 // give the IEEE bit pattern of the constant. As far as the layout into 58 // memory is concerned, we interpret these as uint64 or uint32 constants. 59 case strings.HasPrefix(sym.Name, "$f64."), strings.HasPrefix(sym.Name, "$f32."): 60 size := 64 61 if sym.Name[2:4] == "32" { 62 size = 32 63 } 64 delete(p.Missing, sym) 65 fbits, err := strconv.ParseUint(sym.Name[len("$f64."):], 16, size) 66 if err != nil { 67 p.errorf("unexpected floating point symbol %s", sym) 68 continue 69 } 70 data := make([]byte, size/8) 71 if size == 64 { 72 p.byteorder.PutUint64(data, fbits) 73 } else { 74 p.byteorder.PutUint32(data, uint32(fbits)) 75 } 76 p.addSym(&Sym{ 77 Sym: &goobj.Sym{ 78 SymID: sym, 79 Kind: goobj.SRODATA, 80 Size: size / 8, 81 }, 82 Bytes: data, 83 }) 84 } 85 } 86 } 87 88 // autoConst defines the automatically generated constant symbols needed by p. 89 func (p *Prog) autoConst() { 90 for sym := range p.Missing { 91 switch { 92 case strings.HasPrefix(sym.Name, "go.weak."): 93 // weak symbol resolves to actual symbol if present, or else nil. 94 delete(p.Missing, sym) 95 targ := sym 96 targ.Name = sym.Name[len("go.weak."):] 97 var addr Addr 98 if s := p.Syms[targ]; s != nil { 99 addr = s.Addr 100 } 101 p.defineConst(sym.Name, addr) 102 } 103 } 104 } 105 106 // defineConst defines a new symbol with the given name and constant address. 107 func (p *Prog) defineConst(name string, addr Addr) { 108 sym := goobj.SymID{Name: name} 109 p.addSym(&Sym{ 110 Sym: &goobj.Sym{ 111 SymID: sym, 112 Kind: goobj.SCONST, 113 }, 114 Package: nil, 115 Addr: addr, 116 }) 117 }