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