github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/cmd/internal/obj/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 obj 33 34 import ( 35 "fmt" 36 "log" 37 "os" 38 "path/filepath" 39 "runtime" 40 ) 41 42 func yy_isalpha(c int) bool { 43 return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' 44 } 45 46 var headers = []struct { 47 name string 48 val int 49 }{ 50 {"darwin", Hdarwin}, 51 {"dragonfly", Hdragonfly}, 52 {"elf", Helf}, 53 {"freebsd", Hfreebsd}, 54 {"linux", Hlinux}, 55 {"android", Hlinux}, // must be after "linux" entry or else headstr(Hlinux) == "android" 56 {"nacl", Hnacl}, 57 {"netbsd", Hnetbsd}, 58 {"openbsd", Hopenbsd}, 59 {"plan9", Hplan9}, 60 {"solaris", Hsolaris}, 61 {"windows", Hwindows}, 62 {"windowsgui", Hwindows}, 63 } 64 65 func headtype(name string) int { 66 for i := 0; i < len(headers); i++ { 67 if name == headers[i].name { 68 return headers[i].val 69 } 70 } 71 return -1 72 } 73 74 var headstr_buf string 75 76 func Headstr(v int) string { 77 for i := 0; i < len(headers); i++ { 78 if v == headers[i].val { 79 return headers[i].name 80 } 81 } 82 headstr_buf = fmt.Sprintf("%d", v) 83 return headstr_buf 84 } 85 86 func Linknew(arch *LinkArch) *Link { 87 ctxt := new(Link) 88 ctxt.Hash = make(map[SymVer]*LSym) 89 ctxt.Arch = arch 90 ctxt.Version = HistVersion 91 ctxt.Goroot = Getgoroot() 92 ctxt.Goroot_final = os.Getenv("GOROOT_FINAL") 93 if runtime.GOOS == "windows" { 94 // TODO(rsc): Remove ctxt.Windows and let callers use runtime.GOOS. 95 ctxt.Windows = 1 96 } 97 98 var buf string 99 buf, _ = os.Getwd() 100 if buf == "" { 101 buf = "/???" 102 } 103 buf = filepath.ToSlash(buf) 104 ctxt.Pathname = buf 105 106 ctxt.LineHist.GOROOT = ctxt.Goroot 107 ctxt.LineHist.GOROOT_FINAL = ctxt.Goroot_final 108 ctxt.LineHist.Dir = ctxt.Pathname 109 110 ctxt.Headtype = headtype(Getgoos()) 111 if ctxt.Headtype < 0 { 112 log.Fatalf("unknown goos %s", Getgoos()) 113 } 114 115 // Record thread-local storage offset. 116 // TODO(rsc): Move tlsoffset back into the linker. 117 switch ctxt.Headtype { 118 default: 119 log.Fatalf("unknown thread-local storage offset for %s", Headstr(ctxt.Headtype)) 120 121 case Hplan9, Hwindows: 122 break 123 124 /* 125 * ELF uses TLS offset negative from FS. 126 * Translate 0(FS) and 8(FS) into -16(FS) and -8(FS). 127 * Known to low-level assembly in package runtime and runtime/cgo. 128 */ 129 case Hlinux, 130 Hfreebsd, 131 Hnetbsd, 132 Hopenbsd, 133 Hdragonfly, 134 Hsolaris: 135 ctxt.Tlsoffset = -1 * ctxt.Arch.Ptrsize 136 137 case Hnacl: 138 switch ctxt.Arch.Thechar { 139 default: 140 log.Fatalf("unknown thread-local storage offset for nacl/%s", ctxt.Arch.Name) 141 142 case '5': 143 ctxt.Tlsoffset = 0 144 145 case '6': 146 ctxt.Tlsoffset = 0 147 148 case '8': 149 ctxt.Tlsoffset = -8 150 } 151 152 /* 153 * OS X system constants - offset from 0(GS) to our TLS. 154 * Explained in ../../runtime/cgo/gcc_darwin_*.c. 155 */ 156 case Hdarwin: 157 switch ctxt.Arch.Thechar { 158 default: 159 log.Fatalf("unknown thread-local storage offset for darwin/%s", ctxt.Arch.Name) 160 161 case '5': 162 ctxt.Tlsoffset = 0 // dummy value, not needed 163 164 case '6': 165 ctxt.Tlsoffset = 0x8a0 166 167 case '7': 168 ctxt.Tlsoffset = 0 // dummy value, not needed 169 170 case '8': 171 ctxt.Tlsoffset = 0x468 172 } 173 } 174 175 // On arm, record goarm. 176 if ctxt.Arch.Thechar == '5' { 177 p := Getgoarm() 178 if p != "" { 179 ctxt.Goarm = int32(Atoi(p)) 180 } else { 181 ctxt.Goarm = 6 182 } 183 } 184 185 return ctxt 186 } 187 188 func linknewsym(ctxt *Link, symb string, v int) *LSym { 189 s := new(LSym) 190 *s = LSym{} 191 192 s.Name = symb 193 s.Type = 0 194 s.Version = int16(v) 195 s.Value = 0 196 s.Size = 0 197 198 return s 199 } 200 201 func _lookup(ctxt *Link, symb string, v int, creat int) *LSym { 202 s := ctxt.Hash[SymVer{symb, v}] 203 if s != nil || creat == 0 { 204 return s 205 } 206 207 s = linknewsym(ctxt, symb, v) 208 ctxt.Hash[SymVer{symb, v}] = s 209 210 return s 211 } 212 213 func Linklookup(ctxt *Link, name string, v int) *LSym { 214 return _lookup(ctxt, name, v, 1) 215 } 216 217 // read-only lookup 218 func linkrlookup(ctxt *Link, name string, v int) *LSym { 219 return _lookup(ctxt, name, v, 0) 220 } 221 222 func Linksymfmt(s *LSym) string { 223 if s == nil { 224 return "<nil>" 225 } 226 return s.Name 227 }