github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/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 returned 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 sectsymNames := make(map[string]bool) 682 counter := 0 683 for i := 0; uint(i) < elfobj.nsect; i++ { 684 sect = &elfobj.sect[i] 685 if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" { 686 if err := elfmap(elfobj, sect); err != nil { 687 return errorf("%s: malformed elf file: %v", pn, err) 688 } 689 // We assume the soft-float ABI unless we see a tag indicating otherwise. 690 if initEhdrFlags == 0x5000002 { 691 ehdrFlags = 0x5000202 692 } else { 693 ehdrFlags = initEhdrFlags 694 } 695 found, newEhdrFlags, err := parseArmAttributes(e, sect.base[:sect.size]) 696 if err != nil { 697 // TODO(dfc) should this return an error? 698 log.Printf("%s: %v", pn, err) 699 } 700 if found { 701 ehdrFlags = newEhdrFlags 702 } 703 } 704 if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 { 705 continue 706 } 707 if sect.type_ != ElfSectNobits { 708 if err := elfmap(elfobj, sect); err != nil { 709 return errorf("%s: malformed elf file: %v", pn, err) 710 } 711 } 712 713 name := fmt.Sprintf("%s(%s)", pkg, sect.name) 714 for sectsymNames[name] { 715 counter++ 716 name = fmt.Sprintf("%s(%s%d)", pkg, sect.name, counter) 717 } 718 sectsymNames[name] = true 719 720 s := syms.Lookup(name, localSymVersion) 721 722 switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) { 723 default: 724 return errorf("%s: unexpected flags for ELF section %s", pn, sect.name) 725 726 case ElfSectFlagAlloc: 727 s.Type = sym.SRODATA 728 729 case ElfSectFlagAlloc + ElfSectFlagWrite: 730 if sect.type_ == ElfSectNobits { 731 s.Type = sym.SNOPTRBSS 732 } else { 733 s.Type = sym.SNOPTRDATA 734 } 735 736 case ElfSectFlagAlloc + ElfSectFlagExec: 737 s.Type = sym.STEXT 738 } 739 740 if sect.name == ".got" || sect.name == ".toc" { 741 s.Type = sym.SELFGOT 742 } 743 if sect.type_ == ElfSectProgbits { 744 s.P = sect.base 745 s.P = s.P[:sect.size] 746 } 747 748 s.Size = int64(sect.size) 749 s.Align = int32(sect.align) 750 sect.sym = s 751 } 752 753 // enter sub-symbols into symbol table. 754 // symbol 0 is the null symbol. 755 symbols := make([]*sym.Symbol, elfobj.nsymtab) 756 757 for i := 1; i < elfobj.nsymtab; i++ { 758 var elfsym ElfSym 759 if err := readelfsym(arch, syms, elfobj, i, &elfsym, 1, localSymVersion); err != nil { 760 return errorf("%s: malformed elf file: %v", pn, err) 761 } 762 symbols[i] = elfsym.sym 763 if elfsym.type_ != ElfSymTypeFunc && elfsym.type_ != ElfSymTypeObject && elfsym.type_ != ElfSymTypeNone && elfsym.type_ != ElfSymTypeCommon { 764 continue 765 } 766 if elfsym.shndx == ElfSymShnCommon || elfsym.type_ == ElfSymTypeCommon { 767 s := elfsym.sym 768 if uint64(s.Size) < elfsym.size { 769 s.Size = int64(elfsym.size) 770 } 771 if s.Type == 0 || s.Type == sym.SXREF { 772 s.Type = sym.SNOPTRBSS 773 } 774 continue 775 } 776 777 if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 { 778 continue 779 } 780 781 // even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols 782 if elfsym.sym == nil { 783 continue 784 } 785 sect = &elfobj.sect[elfsym.shndx] 786 if sect.sym == nil { 787 if strings.HasPrefix(elfsym.name, ".Linfo_string") { // clang does this 788 continue 789 } 790 791 if elfsym.name == "" && elfsym.type_ == 0 && sect.name == ".debug_str" { 792 // This reportedly happens with clang 3.7 on ARM. 793 // See issue 13139. 794 continue 795 } 796 797 if strings.HasPrefix(elfsym.name, ".LASF") { // gcc on s390x does this 798 continue 799 } 800 return errorf("%v: sym#%d: ignoring symbol in section %d (type %d)", elfsym.sym, i, elfsym.shndx, elfsym.type_) 801 } 802 803 s := elfsym.sym 804 if s.Outer != nil { 805 if s.Attr.DuplicateOK() { 806 continue 807 } 808 return errorf("duplicate symbol reference: %s in both %s and %s", s.Name, s.Outer.Name, sect.sym.Name) 809 } 810 811 s.Sub = sect.sym.Sub 812 sect.sym.Sub = s 813 s.Type = sect.sym.Type 814 s.Attr |= sym.AttrSubSymbol 815 if !s.Attr.CgoExportDynamic() { 816 s.SetDynimplib("") // satisfy dynimport 817 } 818 s.Value = int64(elfsym.value) 819 s.Size = int64(elfsym.size) 820 s.Outer = sect.sym 821 if sect.sym.Type == sym.STEXT { 822 if s.Attr.External() && !s.Attr.DuplicateOK() { 823 return errorf("%v: duplicate symbol definition", s) 824 } 825 s.Attr |= sym.AttrExternal 826 } 827 828 if elfobj.machine == ElfMachPower64 { 829 flag := int(elfsym.other) >> 5 830 if 2 <= flag && flag <= 6 { 831 s.SetLocalentry(1 << uint(flag-2)) 832 } else if flag == 7 { 833 return errorf("%v: invalid sym.other 0x%x", s, elfsym.other) 834 } 835 } 836 } 837 838 // Sort outer lists by address, adding to textp. 839 // This keeps textp in increasing address order. 840 for i := uint(0); i < elfobj.nsect; i++ { 841 s := elfobj.sect[i].sym 842 if s == nil { 843 continue 844 } 845 if s.Sub != nil { 846 s.Sub = sym.SortSub(s.Sub) 847 } 848 if s.Type == sym.STEXT { 849 if s.Attr.OnList() { 850 return errorf("symbol %s listed multiple times", s.Name) 851 } 852 s.Attr |= sym.AttrOnList 853 textp = append(textp, s) 854 for s = s.Sub; s != nil; s = s.Sub { 855 if s.Attr.OnList() { 856 return errorf("symbol %s listed multiple times", s.Name) 857 } 858 s.Attr |= sym.AttrOnList 859 textp = append(textp, s) 860 } 861 } 862 } 863 864 // load relocations 865 for i := uint(0); i < elfobj.nsect; i++ { 866 rsect := &elfobj.sect[i] 867 if rsect.type_ != ElfSectRela && rsect.type_ != ElfSectRel { 868 continue 869 } 870 if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil { 871 continue 872 } 873 sect = &elfobj.sect[rsect.info] 874 if err := elfmap(elfobj, rsect); err != nil { 875 return errorf("malformed elf file: %v", err) 876 } 877 rela := 0 878 if rsect.type_ == ElfSectRela { 879 rela = 1 880 } 881 n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela)) 882 r := make([]sym.Reloc, n) 883 p := rsect.base 884 for j := 0; j < n; j++ { 885 var add uint64 886 rp := &r[j] 887 var info uint64 888 if is64 != 0 { 889 // 64-bit rel/rela 890 rp.Off = int32(e.Uint64(p)) 891 892 p = p[8:] 893 info = e.Uint64(p) 894 p = p[8:] 895 if rela != 0 { 896 add = e.Uint64(p) 897 p = p[8:] 898 } 899 } else { 900 // 32-bit rel/rela 901 rp.Off = int32(e.Uint32(p)) 902 903 p = p[4:] 904 info = uint64(e.Uint32(p)) 905 info = info>>8<<32 | info&0xff // convert to 64-bit info 906 p = p[4:] 907 if rela != 0 { 908 add = uint64(e.Uint32(p)) 909 p = p[4:] 910 } 911 } 912 913 if info&0xffffffff == 0 { // skip R_*_NONE relocation 914 j-- 915 n-- 916 continue 917 } 918 919 if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol 920 rp.Sym = nil 921 } else { 922 var elfsym ElfSym 923 if err := readelfsym(arch, syms, elfobj, int(info>>32), &elfsym, 0, 0); err != nil { 924 return errorf("malformed elf file: %v", err) 925 } 926 elfsym.sym = symbols[info>>32] 927 if elfsym.sym == nil { 928 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_) 929 } 930 931 rp.Sym = elfsym.sym 932 } 933 934 rp.Type = 256 + objabi.RelocType(info) 935 rp.Siz, err = relSize(arch, pn, uint32(info)) 936 if err != nil { 937 return nil, 0, err 938 } 939 if rela != 0 { 940 rp.Add = int64(add) 941 } else { 942 // load addend from image 943 if rp.Siz == 4 { 944 rp.Add = int64(e.Uint32(sect.base[rp.Off:])) 945 } else if rp.Siz == 8 { 946 rp.Add = int64(e.Uint64(sect.base[rp.Off:])) 947 } else { 948 return errorf("invalid rela size %d", rp.Siz) 949 } 950 } 951 952 if rp.Siz == 2 { 953 rp.Add = int64(int16(rp.Add)) 954 } 955 if rp.Siz == 4 { 956 rp.Add = int64(int32(rp.Add)) 957 } 958 } 959 960 //print("rel %s %d %d %s %#llx\n", sect->sym->name, rp->type, rp->siz, rp->sym->name, rp->add); 961 sort.Sort(sym.RelocByOff(r[:n])) 962 // just in case 963 964 s := sect.sym 965 s.R = r 966 s.R = s.R[:n] 967 } 968 969 return textp, ehdrFlags, nil 970 } 971 972 func section(elfobj *ElfObj, name string) *ElfSect { 973 for i := 0; uint(i) < elfobj.nsect; i++ { 974 if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name { 975 return &elfobj.sect[i] 976 } 977 } 978 return nil 979 } 980 981 func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) { 982 if sect.base != nil { 983 return nil 984 } 985 986 if sect.off+sect.size > uint64(elfobj.length) { 987 err = fmt.Errorf("elf section past end of file") 988 return err 989 } 990 991 sect.base = make([]byte, sect.size) 992 if elfobj.f.Seek(int64(uint64(elfobj.base)+sect.off), 0) < 0 { 993 return fmt.Errorf("short read: seek not successful") 994 } 995 if _, err := io.ReadFull(elfobj.f, sect.base); err != nil { 996 return fmt.Errorf("short read: %v", err) 997 } 998 999 return nil 1000 } 1001 1002 func readelfsym(arch *sys.Arch, syms *sym.Symbols, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) { 1003 if i >= elfobj.nsymtab || i < 0 { 1004 err = fmt.Errorf("invalid elf symbol index") 1005 return err 1006 } 1007 1008 if i == 0 { 1009 return fmt.Errorf("readym: read null symbol!") 1010 } 1011 1012 if elfobj.is64 != 0 { 1013 b := new(ElfSymBytes64) 1014 binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF64SYMSIZE:(i+1)*ELF64SYMSIZE]), elfobj.e, b) 1015 elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):]) 1016 elfsym.value = elfobj.e.Uint64(b.Value[:]) 1017 elfsym.size = elfobj.e.Uint64(b.Size[:]) 1018 elfsym.shndx = elfobj.e.Uint16(b.Shndx[:]) 1019 elfsym.bind = b.Info >> 4 1020 elfsym.type_ = b.Info & 0xf 1021 elfsym.other = b.Other 1022 } else { 1023 b := new(ElfSymBytes) 1024 binary.Read(bytes.NewReader(elfobj.symtab.base[i*ELF32SYMSIZE:(i+1)*ELF32SYMSIZE]), elfobj.e, b) 1025 elfsym.name = cstring(elfobj.symstr.base[elfobj.e.Uint32(b.Name[:]):]) 1026 elfsym.value = uint64(elfobj.e.Uint32(b.Value[:])) 1027 elfsym.size = uint64(elfobj.e.Uint32(b.Size[:])) 1028 elfsym.shndx = elfobj.e.Uint16(b.Shndx[:]) 1029 elfsym.bind = b.Info >> 4 1030 elfsym.type_ = b.Info & 0xf 1031 elfsym.other = b.Other 1032 } 1033 1034 var s *sym.Symbol 1035 if elfsym.name == "_GLOBAL_OFFSET_TABLE_" { 1036 elfsym.name = ".got" 1037 } 1038 if elfsym.name == ".TOC." { 1039 // Magic symbol on ppc64. Will be set to this object 1040 // file's .got+0x8000. 1041 elfsym.bind = ElfSymBindLocal 1042 } 1043 1044 switch elfsym.type_ { 1045 case ElfSymTypeSection: 1046 s = elfobj.sect[elfsym.shndx].sym 1047 1048 case ElfSymTypeObject, ElfSymTypeFunc, ElfSymTypeNone, ElfSymTypeCommon: 1049 switch elfsym.bind { 1050 case ElfSymBindGlobal: 1051 if needSym != 0 { 1052 s = syms.Lookup(elfsym.name, 0) 1053 1054 // for global scoped hidden symbols we should insert it into 1055 // symbol hash table, but mark them as hidden. 1056 // __i686.get_pc_thunk.bx is allowed to be duplicated, to 1057 // workaround that we set dupok. 1058 // TODO(minux): correctly handle __i686.get_pc_thunk.bx without 1059 // set dupok generally. See https://golang.org/cl/5823055 1060 // comment #5 for details. 1061 if s != nil && elfsym.other == 2 { 1062 s.Attr |= sym.AttrDuplicateOK | sym.AttrVisibilityHidden 1063 } 1064 } 1065 1066 case ElfSymBindLocal: 1067 if arch.Family == sys.ARM && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d")) { 1068 // binutils for arm generate these mapping 1069 // symbols, ignore these 1070 break 1071 } 1072 1073 if elfsym.name == ".TOC." { 1074 // We need to be able to look this up, 1075 // so put it in the hash table. 1076 if needSym != 0 { 1077 s = syms.Lookup(elfsym.name, localSymVersion) 1078 s.Attr |= sym.AttrVisibilityHidden 1079 } 1080 1081 break 1082 } 1083 1084 if needSym != 0 { 1085 // local names and hidden global names are unique 1086 // and should only be referenced by their index, not name, so we 1087 // don't bother to add them into the hash table 1088 s = syms.Newsym(elfsym.name, localSymVersion) 1089 1090 s.Attr |= sym.AttrVisibilityHidden 1091 } 1092 1093 case ElfSymBindWeak: 1094 if needSym != 0 { 1095 s = syms.Lookup(elfsym.name, 0) 1096 if elfsym.other == 2 { 1097 s.Attr |= sym.AttrVisibilityHidden 1098 } 1099 } 1100 1101 default: 1102 err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind) 1103 return err 1104 } 1105 } 1106 1107 // TODO(mwhudson): the test of VisibilityHidden here probably doesn't make 1108 // sense and should be removed when someone has thought about it properly. 1109 if s != nil && s.Type == 0 && !s.Attr.VisibilityHidden() && elfsym.type_ != ElfSymTypeSection { 1110 s.Type = sym.SXREF 1111 } 1112 elfsym.sym = s 1113 1114 return nil 1115 } 1116 1117 func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, error) { 1118 // TODO(mdempsky): Replace this with a struct-valued switch statement 1119 // once golang.org/issue/15164 is fixed or found to not impair cmd/link 1120 // performance. 1121 1122 const ( 1123 AMD64 = uint32(sys.AMD64) 1124 ARM = uint32(sys.ARM) 1125 I386 = uint32(sys.I386) 1126 PPC64 = uint32(sys.PPC64) 1127 S390X = uint32(sys.S390X) 1128 ) 1129 1130 switch uint32(arch.Family) | elftype<<24 { 1131 default: 1132 return 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype) 1133 1134 case S390X | uint32(elf.R_390_8)<<24: 1135 return 1, nil 1136 1137 case PPC64 | uint32(elf.R_PPC64_TOC16)<<24, 1138 PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<24, 1139 PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<24, 1140 PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<24, 1141 PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<24, 1142 PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<24, 1143 PPC64 | uint32(elf.R_PPC64_REL16_LO)<<24, 1144 PPC64 | uint32(elf.R_PPC64_REL16_HI)<<24, 1145 PPC64 | uint32(elf.R_PPC64_REL16_HA)<<24, 1146 S390X | uint32(elf.R_390_16)<<24, 1147 S390X | uint32(elf.R_390_GOT16)<<24, 1148 S390X | uint32(elf.R_390_PC16)<<24, 1149 S390X | uint32(elf.R_390_PC16DBL)<<24, 1150 S390X | uint32(elf.R_390_PLT16DBL)<<24: 1151 return 2, nil 1152 1153 case ARM | uint32(elf.R_ARM_ABS32)<<24, 1154 ARM | uint32(elf.R_ARM_GOT32)<<24, 1155 ARM | uint32(elf.R_ARM_PLT32)<<24, 1156 ARM | uint32(elf.R_ARM_GOTOFF)<<24, 1157 ARM | uint32(elf.R_ARM_GOTPC)<<24, 1158 ARM | uint32(elf.R_ARM_THM_PC22)<<24, 1159 ARM | uint32(elf.R_ARM_REL32)<<24, 1160 ARM | uint32(elf.R_ARM_CALL)<<24, 1161 ARM | uint32(elf.R_ARM_V4BX)<<24, 1162 ARM | uint32(elf.R_ARM_GOT_PREL)<<24, 1163 ARM | uint32(elf.R_ARM_PC24)<<24, 1164 ARM | uint32(elf.R_ARM_JUMP24)<<24, 1165 AMD64 | uint32(elf.R_X86_64_PC32)<<24, 1166 AMD64 | uint32(elf.R_X86_64_PLT32)<<24, 1167 AMD64 | uint32(elf.R_X86_64_GOTPCREL)<<24, 1168 AMD64 | uint32(elf.R_X86_64_GOTPCRELX)<<24, 1169 AMD64 | uint32(elf.R_X86_64_REX_GOTPCRELX)<<24, 1170 I386 | uint32(elf.R_386_32)<<24, 1171 I386 | uint32(elf.R_386_PC32)<<24, 1172 I386 | uint32(elf.R_386_GOT32)<<24, 1173 I386 | uint32(elf.R_386_PLT32)<<24, 1174 I386 | uint32(elf.R_386_GOTOFF)<<24, 1175 I386 | uint32(elf.R_386_GOTPC)<<24, 1176 I386 | uint32(elf.R_386_GOT32X)<<24, 1177 PPC64 | uint32(elf.R_PPC64_REL24)<<24, 1178 PPC64 | uint32(elf.R_PPC_REL32)<<24, 1179 S390X | uint32(elf.R_390_32)<<24, 1180 S390X | uint32(elf.R_390_PC32)<<24, 1181 S390X | uint32(elf.R_390_GOT32)<<24, 1182 S390X | uint32(elf.R_390_PLT32)<<24, 1183 S390X | uint32(elf.R_390_PC32DBL)<<24, 1184 S390X | uint32(elf.R_390_PLT32DBL)<<24, 1185 S390X | uint32(elf.R_390_GOTPCDBL)<<24, 1186 S390X | uint32(elf.R_390_GOTENT)<<24: 1187 return 4, nil 1188 1189 case AMD64 | uint32(elf.R_X86_64_64)<<24, 1190 AMD64 | uint32(elf.R_X86_64_PC64)<<24, 1191 PPC64 | uint32(elf.R_PPC64_ADDR64)<<24, 1192 S390X | uint32(elf.R_390_GLOB_DAT)<<24, 1193 S390X | uint32(elf.R_390_RELATIVE)<<24, 1194 S390X | uint32(elf.R_390_GOTOFF)<<24, 1195 S390X | uint32(elf.R_390_GOTPC)<<24, 1196 S390X | uint32(elf.R_390_64)<<24, 1197 S390X | uint32(elf.R_390_PC64)<<24, 1198 S390X | uint32(elf.R_390_GOT64)<<24, 1199 S390X | uint32(elf.R_390_PLT64)<<24: 1200 return 8, nil 1201 } 1202 } 1203 1204 func cstring(x []byte) string { 1205 i := bytes.IndexByte(x, '\x00') 1206 if i >= 0 { 1207 x = x[:i] 1208 } 1209 return string(x) 1210 }