github.com/sanprasirt/go@v0.0.0-20170607001320-a027466e4b6d/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/objabi" 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 SymKind 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 func (s *Symbol) Len() int64 { 93 return s.Size 94 } 95 96 // Attribute is a set of common symbol attributes. 97 type Attribute int16 98 99 const ( 100 // AttrDuplicateOK marks a symbol that can be present in multiple object 101 // files. 102 AttrDuplicateOK Attribute = 1 << iota 103 // AttrExternal marks function symbols loaded from host object files. 104 AttrExternal 105 // AttrNoSplit marks functions that cannot split the stack; the linker 106 // cares because it checks that there are no call chains of nosplit 107 // functions that require more than StackLimit bytes (see 108 // lib.go:dostkcheck) 109 AttrNoSplit 110 // AttrReachable marks symbols that are transitively referenced from the 111 // entry points. Unreachable symbols are not written to the output. 112 AttrReachable 113 // AttrCgoExportDynamic and AttrCgoExportStatic mark symbols referenced 114 // by directives written by cgo (in response to //export directives in 115 // the source). 116 AttrCgoExportDynamic 117 AttrCgoExportStatic 118 // AttrSpecial marks symbols that do not have their address (i.e. Value) 119 // computed by the usual mechanism of data.go:dodata() & 120 // data.go:address(). 121 AttrSpecial 122 // AttrStackCheck is used by dostkcheck to only check each NoSplit 123 // function's stack usage once. 124 AttrStackCheck 125 // AttrNotInSymbolTable marks symbols that are not written to the symbol table. 126 AttrNotInSymbolTable 127 // AttrOnList marks symbols that are on some list (such as the list of 128 // all text symbols, or one of the lists of data symbols) and is 129 // consulted to avoid bugs where a symbol is put on a list twice. 130 AttrOnList 131 // AttrLocal marks symbols that are only visible within the module 132 // (exectuable or shared library) being linked. Only relevant when 133 // dynamically linking Go code. 134 AttrLocal 135 // AttrReflectMethod marks certain methods from the reflect package that 136 // can be used to call arbitrary methods. If no symbol with this bit set 137 // is marked as reachable, more dead code elimination can be done. 138 AttrReflectMethod 139 // AttrMakeTypelink Amarks types that should be added to the typelink 140 // table. See typelinks.go:typelinks(). 141 AttrMakeTypelink 142 // AttrShared marks symbols compiled with the -shared option. 143 AttrShared 144 // 14 attributes defined so far. 145 ) 146 147 func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 } 148 func (a Attribute) External() bool { return a&AttrExternal != 0 } 149 func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 } 150 func (a Attribute) Reachable() bool { return a&AttrReachable != 0 } 151 func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 } 152 func (a Attribute) CgoExportStatic() bool { return a&AttrCgoExportStatic != 0 } 153 func (a Attribute) Special() bool { return a&AttrSpecial != 0 } 154 func (a Attribute) StackCheck() bool { return a&AttrStackCheck != 0 } 155 func (a Attribute) NotInSymbolTable() bool { return a&AttrNotInSymbolTable != 0 } 156 func (a Attribute) OnList() bool { return a&AttrOnList != 0 } 157 func (a Attribute) Local() bool { return a&AttrLocal != 0 } 158 func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 } 159 func (a Attribute) MakeTypelink() bool { return a&AttrMakeTypelink != 0 } 160 func (a Attribute) Shared() bool { return a&AttrShared != 0 } 161 162 func (a Attribute) CgoExport() bool { 163 return a.CgoExportDynamic() || a.CgoExportStatic() 164 } 165 166 func (a *Attribute) Set(flag Attribute, value bool) { 167 if value { 168 *a |= flag 169 } else { 170 *a &^= flag 171 } 172 } 173 174 // Reloc is a relocation. 175 // 176 // The typical Reloc rewrites part of a symbol at offset Off to address Sym. 177 // A Reloc is stored in a slice on the Symbol it rewrites. 178 // 179 // Relocations are generated by the compiler as the type 180 // cmd/internal/obj.Reloc, which is encoded into the object file wire 181 // format and decoded by the linker into this type. A separate type is 182 // used to hold linker-specific state about the relocation. 183 // 184 // Some relocations are created by cmd/link. 185 type Reloc struct { 186 Off int32 // offset to rewrite 187 Siz uint8 // number of bytes to rewrite, 1, 2, or 4 188 Done uint8 // set to 1 when relocation is complete 189 Variant RelocVariant // variation on Type 190 Type objabi.RelocType // the relocation type 191 Add int64 // addend 192 Xadd int64 // addend passed to external linker 193 Sym *Symbol // symbol the relocation addresses 194 Xsym *Symbol // symbol passed to external linker 195 } 196 197 type Auto struct { 198 Asym *Symbol 199 Gotype *Symbol 200 Aoffset int32 201 Name int16 202 } 203 204 type Shlib struct { 205 Path string 206 Hash []byte 207 Deps []string 208 File *elf.File 209 gcdataAddresses map[*Symbol]uint64 210 } 211 212 // Link holds the context for writing object code from a compiler 213 // or for reading that input into the linker. 214 type Link struct { 215 Syms *Symbols 216 217 Arch *sys.Arch 218 Debugvlog int 219 Bso *bufio.Writer 220 221 Loaded bool // set after all inputs have been loaded as symbols 222 223 Tlsg *Symbol 224 Libdir []string 225 Library []*Library 226 LibraryByPkg map[string]*Library 227 Shlibs []Shlib 228 Tlsoffset int 229 Textp []*Symbol 230 Filesyms []*Symbol 231 Moduledata *Symbol 232 233 PackageFile map[string]string 234 PackageShlib map[string]string 235 236 tramps []*Symbol // trampolines 237 } 238 239 // The smallest possible offset from the hardware stack pointer to a local 240 // variable on the stack. Architectures that use a link register save its value 241 // on the stack in the function prologue and so always have a pointer between 242 // the hardware stack pointer and the local variable area. 243 func (ctxt *Link) FixedFrameSize() int64 { 244 switch ctxt.Arch.Family { 245 case sys.AMD64, sys.I386: 246 return 0 247 case sys.PPC64: 248 // PIC code on ppc64le requires 32 bytes of stack, and it's easier to 249 // just use that much stack always on ppc64x. 250 return int64(4 * ctxt.Arch.PtrSize) 251 default: 252 return int64(ctxt.Arch.PtrSize) 253 } 254 } 255 256 func (l *Link) Logf(format string, args ...interface{}) { 257 fmt.Fprintf(l.Bso, format, args...) 258 l.Bso.Flush() 259 } 260 261 type Library struct { 262 Objref string 263 Srcref string 264 File string 265 Pkg string 266 Shlib string 267 hash string 268 imports []*Library 269 textp []*Symbol // text symbols defined in this library 270 dupTextSyms []*Symbol // dupok text symbols defined in this library 271 } 272 273 func (l Library) String() string { 274 return l.Pkg 275 } 276 277 type FuncInfo struct { 278 Args int32 279 Locals int32 280 Autom []Auto 281 Pcsp Pcdata 282 Pcfile Pcdata 283 Pcline Pcdata 284 Pcinline Pcdata 285 Pcdata []Pcdata 286 Funcdata []*Symbol 287 Funcdataoff []int64 288 File []*Symbol 289 InlTree []InlinedCall 290 } 291 292 // InlinedCall is a node in a local inlining tree (FuncInfo.InlTree). 293 type InlinedCall struct { 294 Parent int32 // index of parent in InlTree 295 File *Symbol // file of the inlined call 296 Line int32 // line number of the inlined call 297 Func *Symbol // function that was inlined 298 } 299 300 type Pcdata struct { 301 P []byte 302 } 303 304 type Pciter struct { 305 d Pcdata 306 p []byte 307 pc uint32 308 nextpc uint32 309 pcscale uint32 310 value int32 311 start int 312 done int 313 } 314 315 // RelocVariant is a linker-internal variation on a relocation. 316 type RelocVariant uint8 317 318 const ( 319 RV_NONE RelocVariant = iota 320 RV_POWER_LO 321 RV_POWER_HI 322 RV_POWER_HA 323 RV_POWER_DS 324 325 // RV_390_DBL is a s390x-specific relocation variant that indicates that 326 // the value to be placed into the relocatable field should first be 327 // divided by 2. 328 RV_390_DBL 329 330 RV_CHECK_OVERFLOW RelocVariant = 1 << 7 331 RV_TYPE_MASK RelocVariant = RV_CHECK_OVERFLOW - 1 332 )