github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/cmd/link/internal/sym/symbol.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package sym 6 7 import ( 8 "cmd/internal/objabi" 9 "cmd/internal/sys" 10 "debug/elf" 11 "fmt" 12 "log" 13 ) 14 15 // Symbol is an entry in the symbol table. 16 type Symbol struct { 17 Name string 18 Type SymKind 19 Version int16 20 Attr Attribute 21 Dynid int32 22 Align int32 23 Elfsym int32 24 LocalElfsym int32 25 Value int64 26 Size int64 27 Sub *Symbol 28 Outer *Symbol 29 Gotype *Symbol 30 File string 31 auxinfo *AuxSymbol 32 Sect *Section 33 FuncInfo *FuncInfo 34 Lib *Library // Package defining this symbol 35 // P contains the raw symbol data. 36 P []byte 37 R []Reloc 38 } 39 40 // AuxSymbol contains less-frequently used sym.Symbol fields. 41 type AuxSymbol struct { 42 extname string 43 dynimplib string 44 dynimpvers string 45 localentry uint8 46 plt int32 47 got int32 48 // ElfType is set for symbols read from shared libraries by ldshlibsyms. It 49 // is not set for symbols defined by the packages being linked or by symbols 50 // read by ldelf (and so is left as elf.STT_NOTYPE). 51 elftype elf.SymType 52 } 53 54 func (s *Symbol) String() string { 55 if s.Version == 0 { 56 return s.Name 57 } 58 return fmt.Sprintf("%s<%d>", s.Name, s.Version) 59 } 60 61 func (s *Symbol) ElfsymForReloc() int32 { 62 // If putelfsym created a local version of this symbol, use that in all 63 // relocations. 64 if s.LocalElfsym != 0 { 65 return s.LocalElfsym 66 } else { 67 return s.Elfsym 68 } 69 } 70 71 func (s *Symbol) Len() int64 { 72 return s.Size 73 } 74 75 func (s *Symbol) Grow(siz int64) { 76 if int64(int(siz)) != siz { 77 log.Fatalf("symgrow size %d too long", siz) 78 } 79 if int64(len(s.P)) >= siz { 80 return 81 } 82 if cap(s.P) < int(siz) { 83 p := make([]byte, 2*(siz+1)) 84 s.P = append(p[:0], s.P...) 85 } 86 s.P = s.P[:siz] 87 } 88 89 func (s *Symbol) AddBytes(bytes []byte) int64 { 90 if s.Type == 0 { 91 s.Type = SDATA 92 } 93 s.Attr |= AttrReachable 94 s.P = append(s.P, bytes...) 95 s.Size = int64(len(s.P)) 96 97 return s.Size 98 } 99 100 func (s *Symbol) AddUint8(v uint8) int64 { 101 off := s.Size 102 if s.Type == 0 { 103 s.Type = SDATA 104 } 105 s.Attr |= AttrReachable 106 s.Size++ 107 s.P = append(s.P, v) 108 109 return off 110 } 111 112 func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) int64 { 113 return s.AddUintXX(arch, uint64(v), 2) 114 } 115 116 func (s *Symbol) AddUint32(arch *sys.Arch, v uint32) int64 { 117 return s.AddUintXX(arch, uint64(v), 4) 118 } 119 120 func (s *Symbol) AddUint64(arch *sys.Arch, v uint64) int64 { 121 return s.AddUintXX(arch, v, 8) 122 } 123 124 func (s *Symbol) AddUint(arch *sys.Arch, v uint64) int64 { 125 return s.AddUintXX(arch, v, arch.PtrSize) 126 } 127 128 func (s *Symbol) SetUint8(arch *sys.Arch, r int64, v uint8) int64 { 129 return s.setUintXX(arch, r, uint64(v), 1) 130 } 131 132 func (s *Symbol) SetUint32(arch *sys.Arch, r int64, v uint32) int64 { 133 return s.setUintXX(arch, r, uint64(v), 4) 134 } 135 136 func (s *Symbol) SetUint(arch *sys.Arch, r int64, v uint64) int64 { 137 return s.setUintXX(arch, r, v, int64(arch.PtrSize)) 138 } 139 140 func (s *Symbol) AddAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 { 141 if s.Type == 0 { 142 s.Type = SDATA 143 } 144 s.Attr |= AttrReachable 145 i := s.Size 146 s.Size += int64(arch.PtrSize) 147 s.Grow(s.Size) 148 r := s.AddRel() 149 r.Sym = t 150 r.Off = int32(i) 151 r.Siz = uint8(arch.PtrSize) 152 r.Type = objabi.R_ADDR 153 r.Add = add 154 return i + int64(r.Siz) 155 } 156 157 func (s *Symbol) AddPCRelPlus(arch *sys.Arch, t *Symbol, add int64) int64 { 158 if s.Type == 0 { 159 s.Type = SDATA 160 } 161 s.Attr |= AttrReachable 162 i := s.Size 163 s.Size += 4 164 s.Grow(s.Size) 165 r := s.AddRel() 166 r.Sym = t 167 r.Off = int32(i) 168 r.Add = add 169 r.Type = objabi.R_PCREL 170 r.Siz = 4 171 if arch.Family == sys.S390X { 172 r.Variant = RV_390_DBL 173 } 174 return i + int64(r.Siz) 175 } 176 177 func (s *Symbol) AddAddr(arch *sys.Arch, t *Symbol) int64 { 178 return s.AddAddrPlus(arch, t, 0) 179 } 180 181 func (s *Symbol) SetAddrPlus(arch *sys.Arch, off int64, t *Symbol, add int64) int64 { 182 if s.Type == 0 { 183 s.Type = SDATA 184 } 185 s.Attr |= AttrReachable 186 if off+int64(arch.PtrSize) > s.Size { 187 s.Size = off + int64(arch.PtrSize) 188 s.Grow(s.Size) 189 } 190 191 r := s.AddRel() 192 r.Sym = t 193 r.Off = int32(off) 194 r.Siz = uint8(arch.PtrSize) 195 r.Type = objabi.R_ADDR 196 r.Add = add 197 return off + int64(r.Siz) 198 } 199 200 func (s *Symbol) SetAddr(arch *sys.Arch, off int64, t *Symbol) int64 { 201 return s.SetAddrPlus(arch, off, t, 0) 202 } 203 204 func (s *Symbol) AddSize(arch *sys.Arch, t *Symbol) int64 { 205 if s.Type == 0 { 206 s.Type = SDATA 207 } 208 s.Attr |= AttrReachable 209 i := s.Size 210 s.Size += int64(arch.PtrSize) 211 s.Grow(s.Size) 212 r := s.AddRel() 213 r.Sym = t 214 r.Off = int32(i) 215 r.Siz = uint8(arch.PtrSize) 216 r.Type = objabi.R_SIZE 217 return i + int64(r.Siz) 218 } 219 220 func (s *Symbol) AddAddrPlus4(t *Symbol, add int64) int64 { 221 if s.Type == 0 { 222 s.Type = SDATA 223 } 224 s.Attr |= AttrReachable 225 i := s.Size 226 s.Size += 4 227 s.Grow(s.Size) 228 r := s.AddRel() 229 r.Sym = t 230 r.Off = int32(i) 231 r.Siz = 4 232 r.Type = objabi.R_ADDR 233 r.Add = add 234 return i + int64(r.Siz) 235 } 236 237 func (s *Symbol) AddRel() *Reloc { 238 s.R = append(s.R, Reloc{}) 239 return &s.R[len(s.R)-1] 240 } 241 242 func (s *Symbol) AddUintXX(arch *sys.Arch, v uint64, wid int) int64 { 243 off := s.Size 244 s.setUintXX(arch, off, v, int64(wid)) 245 return off 246 } 247 248 func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 { 249 if s.Type == 0 { 250 s.Type = SDATA 251 } 252 s.Attr |= AttrReachable 253 if s.Size < off+wid { 254 s.Size = off + wid 255 s.Grow(s.Size) 256 } 257 258 switch wid { 259 case 1: 260 s.P[off] = uint8(v) 261 case 2: 262 arch.ByteOrder.PutUint16(s.P[off:], uint16(v)) 263 case 4: 264 arch.ByteOrder.PutUint32(s.P[off:], uint32(v)) 265 case 8: 266 arch.ByteOrder.PutUint64(s.P[off:], v) 267 } 268 269 return off + wid 270 } 271 272 func (s *Symbol) makeAuxInfo() { 273 if s.auxinfo == nil { 274 s.auxinfo = &AuxSymbol{extname: s.Name, plt: -1, got: -1} 275 } 276 } 277 278 func (s *Symbol) Extname() string { 279 if s.auxinfo == nil { 280 return s.Name 281 } 282 return s.auxinfo.extname 283 } 284 285 func (s *Symbol) SetExtname(n string) { 286 if s.auxinfo == nil { 287 if s.Name == n { 288 return 289 } 290 s.makeAuxInfo() 291 } 292 s.auxinfo.extname = n 293 } 294 295 func (s *Symbol) Dynimplib() string { 296 if s.auxinfo == nil { 297 return "" 298 } 299 return s.auxinfo.dynimplib 300 } 301 302 func (s *Symbol) Dynimpvers() string { 303 if s.auxinfo == nil { 304 return "" 305 } 306 return s.auxinfo.dynimpvers 307 } 308 309 func (s *Symbol) SetDynimplib(lib string) { 310 if s.auxinfo == nil { 311 s.makeAuxInfo() 312 } 313 s.auxinfo.dynimplib = lib 314 } 315 316 func (s *Symbol) SetDynimpvers(vers string) { 317 if s.auxinfo == nil { 318 s.makeAuxInfo() 319 } 320 s.auxinfo.dynimpvers = vers 321 } 322 323 func (s *Symbol) ResetDyninfo() { 324 if s.auxinfo != nil { 325 s.auxinfo.dynimplib = "" 326 s.auxinfo.dynimpvers = "" 327 } 328 } 329 330 func (s *Symbol) Localentry() uint8 { 331 if s.auxinfo == nil { 332 return 0 333 } 334 return s.auxinfo.localentry 335 } 336 337 func (s *Symbol) SetLocalentry(val uint8) { 338 if s.auxinfo == nil { 339 if val != 0 { 340 return 341 } 342 s.makeAuxInfo() 343 } 344 s.auxinfo.localentry = val 345 } 346 347 func (s *Symbol) Plt() int32 { 348 if s.auxinfo == nil { 349 return -1 350 } 351 return s.auxinfo.plt 352 } 353 354 func (s *Symbol) SetPlt(val int32) { 355 if s.auxinfo == nil { 356 if val == -1 { 357 return 358 } 359 s.makeAuxInfo() 360 } 361 s.auxinfo.plt = val 362 } 363 364 func (s *Symbol) Got() int32 { 365 if s.auxinfo == nil { 366 return -1 367 } 368 return s.auxinfo.got 369 } 370 371 func (s *Symbol) SetGot(val int32) { 372 if s.auxinfo == nil { 373 if val == -1 { 374 return 375 } 376 s.makeAuxInfo() 377 } 378 s.auxinfo.got = val 379 } 380 381 func (s *Symbol) ElfType() elf.SymType { 382 if s.auxinfo == nil { 383 return elf.STT_NOTYPE 384 } 385 return s.auxinfo.elftype 386 } 387 388 func (s *Symbol) SetElfType(val elf.SymType) { 389 if s.auxinfo == nil { 390 if val == elf.STT_NOTYPE { 391 return 392 } 393 s.makeAuxInfo() 394 } 395 s.auxinfo.elftype = val 396 } 397 398 // SortSub sorts a linked-list (by Sub) of *Symbol by Value. 399 // Used for sub-symbols when loading host objects (see e.g. ldelf.go). 400 func SortSub(l *Symbol) *Symbol { 401 if l == nil || l.Sub == nil { 402 return l 403 } 404 405 l1 := l 406 l2 := l 407 for { 408 l2 = l2.Sub 409 if l2 == nil { 410 break 411 } 412 l2 = l2.Sub 413 if l2 == nil { 414 break 415 } 416 l1 = l1.Sub 417 } 418 419 l2 = l1.Sub 420 l1.Sub = nil 421 l1 = SortSub(l) 422 l2 = SortSub(l2) 423 424 /* set up lead element */ 425 if l1.Value < l2.Value { 426 l = l1 427 l1 = l1.Sub 428 } else { 429 l = l2 430 l2 = l2.Sub 431 } 432 433 le := l 434 435 for { 436 if l1 == nil { 437 for l2 != nil { 438 le.Sub = l2 439 le = l2 440 l2 = l2.Sub 441 } 442 443 le.Sub = nil 444 break 445 } 446 447 if l2 == nil { 448 for l1 != nil { 449 le.Sub = l1 450 le = l1 451 l1 = l1.Sub 452 } 453 454 break 455 } 456 457 if l1.Value < l2.Value { 458 le.Sub = l1 459 le = l1 460 l1 = l1.Sub 461 } else { 462 le.Sub = l2 463 le = l2 464 l2 = l2.Sub 465 } 466 } 467 468 le.Sub = nil 469 return l 470 } 471 472 type FuncInfo struct { 473 Args int32 474 Locals int32 475 Autom []Auto 476 Pcsp Pcdata 477 Pcfile Pcdata 478 Pcline Pcdata 479 Pcinline Pcdata 480 Pcdata []Pcdata 481 IsStmtSym *Symbol 482 Funcdata []*Symbol 483 Funcdataoff []int64 484 File []*Symbol 485 InlTree []InlinedCall 486 } 487 488 // InlinedCall is a node in a local inlining tree (FuncInfo.InlTree). 489 type InlinedCall struct { 490 Parent int32 // index of parent in InlTree 491 File *Symbol // file of the inlined call 492 Line int32 // line number of the inlined call 493 Func *Symbol // function that was inlined 494 } 495 496 type Pcdata struct { 497 P []byte 498 } 499 500 type Auto struct { 501 Asym *Symbol 502 Gotype *Symbol 503 Aoffset int32 504 Name int16 505 }