github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/cmd/link/internal/ld/link.go (about) 1 // Derived from Inferno utils/6l/l.h and related files. 2 // http://code.google.com/p/inferno-os/source/browse/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/sys" 36 "debug/elf" 37 "fmt" 38 ) 39 40 type LSym struct { 41 Name string 42 Extname string 43 Type int16 44 Version int16 45 Attr Attribute 46 Localentry uint8 47 Dynid int32 48 Plt int32 49 Got int32 50 Align int32 51 Elfsym int32 52 LocalElfsym int32 53 Value int64 54 Size int64 55 // ElfType is set for symbols read from shared libraries by ldshlibsyms. It 56 // is not set for symbols defined by the packages being linked or by symbols 57 // read by ldelf (and so is left as elf.STT_NOTYPE). 58 ElfType elf.SymType 59 Next *LSym 60 Sub *LSym 61 Outer *LSym 62 Gotype *LSym 63 Reachparent *LSym 64 File string 65 Dynimplib string 66 Dynimpvers string 67 Sect *Section 68 FuncInfo *FuncInfo 69 P []byte 70 R []Reloc 71 } 72 73 func (s *LSym) String() string { 74 if s.Version == 0 { 75 return s.Name 76 } 77 return fmt.Sprintf("%s<%d>", s.Name, s.Version) 78 } 79 80 func (s *LSym) ElfsymForReloc() int32 { 81 // If putelfsym created a local version of this symbol, use that in all 82 // relocations. 83 if s.LocalElfsym != 0 { 84 return s.LocalElfsym 85 } else { 86 return s.Elfsym 87 } 88 } 89 90 // Attribute is a set of common symbol attributes. 91 type Attribute int16 92 93 const ( 94 AttrDuplicateOK Attribute = 1 << iota 95 AttrExternal 96 AttrNoSplit 97 AttrReachable 98 AttrCgoExportDynamic 99 AttrCgoExportStatic 100 AttrSpecial 101 AttrStackCheck 102 AttrHidden 103 AttrOnList 104 AttrLocal 105 AttrReflectMethod 106 ) 107 108 func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 } 109 func (a Attribute) External() bool { return a&AttrExternal != 0 } 110 func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 } 111 func (a Attribute) Reachable() bool { return a&AttrReachable != 0 } 112 func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 } 113 func (a Attribute) CgoExportStatic() bool { return a&AttrCgoExportStatic != 0 } 114 func (a Attribute) Special() bool { return a&AttrSpecial != 0 } 115 func (a Attribute) StackCheck() bool { return a&AttrStackCheck != 0 } 116 func (a Attribute) Hidden() bool { return a&AttrHidden != 0 } 117 func (a Attribute) OnList() bool { return a&AttrOnList != 0 } 118 func (a Attribute) Local() bool { return a&AttrLocal != 0 } 119 func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 } 120 121 func (a Attribute) CgoExport() bool { 122 return a.CgoExportDynamic() || a.CgoExportStatic() 123 } 124 125 func (a *Attribute) Set(flag Attribute, value bool) { 126 if value { 127 *a |= flag 128 } else { 129 *a &^= flag 130 } 131 } 132 133 type Reloc struct { 134 Off int32 135 Siz uint8 136 Done uint8 137 Type int32 138 Variant int32 139 Add int64 140 Xadd int64 141 Sym *LSym 142 Xsym *LSym 143 } 144 145 type Auto struct { 146 Asym *LSym 147 Gotype *LSym 148 Aoffset int32 149 Name int16 150 } 151 152 type Shlib struct { 153 Path string 154 Hash []byte 155 Deps []string 156 File *elf.File 157 gcdata_addresses map[*LSym]uint64 158 } 159 160 type Link struct { 161 Goarm int32 162 Headtype int 163 Arch *sys.Arch 164 Debugvlog int32 165 Bso *bufio.Writer 166 Windows int32 167 Goroot string 168 169 // Symbol lookup based on name and indexed by version. 170 Hash []map[string]*LSym 171 172 Allsym []*LSym 173 Tlsg *LSym 174 Libdir []string 175 Library []*Library 176 Shlibs []Shlib 177 Tlsoffset int 178 Diag func(string, ...interface{}) 179 Cursym *LSym 180 Version int 181 Textp []*LSym 182 Filesyms []*LSym 183 Moduledata *LSym 184 LSymBatch []LSym 185 } 186 187 // The smallest possible offset from the hardware stack pointer to a local 188 // variable on the stack. Architectures that use a link register save its value 189 // on the stack in the function prologue and so always have a pointer between 190 // the hardware stack pointer and the local variable area. 191 func (ctxt *Link) FixedFrameSize() int64 { 192 switch ctxt.Arch.Family { 193 case sys.AMD64, sys.I386: 194 return 0 195 case sys.PPC64: 196 // PIC code on ppc64le requires 32 bytes of stack, and it's easier to 197 // just use that much stack always on ppc64x. 198 return int64(4 * ctxt.Arch.PtrSize) 199 case sys.SPARC64: 200 // SPARC64 always requires 176 bytes of stack. 201 return int64(16*8 + 6*8) 202 default: 203 return int64(ctxt.Arch.PtrSize) 204 } 205 } 206 207 func (l *Link) IncVersion() { 208 l.Version++ 209 l.Hash = append(l.Hash, make(map[string]*LSym)) 210 } 211 212 type Library struct { 213 Objref string 214 Srcref string 215 File string 216 Pkg string 217 Shlib string 218 hash []byte 219 } 220 221 type FuncInfo struct { 222 Args int32 223 Locals int32 224 Autom []Auto 225 Pcsp Pcdata 226 Pcfile Pcdata 227 Pcline Pcdata 228 Pcdata []Pcdata 229 Funcdata []*LSym 230 Funcdataoff []int64 231 File []*LSym 232 } 233 234 type Pcdata struct { 235 P []byte 236 } 237 238 type Pciter struct { 239 d Pcdata 240 p []byte 241 pc uint32 242 nextpc uint32 243 pcscale uint32 244 value int32 245 start int 246 done int 247 } 248 249 // Reloc.variant 250 const ( 251 RV_NONE = iota 252 RV_POWER_LO 253 RV_POWER_HI 254 RV_POWER_HA 255 RV_POWER_DS 256 257 // RV_390_DBL is a s390x-specific relocation variant that indicates that 258 // the value to be placed into the relocatable field should first be 259 // divided by 2. 260 RV_390_DBL 261 262 RV_CHECK_OVERFLOW = 1 << 8 263 RV_TYPE_MASK = RV_CHECK_OVERFLOW - 1 264 ) 265 266 // Pcdata iterator. 267 // for(pciterinit(ctxt, &it, &pcd); !it.done; pciternext(&it)) { it.value holds in [it.pc, it.nextpc) } 268 269 // Link holds the context for writing object code from a compiler 270 // to be linker input or for reading that input into the linker. 271 272 // LinkArch is the definition of a single architecture. 273 274 const ( 275 LinkAuto = 0 + iota 276 LinkInternal 277 LinkExternal 278 )