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