github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/cmd/link/internal/ld/ldelf.go (about) 1 package ld 2 3 import ( 4 "bytes" 5 "cmd/internal/bio" 6 "cmd/internal/objabi" 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", 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 flag int 457 var hdr *ElfHdrBytes 458 var hdrbuf [64]uint8 459 var info uint64 460 var is64 int 461 var j int 462 var n int 463 var name string 464 var p []byte 465 var r []Reloc 466 var rela int 467 var rp *Reloc 468 var rsect *ElfSect 469 var s *Symbol 470 var sect *ElfSect 471 var sym ElfSym 472 var symbols []*Symbol 473 if _, err := io.ReadFull(f, hdrbuf[:]); err != nil { 474 Errorf(nil, "%s: malformed elf file: %v", pn, err) 475 return 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 Errorf(nil, "%s: malformed elf file", pn) 481 return 482 } 483 switch hdr.Ident[5] { 484 case ElfDataLsb: 485 e = binary.LittleEndian 486 487 case ElfDataMsb: 488 e = binary.BigEndian 489 490 default: 491 Errorf(nil, "%s: malformed elf file", pn) 492 return 493 } 494 495 // read header 496 elfobj = new(ElfObj) 497 498 elfobj.e = e 499 elfobj.f = f 500 elfobj.base = base 501 elfobj.length = length 502 elfobj.name = pn 503 504 is64 = 0 505 if hdr.Ident[4] == ElfClass64 { 506 is64 = 1 507 hdr := new(ElfHdrBytes64) 508 binary.Read(bytes.NewReader(hdrbuf[:]), binary.BigEndian, hdr) // only byte arrays; byte order doesn't matter 509 elfobj.type_ = uint32(e.Uint16(hdr.Type[:])) 510 elfobj.machine = uint32(e.Uint16(hdr.Machine[:])) 511 elfobj.version = e.Uint32(hdr.Version[:]) 512 elfobj.phoff = e.Uint64(hdr.Phoff[:]) 513 elfobj.shoff = e.Uint64(hdr.Shoff[:]) 514 elfobj.flags = e.Uint32(hdr.Flags[:]) 515 elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:])) 516 elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:])) 517 elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:])) 518 elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:])) 519 elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:])) 520 elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:])) 521 } else { 522 elfobj.type_ = uint32(e.Uint16(hdr.Type[:])) 523 elfobj.machine = uint32(e.Uint16(hdr.Machine[:])) 524 elfobj.version = e.Uint32(hdr.Version[:]) 525 elfobj.entry = uint64(e.Uint32(hdr.Entry[:])) 526 elfobj.phoff = uint64(e.Uint32(hdr.Phoff[:])) 527 elfobj.shoff = uint64(e.Uint32(hdr.Shoff[:])) 528 elfobj.flags = e.Uint32(hdr.Flags[:]) 529 elfobj.ehsize = uint32(e.Uint16(hdr.Ehsize[:])) 530 elfobj.phentsize = uint32(e.Uint16(hdr.Phentsize[:])) 531 elfobj.phnum = uint32(e.Uint16(hdr.Phnum[:])) 532 elfobj.shentsize = uint32(e.Uint16(hdr.Shentsize[:])) 533 elfobj.shnum = uint32(e.Uint16(hdr.Shnum[:])) 534 elfobj.shstrndx = uint32(e.Uint16(hdr.Shstrndx[:])) 535 } 536 537 elfobj.is64 = is64 538 539 if v := uint32(hdr.Ident[6]); v != elfobj.version { 540 Errorf(nil, "%s: malformed elf version: got %d, want %d", pn, v, elfobj.version) 541 return 542 } 543 544 if e.Uint16(hdr.Type[:]) != ElfTypeRelocatable { 545 Errorf(nil, "%s: elf but not elf relocatable object", pn) 546 return 547 } 548 549 switch SysArch.Family { 550 default: 551 Errorf(nil, "%s: elf %s unimplemented", pn, SysArch.Name) 552 return 553 554 case sys.MIPS: 555 if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass32 { 556 Errorf(nil, "%s: elf object but not mips", pn) 557 return 558 } 559 560 case sys.MIPS64: 561 if elfobj.machine != ElfMachMips || hdr.Ident[4] != ElfClass64 { 562 Errorf(nil, "%s: elf object but not mips64", pn) 563 return 564 } 565 566 case sys.ARM: 567 if e != binary.LittleEndian || elfobj.machine != ElfMachArm || hdr.Ident[4] != ElfClass32 { 568 Errorf(nil, "%s: elf object but not arm", pn) 569 return 570 } 571 572 case sys.AMD64: 573 if e != binary.LittleEndian || elfobj.machine != ElfMachAmd64 || hdr.Ident[4] != ElfClass64 { 574 Errorf(nil, "%s: elf object but not amd64", pn) 575 return 576 } 577 578 case sys.ARM64: 579 if e != binary.LittleEndian || elfobj.machine != ElfMachArm64 || hdr.Ident[4] != ElfClass64 { 580 Errorf(nil, "%s: elf object but not arm64", pn) 581 return 582 } 583 584 case sys.I386: 585 if e != binary.LittleEndian || elfobj.machine != ElfMach386 || hdr.Ident[4] != ElfClass32 { 586 Errorf(nil, "%s: elf object but not 386", pn) 587 return 588 } 589 590 case sys.PPC64: 591 if elfobj.machine != ElfMachPower64 || hdr.Ident[4] != ElfClass64 { 592 Errorf(nil, "%s: elf object but not ppc64", pn) 593 return 594 } 595 596 case sys.S390X: 597 if elfobj.machine != ElfMachS390 || hdr.Ident[4] != ElfClass64 { 598 Errorf(nil, "%s: elf object but not s390x", pn) 599 return 600 } 601 } 602 603 // load section list into memory. 604 elfobj.sect = make([]ElfSect, elfobj.shnum) 605 606 elfobj.nsect = uint(elfobj.shnum) 607 for i := 0; uint(i) < elfobj.nsect; i++ { 608 if f.Seek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) < 0 { 609 Errorf(nil, "%s: malformed elf file", pn) 610 return 611 } 612 sect = &elfobj.sect[i] 613 if is64 != 0 { 614 var b ElfSectBytes64 615 616 if err := binary.Read(f, e, &b); err != nil { 617 Errorf(nil, "%s: malformed elf file: %v", pn, err) 618 return 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 Errorf(nil, "%s: malformed elf file: %v", pn, err) 636 return 637 } 638 639 sect.nameoff = e.Uint32(b.Name[:]) 640 sect.type_ = e.Uint32(b.Type[:]) 641 sect.flags = uint64(e.Uint32(b.Flags[:])) 642 sect.addr = uint64(e.Uint32(b.Addr[:])) 643 sect.off = uint64(e.Uint32(b.Off[:])) 644 sect.size = uint64(e.Uint32(b.Size[:])) 645 sect.link = e.Uint32(b.Link[:]) 646 sect.info = e.Uint32(b.Info[:]) 647 sect.align = uint64(e.Uint32(b.Align[:])) 648 sect.entsize = uint64(e.Uint32(b.Entsize[:])) 649 } 650 } 651 652 // read section string table and translate names 653 if elfobj.shstrndx >= uint32(elfobj.nsect) { 654 Errorf(nil, "%s: malformed elf file: shstrndx out of range %d >= %d", pn, elfobj.shstrndx, elfobj.nsect) 655 return 656 } 657 658 sect = &elfobj.sect[elfobj.shstrndx] 659 if err := elfmap(elfobj, sect); err != nil { 660 Errorf(nil, "%s: malformed elf file: %v", pn, err) 661 return 662 } 663 for i := 0; uint(i) < elfobj.nsect; i++ { 664 if elfobj.sect[i].nameoff != 0 { 665 elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:]) 666 } 667 } 668 669 // load string table for symbols into memory. 670 elfobj.symtab = section(elfobj, ".symtab") 671 672 if elfobj.symtab == nil { 673 // our work is done here - no symbols means nothing can refer to this file 674 return 675 } 676 677 if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) { 678 Errorf(nil, "%s: elf object has symbol table with invalid string table link", pn) 679 return 680 } 681 682 elfobj.symstr = &elfobj.sect[elfobj.symtab.link] 683 if is64 != 0 { 684 elfobj.nsymtab = int(elfobj.symtab.size / ELF64SYMSIZE) 685 } else { 686 elfobj.nsymtab = int(elfobj.symtab.size / ELF32SYMSIZE) 687 } 688 689 if err := elfmap(elfobj, elfobj.symtab); err != nil { 690 Errorf(nil, "%s: malformed elf file: %v", pn, err) 691 return 692 } 693 if err := elfmap(elfobj, elfobj.symstr); err != nil { 694 Errorf(nil, "%s: malformed elf file: %v", pn, err) 695 return 696 } 697 698 // load text and data segments into memory. 699 // they are not as small as the section lists, but we'll need 700 // the memory anyway for the symbol images, so we might 701 // as well use one large chunk. 702 703 // create symbols for elfmapped sections 704 for i := 0; uint(i) < elfobj.nsect; i++ { 705 sect = &elfobj.sect[i] 706 if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" { 707 if err := elfmap(elfobj, sect); err != nil { 708 Errorf(nil, "%s: malformed elf file: %v", pn, err) 709 return 710 } 711 parseArmAttributes(ctxt, e, sect.base[:sect.size]) 712 } 713 if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 { 714 continue 715 } 716 if sect.type_ != ElfSectNobits { 717 if err := elfmap(elfobj, sect); err != nil { 718 Errorf(nil, "%s: malformed elf file: %v", pn, err) 719 return 720 } 721 } 722 723 name = fmt.Sprintf("%s(%s)", pkg, sect.name) 724 s = ctxt.Syms.Lookup(name, localSymVersion) 725 726 switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) { 727 default: 728 Errorf(nil, "%s: unexpected flags for ELF section %s", pn, sect.name) 729 return 730 731 case ElfSectFlagAlloc: 732 s.Type = SRODATA 733 734 case ElfSectFlagAlloc + ElfSectFlagWrite: 735 if sect.type_ == ElfSectNobits { 736 s.Type = SNOPTRBSS 737 } else { 738 s.Type = SNOPTRDATA 739 } 740 741 case ElfSectFlagAlloc + ElfSectFlagExec: 742 s.Type = STEXT 743 } 744 745 if sect.name == ".got" || sect.name == ".toc" { 746 s.Type = SELFGOT 747 } 748 if sect.type_ == ElfSectProgbits { 749 s.P = sect.base 750 s.P = s.P[:sect.size] 751 } 752 753 s.Size = int64(sect.size) 754 s.Align = int32(sect.align) 755 sect.sym = s 756 } 757 758 // enter sub-symbols into symbol table. 759 // symbol 0 is the null symbol. 760 symbols = make([]*Symbol, elfobj.nsymtab) 761 762 for i := 1; i < elfobj.nsymtab; i++ { 763 if err := readelfsym(ctxt, elfobj, i, &sym, 1, localSymVersion); err != nil { 764 Errorf(nil, "%s: malformed elf file: %v", pn, err) 765 return 766 } 767 symbols[i] = sym.sym 768 if sym.type_ != ElfSymTypeFunc && sym.type_ != ElfSymTypeObject && sym.type_ != ElfSymTypeNone && sym.type_ != ElfSymTypeCommon { 769 continue 770 } 771 if sym.shndx == ElfSymShnCommon || sym.type_ == ElfSymTypeCommon { 772 s = sym.sym 773 if uint64(s.Size) < sym.size { 774 s.Size = int64(sym.size) 775 } 776 if s.Type == 0 || s.Type == SXREF { 777 s.Type = SNOPTRBSS 778 } 779 continue 780 } 781 782 if uint(sym.shndx) >= elfobj.nsect || sym.shndx == 0 { 783 continue 784 } 785 786 // even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols 787 if sym.sym == nil { 788 continue 789 } 790 sect = &elfobj.sect[sym.shndx] 791 if sect.sym == nil { 792 if strings.HasPrefix(sym.name, ".Linfo_string") { // clang does this 793 continue 794 } 795 796 if sym.name == "" && sym.type_ == 0 && sect.name == ".debug_str" { 797 // This reportedly happens with clang 3.7 on ARM. 798 // See issue 13139. 799 continue 800 } 801 802 if strings.HasPrefix(sym.name, ".LASF") { // gcc on s390x does this 803 continue 804 } 805 Errorf(sym.sym, "%s: sym#%d: ignoring symbol in section %d (type %d)", pn, i, sym.shndx, sym.type_) 806 continue 807 } 808 809 s = sym.sym 810 if s.Outer != nil { 811 if s.Attr.DuplicateOK() { 812 continue 813 } 814 Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name) 815 } 816 817 s.Sub = sect.sym.Sub 818 sect.sym.Sub = s 819 s.Type = sect.sym.Type | s.Type&^SMASK | SSUB 820 if !s.Attr.CgoExportDynamic() { 821 s.Dynimplib = "" // satisfy dynimport 822 } 823 s.Value = int64(sym.value) 824 s.Size = int64(sym.size) 825 s.Outer = sect.sym 826 if sect.sym.Type == STEXT { 827 if s.Attr.External() && !s.Attr.DuplicateOK() { 828 Errorf(s, "%s: duplicate symbol definition", pn) 829 } 830 s.Attr |= AttrExternal 831 } 832 833 if elfobj.machine == ElfMachPower64 { 834 flag = int(sym.other) >> 5 835 if 2 <= flag && flag <= 6 { 836 s.Localentry = 1 << uint(flag-2) 837 } else if flag == 7 { 838 Errorf(s, "%s: invalid sym.other 0x%x", pn, sym.other) 839 } 840 } 841 } 842 843 // Sort outer lists by address, adding to textp. 844 // This keeps textp in increasing address order. 845 for i := 0; uint(i) < elfobj.nsect; i++ { 846 s = elfobj.sect[i].sym 847 if s == nil { 848 continue 849 } 850 if s.Sub != nil { 851 s.Sub = listsort(s.Sub) 852 } 853 if s.Type == STEXT { 854 if s.Attr.OnList() { 855 log.Fatalf("symbol %s listed multiple times", s.Name) 856 } 857 s.Attr |= AttrOnList 858 ctxt.Textp = append(ctxt.Textp, s) 859 for s = s.Sub; s != nil; s = s.Sub { 860 if s.Attr.OnList() { 861 log.Fatalf("symbol %s listed multiple times", s.Name) 862 } 863 s.Attr |= AttrOnList 864 ctxt.Textp = append(ctxt.Textp, s) 865 } 866 } 867 } 868 869 // load relocations 870 for i := 0; uint(i) < elfobj.nsect; i++ { 871 rsect = &elfobj.sect[i] 872 if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel { 873 continue 874 } 875 if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil { 876 continue 877 } 878 sect = &elfobj.sect[rsect.info] 879 if err := elfmap(elfobj, rsect); err != nil { 880 Errorf(nil, "%s: malformed elf file: %v", pn, err) 881 return 882 } 883 rela = 0 884 if rsect.type_ == ElfSectRela { 885 rela = 1 886 } 887 n = int(rsect.size / uint64(4+4*is64) / uint64(2+rela)) 888 r = make([]Reloc, n) 889 p = rsect.base 890 for j = 0; j < n; j++ { 891 add = 0 892 rp = &r[j] 893 if is64 != 0 { 894 // 64-bit rel/rela 895 rp.Off = int32(e.Uint64(p)) 896 897 p = p[8:] 898 info = e.Uint64(p) 899 p = p[8:] 900 if rela != 0 { 901 add = e.Uint64(p) 902 p = p[8:] 903 } 904 } else { 905 // 32-bit rel/rela 906 rp.Off = int32(e.Uint32(p)) 907 908 p = p[4:] 909 info = uint64(e.Uint32(p)) 910 info = info>>8<<32 | info&0xff // convert to 64-bit info 911 p = p[4:] 912 if rela != 0 { 913 add = uint64(e.Uint32(p)) 914 p = p[4:] 915 } 916 } 917 918 if info&0xffffffff == 0 { // skip R_*_NONE relocation 919 j-- 920 n-- 921 continue 922 } 923 924 if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol 925 rp.Sym = nil 926 } else { 927 if err := readelfsym(ctxt, elfobj, int(info>>32), &sym, 0, 0); err != nil { 928 Errorf(nil, "%s: malformed elf file: %v", pn, err) 929 return 930 } 931 sym.sym = symbols[info>>32] 932 if sym.sym == nil { 933 Errorf(nil, "%s: malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", pn, sect.sym.Name, j, int(info>>32), sym.name, sym.shndx, sym.type_) 934 return 935 } 936 937 rp.Sym = sym.sym 938 } 939 940 rp.Type = 256 + objabi.RelocType(info) 941 rp.Siz = relSize(ctxt, pn, uint32(info)) 942 if rela != 0 { 943 rp.Add = int64(add) 944 } else { 945 // load addend from image 946 if rp.Siz == 4 { 947 rp.Add = int64(e.Uint32(sect.base[rp.Off:])) 948 } else if rp.Siz == 8 { 949 rp.Add = int64(e.Uint64(sect.base[rp.Off:])) 950 } else { 951 Errorf(nil, "invalid rela size %d", rp.Siz) 952 } 953 } 954 955 if rp.Siz == 2 { 956 rp.Add = int64(int16(rp.Add)) 957 } 958 if rp.Siz == 4 { 959 rp.Add = int64(int32(rp.Add)) 960 } 961 } 962 963 //print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add); 964 sort.Sort(rbyoff(r[:n])) 965 // just in case 966 967 s = sect.sym 968 s.R = r 969 s.R = s.R[:n] 970 } 971 } 972 973 func section(elfobj *ElfObj, name string) *ElfSect { 974 for i := 0; uint(i) < elfobj.nsect; i++ { 975 if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name { 976 return &elfobj.sect[i] 977 } 978 } 979 return nil 980 } 981 982 func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) { 983 if sect.base != nil { 984 return nil 985 } 986 987 if sect.off+sect.size > uint64(elfobj.length) { 988 err = fmt.Errorf("elf section past end of file") 989 return err 990 } 991 992 sect.base = make([]byte, sect.size) 993 if elfobj.f.Seek(int64(uint64(elfobj.base)+sect.off), 0) < 0 { 994 return fmt.Errorf("short read: seek not successful") 995 } 996 if _, err := io.ReadFull(elfobj.f, sect.base); err != nil { 997 return fmt.Errorf("short read: %v", err) 998 } 999 1000 return nil 1001 } 1002 1003 func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, localSymVersion int) (err error) { 1004 if i >= elfobj.nsymtab || i < 0 { 1005 err = fmt.Errorf("invalid elf symbol index") 1006 return err 1007 } 1008 1009 if i == 0 { 1010 Errorf(nil, "readym: read null symbol!") 1011 } 1012 1013 if elfobj.is64 != 0 { 1014 b := new(ElfSymBytes64) 1015 binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b) 1016 sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):]) 1017 sym.value = elfobj.e.Uint64(b.Value[:]) 1018 sym.size = elfobj.e.Uint64(b.Size[:]) 1019 sym.shndx = elfobj.e.Uint16(b.Shndx[:]) 1020 sym.bind = b.Info >> 4 1021 sym.type_ = b.Info & 0xf 1022 sym.other = b.Other 1023 } else { 1024 b := new(ElfSymBytes) 1025 binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b) 1026 sym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):]) 1027 sym.value = uint64(elfobj.e.Uint32(b.Value[:])) 1028 sym.size = uint64(elfobj.e.Uint32(b.Size[:])) 1029 sym.shndx = elfobj.e.Uint16(b.Shndx[:]) 1030 sym.bind = b.Info >> 4 1031 sym.type_ = b.Info & 0xf 1032 sym.other = b.Other 1033 } 1034 1035 var s *Symbol 1036 if sym.name == "_GLOBAL_OFFSET_TABLE_" { 1037 sym.name = ".got" 1038 } 1039 if sym.name == ".TOC." { 1040 // Magic symbol on ppc64. Will be set to this object 1041 // file's .got+0x8000. 1042 sym.bind = ElfSymBindLocal 1043 } 1044 1045 switch sym.type_ { 1046 case ElfSymTypeSection: 1047 s = elfobj.sect[sym.shndx].sym 1048 1049 case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon: 1050 switch sym.bind { 1051 case ElfSymBindGlobal: 1052 if needSym != 0 { 1053 s = ctxt.Syms.Lookup(sym.name, 0) 1054 1055 // for global scoped hidden symbols we should insert it into 1056 // symbol hash table, but mark them as hidden. 1057 // __i686.get_pc_thunk.bx is allowed to be duplicated, to 1058 // workaround that we set dupok. 1059 // TODO(minux): correctly handle __i686.get_pc_thunk.bx without 1060 // set dupok generally. See http://codereview.appspot.com/5823055/ 1061 // comment #5 for details. 1062 if s != nil && sym.other == 2 { 1063 s.Type |= SHIDDEN 1064 s.Attr |= AttrDuplicateOK 1065 } 1066 } 1067 1068 case ElfSymBindLocal: 1069 if SysArch.Family == sys.ARM && (strings.HasPrefix(sym.name, "$a") || strings.HasPrefix(sym.name, "$d")) { 1070 // binutils for arm generate these mapping 1071 // symbols, ignore these 1072 break 1073 } 1074 1075 if sym.name == ".TOC." { 1076 // We need to be able to look this up, 1077 // so put it in the hash table. 1078 if needSym != 0 { 1079 s = ctxt.Syms.Lookup(sym.name, localSymVersion) 1080 s.Type |= SHIDDEN 1081 } 1082 1083 break 1084 } 1085 1086 if needSym != 0 { 1087 // local names and hidden global names are unique 1088 // and should only be referenced by their index, not name, so we 1089 // don't bother to add them into the hash table 1090 s = ctxt.Syms.newsym(sym.name, localSymVersion) 1091 1092 s.Type |= SHIDDEN 1093 } 1094 1095 case ElfSymBindWeak: 1096 if needSym != 0 { 1097 s = ctxt.Syms.Lookup(sym.name, 0) 1098 if sym.other == 2 { 1099 s.Type |= SHIDDEN 1100 } 1101 } 1102 1103 default: 1104 err = fmt.Errorf("%s: invalid symbol binding %d", sym.name, sym.bind) 1105 return err 1106 } 1107 } 1108 1109 if s != nil && s.Type == 0 && sym.type_ != ElfSymTypeSection { 1110 s.Type = SXREF 1111 } 1112 sym.sym = s 1113 1114 return nil 1115 } 1116 1117 type rbyoff []Reloc 1118 1119 func (x rbyoff) Len() int { 1120 return len(x) 1121 } 1122 1123 func (x rbyoff) Swap(i, j int) { 1124 x[i], x[j] = x[j], x[i] 1125 } 1126 1127 func (x rbyoff) Less(i, j int) bool { 1128 a := &x[i] 1129 b := &x[j] 1130 if a.Off < b.Off { 1131 return true 1132 } 1133 if a.Off > b.Off { 1134 return false 1135 } 1136 return false 1137 } 1138 1139 func relSize(ctxt *Link, pn string, elftype uint32) uint8 { 1140 // TODO(mdempsky): Replace this with a struct-valued switch statement 1141 // once golang.org/issue/15164 is fixed or found to not impair cmd/link 1142 // performance. 1143 1144 const ( 1145 AMD64 = uint32(sys.AMD64) 1146 ARM = uint32(sys.ARM) 1147 I386 = uint32(sys.I386) 1148 PPC64 = uint32(sys.PPC64) 1149 S390X = uint32(sys.S390X) 1150 ) 1151 1152 switch uint32(SysArch.Family) | elftype<<24 { 1153 default: 1154 Errorf(nil, "%s: unknown relocation type %d; compiled without -fpic?", pn, elftype) 1155 fallthrough 1156 1157 case S390X | R_390_8<<24: 1158 return 1 1159 1160 case PPC64 | R_PPC64_TOC16<<24, 1161 PPC64 | R_PPC64_TOC16_LO<<24, 1162 PPC64 | R_PPC64_TOC16_HI<<24, 1163 PPC64 | R_PPC64_TOC16_HA<<24, 1164 PPC64 | R_PPC64_TOC16_DS<<24, 1165 PPC64 | R_PPC64_TOC16_LO_DS<<24, 1166 PPC64 | R_PPC64_REL16_LO<<24, 1167 PPC64 | R_PPC64_REL16_HI<<24, 1168 PPC64 | R_PPC64_REL16_HA<<24, 1169 S390X | R_390_16<<24, 1170 S390X | R_390_GOT16<<24, 1171 S390X | R_390_PC16<<24, 1172 S390X | R_390_PC16DBL<<24, 1173 S390X | R_390_PLT16DBL<<24: 1174 return 2 1175 1176 case ARM | R_ARM_ABS32<<24, 1177 ARM | R_ARM_GOT32<<24, 1178 ARM | R_ARM_PLT32<<24, 1179 ARM | R_ARM_GOTOFF<<24, 1180 ARM | R_ARM_GOTPC<<24, 1181 ARM | R_ARM_THM_PC22<<24, 1182 ARM | R_ARM_REL32<<24, 1183 ARM | R_ARM_CALL<<24, 1184 ARM | R_ARM_V4BX<<24, 1185 ARM | R_ARM_GOT_PREL<<24, 1186 ARM | R_ARM_PC24<<24, 1187 ARM | R_ARM_JUMP24<<24, 1188 AMD64 | R_X86_64_PC32<<24, 1189 AMD64 | R_X86_64_PLT32<<24, 1190 AMD64 | R_X86_64_GOTPCREL<<24, 1191 AMD64 | R_X86_64_GOTPCRELX<<24, 1192 AMD64 | R_X86_64_REX_GOTPCRELX<<24, 1193 I386 | R_386_32<<24, 1194 I386 | R_386_PC32<<24, 1195 I386 | R_386_GOT32<<24, 1196 I386 | R_386_PLT32<<24, 1197 I386 | R_386_GOTOFF<<24, 1198 I386 | R_386_GOTPC<<24, 1199 I386 | R_386_GOT32X<<24, 1200 PPC64 | R_PPC64_REL24<<24, 1201 PPC64 | R_PPC_REL32<<24, 1202 S390X | R_390_32<<24, 1203 S390X | R_390_PC32<<24, 1204 S390X | R_390_GOT32<<24, 1205 S390X | R_390_PLT32<<24, 1206 S390X | R_390_PC32DBL<<24, 1207 S390X | R_390_PLT32DBL<<24, 1208 S390X | R_390_GOTPCDBL<<24, 1209 S390X | R_390_GOTENT<<24: 1210 return 4 1211 1212 case AMD64 | R_X86_64_64<<24, 1213 PPC64 | R_PPC64_ADDR64<<24, 1214 S390X | R_390_GLOB_DAT<<24, 1215 S390X | R_390_RELATIVE<<24, 1216 S390X | R_390_GOTOFF<<24, 1217 S390X | R_390_GOTPC<<24, 1218 S390X | R_390_64<<24, 1219 S390X | R_390_PC64<<24, 1220 S390X | R_390_GOT64<<24, 1221 S390X | R_390_PLT64<<24: 1222 return 8 1223 } 1224 }