github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/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 "cmd/internal/obj" 35 "debug/elf" 36 "encoding/binary" 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 Args int32 54 Locals 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 Next *LSym 62 Sub *LSym 63 Outer *LSym 64 Gotype *LSym 65 Reachparent *LSym 66 File string 67 Dynimplib string 68 Dynimpvers string 69 Sect *Section 70 Autom []Auto 71 Pcln *Pcln 72 P []byte 73 R []Reloc 74 } 75 76 func (s *LSym) String() string { 77 if s.Version == 0 { 78 return s.Name 79 } 80 return fmt.Sprintf("%s<%d>", s.Name, s.Version) 81 } 82 83 func (s *LSym) ElfsymForReloc() int32 { 84 // If putelfsym created a local version of this symbol, use that in all 85 // relocations. 86 if s.LocalElfsym != 0 { 87 return s.LocalElfsym 88 } else { 89 return s.Elfsym 90 } 91 } 92 93 // Attribute is a set of common symbol attributes. 94 type Attribute int16 95 96 const ( 97 AttrDuplicateOK Attribute = 1 << iota 98 AttrExternal 99 AttrNoSplit 100 AttrReachable 101 AttrCgoExportDynamic 102 AttrCgoExportStatic 103 AttrSpecial 104 AttrStackCheck 105 AttrHidden 106 AttrOnList 107 AttrLocal 108 AttrReflectMethod 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 124 func (a Attribute) CgoExport() bool { 125 return a.CgoExportDynamic() || a.CgoExportStatic() 126 } 127 128 func (a *Attribute) Set(flag Attribute, value bool) { 129 if value { 130 *a |= flag 131 } else { 132 *a &^= flag 133 } 134 } 135 136 type Reloc struct { 137 Off int32 138 Siz uint8 139 Done uint8 140 Type int32 141 Variant int32 142 Add int64 143 Xadd int64 144 Sym *LSym 145 Xsym *LSym 146 } 147 148 type Auto struct { 149 Asym *LSym 150 Gotype *LSym 151 Aoffset int32 152 Name int16 153 } 154 155 type Shlib struct { 156 Path string 157 Hash []byte 158 Deps []string 159 File *elf.File 160 gcdata_addresses map[*LSym]uint64 161 } 162 163 type Link struct { 164 Thechar int32 165 Thestring string 166 Goarm int32 167 Headtype int 168 Arch *LinkArch 169 Debugvlog int32 170 Bso *obj.Biobuf 171 Windows int32 172 Goroot string 173 174 // Symbol lookup based on name and indexed by version. 175 Hash []map[string]*LSym 176 177 Allsym []*LSym 178 Tlsg *LSym 179 Libdir []string 180 Library []*Library 181 Shlibs []Shlib 182 Tlsoffset int 183 Diag func(string, ...interface{}) 184 Cursym *LSym 185 Version int 186 Textp *LSym 187 Etextp *LSym 188 Nhistfile int32 189 Filesyms *LSym 190 Moduledata *LSym 191 LSymBatch []LSym 192 } 193 194 // The smallest possible offset from the hardware stack pointer to a local 195 // variable on the stack. Architectures that use a link register save its value 196 // on the stack in the function prologue and so always have a pointer between 197 // the hardware stack pointer and the local variable area. 198 func (ctxt *Link) FixedFrameSize() int64 { 199 switch ctxt.Arch.Thechar { 200 case '6', '8': 201 return 0 202 case '9': 203 // PIC code on ppc64le requires 32 bytes of stack, and it's easier to 204 // just use that much stack always on ppc64x. 205 return int64(4 * ctxt.Arch.Ptrsize) 206 default: 207 return int64(ctxt.Arch.Ptrsize) 208 } 209 } 210 211 func (l *Link) IncVersion() { 212 l.Version++ 213 l.Hash = append(l.Hash, make(map[string]*LSym)) 214 } 215 216 type LinkArch struct { 217 ByteOrder binary.ByteOrder 218 Name string 219 Thechar int 220 Minlc int 221 Ptrsize int 222 Regsize int 223 } 224 225 type Library struct { 226 Objref string 227 Srcref string 228 File string 229 Pkg string 230 Shlib string 231 hash []byte 232 } 233 234 type Pcln struct { 235 Pcsp Pcdata 236 Pcfile Pcdata 237 Pcline Pcdata 238 Pcdata []Pcdata 239 Funcdata []*LSym 240 Funcdataoff []int64 241 File []*LSym 242 } 243 244 type Pcdata struct { 245 P []byte 246 } 247 248 type Pciter struct { 249 d Pcdata 250 p []byte 251 pc uint32 252 nextpc uint32 253 pcscale uint32 254 value int32 255 start int 256 done int 257 } 258 259 // Reloc.variant 260 const ( 261 RV_NONE = iota 262 RV_POWER_LO 263 RV_POWER_HI 264 RV_POWER_HA 265 RV_POWER_DS 266 267 // RV_390_DBL is a s390x-specific relocation variant that indicates that 268 // the value to be placed into the relocatable field should first be 269 // divided by 2. 270 RV_390_DBL 271 272 RV_CHECK_OVERFLOW = 1 << 8 273 RV_TYPE_MASK = RV_CHECK_OVERFLOW - 1 274 ) 275 276 // Pcdata iterator. 277 // for(pciterinit(ctxt, &it, &pcd); !it.done; pciternext(&it)) { it.value holds in [it.pc, it.nextpc) } 278 279 // Link holds the context for writing object code from a compiler 280 // to be linker input or for reading that input into the linker. 281 282 // LinkArch is the definition of a single architecture. 283 284 const ( 285 LinkAuto = 0 + iota 286 LinkInternal 287 LinkExternal 288 )