github.com/d4l3k/go@v0.0.0-20151015000803-65fc379daeda/src/cmd/link/internal/ld/sym.go (about) 1 // Derived from Inferno utils/6l/obj.c and utils/6l/span.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c 3 // http://code.google.com/p/inferno-os/source/browse/utils/6l/span.c 4 // 5 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 6 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 7 // Portions Copyright © 1997-1999 Vita Nuova Limited 8 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 9 // Portions Copyright © 2004,2006 Bruce Ellis 10 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 11 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 12 // Portions Copyright © 2009 The Go Authors. All rights reserved. 13 // 14 // Permission is hereby granted, free of charge, to any person obtaining a copy 15 // of this software and associated documentation files (the "Software"), to deal 16 // in the Software without restriction, including without limitation the rights 17 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 // copies of the Software, and to permit persons to whom the Software is 19 // furnished to do so, subject to the following conditions: 20 // 21 // The above copyright notice and this permission notice shall be included in 22 // all copies or substantial portions of the Software. 23 // 24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 30 // THE SOFTWARE. 31 32 package ld 33 34 import ( 35 "cmd/internal/obj" 36 "log" 37 "os" 38 "path/filepath" 39 "strconv" 40 ) 41 42 var headers = []struct { 43 name string 44 val int 45 }{ 46 {"darwin", obj.Hdarwin}, 47 {"dragonfly", obj.Hdragonfly}, 48 {"elf", obj.Helf}, 49 {"freebsd", obj.Hfreebsd}, 50 {"linux", obj.Hlinux}, 51 {"android", obj.Hlinux}, // must be after "linux" entry or else headstr(Hlinux) == "android" 52 {"nacl", obj.Hnacl}, 53 {"netbsd", obj.Hnetbsd}, 54 {"openbsd", obj.Hopenbsd}, 55 {"plan9", obj.Hplan9}, 56 {"solaris", obj.Hsolaris}, 57 {"windows", obj.Hwindows}, 58 {"windowsgui", obj.Hwindows}, 59 } 60 61 func linknew(arch *LinkArch) *Link { 62 ctxt := new(Link) 63 ctxt.Hash = make(map[symVer]*LSym) 64 ctxt.Arch = arch 65 ctxt.Version = obj.HistVersion 66 ctxt.Goroot = obj.Getgoroot() 67 68 p := obj.Getgoarch() 69 if p != arch.Name { 70 log.Fatalf("invalid goarch %s (want %s)", p, arch.Name) 71 } 72 73 var buf string 74 buf, _ = os.Getwd() 75 if buf == "" { 76 buf = "/???" 77 } 78 buf = filepath.ToSlash(buf) 79 80 ctxt.Headtype = headtype(obj.Getgoos()) 81 if ctxt.Headtype < 0 { 82 log.Fatalf("unknown goos %s", obj.Getgoos()) 83 } 84 85 // Record thread-local storage offset. 86 // TODO(rsc): Move tlsoffset back into the linker. 87 switch ctxt.Headtype { 88 default: 89 log.Fatalf("unknown thread-local storage offset for %s", Headstr(ctxt.Headtype)) 90 91 case obj.Hplan9, obj.Hwindows: 92 break 93 94 /* 95 * ELF uses TLS offset negative from FS. 96 * Translate 0(FS) and 8(FS) into -16(FS) and -8(FS). 97 * Known to low-level assembly in package runtime and runtime/cgo. 98 */ 99 case obj.Hlinux, 100 obj.Hfreebsd, 101 obj.Hnetbsd, 102 obj.Hopenbsd, 103 obj.Hdragonfly, 104 obj.Hsolaris: 105 ctxt.Tlsoffset = -1 * ctxt.Arch.Ptrsize 106 107 case obj.Hnacl: 108 switch ctxt.Arch.Thechar { 109 default: 110 log.Fatalf("unknown thread-local storage offset for nacl/%s", ctxt.Arch.Name) 111 112 case '5': 113 ctxt.Tlsoffset = 0 114 115 case '6': 116 ctxt.Tlsoffset = 0 117 118 case '8': 119 ctxt.Tlsoffset = -8 120 } 121 122 /* 123 * OS X system constants - offset from 0(GS) to our TLS. 124 * Explained in ../../runtime/cgo/gcc_darwin_*.c. 125 */ 126 case obj.Hdarwin: 127 switch ctxt.Arch.Thechar { 128 default: 129 log.Fatalf("unknown thread-local storage offset for darwin/%s", ctxt.Arch.Name) 130 131 case '5': 132 ctxt.Tlsoffset = 0 // dummy value, not needed 133 134 case '6': 135 ctxt.Tlsoffset = 0x8a0 136 137 case '7': 138 ctxt.Tlsoffset = 0 // dummy value, not needed 139 140 case '8': 141 ctxt.Tlsoffset = 0x468 142 } 143 } 144 145 // On arm, record goarm. 146 if ctxt.Arch.Thechar == '5' { 147 ctxt.Goarm = obj.Getgoarm() 148 } 149 150 return ctxt 151 } 152 153 func linknewsym(ctxt *Link, symb string, v int) *LSym { 154 s := new(LSym) 155 *s = LSym{} 156 157 s.Dynid = -1 158 s.Plt = -1 159 s.Got = -1 160 s.Name = symb 161 s.Type = 0 162 s.Version = int16(v) 163 s.Value = 0 164 s.Size = 0 165 ctxt.Nsymbol++ 166 167 s.Allsym = ctxt.Allsym 168 ctxt.Allsym = s 169 170 return s 171 } 172 173 type symVer struct { 174 sym string 175 ver int 176 } 177 178 func _lookup(ctxt *Link, symb string, v int, creat int) *LSym { 179 s := ctxt.Hash[symVer{symb, v}] 180 if s != nil { 181 return s 182 } 183 if creat == 0 { 184 return nil 185 } 186 187 s = linknewsym(ctxt, symb, v) 188 s.Extname = s.Name 189 ctxt.Hash[symVer{symb, v}] = s 190 return s 191 } 192 193 func Linklookup(ctxt *Link, name string, v int) *LSym { 194 return _lookup(ctxt, name, v, 1) 195 } 196 197 // read-only lookup 198 func Linkrlookup(ctxt *Link, name string, v int) *LSym { 199 return _lookup(ctxt, name, v, 0) 200 } 201 202 func Headstr(v int) string { 203 for i := 0; i < len(headers); i++ { 204 if v == headers[i].val { 205 return headers[i].name 206 } 207 } 208 return strconv.Itoa(v) 209 } 210 211 func headtype(name string) int { 212 for i := 0; i < len(headers); i++ { 213 if name == headers[i].name { 214 return headers[i].val 215 } 216 } 217 return -1 218 }