github.com/euank/go@v0.0.0-20160829210321-495514729181/src/cmd/link/internal/ld/link.go (about) 1 // Derived from Inferno utils/6l/l.h and related files. 2 // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 package ld 32 33 import ( 34 "bufio" 35 "cmd/internal/obj" 36 "cmd/internal/sys" 37 "debug/elf" 38 "fmt" 39 ) 40 41 // Symbol is an entry in the symbol table. 42 type Symbol struct { 43 Name string 44 Extname string 45 Type int16 46 Version int16 47 Attr Attribute 48 Localentry uint8 49 Dynid int32 50 Plt int32 51 Got int32 52 Align int32 53 Elfsym int32 54 LocalElfsym int32 55 Value int64 56 Size int64 57 // ElfType is set for symbols read from shared libraries by ldshlibsyms. It 58 // is not set for symbols defined by the packages being linked or by symbols 59 // read by ldelf (and so is left as elf.STT_NOTYPE). 60 ElfType elf.SymType 61 Sub *Symbol 62 Outer *Symbol 63 Gotype *Symbol 64 Reachparent *Symbol 65 File string 66 Dynimplib string 67 Dynimpvers string 68 Sect *Section 69 FuncInfo *FuncInfo 70 // P contains the raw symbol data. 71 P []byte 72 R []Reloc 73 } 74 75 func (s *Symbol) String() string { 76 if s.Version == 0 { 77 return s.Name 78 } 79 return fmt.Sprintf("%s<%d>", s.Name, s.Version) 80 } 81 82 func (s *Symbol) ElfsymForReloc() int32 { 83 // If putelfsym created a local version of this symbol, use that in all 84 // relocations. 85 if s.LocalElfsym != 0 { 86 return s.LocalElfsym 87 } else { 88 return s.Elfsym 89 } 90 } 91 92 // Attribute is a set of common symbol attributes. 93 type Attribute int16 94 95 const ( 96 AttrDuplicateOK Attribute = 1 << iota 97 AttrExternal 98 AttrNoSplit 99 AttrReachable 100 AttrCgoExportDynamic 101 AttrCgoExportStatic 102 AttrSpecial 103 AttrStackCheck 104 AttrHidden 105 AttrOnList 106 AttrLocal 107 AttrReflectMethod 108 ) 109 110 func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 } 111 func (a Attribute) External() bool { return a&AttrExternal != 0 } 112 func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 } 113 func (a Attribute) Reachable() bool { return a&AttrReachable != 0 } 114 func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 } 115 func (a Attribute) CgoExportStatic() bool { return a&AttrCgoExportStatic != 0 } 116 func (a Attribute) Special() bool { return a&AttrSpecial != 0 } 117 func (a Attribute) StackCheck() bool { return a&AttrStackCheck != 0 } 118 func (a Attribute) Hidden() bool { return a&AttrHidden != 0 } 119 func (a Attribute) OnList() bool { return a&AttrOnList != 0 } 120 func (a Attribute) Local() bool { return a&AttrLocal != 0 } 121 func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 } 122 123 func (a Attribute) CgoExport() bool { 124 return a.CgoExportDynamic() || a.CgoExportStatic() 125 } 126 127 func (a *Attribute) Set(flag Attribute, value bool) { 128 if value { 129 *a |= flag 130 } else { 131 *a &^= flag 132 } 133 } 134 135 type Reloc struct { 136 Off int32 137 Siz uint8 138 Done uint8 139 Type obj.RelocType 140 Variant int32 141 Add int64 142 Xadd int64 143 Sym *Symbol 144 Xsym *Symbol 145 } 146 147 type Auto struct { 148 Asym *Symbol 149 Gotype *Symbol 150 Aoffset int32 151 Name int16 152 } 153 154 type Shlib struct { 155 Path string 156 Hash []byte 157 Deps []string 158 File *elf.File 159 gcdataAddresses map[*Symbol]uint64 160 } 161 162 type Link struct { 163 Goarm int32 164 Headtype int 165 Arch *sys.Arch 166 Debugvlog int 167 Bso *bufio.Writer 168 Windows int32 169 Goroot string 170 171 // Symbol lookup based on name and indexed by version. 172 Hash []map[string]*Symbol 173 174 Allsym []*Symbol 175 Tlsg *Symbol 176 Libdir []string 177 Library []*Library 178 Shlibs []Shlib 179 Tlsoffset int 180 181 Cursym *Symbol 182 Version int 183 Textp []*Symbol 184 Filesyms []*Symbol 185 Moduledata *Symbol 186 SymbolBatch []Symbol 187 } 188 189 // The smallest possible offset from the hardware stack pointer to a local 190 // variable on the stack. Architectures that use a link register save its value 191 // on the stack in the function prologue and so always have a pointer between 192 // the hardware stack pointer and the local variable area. 193 func (ctxt *Link) FixedFrameSize() int64 { 194 switch ctxt.Arch.Family { 195 case sys.AMD64, sys.I386: 196 return 0 197 case sys.PPC64: 198 // PIC code on ppc64le requires 32 bytes of stack, and it's easier to 199 // just use that much stack always on ppc64x. 200 return int64(4 * ctxt.Arch.PtrSize) 201 default: 202 return int64(ctxt.Arch.PtrSize) 203 } 204 } 205 206 func (l *Link) IncVersion() { 207 l.Version++ 208 l.Hash = append(l.Hash, make(map[string]*Symbol)) 209 } 210 211 func (l *Link) Logf(format string, args ...interface{}) { 212 fmt.Fprintf(l.Bso, format, args...) 213 l.Bso.Flush() 214 } 215 216 type Library struct { 217 Objref string 218 Srcref string 219 File string 220 Pkg string 221 Shlib string 222 hash []byte 223 } 224 225 type FuncInfo struct { 226 Args int32 227 Locals int32 228 Autom []Auto 229 Pcsp Pcdata 230 Pcfile Pcdata 231 Pcline Pcdata 232 Pcdata []Pcdata 233 Funcdata []*Symbol 234 Funcdataoff []int64 235 File []*Symbol 236 } 237 238 type Pcdata struct { 239 P []byte 240 } 241 242 type Pciter struct { 243 d Pcdata 244 p []byte 245 pc uint32 246 nextpc uint32 247 pcscale uint32 248 value int32 249 start int 250 done int 251 } 252 253 // Reloc.variant 254 const ( 255 RV_NONE = iota 256 RV_POWER_LO 257 RV_POWER_HI 258 RV_POWER_HA 259 RV_POWER_DS 260 261 // RV_390_DBL is a s390x-specific relocation variant that indicates that 262 // the value to be placed into the relocatable field should first be 263 // divided by 2. 264 RV_390_DBL 265 266 RV_CHECK_OVERFLOW = 1 << 8 267 RV_TYPE_MASK = RV_CHECK_OVERFLOW - 1 268 ) 269 270 // Pcdata iterator. 271 // for(pciterinit(ctxt, &it, &pcd); !it.done; pciternext(&it)) { it.value holds in [it.pc, it.nextpc) } 272 273 // Link holds the context for writing object code from a compiler 274 // to be linker input or for reading that input into the linker. 275 276 // LinkArch is the definition of a single architecture. 277 278 const ( 279 LinkAuto = 0 + iota 280 LinkInternal 281 LinkExternal 282 )