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