github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/cmd/link/internal/ld/ldelf.go (about) 1 package ld 2 3 import ( 4 "bytes" 5 "cmd/internal/bio" 6 "cmd/internal/obj" 7 "cmd/internal/sys" 8 "encoding/binary" 9 "fmt" 10 "io" 11 "log" 12 "sort" 13 "strings" 14 ) 15 16 /* 17 Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c 18 http://code.swtch.com/plan9port/src/tip/src/libmach/ 19 20 Copyright © 2004 Russ Cox. 21 Portions Copyright © 2008-2010 Google Inc. 22 Portions Copyright © 2010 The Go Authors. 23 24 Permission is hereby granted, free of charge, to any person obtaining a copy 25 of this software and associated documentation files (the "Software"), to deal 26 in the Software without restriction, including without limitation the rights 27 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 28 copies of the Software, and to permit persons to whom the Software is 29 furnished to do so, subject to the following conditions: 30 31 The above copyright notice and this permission notice shall be included in 32 all copies or substantial portions of the Software. 33 34 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 35 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 36 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 37 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 38 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 39 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 40 THE SOFTWARE. 41 */ 42 const ( 43 ElfClassNone = 0 44 ElfClass32 = 1 45 ElfClass64 = 2 46 ) 47 48 const ( 49 ElfDataNone = 0 50 ElfDataLsb = 1 51 ElfDataMsb = 2 52 ) 53 54 const ( 55 ElfTypeNone = 0 56 ElfTypeRelocatable = 1 57 ElfTypeExecutable = 2 58 ElfTypeSharedObject = 3 59 ElfTypeCore = 4 60 ) 61 62 const ( 63 ElfMachNone = 0 64 ElfMach32100 = 1 65 ElfMachSparc = 2 66 ElfMach386 = 3 67 ElfMach68000 = 4 68 ElfMach88000 = 5 69 ElfMach486 = 6 70 ElfMach860 = 7 71 ElfMachMips = 8 72 ElfMachS370 = 9 73 ElfMachMipsLe = 10 74 ElfMachParisc = 15 75 ElfMachVpp500 = 17 76 ElfMachSparc32Plus = 18 77 ElfMach960 = 19 78 ElfMachPower = 20 79 ElfMachPower64 = 21 80 ElfMachS390 = 22 81 ElfMachV800 = 36 82 ElfMachFr20 = 37 83 ElfMachRh32 = 38 84 ElfMachRce = 39 85 ElfMachArm = 40 86 ElfMachAlpha = 41 87 ElfMachSH = 42 88 ElfMachSparc9 = 43 89 ElfMachAmd64 = 62 90 ElfMachArm64 = 183 91 ) 92 93 const ( 94 ElfAbiNone = 0 95 ElfAbiSystemV = 0 96 ElfAbiHPUX = 1 97 ElfAbiNetBSD = 2 98 ElfAbiLinux = 3 99 ElfAbiSolaris = 6 100 ElfAbiAix = 7 101 ElfAbiIrix = 8 102 ElfAbiFreeBSD = 9 103 ElfAbiTru64 = 10 104 ElfAbiModesto = 11 105 ElfAbiOpenBSD = 12 106 ElfAbiARM = 97 107 ElfAbiEmbedded = 255 108 ) 109 110 const ( 111 ElfSectNone = 0 112 ElfSectProgbits = 1 113 ElfSectSymtab = 2 114 ElfSectStrtab = 3 115 ElfSectRela = 4 116 ElfSectHash = 5 117 ElfSectDynamic = 6 118 ElfSectNote = 7 119 ElfSectNobits = 8 120 ElfSectRel = 9 121 ElfSectShlib = 10 122 ElfSectDynsym = 11 123 ElfSectFlagWrite = 0x1 124 ElfSectFlagAlloc = 0x2 125 ElfSectFlagExec = 0x4 126 ) 127 128 const ( 129 ElfSymBindLocal = 0 130 ElfSymBindGlobal = 1 131 ElfSymBindWeak = 2 132 ) 133 134 const ( 135 ElfSymTypeNone = 0 136 ElfSymTypeObject = 1 137 ElfSymTypeFunc = 2 138 ElfSymTypeSection = 3 139 ElfSymTypeFile = 4 140 ) 141 142 const ( 143 ElfSymShnNone = 0 144 ElfSymShnAbs = 0xFFF1 145 ElfSymShnCommon = 0xFFF2 146 ) 147 148 const ( 149 ElfProgNone = 0 150 ElfProgLoad = 1 151 ElfProgDynamic = 2 152 ElfProgInterp = 3 153 ElfProgNote = 4 154 ElfProgShlib = 5 155 ElfProgPhdr = 6 156 ElfProgFlagExec = 0x1 157 ElfProgFlagWrite = 0x2 158 ElfProgFlagRead = 0x4 159 ) 160 161 const ( 162 ElfNotePrStatus = 1 163 ElfNotePrFpreg = 2 164 ElfNotePrPsinfo = 3 165 ElfNotePrTaskstruct = 4 166 ElfNotePrAuxv = 6 167 ElfNotePrXfpreg = 0x46e62b7f 168 ) 169 170 type ElfHdrBytes struct { 171 Ident [16]uint8 172 Type [2]uint8 173 Machine [2]uint8 174 Version [4]uint8 175 Entry [4]uint8 176 Phoff [4]uint8 177 Shoff [4]uint8 178 Flags [4]uint8 179 Ehsize [2]uint8 180 Phentsize [2]uint8 181 Phnum [2]uint8 182 Shentsize [2]uint8 183 Shnum [2]uint8 184 Shstrndx [2]uint8 185 } 186 187 type ElfSectBytes struct { 188 Name [4]uint8 189 Type [4]uint8 190 Flags [4]uint8 191 Addr [4]uint8 192 Off [4]uint8 193 Size [4]uint8 194 Link [4]uint8 195 Info [4]uint8 196 Align [4]uint8 197 Entsize [4]uint8 198 } 199 200 type ElfProgBytes struct { 201 } 202 203 type ElfSymBytes struct { 204 Name [4]uint8 205 Value [4]uint8 206 Size [4]uint8 207 Info uint8 208 Other uint8 209 Shndx [2]uint8 210 } 211 212 type ElfHdrBytes64 struct { 213 Ident [16]uint8 214 Type [2]uint8 215 Machine [2]uint8 216 Version [4]uint8 217 Entry [8]uint8 218 Phoff [8]uint8 219 Shoff [8]uint8 220 Flags [4]uint8 221 Ehsize [2]uint8 222 Phentsize [2]uint8 223 Phnum [2]uint8 224 Shentsize [2]uint8 225 Shnum [2]uint8 226 Shstrndx [2]uint8 227 } 228 229 type ElfSectBytes64 struct { 230 Name [4]uint8 231 Type [4]uint8 232 Flags [8]uint8 233 Addr [8]uint8 234 Off [8]uint8 235 Size [8]uint8 236 Link [4]uint8 237 Info [4]uint8 238 Align [8]uint8 239 Entsize [8]uint8 240 } 241 242 type ElfProgBytes64 struct { 243 } 244 245 type ElfSymBytes64 struct { 246 Name [4]uint8 247 Info uint8 248 Other uint8 249 Shndx [2]uint8 250 Value [8]uint8 251 Size [8]uint8 252 } 253 254 type ElfSect struct { 255 name string 256 nameoff uint32 257 type_ uint32 258 flags uint64 259 addr uint64 260 off uint64 261 size uint64 262 link uint32 263 info uint32 264 align uint64 265 entsize uint64 266 base []byte 267 sym *LSym 268 } 269 270 type ElfObj struct { 271 f *bio.Reader 272 base int64 // offset in f where ELF begins 273 length int64 // length of ELF 274 is64 int 275 name string 276 e binary.ByteOrder 277 sect []ElfSect 278 nsect uint 279 shstrtab string 280 nsymtab int 281 symtab *ElfSect 282 symstr *ElfSect 283 type_ uint32 284 machine uint32 285 version uint32 286 entry uint64 287 phoff uint64 288 shoff uint64 289 flags uint32 290 ehsize uint32 291 phentsize uint32 292 phnum uint32 293 shentsize uint32 294 shnum uint32 295 shstrndx uint32 296 } 297 298 type ElfSym struct { 299 name string 300 value uint64 301 size uint64 302 bind uint8 303 type_ uint8 304 other uint8 305 shndx uint16 306 sym *LSym 307 } 308 309 var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'} 310 311 func valuecmp(a *LSym, b *LSym) int { 312 if a.Value < b.Value { 313 return -1 314 } 315 if a.Value > b.Value { 316 return +1 317 } 318 return 0 319 } 320 321 const ( 322 Tag_file = 1 323 Tag_CPU_name = 4 324 Tag_CPU_raw_name = 5 325 Tag_compatibility = 32 326 Tag_nodefaults = 64 327 Tag_also_compatible_with = 65 328 Tag_ABI_VFP_args = 28 329 ) 330 331 type elfAttribute struct { 332 tag uint64 333 sval string 334 ival uint64 335 } 336 337 type elfAttributeList struct { 338 data []byte 339 err error 340 } 341 342 func (a *elfAttributeList) string() string { 343 if a.err != nil { 344 return "" 345 } 346 nul := bytes.IndexByte(a.data, 0) 347 if nul < 0 { 348 a.err = io.EOF 349 return "" 350 } 351 s := string(a.data[:nul]) 352 a.data = a.data[nul+1:] 353 return s 354 } 355 356 func (a *elfAttributeList) uleb128() uint64 { 357 if a.err != nil { 358 return 0 359 } 360 v, size := binary.Uvarint(a.data) 361 a.data = a.data[size:] 362 return v 363 } 364 365 // Read an elfAttribute from the list following the rules used on ARM systems. 366 func (a *elfAttributeList) armAttr() elfAttribute { 367 attr := elfAttribute{tag: a.uleb128()} 368 switch { 369 case attr.tag == Tag_compatibility: 370 attr.ival = a.uleb128() 371 attr.sval = a.string() 372 373 case attr.tag == 64: // Tag_nodefaults has no argument 374 375 case attr.tag == 65: // Tag_also_compatible_with 376 // Not really, but we don't actually care about this tag. 377 attr.sval = a.string() 378 379 // Tag with string argument 380 case attr.tag == Tag_CPU_name || attr.tag == Tag_CPU_raw_name || (attr.tag >= 32 && attr.tag&1 != 0): 381 attr.sval = a.string() 382 383 default: // Tag with integer argument 384 attr.ival = a.uleb128() 385 } 386 return attr 387 } 388 389 func (a *elfAttributeList) done() bool { 390 if a.err != nil || len(a.data) == 0 { 391 return true 392 } 393 return false 394 } 395 396 // Look for the attribute that indicates the object uses the hard-float ABI (a 397 // file-level attribute with tag Tag_VFP_arch and value 1). Unfortunately the 398 // format used means that we have to parse all of the file-level attributes to 399 // find the one we are looking for. This format is slightly documented in "ELF 400 // for the ARM Architecture" but mostly this is derived from reading the source 401 // to gold and readelf. 402 func parseArmAttributes(e binary.ByteOrder, data []byte) { 403 // We assume the soft-float ABI unless we see a tag indicating otherwise. 404 if ehdr.flags == 0x5000002 { 405 ehdr.flags = 0x5000202 406 } 407 if data[0] != 'A' { 408 fmt.Fprintf(Bso, ".ARM.attributes has unexpected format %c\n", data[0]) 409 return 410 } 411 data = data[1:] 412 for len(data) != 0 { 413 sectionlength := e.Uint32(data) 414 sectiondata := data[4:sectionlength] 415 data = data[sectionlength:] 416 417 nulIndex := bytes.IndexByte(sectiondata, 0) 418 if nulIndex < 0 { 419 fmt.Fprintf(Bso, "corrupt .ARM.attributes (section name not NUL-terminated)\n") 420 return 421 } 422 name := string(sectiondata[:nulIndex]) 423 sectiondata = sectiondata[nulIndex+1:] 424 425 if name != "aeabi" { 426 continue 427 } 428 for len(sectiondata) != 0 { 429 subsectiontag, sz := binary.Uvarint(sectiondata) 430 subsectionsize := e.Uint32(sectiondata[sz:]) 431 subsectiondata := sectiondata[sz+4 : subsectionsize] 432 sectiondata = sectiondata[subsectionsize:] 433 434 if subsectiontag == Tag_file { 435 attrList := elfAttributeList{data: subsectiondata} 436 for !attrList.done() { 437 attr := attrList.armAttr() 438 if attr.tag == Tag_ABI_VFP_args && attr.ival == 1 { 439 ehdr.flags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI 440 } 441 } 442 if attrList.err != nil { 443 fmt.Fprintf(Bso, "could not parse .ARM.attributes\n") 444 } 445 } 446 } 447 } 448 } 449 450 func ldelf(f *bio.Reader, pkg string, length int64, pn string) { 451 if Debug['v'] != 0 { 452 fmt.Fprintf(Bso, "%5.2f ldelf %s\n", obj.Cputime(), pn) 453 } 454 455 Ctxt.IncVersion() 456 base := f.Offset() 457 458 var add uint64 459 var e binary.ByteOrder 460 var elfobj *ElfObj 461 var err error 462 var flag int 463 var hdr *ElfHdrBytes 464 var hdrbuf [64]uint8 465 var info uint64 466 var is64 int 467 var j int 468 var n int 469 var name string 470 var p []byte 471 var r []Reloc 472 var rela int 473 var rp *Reloc 474 var rsect *ElfSect 475 var s *LSym 476 var sect *ElfSect 477 var sym ElfSym 478 var symbols []*LSym 479 if _, err := io.ReadFull(f, hdrbuf[:]); err != nil { 480 goto bad 481 } 482 hdr = new(ElfHdrBytes) 483 binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter 484 if string(hdr.Ident[:4]) != "\x7FELF" { 485 goto bad 486 } 487 switch hdr.Ident[5] { 488 case ElfDataLsb: 489 e = binary.LittleEndian 490 491 case ElfDataMsb: 492 e = binary.BigEndian 493 494 default: 495 goto bad 496 } 497 498 // read header 499 elfobj = new(ElfObj) 500 501 elfobj.e = e 502 elfobj.f = f 503 elfobj.base = base 504 elfobj.length = length 505 elfobj.name = pn 506 507 is64 = 0 508 if hdr.Ident[4] == ElfClass64 { 509 is64 = 1 510 hdr := new(ElfHdrBytes64) 511 binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter 512 elfobj.type_ = uint32(e.Uint16(hdr.Type[:])) 513 elfobj.machine = uint32(e.Uint16(hdr.Machine[:])) 514 elfobj.version = e.Uint32(hdr.Version[:]) 515 elfobj.phoff = e.Uint64(hdr.Phoff[:]) 516 elfobj.shoff = e.Uint64(hdr.Shoff[:]) 517 elfobj.flags = e.Uint32(hdr.Flags[:]) 518 elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:])) 519 elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:])) 520 elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:])) 521 elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:])) 522 elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:])) 523 elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:])) 524 } else { 525 elfobj.type_ = uint32(e.Uint16(hdr.Type[:])) 526 elfobj.machine = uint32(e.Uint16(hdr.Machine[:])) 527 elfobj.version = e.Uint32(hdr.Version[:]) 528 elfobj.entry = uint64(e.Uint32(hdr.Entry[:])) 529 elfobj.phoff = uint64(e.Uint32(hdr.Phoff[:])) 530 elfobj.shoff = uint64(e.Uint32(hdr.Shoff[:])) 531 elfobj.flags = e.Uint32(hdr.Flags[:]) 532 elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:])) 533 elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:])) 534 elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:])) 535 elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:])) 536 elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:])) 537 elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:])) 538 } 539 540 elfobj.is64 = is64 541 542 if uint32(hdr.Ident[6]) != elfobj.version { 543 goto bad 544 } 545 546 if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable { 547 Diag("%s: elf but not elf relocatable object", pn) 548 return 549 } 550 551 switch SysArch.Family { 552 default: 553 Diag("%s: elf %s unimplemented", pn, SysArch.Name) 554 return 555 556 case sys.MIPS64: 557 if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 { 558 Diag("%s: elf object but not mips64", pn) 559 return 560 } 561 562 case sys.ARM: 563 if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 { 564 Diag("%s: elf object but not arm", pn) 565 return 566 } 567 568 case sys.AMD64: 569 if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 { 570 Diag("%s: elf object but not amd64", pn) 571 return 572 } 573 574 case sys.ARM64: 575 if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 { 576 Diag("%s: elf object but not arm64", pn) 577 return 578 } 579 580 case sys.I386: 581 if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 { 582 Diag("%s: elf object but not 386", pn) 583 return 584 } 585 586 case sys.PPC64: 587 if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 { 588 Diag("%s: elf object but not ppc64", pn) 589 return 590 } 591 592 case sys.S390X: 593 if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 { 594 Diag("%s: elf object but not s390x", pn) 595 return 596 } 597 598 case sys.SPARC64: 599 if elfobj.machine != ElfMachSparc9 || hdr.Ident[4] != ElfClass64 { 600 Diag("%s: elf object but not sparc64", pn) 601 return 602 } 603 } 604 605 // load section list into memory. 606 elfobj.sect = make([]ElfSect, elfobj.shnum) 607 608 elfobj.nsect = uint(elfobj.shnum) 609 for i := 0; uint(i) < elfobj.nsect; i++ { 610 if f.Seek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 { 611 goto bad 612 } 613 sect = &elfobj.sect[i] 614 if is64 != 0 { 615 var b ElfSectBytes64 616 617 if err = binary.Read(f, e, &b); err != nil { 618 goto bad 619 } 620 621 sect.nameoff = e.Uint32(b.Name[:]) 622 sect.type_ = e.Uint32(b.Type[:]) 623 sect.flags = e.Uint64(b.Flags[:]) 624 sect.addr = e.Uint64(b.Addr[:]) 625 sect.off = e.Uint64(b.Off[:]) 626 sect.size = e.Uint64(b.Size[:]) 627 sect.link = e.Uint32(b.Link[:]) 628 sect.info = e.Uint32(b.Info[:]) 629 sect.align = e.Uint64(b.Align[:]) 630 sect.entsize = e.Uint64(b.Entsize[:]) 631 } else { 632 var b ElfSectBytes 633 634 if err = binary.Read(f, e, &b); err != nil { 635 goto bad 636 } 637 638 sect.nameoff = e.Uint32(b.Name[:]) 639 sect.type_ = e.Uint32(b.Type[:]) 640 sect.flags = uint64(e.Uint32(b.Flags[:])) 641 sect.addr = uint64(e.Uint32(b.Addr[:])) 642 sect.off = uint64(e.Uint32(b.Off[:])) 643 sect.size = uint64(e.Uint32(b.Size[:])) 644 sect.link = e.Uint32(b.Link[:]) 645 sect.info = e.Uint32(b.Info[:]) 646 sect.align = uint64(e.Uint32(b.Align[:])) 647 sect.entsize = uint64(e.Uint32(b.Entsize[:])) 648 } 649 } 650 651 // read section string table and translate names 652 if elfobj.shstrndx >= uint32(elfobj.nsect) { 653 err = fmt.Errorf("shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect) 654 goto bad 655 } 656 657 sect = &elfobj.sect[elfobj.shstrndx] 658 if err = elfmap(elfobj, sect); err != nil { 659 goto bad 660 } 661 for i := 0; uint(i) < elfobj.nsect; i++ { 662 if elfobj.sect[i].nameoff != 0 { 663 elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:]) 664 } 665 } 666 667 // load string table for symbols into memory. 668 elfobj.symtab = section(elfobj, ".symtab") 669 670 if elfobj.symtab == nil { 671 // our work is done here - no symbols means nothing can refer to this file 672 return 673 } 674 675 if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) { 676 Diag("%s: elf object has symbol table with invalid string table link", pn) 677 return 678 } 679 680 elfobj.symstr = &elfobj.sect[elfobj.symtab.link] 681 if is64 != 0 { 682 elfobj.nsymtab = int(elfobj.symtab.size / ELF64SYMSIZE) 683 } else { 684 elfobj.nsymtab = int(elfobj.symtab.size / ELF32SYMSIZE) 685 } 686 687 if err = elfmap(elfobj, elfobj.symtab); err != nil { 688 goto bad 689 } 690 if err = elfmap(elfobj, elfobj.symstr); err != nil { 691 goto bad 692 } 693 694 // load text and data segments into memory. 695 // they are not as small as the section lists, but we'll need 696 // the memory anyway for the symbol images, so we might 697 // as well use one large chunk. 698 699 // create symbols for elfmapped sections 700 for i := 0; uint(i) < elfobj.nsect; i++ { 701 sect = &elfobj.sect[i] 702 if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" { 703 if err = elfmap(elfobj, sect); err != nil { 704 goto bad 705 } 706 parseArmAttributes(e, sect.base[:sect.size]) 707 } 708 if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 { 709 continue 710 } 711 if sect.type_ != ElfSectNobits { 712 if err = elfmap(elfobj, sect); err != nil { 713 goto bad 714 } 715 } 716 717 name = fmt.Sprintf("%s(%s)", pkg, sect.name) 718 s = Linklookup(Ctxt, name, Ctxt.Version) 719 720 switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) { 721 default: 722 err = fmt.Errorf("unexpected flags for ELF section %s", sect.name) 723 goto bad 724 725 case ElfSectFlagAlloc: 726 s.Type = obj.SRODATA 727 728 case ElfSectFlagAlloc + ElfSectFlagWrite: 729 if sect.type_ == ElfSectNobits { 730 s.Type = obj.SNOPTRBSS 731 } else { 732 s.Type = obj.SNOPTRDATA 733 } 734 735 case ElfSectFlagAlloc + ElfSectFlagExec: 736 s.Type = obj.STEXT 737 } 738 739 if sect.name == ".got" || sect.name == ".toc" { 740 s.Type = obj.SELFGOT 741 } 742 if sect.type_ == ElfSectProgbits { 743 s.P = sect.base 744 s.P = s.P[:sect.size] 745 } 746 747 s.Size = int64(sect.size) 748 s.Align = int32(sect.align) 749 sect.sym = s 750 } 751 752 // enter sub-symbols into symbol table. 753 // symbol 0 is the null symbol. 754 symbols = make([]*LSym, elfobj.nsymtab) 755 756 for i := 1; i < elfobj.nsymtab; i++ { 757 if err = readelfsym(elfobj, i, &sym, 1); err != nil { 758 goto bad 759 } 760 symbols[i] = sym.sym 761 if sym.type_ != ElfSymTypeFunc && sym.type_ != ElfSymTypeObject && sym.type_ != ElfSymTypeNone { 762 continue 763 } 764 if sym.shndx == ElfSymShnCommon { 765 s = sym.sym 766 if uint64(s.Size) < sym.size { 767 s.Size = int64(sym.size) 768 } 769 if s.Type == 0 || s.Type == obj.SXREF { 770 s.Type = obj.SNOPTRBSS 771 } 772 continue 773 } 774 775 if uint(sym.shndx) >= elfobj.nsect || sym.shndx == 0 { 776 continue 777 } 778 779 // even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols 780 if sym.sym == nil { 781 continue 782 } 783 sect = &elfobj.sect[sym.shndx] 784 if sect.sym == nil { 785 if strings.HasPrefix(sym.name, ".Linfo_string") { // clang does this 786 continue 787 } 788 789 if sym.name == "" && sym.type_ == 0 && sect.name == ".debug_str" { 790 // This reportedly happens with clang 3.7 on ARM. 791 // See issue 13139. 792 continue 793 } 794 795 if strings.HasPrefix(sym.name, ".LASF") { // gcc on s390x does this 796 continue 797 } 798 Diag("%s: sym#%d: ignoring %s in section %d (type %d)", pn, i, sym.name, sym.shndx, sym.type_) 799 continue 800 } 801 802 s = sym.sym 803 if s.Outer != nil { 804 if s.Attr.DuplicateOK() { 805 continue 806 } 807 Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name) 808 } 809 810 s.Sub = sect.sym.Sub 811 sect.sym.Sub = s 812 s.Type = sect.sym.Type | s.Type&^obj.SMASK | obj.SSUB 813 if !s.Attr.CgoExportDynamic() { 814 s.Dynimplib = "" // satisfy dynimport 815 } 816 s.Value = int64(sym.value) 817 s.Size = int64(sym.size) 818 s.Outer = sect.sym 819 if sect.sym.Type == obj.STEXT { 820 if s.Attr.External() && !s.Attr.DuplicateOK() { 821 Diag("%s: duplicate definition of %s", pn, s.Name) 822 } 823 s.Attr |= AttrExternal 824 } 825 826 if elfobj.machine == ElfMachPower64 { 827 flag = int(sym.other) >> 5 828 if 2 <= flag && flag <= 6 { 829 s.Localentry = 1 << uint(flag-2) 830 } else if flag == 7 { 831 Diag("%s: invalid sym.other 0x%x for %s", pn, sym.other, s.Name) 832 } 833 } 834 } 835 836 // Sort outer lists by address, adding to textp. 837 // This keeps textp in increasing address order. 838 for i := 0; uint(i) < elfobj.nsect; i++ { 839 s = elfobj.sect[i].sym 840 if s == nil { 841 continue 842 } 843 if s.Sub != nil { 844 s.Sub = listsort(s.Sub, valuecmp, listsubp) 845 } 846 if s.Type == obj.STEXT { 847 if s.Attr.OnList() { 848 log.Fatalf("symbol %s listed multiple times", s.Name) 849 } 850 s.Attr |= AttrOnList 851 Ctxt.Textp = append(Ctxt.Textp, s) 852 for s = s.Sub; s != nil; s = s.Sub { 853 if s.Attr.OnList() { 854 log.Fatalf("symbol %s listed multiple times", s.Name) 855 } 856 s.Attr |= AttrOnList 857 Ctxt.Textp = append(Ctxt.Textp, s) 858 } 859 } 860 } 861 862 // load relocations 863 for i := 0; uint(i) < elfobj.nsect; i++ { 864 rsect = &elfobj.sect[i] 865 if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel { 866 continue 867 } 868 if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil { 869 continue 870 } 871 sect = &elfobj.sect[rsect.info] 872 if err = elfmap(elfobj, rsect); err != nil { 873 goto bad 874 } 875 rela = 0 876 if rsect.type_ == ElfSectRela { 877 rela = 1 878 } 879 n = int(rsect.size / uint64(4+4*is64) / uint64(2+rela)) 880 r = make([]Reloc, n) 881 p = rsect.base 882 for j = 0; j < n; j++ { 883 add = 0 884 rp = &r[j] 885 if is64 != 0 { 886 // 64-bit rel/rela 887 rp.Off = int32(e.Uint64(p)) 888 889 p = p[8:] 890 info = e.Uint64(p) 891 p = p[8:] 892 if rela != 0 { 893 add = e.Uint64(p) 894 p = p[8:] 895 } 896 } else { 897 // 32-bit rel/rela 898 rp.Off = int32(e.Uint32(p)) 899 900 p = p[4:] 901 info = uint64(e.Uint32(p)) 902 info = info>>8<<32 | info&0xff // convert to 64-bit info 903 p = p[4:] 904 if rela != 0 { 905 add = uint64(e.Uint32(p)) 906 p = p[4:] 907 } 908 } 909 910 if info&0xffffffff == 0 { // skip R_*_NONE relocation 911 j-- 912 n-- 913 continue 914 } 915 916 if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol 917 rp.Sym = nil 918 } else { 919 if err = readelfsym(elfobj, int(info>>32), &sym, 0); err != nil { 920 goto bad 921 } 922 sym.sym = symbols[info>>32] 923 if sym.sym == nil { 924 err = fmt.Errorf("%s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", sect.sym.Name, j, int(info>>32), sym.name, sym.shndx, sym.type_) 925 goto bad 926 } 927 928 rp.Sym = sym.sym 929 } 930 931 rp.Type = 256 + int32(info) 932 rp.Siz = relSize(pn, uint32(info)) 933 if rela != 0 { 934 rp.Add = int64(add) 935 } else { 936 // load addend from image 937 if rp.Siz == 4 { 938 rp.Add = int64(e.Uint32(sect.base[rp.Off:])) 939 } else if rp.Siz == 8 { 940 rp.Add = int64(e.Uint64(sect.base[rp.Off:])) 941 } else { 942 Diag("invalid rela size %d", rp.Siz) 943 } 944 } 945 946 if rp.Siz == 2 { 947 rp.Add = int64(int16(rp.Add)) 948 } 949 if rp.Siz == 4 { 950 rp.Add = int64(int32(rp.Add)) 951 } 952 } 953 954 //print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add); 955 sort.Sort(rbyoff(r[:n])) 956 // just in case 957 958 s = sect.sym 959 s.R = r 960 s.R = s.R[:n] 961 } 962 963 return 964 965 bad: 966 Diag("%s: malformed elf file: %v", pn, err) 967 } 968 969 func section(elfobj *ElfObj, name string) *ElfSect { 970 for i := 0; uint(i) < elfobj.nsect; i++ { 971 if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name { 972 return &elfobj.sect[i] 973 } 974 } 975 return nil 976 } 977 978 func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) { 979 if sect.base != nil { 980 return nil 981 } 982 983 if sect.off+sect.size > uint64(elfobj.length) { 984 err = fmt.Errorf("elf section past end of file") 985 return err 986 } 987 988 sect.base = make([]byte, sect.size) 989 if elfobj.f.Seek(int64(uint64(elfobj.base)+sect.off), 0) < 0 { 990 return fmt.Errorf("short read: seek not successful") 991 } 992 if _, err := io.ReadFull(elfobj.f, sect.base); err != nil { 993 return fmt.Errorf("short read: %v", err) 994 } 995 996 return nil 997 } 998 999 func readelfsym(elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) { 1000 if i >= elfobj.nsymtab || i < 0 { 1001 err = fmt.Errorf("invalid elf symbol index") 1002 return err 1003 } 1004 1005 if i == 0 { 1006 Diag("readym: read null symbol!") 1007 } 1008 1009 if elfobj.is64 != 0 { 1010 b := new(ElfSymBytes64) 1011 binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b) 1012 sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):]) 1013 sym.value = elfobj.e.Uint64(b.Value[:]) 1014 sym.size = elfobj.e.Uint64(b.Size[:]) 1015 sym.shndx = elfobj.e.Uint16(b.Shndx[:]) 1016 sym.bind = b.Info >> 4 1017 sym.type_ = b.Info & 0xf 1018 sym.other = b.Other 1019 } else { 1020 b := new(ElfSymBytes) 1021 binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b) 1022 sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):]) 1023 sym.value = uint64(elfobj.e.Uint32(b.Value[:])) 1024 sym.size = uint64(elfobj.e.Uint32(b.Size[:])) 1025 sym.shndx = elfobj.e.Uint16(b.Shndx[:]) 1026 sym.bind = b.Info >> 4 1027 sym.type_ = b.Info & 0xf 1028 sym.other = b.Other 1029 } 1030 1031 var s *LSym 1032 if sym.name == "_GLOBAL_OFFSET_TABLE_" { 1033 sym.name = ".got" 1034 } 1035 if sym.name == ".TOC." { 1036 // Magic symbol on ppc64. Will be set to this object 1037 // file's .got+0x8000. 1038 sym.bind = ElfSymBindLocal 1039 } 1040 1041 switch sym.type_ { 1042 case ElfSymTypeSection: 1043 s = elfobj.sect[sym.shndx].sym 1044 1045 case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone: 1046 switch sym.bind { 1047 case ElfSymBindGlobal: 1048 if needSym != 0 { 1049 s = Linklookup(Ctxt, sym.name, 0) 1050 1051 // for global scoped hidden symbols we should insert it into 1052 // symbol hash table, but mark them as hidden. 1053 // __i686.get_pc_thunk.bx is allowed to be duplicated, to 1054 // workaround that we set dupok. 1055 // TODO(minux): correctly handle __i686.get_pc_thunk.bx without 1056 // set dupok generally. See http://codereview.appspot.com/5823055/ 1057 // comment #5 for details. 1058 if s != nil && sym.other == 2 { 1059 s.Type |= obj.SHIDDEN 1060 s.Attr |= AttrDuplicateOK 1061 } 1062 } 1063 1064 case ElfSymBindLocal: 1065 if SysArch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) { 1066 // binutils for arm generate these mapping 1067 // symbols, ignore these 1068 break 1069 } 1070 1071 if sym.name == ".TOC." { 1072 // We need to be able to look this up, 1073 // so put it in the hash table. 1074 if needSym != 0 { 1075 s = Linklookup(Ctxt, sym.name, Ctxt.Version) 1076 s.Type |= obj.SHIDDEN 1077 } 1078 1079 break 1080 } 1081 1082 if needSym != 0 { 1083 // local names and hidden global names are unique 1084 // and should only be referenced by their index, not name, so we 1085 // don't bother to add them into the hash table 1086 s = linknewsym(Ctxt, sym.name, Ctxt.Version) 1087 1088 s.Type |= obj.SHIDDEN 1089 } 1090 1091 case ElfSymBindWeak: 1092 if needSym != 0 { 1093 s = Linklookup(Ctxt, sym.name, 0) 1094 if sym.other == 2 { 1095 s.Type |= obj.SHIDDEN 1096 } 1097 } 1098 1099 default: 1100 err = fmt.Errorf("%s: invalid symbol binding %d", sym.name, sym.bind) 1101 return err 1102 } 1103 } 1104 1105 if s != nil && s.Type == 0 && sym.type_ != ElfSymTypeSection { 1106 s.Type = obj.SXREF 1107 } 1108 sym.sym = s 1109 1110 return nil 1111 } 1112 1113 type rbyoff []Reloc 1114 1115 func (x rbyoff) Len() int { 1116 return len(x) 1117 } 1118 1119 func (x rbyoff) Swap(i, j int) { 1120 x[i], x[j] = x[j], x[i] 1121 } 1122 1123 func (x rbyoff) Less(i, j int) bool { 1124 a := &x[i] 1125 b := &x[j] 1126 if a.Off < b.Off { 1127 return true 1128 } 1129 if a.Off > b.Off { 1130 return false 1131 } 1132 return false 1133 } 1134 1135 func relSize(pn string, elftype uint32) uint8 { 1136 // TODO(mdempsky): Replace this with a struct-valued switch statement 1137 // once golang.org/issue/15164 is fixed or found to not impair cmd/link 1138 // performance. 1139 1140 const ( 1141 AMD64 = uint32(sys.AMD64) 1142 ARM = uint32(sys.ARM) 1143 I386 = uint32(sys.I386) 1144 PPC64 = uint32(sys.PPC64) 1145 S390X = uint32(sys.S390X) 1146 SPARC64 = uint32(sys.SPARC64) 1147 ) 1148 1149 switch uint32(SysArch.Family) | elftype<<24 { 1150 default: 1151 Diag("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype) 1152 fallthrough 1153 1154 case SPARC64 | R_SPARC_GOTDATA_OP<<24: 1155 // These are "special" and don't technically have a size. 1156 return 0 1157 1158 case SPARC64 | R_SPARC_8<<24, 1159 SPARC64 | R_SPARC_DISP8<<24: 1160 return 1 1161 1162 case SPARC64 | R_SPARC_16<<24, 1163 SPARC64 | R_SPARC_DISP16<<24, 1164 SPARC64 | R_SPARC_UA16<<24: 1165 return 2 1166 1167 case SPARC64 | R_SPARC_32<<24, 1168 SPARC64 | R_SPARC_DISP32<<24, 1169 SPARC64 | R_SPARC_WDISP30<<24, 1170 SPARC64 | R_SPARC_WDISP22<<24, 1171 SPARC64 | R_SPARC_HI22<<24, 1172 SPARC64 | R_SPARC_22<<24, 1173 SPARC64 | R_SPARC_13<<24, 1174 SPARC64 | R_SPARC_LO10<<24, 1175 SPARC64 | R_SPARC_GOT10<<24, 1176 SPARC64 | R_SPARC_GOT13<<24, 1177 SPARC64 | R_SPARC_GOT22<<24, 1178 SPARC64 | R_SPARC_PC10<<24, 1179 SPARC64 | R_SPARC_PC22<<24, 1180 SPARC64 | R_SPARC_WPLT30<<24, 1181 SPARC64 | R_SPARC_UA32<<24, 1182 SPARC64 | R_SPARC_PLT32<<24, 1183 SPARC64 | R_SPARC_HIPLT22<<24, 1184 SPARC64 | R_SPARC_LOPLT10<<24, 1185 SPARC64 | R_SPARC_PCPLT32<<24, 1186 SPARC64 | R_SPARC_PCPLT22<<24, 1187 SPARC64 | R_SPARC_PCPLT10<<24, 1188 SPARC64 | R_SPARC_10<<24, 1189 SPARC64 | R_SPARC_11<<24, 1190 SPARC64 | R_SPARC_OLO10<<24, 1191 SPARC64 | R_SPARC_HH22<<24, 1192 SPARC64 | R_SPARC_HM10<<24, 1193 SPARC64 | R_SPARC_LM22<<24, 1194 SPARC64 | R_SPARC_PC_HH22<<24, 1195 SPARC64 | R_SPARC_PC_HM10<<24, 1196 SPARC64 | R_SPARC_PC_LM22<<24, 1197 SPARC64 | R_SPARC_WDISP16<<24, 1198 SPARC64 | R_SPARC_WDISP19<<24, 1199 SPARC64 | R_SPARC_7<<24, 1200 SPARC64 | R_SPARC_5<<24, 1201 SPARC64 | R_SPARC_6<<24, 1202 SPARC64 | R_SPARC_HIX22<<24, 1203 SPARC64 | R_SPARC_LOX10<<24, 1204 SPARC64 | R_SPARC_H44<<24, 1205 SPARC64 | R_SPARC_M44<<24, 1206 SPARC64 | R_SPARC_L44<<24, 1207 SPARC64 | R_SPARC_TLS_GD_HI22<<24, 1208 SPARC64 | R_SPARC_TLS_GD_LO10<<24, 1209 SPARC64 | R_SPARC_TLS_LDM_HI22<<24, 1210 SPARC64 | R_SPARC_TLS_LDM_LO10<<24, 1211 SPARC64 | R_SPARC_TLS_LDO_HIX22<<24, 1212 SPARC64 | R_SPARC_TLS_LDO_LOX10<<24, 1213 SPARC64 | R_SPARC_TLS_IE_HI22<<24, 1214 SPARC64 | R_SPARC_TLS_IE_LO10<<24, 1215 SPARC64 | R_SPARC_TLS_LE_HIX22<<24, 1216 SPARC64 | R_SPARC_TLS_LE_LOX10<<24, 1217 SPARC64 | R_SPARC_TLS_DTPMOD32<<24, 1218 SPARC64 | R_SPARC_TLS_DTPOFF32<<24, 1219 SPARC64 | R_SPARC_TLS_TPOFF32<<24, 1220 SPARC64 | R_SPARC_GOTDATA_HIX22<<24, 1221 SPARC64 | R_SPARC_GOTDATA_LOX10<<24, 1222 SPARC64 | R_SPARC_GOTDATA_OP_HIX22<<24, 1223 SPARC64 | R_SPARC_GOTDATA_OP_LOX10<<24, 1224 SPARC64 | R_SPARC_H34<<24, 1225 SPARC64 | R_SPARC_SIZE32<<24, 1226 SPARC64 | R_SPARC_WDISP10<<24: 1227 return 4 1228 1229 case SPARC64 | R_SPARC_GLOB_DAT<<24, 1230 SPARC64 | R_SPARC_RELATIVE<<24, 1231 SPARC64 | R_SPARC_64<<24, 1232 SPARC64 | R_SPARC_DISP64<<24, 1233 SPARC64 | R_SPARC_PLT64<<24, 1234 SPARC64 | R_SPARC_UA64<<24, 1235 SPARC64 | R_SPARC_TLS_DTPMOD64<<24, 1236 SPARC64 | R_SPARC_TLS_DTPOFF64<<24, 1237 SPARC64 | R_SPARC_TLS_TPOFF64<<24, 1238 SPARC64 | R_SPARC_SIZE64<<24: 1239 return 8 1240 1241 case S390X | R_390_8<<24: 1242 return 1 1243 1244 case PPC64 | R_PPC64_TOC16<<24, 1245 PPC64 | R_PPC64_TOC16_LO<<24, 1246 PPC64 | R_PPC64_TOC16_HI<<24, 1247 PPC64 | R_PPC64_TOC16_HA<<24, 1248 PPC64 | R_PPC64_TOC16_DS<<24, 1249 PPC64 | R_PPC64_TOC16_LO_DS<<24, 1250 PPC64 | R_PPC64_REL16_LO<<24, 1251 PPC64 | R_PPC64_REL16_HI<<24, 1252 PPC64 | R_PPC64_REL16_HA<<24, 1253 S390X | R_390_16<<24, 1254 S390X | R_390_GOT16<<24, 1255 S390X | R_390_PC16<<24, 1256 S390X | R_390_PC16DBL<<24, 1257 S390X | R_390_PLT16DBL<<24: 1258 return 2 1259 1260 case ARM | R_ARM_ABS32<<24, 1261 ARM | R_ARM_GOT32<<24, 1262 ARM | R_ARM_PLT32<<24, 1263 ARM | R_ARM_GOTOFF<<24, 1264 ARM | R_ARM_GOTPC<<24, 1265 ARM | R_ARM_THM_PC22<<24, 1266 ARM | R_ARM_REL32<<24, 1267 ARM | R_ARM_CALL<<24, 1268 ARM | R_ARM_V4BX<<24, 1269 ARM | R_ARM_GOT_PREL<<24, 1270 ARM | R_ARM_PC24<<24, 1271 ARM | R_ARM_JUMP24<<24, 1272 AMD64 | R_X86_64_PC32<<24, 1273 AMD64 | R_X86_64_PLT32<<24, 1274 AMD64 | R_X86_64_GOTPCREL<<24, 1275 AMD64 | R_X86_64_GOTPCRELX<<24, 1276 AMD64 | R_X86_64_REX_GOTPCRELX<<24, 1277 I386 | R_386_32<<24, 1278 I386 | R_386_PC32<<24, 1279 I386 | R_386_GOT32<<24, 1280 I386 | R_386_PLT32<<24, 1281 I386 | R_386_GOTOFF<<24, 1282 I386 | R_386_GOTPC<<24, 1283 I386 | R_386_GOT32X<<24, 1284 PPC64 | R_PPC64_REL24<<24, 1285 PPC64 | R_PPC_REL32<<24, 1286 S390X | R_390_32<<24, 1287 S390X | R_390_PC32<<24, 1288 S390X | R_390_GOT32<<24, 1289 S390X | R_390_PLT32<<24, 1290 S390X | R_390_PC32DBL<<24, 1291 S390X | R_390_PLT32DBL<<24, 1292 S390X | R_390_GOTPCDBL<<24, 1293 S390X | R_390_GOTENT<<24: 1294 return 4 1295 1296 case AMD64 | R_X86_64_64<<24, 1297 PPC64 | R_PPC64_ADDR64<<24, 1298 S390X | R_390_GLOB_DAT<<24, 1299 S390X | R_390_RELATIVE<<24, 1300 S390X | R_390_GOTOFF<<24, 1301 S390X | R_390_GOTPC<<24, 1302 S390X | R_390_64<<24, 1303 S390X | R_390_PC64<<24, 1304 S390X | R_390_GOT64<<24, 1305 S390X | R_390_PLT64<<24: 1306 return 8 1307 } 1308 }