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