github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/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 default: 200 return int64(ctxt.Arch.PtrSize) 201 } 202 } 203 204 func (l *Link) IncVersion() { 205 l.Version++ 206 l.Hash = append(l.Hash, make(map[string]*LSym)) 207 } 208 209 type Library struct { 210 Objref string 211 Srcref string 212 File string 213 Pkg string 214 Shlib string 215 hash []byte 216 } 217 218 type FuncInfo struct { 219 Args int32 220 Locals int32 221 Autom []Auto 222 Pcsp Pcdata 223 Pcfile Pcdata 224 Pcline Pcdata 225 Pcdata []Pcdata 226 Funcdata []*LSym 227 Funcdataoff []int64 228 File []*LSym 229 } 230 231 type Pcdata struct { 232 P []byte 233 } 234 235 type Pciter struct { 236 d Pcdata 237 p []byte 238 pc uint32 239 nextpc uint32 240 pcscale uint32 241 value int32 242 start int 243 done int 244 } 245 246 // Reloc.variant 247 const ( 248 RV_NONE = iota 249 RV_POWER_LO 250 RV_POWER_HI 251 RV_POWER_HA 252 RV_POWER_DS 253 254 // RV_390_DBL is a s390x-specific relocation variant that indicates that 255 // the value to be placed into the relocatable field should first be 256 // divided by 2. 257 RV_390_DBL 258 259 RV_CHECK_OVERFLOW = 1 << 8 260 RV_TYPE_MASK = RV_CHECK_OVERFLOW - 1 261 ) 262 263 // Pcdata iterator. 264 // for(pciterinit(ctxt, &it, &pcd); !it.done; pciternext(&it)) { it.value holds in [it.pc, it.nextpc) } 265 266 // Link holds the context for writing object code from a compiler 267 // to be linker input or for reading that input into the linker. 268 269 // LinkArch is the definition of a single architecture. 270 271 const ( 272 LinkAuto = 0 + iota 273 LinkInternal 274 LinkExternal 275 )