github.com/dannin/go@v0.0.0-20161031215817-d35dfd405eaa/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 obj.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 // 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 AttrMakeTypelink 109 ) 110 111 func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 } 112 func (a Attribute) External() bool { return a&AttrExternal != 0 } 113 func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 } 114 func (a Attribute) Reachable() bool { return a&AttrReachable != 0 } 115 func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 } 116 func (a Attribute) CgoExportStatic() bool { return a&AttrCgoExportStatic != 0 } 117 func (a Attribute) Special() bool { return a&AttrSpecial != 0 } 118 func (a Attribute) StackCheck() bool { return a&AttrStackCheck != 0 } 119 func (a Attribute) Hidden() bool { return a&AttrHidden != 0 } 120 func (a Attribute) OnList() bool { return a&AttrOnList != 0 } 121 func (a Attribute) Local() bool { return a&AttrLocal != 0 } 122 func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 } 123 func (a Attribute) MakeTypelink() bool { return a&AttrMakeTypelink != 0 } 124 125 func (a Attribute) CgoExport() bool { 126 return a.CgoExportDynamic() || a.CgoExportStatic() 127 } 128 129 func (a *Attribute) Set(flag Attribute, value bool) { 130 if value { 131 *a |= flag 132 } else { 133 *a &^= flag 134 } 135 } 136 137 // Reloc is a relocation. 138 // 139 // The typical Reloc rewrites part of a symbol at offset Off to address Sym. 140 // A Reloc is stored in a slice on the Symbol it rewrites. 141 // 142 // Relocations are generated by the compiler as the type 143 // cmd/internal/obj.Reloc, which is encoded into the object file wire 144 // format and decoded by the linker into this type. A separate type is 145 // used to hold linker-specific state about the relocation. 146 // 147 // Some relocations are created by cmd/link. 148 type Reloc struct { 149 Off int32 // offset to rewrite 150 Siz uint8 // number of bytes to rewrite, 1, 2, or 4 151 Done uint8 // set to 1 when relocation is complete 152 Variant RelocVariant // variation on Type 153 Type obj.RelocType // the relocation type 154 Add int64 // addend 155 Xadd int64 // addend passed to external linker 156 Sym *Symbol // symbol the relocation addresses 157 Xsym *Symbol // symbol passed to external linker 158 } 159 160 type Auto struct { 161 Asym *Symbol 162 Gotype *Symbol 163 Aoffset int32 164 Name int16 165 } 166 167 type Shlib struct { 168 Path string 169 Hash []byte 170 Deps []string 171 File *elf.File 172 gcdataAddresses map[*Symbol]uint64 173 } 174 175 // Link holds the context for writing object code from a compiler 176 // or for reading that input into the linker. 177 type Link struct { 178 Syms *Symbols 179 180 Arch *sys.Arch 181 Debugvlog int 182 Bso *bufio.Writer 183 184 Loaded bool // set after all inputs have been loaded as symbols 185 186 Tlsg *Symbol 187 Libdir []string 188 Library []*Library 189 Shlibs []Shlib 190 Tlsoffset int 191 Textp []*Symbol 192 Filesyms []*Symbol 193 Moduledata *Symbol 194 195 tramps []*Symbol // trampolines 196 } 197 198 // The smallest possible offset from the hardware stack pointer to a local 199 // variable on the stack. Architectures that use a link register save its value 200 // on the stack in the function prologue and so always have a pointer between 201 // the hardware stack pointer and the local variable area. 202 func (ctxt *Link) FixedFrameSize() int64 { 203 switch ctxt.Arch.Family { 204 case sys.AMD64, sys.I386: 205 return 0 206 case sys.PPC64: 207 // PIC code on ppc64le requires 32 bytes of stack, and it's easier to 208 // just use that much stack always on ppc64x. 209 return int64(4 * ctxt.Arch.PtrSize) 210 default: 211 return int64(ctxt.Arch.PtrSize) 212 } 213 } 214 215 func (l *Link) Logf(format string, args ...interface{}) { 216 fmt.Fprintf(l.Bso, format, args...) 217 l.Bso.Flush() 218 } 219 220 type Library struct { 221 Objref string 222 Srcref string 223 File string 224 Pkg string 225 Shlib string 226 hash []byte 227 imports []*Library 228 textp []*Symbol // text symbols defined in this library 229 dupTextSyms []*Symbol // dupok text symbols defined in this library 230 } 231 232 func (l Library) String() string { 233 return l.Pkg 234 } 235 236 type FuncInfo struct { 237 Args int32 238 Locals int32 239 Autom []Auto 240 Pcsp Pcdata 241 Pcfile Pcdata 242 Pcline Pcdata 243 Pcdata []Pcdata 244 Funcdata []*Symbol 245 Funcdataoff []int64 246 File []*Symbol 247 } 248 249 type Pcdata struct { 250 P []byte 251 } 252 253 type Pciter struct { 254 d Pcdata 255 p []byte 256 pc uint32 257 nextpc uint32 258 pcscale uint32 259 value int32 260 start int 261 done int 262 } 263 264 // RelocVariant is a linker-internal variation on a relocation. 265 type RelocVariant uint8 266 267 const ( 268 RV_NONE RelocVariant = iota 269 RV_POWER_LO 270 RV_POWER_HI 271 RV_POWER_HA 272 RV_POWER_DS 273 274 // RV_390_DBL is a s390x-specific relocation variant that indicates that 275 // the value to be placed into the relocatable field should first be 276 // divided by 2. 277 RV_390_DBL 278 279 RV_CHECK_OVERFLOW RelocVariant = 1 << 7 280 RV_TYPE_MASK RelocVariant = RV_CHECK_OVERFLOW - 1 281 )