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 ElfSymTypeCommon = 5 141 ElfSymTypeTLS = 6 142 ) 143 144 const ( 145 ElfSymShnNone = 0 146 ElfSymShnAbs = 0xFFF1 147 ElfSymShnCommon = 0xFFF2 148 ) 149 150 const ( 151 ElfProgNone = 0 152 ElfProgLoad = 1 153 ElfProgDynamic = 2 154 ElfProgInterp = 3 155 ElfProgNote = 4 156 ElfProgShlib = 5 157 ElfProgPhdr = 6 158 ElfProgFlagExec = 0x1 159 ElfProgFlagWrite = 0x2 160 ElfProgFlagRead = 0x4 161 ) 162 163 const ( 164 ElfNotePrStatus = 1 165 ElfNotePrFpreg = 2 166 ElfNotePrPsinfo = 3 167 ElfNotePrTaskstruct = 4 168 ElfNotePrAuxv = 6 169 ElfNotePrXfpreg = 0x46e62b7f 170 ) 171 172 type ElfHdrBytes struct { 173 Ident [16]uint8 174 Type [2]uint8 175 Machine [2]uint8 176 Version [4]uint8 177 Entry [4]uint8 178 Phoff [4]uint8 179 Shoff [4]uint8 180 Flags [4]uint8 181 Ehsize [2]uint8 182 Phentsize [2]uint8 183 Phnum [2]uint8 184 Shentsize [2]uint8 185 Shnum [2]uint8 186 Shstrndx [2]uint8 187 } 188 189 type ElfSectBytes struct { 190 Name [4]uint8 191 Type [4]uint8 192 Flags [4]uint8 193 Addr [4]uint8 194 Off [4]uint8 195 Size [4]uint8 196 Link [4]uint8 197 Info [4]uint8 198 Align [4]uint8 199 Entsize [4]uint8 200 } 201 202 type ElfProgBytes struct { 203 } 204 205 type ElfSymBytes struct { 206 Name [4]uint8 207 Value [4]uint8 208 Size [4]uint8 209 Info uint8 210 Other uint8 211 Shndx [2]uint8 212 } 213 214 type ElfHdrBytes64 struct { 215 Ident [16]uint8 216 Type [2]uint8 217 Machine [2]uint8 218 Version [4]uint8 219 Entry [8]uint8 220 Phoff [8]uint8 221 Shoff [8]uint8 222 Flags [4]uint8 223 Ehsize [2]uint8 224 Phentsize [2]uint8 225 Phnum [2]uint8 226 Shentsize [2]uint8 227 Shnum [2]uint8 228 Shstrndx [2]uint8 229 } 230 231 type ElfSectBytes64 struct { 232 Name [4]uint8 233 Type [4]uint8 234 Flags [8]uint8 235 Addr [8]uint8 236 Off [8]uint8 237 Size [8]uint8 238 Link [4]uint8 239 Info [4]uint8 240 Align [8]uint8 241 Entsize [8]uint8 242 } 243 244 type ElfProgBytes64 struct { 245 } 246 247 type ElfSymBytes64 struct { 248 Name [4]uint8 249 Info uint8 250 Other uint8 251 Shndx [2]uint8 252 Value [8]uint8 253 Size [8]uint8 254 } 255 256 type ElfSect struct { 257 name string 258 nameoff uint32 259 type_ uint32 260 flags uint64 261 addr uint64 262 off uint64 263 size uint64 264 link uint32 265 info uint32 266 align uint64 267 entsize uint64 268 base []byte 269 sym *Symbol 270 } 271 272 type ElfObj struct { 273 f *bio.Reader 274 base int64 // offset in f where ELF begins 275 length int64 // length of ELF 276 is64 int 277 name string 278 e binary.ByteOrder 279 sect []ElfSect 280 nsect uint 281 shstrtab string 282 nsymtab int 283 symtab *ElfSect 284 symstr *ElfSect 285 type_ uint32 286 machine uint32 287 version uint32 288 entry uint64 289 phoff uint64 290 shoff uint64 291 flags uint32 292 ehsize uint32 293 phentsize uint32 294 phnum uint32 295 shentsize uint32 296 shnum uint32 297 shstrndx uint32 298 } 299 300 type ElfSym struct { 301 name string 302 value uint64 303 size uint64 304 bind uint8 305 type_ uint8 306 other uint8 307 shndx uint16 308 sym *Symbol 309 } 310 311 var ElfMagic = [4]uint8{0x7F, 'E', 'L', 'F'} 312 313 const ( 314 TagFile = 1 315 TagCPUName = 4 316 TagCPURawName = 5 317 TagCompatibility = 32 318 TagNoDefaults = 64 319 TagAlsoCompatibleWith = 65 320 TagABIVFPArgs = 28 321 ) 322 323 type elfAttribute struct { 324 tag uint64 325 sval string 326 ival uint64 327 } 328 329 type elfAttributeList struct { 330 data []byte 331 err error 332 } 333 334 func (a *elfAttributeList) string() string { 335 if a.err != nil { 336 return "" 337 } 338 nul := bytes.IndexByte(a.data, 0) 339 if nul < 0 { 340 a.err = io.EOF 341 return "" 342 } 343 s := string(a.data[:nul]) 344 a.data = a.data[nul+1:] 345 return s 346 } 347 348 func (a *elfAttributeList) uleb128() uint64 { 349 if a.err != nil { 350 return 0 351 } 352 v, size := binary.Uvarint(a.data) 353 a.data = a.data[size:] 354 return v 355 } 356 357 // Read an elfAttribute from the list following the rules used on ARM systems. 358 func (a *elfAttributeList) armAttr() elfAttribute { 359 attr := elfAttribute{tag: a.uleb128()} 360 switch { 361 case attr.tag == TagCompatibility: 362 attr.ival = a.uleb128() 363 attr.sval = a.string() 364 365 case attr.tag == 64: // Tag_nodefaults has no argument 366 367 case attr.tag == 65: // Tag_also_compatible_with 368 // Not really, but we don't actually care about this tag. 369 attr.sval = a.string() 370 371 // Tag with string argument 372 case attr.tag == TagCPUName || attr.tag == TagCPURawName || (attr.tag >= 32 && attr.tag&1 != 0): 373 attr.sval = a.string() 374 375 default: // Tag with integer argument 376 attr.ival = a.uleb128() 377 } 378 return attr 379 } 380 381 func (a *elfAttributeList) done() bool { 382 if a.err != nil || len(a.data) == 0 { 383 return true 384 } 385 return false 386 } 387 388 // Look for the attribute that indicates the object uses the hard-float ABI (a 389 // file-level attribute with tag Tag_VFP_arch and value 1). Unfortunately the 390 // format used means that we have to parse all of the file-level attributes to 391 // find the one we are looking for. This format is slightly documented in "ELF 392 // for the ARM Architecture" but mostly this is derived from reading the source 393 // to gold and readelf. 394 func parseArmAttributes(ctxt *Link, e binary.ByteOrder, data []byte) { 395 // We assume the soft-float ABI unless we see a tag indicating otherwise. 396 if ehdr.flags == 0x5000002 { 397 ehdr.flags = 0x5000202 398 } 399 if data[0] != 'A' { 400 // TODO(dfc) should this be ctxt.Diag ? 401 ctxt.Logf(".ARM.attributes has unexpected format %c\n", data[0]) 402 return 403 } 404 data = data[1:] 405 for len(data) != 0 { 406 sectionlength := e.Uint32(data) 407 sectiondata := data[4:sectionlength] 408 data = data[sectionlength:] 409 410 nulIndex := bytes.IndexByte(sectiondata, 0) 411 if nulIndex < 0 { 412 // TODO(dfc) should this be ctxt.Diag ? 413 ctxt.Logf("corrupt .ARM.attributes (section name not NUL-terminated)\n") 414 return 415 } 416 name := string(sectiondata[:nulIndex]) 417 sectiondata = sectiondata[nulIndex+1:] 418 419 if name != "aeabi" { 420 continue 421 } 422 for len(sectiondata) != 0 { 423 subsectiontag, sz := binary.Uvarint(sectiondata) 424 subsectionsize := e.Uint32(sectiondata[sz:]) 425 subsectiondata := sectiondata[sz+4 : subsectionsize] 426 sectiondata = sectiondata[subsectionsize:] 427 428 if subsectiontag == TagFile { 429 attrList := elfAttributeList{data: subsectiondata} 430 for !attrList.done() { 431 attr := attrList.armAttr() 432 if attr.tag == TagABIVFPArgs && attr.ival == 1 { 433 ehdr.flags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI 434 } 435 } 436 if attrList.err != nil { 437 // TODO(dfc) should this be ctxt.Diag ? 438 ctxt.Logf("could not parse .ARM.attributes\n") 439 } 440 } 441 } 442 } 443 } 444 445 func ldelf(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { 446 if ctxt.Debugvlog != 0 { 447 ctxt.Logf("%5.2f ldelf %s\n", obj.Cputime(), pn) 448 } 449 450 localSymVersion := ctxt.Syms.IncVersion() 451 base := f.Offset() 452 453 var add uint64 454 var e binary.ByteOrder 455 var elfobj *ElfObj 456 var err error 457 var flag int 458 var hdr *ElfHdrBytes 459 var hdrbuf [64]uint8 460 var info uint64 461 var is64 int 462 var j int 463 var n int 464 var name string 465 var p []byte 466 var r []Reloc 467 var rela int 468 var rp *Reloc 469 var rsect *ElfSect 470 var s *Symbol 471 var sect *ElfSect 472 var sym ElfSym 473 var symbols []*Symbol 474 if _, err := io.ReadFull(f, hdrbuf[:]); err != nil { 475 goto bad 476 } 477 hdr = new(ElfHdrBytes) 478 binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter 479 if string(hdr.Ident[:4]) != "\x7FELF" { 480 goto bad 481 } 482 switch hdr.Ident[5] { 483 case ElfDataLsb: 484 e = binary.LittleEndian 485 486 case ElfDataMsb: 487 e = binary.BigEndian 488 489 default: 490 goto bad 491 } 492 493 // read header 494 elfobj = new(ElfObj) 495 496 elfobj.e = e 497 elfobj.f = f 498 elfobj.base = base 499 elfobj.length = length 500 elfobj.name = pn 501 502 is64 = 0 503 if hdr.Ident[4] == ElfClass64 { 504 is64 = 1 505 hdr := new(ElfHdrBytes64) 506 binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter 507 elfobj.type_ = uint32(e.Uint16(hdr.Type[:])) 508 elfobj.machine = uint32(e.Uint16(hdr.Machine[:])) 509 elfobj.version = e.Uint32(hdr.Version[:]) 510 elfobj.phoff = e.Uint64(hdr.Phoff[:]) 511 elfobj.shoff = e.Uint64(hdr.Shoff[:]) 512 elfobj.flags = e.Uint32(hdr.Flags[:]) 513 elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:])) 514 elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:])) 515 elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:])) 516 elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:])) 517 elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:])) 518 elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:])) 519 } else { 520 elfobj.type_ = uint32(e.Uint16(hdr.Type[:])) 521 elfobj.machine = uint32(e.Uint16(hdr.Machine[:])) 522 elfobj.version = e.Uint32(hdr.Version[:]) 523 elfobj.entry = uint64(e.Uint32(hdr.Entry[:])) 524 elfobj.phoff = uint64(e.Uint32(hdr.Phoff[:])) 525 elfobj.shoff = uint64(e.Uint32(hdr.Shoff[:])) 526 elfobj.flags = e.Uint32(hdr.Flags[:]) 527 elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:])) 528 elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:])) 529 elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:])) 530 elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:])) 531 elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:])) 532 elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:])) 533 } 534 535 elfobj.is64 = is64 536 537 if uint32(hdr.Ident[6]) != elfobj.version { 538 goto bad 539 } 540 541 if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable { 542 Errorf(nil, "%s: elf but not elf relocatable object", pn) 543 return 544 } 545 546 switch SysArch.Family { 547 default: 548 Errorf(nil, "%s: elf %s unimplemented", pn, SysArch.Name) 549 return 550 551 case sys.MIPS: 552 if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass32 { 553 Errorf(nil, "%s: elf object but not mips", pn) 554 return 555 } 556 557 case sys.MIPS64: 558 if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 { 559 Errorf(nil, "%s: elf object but not mips64", pn) 560 return 561 } 562 563 case sys.ARM: 564 if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 { 565 Errorf(nil, "%s: elf object but not arm", pn) 566 return 567 } 568 569 case sys.AMD64: 570 if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 { 571 Errorf(nil, "%s: elf object but not amd64", pn) 572 return 573 } 574 575 case sys.ARM64: 576 if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 { 577 Errorf(nil, "%s: elf object but not arm64", pn) 578 return 579 } 580 581 case sys.I386: 582 if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 { 583 Errorf(nil, "%s: elf object but not 386", pn) 584 return 585 } 586 587 case sys.PPC64: 588 if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 { 589 Errorf(nil, "%s: elf object but not ppc64", pn) 590 return 591 } 592 593 case sys.S390X: 594 if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 { 595 Errorf(nil, "%s: elf object but not s390x", pn) 596 return 597 } 598 } 599 600 // load section list into memory. 601 elfobj.sect = make([]ElfSect, elfobj.shnum) 602 603 elfobj.nsect = uint(elfobj.shnum) 604 for i := 0; uint(i) < elfobj.nsect; i++ { 605 if f.Seek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 { 606 goto bad 607 } 608 sect = &elfobj.sect[i] 609 if is64 != 0 { 610 var b ElfSectBytes64 611 612 if err = binary.Read(f, e, &b); err != nil { 613 goto bad 614 } 615 616 sect.nameoff = e.Uint32(b.Name[:]) 617 sect.type_ = e.Uint32(b.Type[:]) 618 sect.flags = e.Uint64(b.Flags[:]) 619 sect.addr = e.Uint64(b.Addr[:]) 620 sect.off = e.Uint64(b.Off[:]) 621 sect.size = e.Uint64(b.Size[:]) 622 sect.link = e.Uint32(b.Link[:]) 623 sect.info = e.Uint32(b.Info[:]) 624 sect.align = e.Uint64(b.Align[:]) 625 sect.entsize = e.Uint64(b.Entsize[:]) 626 } else { 627 var b ElfSectBytes 628 629 if err = binary.Read(f, e, &b); err != nil { 630 goto bad 631 } 632 633 sect.nameoff = e.Uint32(b.Name[:]) 634 sect.type_ = e.Uint32(b.Type[:]) 635 sect.flags = uint64(e.Uint32(b.Flags[:])) 636 sect.addr = uint64(e.Uint32(b.Addr[:])) 637 sect.off = uint64(e.Uint32(b.Off[:])) 638 sect.size = uint64(e.Uint32(b.Size[:])) 639 sect.link = e.Uint32(b.Link[:]) 640 sect.info = e.Uint32(b.Info[:]) 641 sect.align = uint64(e.Uint32(b.Align[:])) 642 sect.entsize = uint64(e.Uint32(b.Entsize[:])) 643 } 644 } 645 646 // read section string table and translate names 647 if elfobj.shstrndx >= uint32(elfobj.nsect) { 648 err = fmt.Errorf("shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect) 649 goto bad 650 } 651 652 sect = &elfobj.sect[elfobj.shstrndx] 653 if err = elfmap(elfobj, sect); err != nil { 654 goto bad 655 } 656 for i := 0; uint(i) < elfobj.nsect; i++ { 657 if elfobj.sect[i].nameoff != 0 { 658 elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:]) 659 } 660 } 661 662 // load string table for symbols into memory. 663 elfobj.symtab = section(elfobj, ".symtab") 664 665 if elfobj.symtab == nil { 666 // our work is done here - no symbols means nothing can refer to this file 667 return 668 } 669 670 if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) { 671 Errorf(nil, "%s: elf object has symbol table with invalid string table link", pn) 672 return 673 } 674 675 elfobj.symstr = &elfobj.sect[elfobj.symtab.link] 676 if is64 != 0 { 677 elfobj.nsymtab = int(elfobj.symtab.size / ELF64SYMSIZE) 678 } else { 679 elfobj.nsymtab = int(elfobj.symtab.size / ELF32SYMSIZE) 680 } 681 682 if err = elfmap(elfobj, elfobj.symtab); err != nil { 683 goto bad 684 } 685 if err = elfmap(elfobj, elfobj.symstr); err != nil { 686 goto bad 687 } 688 689 // load text and data segments into memory. 690 // they are not as small as the section lists, but we'll need 691 // the memory anyway for the symbol images, so we might 692 // as well use one large chunk. 693 694 // create symbols for elfmapped sections 695 for i := 0; uint(i) < elfobj.nsect; i++ { 696 sect = &elfobj.sect[i] 697 if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" { 698 if err = elfmap(elfobj, sect); err != nil { 699 goto bad 700 } 701 parseArmAttributes(ctxt, e, sect.base[:sect.size]) 702 } 703 if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 { 704 continue 705 } 706 if sect.type_ != ElfSectNobits { 707 if err = elfmap(elfobj, sect); err != nil { 708 goto bad 709 } 710 } 711 712 name = fmt.Sprintf("%s(%s)", pkg, sect.name) 713 s = ctxt.Syms.Lookup(name, localSymVersion) 714 715 switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) { 716 default: 717 err = fmt.Errorf("unexpected flags for ELF section %s", sect.name) 718 goto bad 719 720 case ElfSectFlagAlloc: 721 s.Type = obj.SRODATA 722 723 case ElfSectFlagAlloc + ElfSectFlagWrite: 724 if sect.type_ == ElfSectNobits { 725 s.Type = obj.SNOPTRBSS 726 } else { 727 s.Type = obj.SNOPTRDATA 728 } 729 730 case ElfSectFlagAlloc + ElfSectFlagExec: 731 s.Type = obj.STEXT 732 } 733 734 if sect.name == ".got" || sect.name == ".toc" { 735 s.Type = obj.SELFGOT 736 } 737 if sect.type_ == ElfSectProgbits { 738 s.P = sect.base 739 s.P = s.P[:sect.size] 740 } 741 742 s.Size = int64(sect.size) 743 s.Align = int32(sect.align) 744 sect.sym = s 745 } 746 747 // enter sub-symbols into symbol table. 748 // symbol 0 is the null symbol. 749 symbols = make([]*Symbol, elfobj.nsymtab) 750 751 for i := 1; i < elfobj.nsymtab; i++ { 752 if err = readelfsym(ctxt, elfobj, i, &sym, 1, localSymVersion); err != nil { 753 goto bad 754 } 755 symbols[i] = sym.sym 756 if sym.type_ != ElfSymTypeFunc && sym.type_ != ElfSymTypeObject && sym.type_ != ElfSymTypeNone && sym.type_ != ElfSymTypeCommon { 757 continue 758 } 759 if sym.shndx == ElfSymShnCommon || sym.type_ == ElfSymTypeCommon { 760 s = sym.sym 761 if uint64(s.Size) < sym.size { 762 s.Size = int64(sym.size) 763 } 764 if s.Type == 0 || s.Type == obj.SXREF { 765 s.Type = obj.SNOPTRBSS 766 } 767 continue 768 } 769 770 if uint(sym.shndx) >= elfobj.nsect || sym.shndx == 0 { 771 continue 772 } 773 774 // even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols 775 if sym.sym == nil { 776 continue 777 } 778 sect = &elfobj.sect[sym.shndx] 779 if sect.sym == nil { 780 if strings.HasPrefix(sym.name, ".Linfo_string") { // clang does this 781 continue 782 } 783 784 if sym.name == "" && sym.type_ == 0 && sect.name == ".debug_str" { 785 // This reportedly happens with clang 3.7 on ARM. 786 // See issue 13139. 787 continue 788 } 789 790 if strings.HasPrefix(sym.name, ".LASF") { // gcc on s390x does this 791 continue 792 } 793 Errorf(sym.sym, "%s: sym#%d: ignoring symbol in section %d (type %d)", pn, i, sym.shndx, sym.type_) 794 continue 795 } 796 797 s = sym.sym 798 if s.Outer != nil { 799 if s.Attr.DuplicateOK() { 800 continue 801 } 802 Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name) 803 } 804 805 s.Sub = sect.sym.Sub 806 sect.sym.Sub = s 807 s.Type = sect.sym.Type | s.Type&^obj.SMASK | obj.SSUB 808 if !s.Attr.CgoExportDynamic() { 809 s.Dynimplib = "" // satisfy dynimport 810 } 811 s.Value = int64(sym.value) 812 s.Size = int64(sym.size) 813 s.Outer = sect.sym 814 if sect.sym.Type == obj.STEXT { 815 if s.Attr.External() && !s.Attr.DuplicateOK() { 816 Errorf(s, "%s: duplicate symbol definition", pn) 817 } 818 s.Attr |= AttrExternal 819 } 820 821 if elfobj.machine == ElfMachPower64 { 822 flag = int(sym.other) >> 5 823 if 2 <= flag && flag <= 6 { 824 s.Localentry = 1 << uint(flag-2) 825 } else if flag == 7 { 826 Errorf(s, "%s: invalid sym.other 0x%x", pn, sym.other) 827 } 828 } 829 } 830 831 // Sort outer lists by address, adding to textp. 832 // This keeps textp in increasing address order. 833 for i := 0; uint(i) < elfobj.nsect; i++ { 834 s = elfobj.sect[i].sym 835 if s == nil { 836 continue 837 } 838 if s.Sub != nil { 839 s.Sub = listsort(s.Sub) 840 } 841 if s.Type == obj.STEXT { 842 if s.Attr.OnList() { 843 log.Fatalf("symbol %s listed multiple times", s.Name) 844 } 845 s.Attr |= AttrOnList 846 ctxt.Textp = append(ctxt.Textp, s) 847 for s = s.Sub; s != nil; s = s.Sub { 848 if s.Attr.OnList() { 849 log.Fatalf("symbol %s listed multiple times", s.Name) 850 } 851 s.Attr |= AttrOnList 852 ctxt.Textp = append(ctxt.Textp, s) 853 } 854 } 855 } 856 857 // load relocations 858 for i := 0; uint(i) < elfobj.nsect; i++ { 859 rsect = &elfobj.sect[i] 860 if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel { 861 continue 862 } 863 if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil { 864 continue 865 } 866 sect = &elfobj.sect[rsect.info] 867 if err = elfmap(elfobj, rsect); err != nil { 868 goto bad 869 } 870 rela = 0 871 if rsect.type_ == ElfSectRela { 872 rela = 1 873 } 874 n = int(rsect.size / uint64(4+4*is64) / uint64(2+rela)) 875 r = make([]Reloc, n) 876 p = rsect.base 877 for j = 0; j < n; j++ { 878 add = 0 879 rp = &r[j] 880 if is64 != 0 { 881 // 64-bit rel/rela 882 rp.Off = int32(e.Uint64(p)) 883 884 p = p[8:] 885 info = e.Uint64(p) 886 p = p[8:] 887 if rela != 0 { 888 add = e.Uint64(p) 889 p = p[8:] 890 } 891 } else { 892 // 32-bit rel/rela 893 rp.Off = int32(e.Uint32(p)) 894 895 p = p[4:] 896 info = uint64(e.Uint32(p)) 897 info = info>>8<<32 | info&0xff // convert to 64-bit info 898 p = p[4:] 899 if rela != 0 { 900 add = uint64(e.Uint32(p)) 901 p = p[4:] 902 } 903 } 904 905 if info&0xffffffff == 0 { // skip R_*_NONE relocation 906 j-- 907 n-- 908 continue 909 } 910 911 if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol 912 rp.Sym = nil 913 } else { 914 if err = readelfsym(ctxt, elfobj, int(info>>32), &sym, 0, 0); err != nil { 915 goto bad 916 } 917 sym.sym = symbols[info>>32] 918 if sym.sym == nil { 919 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_) 920 goto bad 921 } 922 923 rp.Sym = sym.sym 924 } 925 926 rp.Type = 256 + obj.RelocType(info) 927 rp.Siz = relSize(ctxt, pn, uint32(info)) 928 if rela != 0 { 929 rp.Add = int64(add) 930 } else { 931 // load addend from image 932 if rp.Siz == 4 { 933 rp.Add = int64(e.Uint32(sect.base[rp.Off:])) 934 } else if rp.Siz == 8 { 935 rp.Add = int64(e.Uint64(sect.base[rp.Off:])) 936 } else { 937 Errorf(nil, "invalid rela size %d", rp.Siz) 938 } 939 } 940 941 if rp.Siz == 2 { 942 rp.Add = int64(int16(rp.Add)) 943 } 944 if rp.Siz == 4 { 945 rp.Add = int64(int32(rp.Add)) 946 } 947 } 948 949 //print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add); 950 sort.Sort(rbyoff(r[:n])) 951 // just in case 952 953 s = sect.sym 954 s.R = r 955 s.R = s.R[:n] 956 } 957 958 return 959 960 bad: 961 Errorf(nil, "%s: malformed elf file: %v", pn, err) 962 } 963 964 func section(elfobj *ElfObj, name string) *ElfSect { 965 for i := 0; uint(i) < elfobj.nsect; i++ { 966 if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name { 967 return &elfobj.sect[i] 968 } 969 } 970 return nil 971 } 972 973 func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) { 974 if sect.base != nil { 975 return nil 976 } 977 978 if sect.off+sect.size > uint64(elfobj.length) { 979 err = fmt.Errorf("elf section past end of file") 980 return err 981 } 982 983 sect.base = make([]byte, sect.size) 984 if elfobj.f.Seek(int64(uint64(elfobj.base)+sect.off), 0) < 0 { 985 return fmt.Errorf("short read: seek not successful") 986 } 987 if _, err := io.ReadFull(elfobj.f, sect.base); err != nil { 988 return fmt.Errorf("short read: %v", err) 989 } 990 991 return nil 992 } 993 994 func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, localSymVersion int) (err error) { 995 if i >= elfobj.nsymtab || i < 0 { 996 err = fmt.Errorf("invalid elf symbol index") 997 return err 998 } 999 1000 if i == 0 { 1001 Errorf(nil, "readym: read null symbol!") 1002 } 1003 1004 if elfobj.is64 != 0 { 1005 b := new(ElfSymBytes64) 1006 binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b) 1007 sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):]) 1008 sym.value = elfobj.e.Uint64(b.Value[:]) 1009 sym.size = elfobj.e.Uint64(b.Size[:]) 1010 sym.shndx = elfobj.e.Uint16(b.Shndx[:]) 1011 sym.bind = b.Info >> 4 1012 sym.type_ = b.Info & 0xf 1013 sym.other = b.Other 1014 } else { 1015 b := new(ElfSymBytes) 1016 binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b) 1017 sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):]) 1018 sym.value = uint64(elfobj.e.Uint32(b.Value[:])) 1019 sym.size = uint64(elfobj.e.Uint32(b.Size[:])) 1020 sym.shndx = elfobj.e.Uint16(b.Shndx[:]) 1021 sym.bind = b.Info >> 4 1022 sym.type_ = b.Info & 0xf 1023 sym.other = b.Other 1024 } 1025 1026 var s *Symbol 1027 if sym.name == "_GLOBAL_OFFSET_TABLE_" { 1028 sym.name = ".got" 1029 } 1030 if sym.name == ".TOC." { 1031 // Magic symbol on ppc64. Will be set to this object 1032 // file's .got+0x8000. 1033 sym.bind = ElfSymBindLocal 1034 } 1035 1036 switch sym.type_ { 1037 case ElfSymTypeSection: 1038 s = elfobj.sect[sym.shndx].sym 1039 1040 case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon: 1041 switch sym.bind { 1042 case ElfSymBindGlobal: 1043 if needSym != 0 { 1044 s = ctxt.Syms.Lookup(sym.name, 0) 1045 1046 // for global scoped hidden symbols we should insert it into 1047 // symbol hash table, but mark them as hidden. 1048 // __i686.get_pc_thunk.bx is allowed to be duplicated, to 1049 // workaround that we set dupok. 1050 // TODO(minux): correctly handle __i686.get_pc_thunk.bx without 1051 // set dupok generally. See http://codereview.appspot.com/5823055/ 1052 // comment #5 for details. 1053 if s != nil && sym.other == 2 { 1054 s.Type |= obj.SHIDDEN 1055 s.Attr |= AttrDuplicateOK 1056 } 1057 } 1058 1059 case ElfSymBindLocal: 1060 if SysArch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) { 1061 // binutils for arm generate these mapping 1062 // symbols, ignore these 1063 break 1064 } 1065 1066 if sym.name == ".TOC." { 1067 // We need to be able to look this up, 1068 // so put it in the hash table. 1069 if needSym != 0 { 1070 s = ctxt.Syms.Lookup(sym.name, localSymVersion) 1071 s.Type |= obj.SHIDDEN 1072 } 1073 1074 break 1075 } 1076 1077 if needSym != 0 { 1078 // local names and hidden global names are unique 1079 // and should only be referenced by their index, not name, so we 1080 // don't bother to add them into the hash table 1081 s = ctxt.Syms.newsym(sym.name, localSymVersion) 1082 1083 s.Type |= obj.SHIDDEN 1084 } 1085 1086 case ElfSymBindWeak: 1087 if needSym != 0 { 1088 s = ctxt.Syms.Lookup(sym.name, 0) 1089 if sym.other == 2 { 1090 s.Type |= obj.SHIDDEN 1091 } 1092 } 1093 1094 default: 1095 err = fmt.Errorf("%s: invalid symbol binding %d", sym.name, sym.bind) 1096 return err 1097 } 1098 } 1099 1100 if s != nil && s.Type == 0 && sym.type_ != ElfSymTypeSection { 1101 s.Type = obj.SXREF 1102 } 1103 sym.sym = s 1104 1105 return nil 1106 } 1107 1108 type rbyoff []Reloc 1109 1110 func (x rbyoff) Len() int { 1111 return len(x) 1112 } 1113 1114 func (x rbyoff) Swap(i, j int) { 1115 x[i], x[j] = x[j], x[i] 1116 } 1117 1118 func (x rbyoff) Less(i, j int) bool { 1119 a := &x[i] 1120 b := &x[j] 1121 if a.Off < b.Off { 1122 return true 1123 } 1124 if a.Off > b.Off { 1125 return false 1126 } 1127 return false 1128 } 1129 1130 func relSize(ctxt *Link, pn string, elftype uint32) uint8 { 1131 // TODO(mdempsky): Replace this with a struct-valued switch statement 1132 // once golang.org/issue/15164 is fixed or found to not impair cmd/link 1133 // performance. 1134 1135 const ( 1136 AMD64 = uint32(sys.AMD64) 1137 ARM = uint32(sys.ARM) 1138 I386 = uint32(sys.I386) 1139 PPC64 = uint32(sys.PPC64) 1140 S390X = uint32(sys.S390X) 1141 ) 1142 1143 switch uint32(SysArch.Family) | elftype<<24 { 1144 default: 1145 Errorf(nil, "%s: unknown relocation type %d; compiled without -fpic?", pn, elftype) 1146 fallthrough 1147 1148 case S390X | R_390_8<<24: 1149 return 1 1150 1151 case PPC64 | R_PPC64_TOC16<<24, 1152 PPC64 | R_PPC64_TOC16_LO<<24, 1153 PPC64 | R_PPC64_TOC16_HI<<24, 1154 PPC64 | R_PPC64_TOC16_HA<<24, 1155 PPC64 | R_PPC64_TOC16_DS<<24, 1156 PPC64 | R_PPC64_TOC16_LO_DS<<24, 1157 PPC64 | R_PPC64_REL16_LO<<24, 1158 PPC64 | R_PPC64_REL16_HI<<24, 1159 PPC64 | R_PPC64_REL16_HA<<24, 1160 S390X | R_390_16<<24, 1161 S390X | R_390_GOT16<<24, 1162 S390X | R_390_PC16<<24, 1163 S390X | R_390_PC16DBL<<24, 1164 S390X | R_390_PLT16DBL<<24: 1165 return 2 1166 1167 case ARM | R_ARM_ABS32<<24, 1168 ARM | R_ARM_GOT32<<24, 1169 ARM | R_ARM_PLT32<<24, 1170 ARM | R_ARM_GOTOFF<<24, 1171 ARM | R_ARM_GOTPC<<24, 1172 ARM | R_ARM_THM_PC22<<24, 1173 ARM | R_ARM_REL32<<24, 1174 ARM | R_ARM_CALL<<24, 1175 ARM | R_ARM_V4BX<<24, 1176 ARM | R_ARM_GOT_PREL<<24, 1177 ARM | R_ARM_PC24<<24, 1178 ARM | R_ARM_JUMP24<<24, 1179 AMD64 | R_X86_64_PC32<<24, 1180 AMD64 | R_X86_64_PLT32<<24, 1181 AMD64 | R_X86_64_GOTPCREL<<24, 1182 AMD64 | R_X86_64_GOTPCRELX<<24, 1183 AMD64 | R_X86_64_REX_GOTPCRELX<<24, 1184 I386 | R_386_32<<24, 1185 I386 | R_386_PC32<<24, 1186 I386 | R_386_GOT32<<24, 1187 I386 | R_386_PLT32<<24, 1188 I386 | R_386_GOTOFF<<24, 1189 I386 | R_386_GOTPC<<24, 1190 I386 | R_386_GOT32X<<24, 1191 PPC64 | R_PPC64_REL24<<24, 1192 PPC64 | R_PPC_REL32<<24, 1193 S390X | R_390_32<<24, 1194 S390X | R_390_PC32<<24, 1195 S390X | R_390_GOT32<<24, 1196 S390X | R_390_PLT32<<24, 1197 S390X | R_390_PC32DBL<<24, 1198 S390X | R_390_PLT32DBL<<24, 1199 S390X | R_390_GOTPCDBL<<24, 1200 S390X | R_390_GOTENT<<24: 1201 return 4 1202 1203 case AMD64 | R_X86_64_64<<24, 1204 PPC64 | R_PPC64_ADDR64<<24, 1205 S390X | R_390_GLOB_DAT<<24, 1206 S390X | R_390_RELATIVE<<24, 1207 S390X | R_390_GOTOFF<<24, 1208 S390X | R_390_GOTPC<<24, 1209 S390X | R_390_64<<24, 1210 S390X | R_390_PC64<<24, 1211 S390X | R_390_GOT64<<24, 1212 S390X | R_390_PLT64<<24: 1213 return 8 1214 } 1215 } 1216