github.com/bir3/gocompiler@v0.3.205/src/cmd/link/internal/loadelf/ldelf.go (about) 1 // Copyright 2019 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/bir3/gocompiler/src/cmd/internal/bio" 11 "github.com/bir3/gocompiler/src/cmd/internal/objabi" 12 "github.com/bir3/gocompiler/src/cmd/internal/sys" 13 "github.com/bir3/gocompiler/src/cmd/link/internal/loader" 14 "github.com/bir3/gocompiler/src/cmd/link/internal/sym" 15 "debug/elf" 16 "encoding/binary" 17 "fmt" 18 "io" 19 "log" 20 "strings" 21 ) 22 23 /* 24 Derived from Plan 9 from User Space's src/libmach/elf.h, elf.c 25 https://github.com/9fans/plan9port/tree/master/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 50 const ( 51 SHT_ARM_ATTRIBUTES = 0x70000003 52 ) 53 54 type ElfSect struct { 55 name string 56 nameoff uint32 57 type_ elf.SectionType 58 flags elf.SectionFlag 59 addr uint64 60 off uint64 61 size uint64 62 link uint32 63 info uint32 64 align uint64 65 entsize uint64 66 base []byte 67 readOnlyMem bool // Is this section in readonly memory? 68 sym loader.Sym 69 } 70 71 type ElfObj struct { 72 f *bio.Reader 73 base int64 // offset in f where ELF begins 74 length int64 // length of ELF 75 is64 int 76 name string 77 e binary.ByteOrder 78 sect []ElfSect 79 nsect uint 80 nsymtab int 81 symtab *ElfSect 82 symstr *ElfSect 83 type_ uint32 84 machine uint32 85 version uint32 86 entry uint64 87 phoff uint64 88 shoff uint64 89 flags uint32 90 ehsize uint32 91 phentsize uint32 92 phnum uint32 93 shentsize uint32 94 shnum uint32 95 shstrndx uint32 96 } 97 98 type ElfSym struct { 99 name string 100 value uint64 101 size uint64 102 bind elf.SymBind 103 type_ elf.SymType 104 other uint8 105 shndx elf.SectionIndex 106 sym loader.Sym 107 } 108 109 const ( 110 TagFile = 1 111 TagCPUName = 4 112 TagCPURawName = 5 113 TagCompatibility = 32 114 TagNoDefaults = 64 115 TagAlsoCompatibleWith = 65 116 TagABIVFPArgs = 28 117 ) 118 119 type elfAttribute struct { 120 tag uint64 121 sval string 122 ival uint64 123 } 124 125 type elfAttributeList struct { 126 data []byte 127 err error 128 } 129 130 func (a *elfAttributeList) string() string { 131 if a.err != nil { 132 return "" 133 } 134 nul := bytes.IndexByte(a.data, 0) 135 if nul < 0 { 136 a.err = io.EOF 137 return "" 138 } 139 s := string(a.data[:nul]) 140 a.data = a.data[nul+1:] 141 return s 142 } 143 144 func (a *elfAttributeList) uleb128() uint64 { 145 if a.err != nil { 146 return 0 147 } 148 v, size := binary.Uvarint(a.data) 149 a.data = a.data[size:] 150 return v 151 } 152 153 // Read an elfAttribute from the list following the rules used on ARM systems. 154 func (a *elfAttributeList) armAttr() elfAttribute { 155 attr := elfAttribute{tag: a.uleb128()} 156 switch { 157 case attr.tag == TagCompatibility: 158 attr.ival = a.uleb128() 159 attr.sval = a.string() 160 161 case attr.tag == TagNoDefaults: // Tag_nodefaults has no argument 162 163 case attr.tag == TagAlsoCompatibleWith: 164 // Not really, but we don't actually care about this tag. 165 attr.sval = a.string() 166 167 // Tag with string argument 168 case attr.tag == TagCPUName || attr.tag == TagCPURawName || (attr.tag >= 32 && attr.tag&1 != 0): 169 attr.sval = a.string() 170 171 default: // Tag with integer argument 172 attr.ival = a.uleb128() 173 } 174 return attr 175 } 176 177 func (a *elfAttributeList) done() bool { 178 if a.err != nil || len(a.data) == 0 { 179 return true 180 } 181 return false 182 } 183 184 // Look for the attribute that indicates the object uses the hard-float ABI (a 185 // file-level attribute with tag Tag_VFP_arch and value 1). Unfortunately the 186 // format used means that we have to parse all of the file-level attributes to 187 // find the one we are looking for. This format is slightly documented in "ELF 188 // for the ARM Architecture" but mostly this is derived from reading the source 189 // to gold and readelf. 190 func parseArmAttributes(e binary.ByteOrder, data []byte) (found bool, ehdrFlags uint32, err error) { 191 found = false 192 if data[0] != 'A' { 193 return false, 0, fmt.Errorf(".ARM.attributes has unexpected format %c\n", data[0]) 194 } 195 data = data[1:] 196 for len(data) != 0 { 197 sectionlength := e.Uint32(data) 198 sectiondata := data[4:sectionlength] 199 data = data[sectionlength:] 200 201 nulIndex := bytes.IndexByte(sectiondata, 0) 202 if nulIndex < 0 { 203 return false, 0, fmt.Errorf("corrupt .ARM.attributes (section name not NUL-terminated)\n") 204 } 205 name := string(sectiondata[:nulIndex]) 206 sectiondata = sectiondata[nulIndex+1:] 207 208 if name != "aeabi" { 209 continue 210 } 211 for len(sectiondata) != 0 { 212 subsectiontag, sz := binary.Uvarint(sectiondata) 213 subsectionsize := e.Uint32(sectiondata[sz:]) 214 subsectiondata := sectiondata[sz+4 : subsectionsize] 215 sectiondata = sectiondata[subsectionsize:] 216 217 if subsectiontag != TagFile { 218 continue 219 } 220 attrList := elfAttributeList{data: subsectiondata} 221 for !attrList.done() { 222 attr := attrList.armAttr() 223 if attr.tag == TagABIVFPArgs && attr.ival == 1 { 224 found = true 225 ehdrFlags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI 226 } 227 } 228 if attrList.err != nil { 229 return false, 0, fmt.Errorf("could not parse .ARM.attributes\n") 230 } 231 } 232 } 233 return found, ehdrFlags, nil 234 } 235 236 // Load loads the ELF file pn from f. 237 // Symbols are installed into the loader, and a slice of the text symbols is returned. 238 // 239 // On ARM systems, Load will attempt to determine what ELF header flags to 240 // emit by scanning the attributes in the ELF file being loaded. The 241 // parameter initEhdrFlags contains the current header flags for the output 242 // object, and the returned ehdrFlags contains what this Load function computes. 243 // TODO: find a better place for this logic. 244 func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, pkg string, length int64, pn string, initEhdrFlags uint32) (textp []loader.Sym, ehdrFlags uint32, err error) { 245 newSym := func(name string, version int) loader.Sym { 246 return l.CreateStaticSym(name) 247 } 248 lookup := l.LookupOrCreateCgoExport 249 errorf := func(str string, args ...interface{}) ([]loader.Sym, uint32, error) { 250 return nil, 0, fmt.Errorf("loadelf: %s: %v", pn, fmt.Sprintf(str, args...)) 251 } 252 253 ehdrFlags = initEhdrFlags 254 255 base := f.Offset() 256 257 var hdrbuf [64]byte 258 if _, err := io.ReadFull(f, hdrbuf[:]); err != nil { 259 return errorf("malformed elf file: %v", err) 260 } 261 262 var e binary.ByteOrder 263 switch elf.Data(hdrbuf[elf.EI_DATA]) { 264 case elf.ELFDATA2LSB: 265 e = binary.LittleEndian 266 267 case elf.ELFDATA2MSB: 268 e = binary.BigEndian 269 270 default: 271 return errorf("malformed elf file, unknown header") 272 } 273 274 hdr := new(elf.Header32) 275 binary.Read(bytes.NewReader(hdrbuf[:]), e, hdr) 276 277 if string(hdr.Ident[:elf.EI_CLASS]) != elf.ELFMAG { 278 return errorf("malformed elf file, bad header") 279 } 280 281 // read header 282 elfobj := new(ElfObj) 283 284 elfobj.e = e 285 elfobj.f = f 286 elfobj.base = base 287 elfobj.length = length 288 elfobj.name = pn 289 290 is64 := 0 291 class := elf.Class(hdrbuf[elf.EI_CLASS]) 292 if class == elf.ELFCLASS64 { 293 is64 = 1 294 hdr := new(elf.Header64) 295 binary.Read(bytes.NewReader(hdrbuf[:]), e, hdr) 296 elfobj.type_ = uint32(hdr.Type) 297 elfobj.machine = uint32(hdr.Machine) 298 elfobj.version = hdr.Version 299 elfobj.entry = hdr.Entry 300 elfobj.phoff = hdr.Phoff 301 elfobj.shoff = hdr.Shoff 302 elfobj.flags = hdr.Flags 303 elfobj.ehsize = uint32(hdr.Ehsize) 304 elfobj.phentsize = uint32(hdr.Phentsize) 305 elfobj.phnum = uint32(hdr.Phnum) 306 elfobj.shentsize = uint32(hdr.Shentsize) 307 elfobj.shnum = uint32(hdr.Shnum) 308 elfobj.shstrndx = uint32(hdr.Shstrndx) 309 } else { 310 elfobj.type_ = uint32(hdr.Type) 311 elfobj.machine = uint32(hdr.Machine) 312 elfobj.version = hdr.Version 313 elfobj.entry = uint64(hdr.Entry) 314 elfobj.phoff = uint64(hdr.Phoff) 315 elfobj.shoff = uint64(hdr.Shoff) 316 elfobj.flags = hdr.Flags 317 elfobj.ehsize = uint32(hdr.Ehsize) 318 elfobj.phentsize = uint32(hdr.Phentsize) 319 elfobj.phnum = uint32(hdr.Phnum) 320 elfobj.shentsize = uint32(hdr.Shentsize) 321 elfobj.shnum = uint32(hdr.Shnum) 322 elfobj.shstrndx = uint32(hdr.Shstrndx) 323 } 324 325 elfobj.is64 = is64 326 327 if v := uint32(hdrbuf[elf.EI_VERSION]); v != elfobj.version { 328 return errorf("malformed elf version: got %d, want %d", v, elfobj.version) 329 } 330 331 if elf.Type(elfobj.type_) != elf.ET_REL { 332 return errorf("elf but not elf relocatable object") 333 } 334 335 mach := elf.Machine(elfobj.machine) 336 switch arch.Family { 337 default: 338 return errorf("elf %s unimplemented", arch.Name) 339 340 case sys.MIPS: 341 if mach != elf.EM_MIPS || class != elf.ELFCLASS32 { 342 return errorf("elf object but not mips") 343 } 344 345 case sys.MIPS64: 346 if mach != elf.EM_MIPS || class != elf.ELFCLASS64 { 347 return errorf("elf object but not mips64") 348 } 349 case sys.Loong64: 350 if mach != elf.EM_LOONGARCH || class != elf.ELFCLASS64 { 351 return errorf("elf object but not loong64") 352 } 353 354 case sys.ARM: 355 if e != binary.LittleEndian || mach != elf.EM_ARM || class != elf.ELFCLASS32 { 356 return errorf("elf object but not arm") 357 } 358 359 case sys.AMD64: 360 if e != binary.LittleEndian || mach != elf.EM_X86_64 || class != elf.ELFCLASS64 { 361 return errorf("elf object but not amd64") 362 } 363 364 case sys.ARM64: 365 if e != binary.LittleEndian || mach != elf.EM_AARCH64 || class != elf.ELFCLASS64 { 366 return errorf("elf object but not arm64") 367 } 368 369 case sys.I386: 370 if e != binary.LittleEndian || mach != elf.EM_386 || class != elf.ELFCLASS32 { 371 return errorf("elf object but not 386") 372 } 373 374 case sys.PPC64: 375 if mach != elf.EM_PPC64 || class != elf.ELFCLASS64 { 376 return errorf("elf object but not ppc64") 377 } 378 379 case sys.RISCV64: 380 if mach != elf.EM_RISCV || class != elf.ELFCLASS64 { 381 return errorf("elf object but not riscv64") 382 } 383 384 case sys.S390X: 385 if mach != elf.EM_S390 || class != elf.ELFCLASS64 { 386 return errorf("elf object but not s390x") 387 } 388 } 389 390 // load section list into memory. 391 elfobj.sect = make([]ElfSect, elfobj.shnum) 392 393 elfobj.nsect = uint(elfobj.shnum) 394 for i := 0; uint(i) < elfobj.nsect; i++ { 395 f.MustSeek(int64(uint64(base)+elfobj.shoff+uint64(int64(i)*int64(elfobj.shentsize))), 0) 396 sect := &elfobj.sect[i] 397 if is64 != 0 { 398 var b elf.Section64 399 if err := binary.Read(f, e, &b); err != nil { 400 return errorf("malformed elf file: %v", err) 401 } 402 403 sect.nameoff = b.Name 404 sect.type_ = elf.SectionType(b.Type) 405 sect.flags = elf.SectionFlag(b.Flags) 406 sect.addr = b.Addr 407 sect.off = b.Off 408 sect.size = b.Size 409 sect.link = b.Link 410 sect.info = b.Info 411 sect.align = b.Addralign 412 sect.entsize = b.Entsize 413 } else { 414 var b elf.Section32 415 416 if err := binary.Read(f, e, &b); err != nil { 417 return errorf("malformed elf file: %v", err) 418 } 419 sect.nameoff = b.Name 420 sect.type_ = elf.SectionType(b.Type) 421 sect.flags = elf.SectionFlag(b.Flags) 422 sect.addr = uint64(b.Addr) 423 sect.off = uint64(b.Off) 424 sect.size = uint64(b.Size) 425 sect.link = b.Link 426 sect.info = b.Info 427 sect.align = uint64(b.Addralign) 428 sect.entsize = uint64(b.Entsize) 429 } 430 } 431 432 // read section string table and translate names 433 if elfobj.shstrndx >= uint32(elfobj.nsect) { 434 return errorf("malformed elf file: shstrndx out of range %d >= %d", elfobj.shstrndx, elfobj.nsect) 435 } 436 437 sect := &elfobj.sect[elfobj.shstrndx] 438 if err := elfmap(elfobj, sect); err != nil { 439 return errorf("malformed elf file: %v", err) 440 } 441 for i := 0; uint(i) < elfobj.nsect; i++ { 442 if elfobj.sect[i].nameoff != 0 { 443 elfobj.sect[i].name = cstring(sect.base[elfobj.sect[i].nameoff:]) 444 } 445 } 446 447 // load string table for symbols into memory. 448 elfobj.symtab = section(elfobj, ".symtab") 449 450 if elfobj.symtab == nil { 451 // our work is done here - no symbols means nothing can refer to this file 452 return 453 } 454 455 if elfobj.symtab.link <= 0 || elfobj.symtab.link >= uint32(elfobj.nsect) { 456 return errorf("elf object has symbol table with invalid string table link") 457 } 458 459 elfobj.symstr = &elfobj.sect[elfobj.symtab.link] 460 if is64 != 0 { 461 elfobj.nsymtab = int(elfobj.symtab.size / elf.Sym64Size) 462 } else { 463 elfobj.nsymtab = int(elfobj.symtab.size / elf.Sym32Size) 464 } 465 466 if err := elfmap(elfobj, elfobj.symtab); err != nil { 467 return errorf("malformed elf file: %v", err) 468 } 469 if err := elfmap(elfobj, elfobj.symstr); err != nil { 470 return errorf("malformed elf file: %v", err) 471 } 472 473 // load text and data segments into memory. 474 // they are not as small as the section lists, but we'll need 475 // the memory anyway for the symbol images, so we might 476 // as well use one large chunk. 477 478 // create symbols for elfmapped sections 479 sectsymNames := make(map[string]bool) 480 counter := 0 481 for i := 0; uint(i) < elfobj.nsect; i++ { 482 sect = &elfobj.sect[i] 483 if sect.type_ == SHT_ARM_ATTRIBUTES && sect.name == ".ARM.attributes" { 484 if err := elfmap(elfobj, sect); err != nil { 485 return errorf("%s: malformed elf file: %v", pn, err) 486 } 487 // We assume the soft-float ABI unless we see a tag indicating otherwise. 488 if initEhdrFlags == 0x5000002 { 489 ehdrFlags = 0x5000202 490 } else { 491 ehdrFlags = initEhdrFlags 492 } 493 found, newEhdrFlags, err := parseArmAttributes(e, sect.base[:sect.size]) 494 if err != nil { 495 // TODO(dfc) should this return an error? 496 log.Printf("%s: %v", pn, err) 497 } 498 if found { 499 ehdrFlags = newEhdrFlags 500 } 501 } 502 if (sect.type_ != elf.SHT_PROGBITS && sect.type_ != elf.SHT_NOBITS) || sect.flags&elf.SHF_ALLOC == 0 { 503 continue 504 } 505 if sect.type_ != elf.SHT_NOBITS { 506 if err := elfmap(elfobj, sect); err != nil { 507 return errorf("%s: malformed elf file: %v", pn, err) 508 } 509 } 510 511 name := fmt.Sprintf("%s(%s)", pkg, sect.name) 512 for sectsymNames[name] { 513 counter++ 514 name = fmt.Sprintf("%s(%s%d)", pkg, sect.name, counter) 515 } 516 sectsymNames[name] = true 517 518 sb := l.MakeSymbolUpdater(lookup(name, localSymVersion)) 519 520 switch sect.flags & (elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_EXECINSTR) { 521 default: 522 return errorf("%s: unexpected flags for ELF section %s", pn, sect.name) 523 524 case elf.SHF_ALLOC: 525 sb.SetType(sym.SRODATA) 526 527 case elf.SHF_ALLOC + elf.SHF_WRITE: 528 if sect.type_ == elf.SHT_NOBITS { 529 sb.SetType(sym.SNOPTRBSS) 530 } else { 531 sb.SetType(sym.SNOPTRDATA) 532 } 533 534 case elf.SHF_ALLOC + elf.SHF_EXECINSTR: 535 sb.SetType(sym.STEXT) 536 } 537 538 if sect.name == ".got" || sect.name == ".toc" { 539 sb.SetType(sym.SELFGOT) 540 } 541 if sect.type_ == elf.SHT_PROGBITS { 542 sb.SetData(sect.base[:sect.size]) 543 } 544 545 sb.SetSize(int64(sect.size)) 546 sb.SetAlign(int32(sect.align)) 547 sb.SetReadOnly(sect.readOnlyMem) 548 549 sect.sym = sb.Sym() 550 } 551 552 // enter sub-symbols into symbol table. 553 // symbol 0 is the null symbol. 554 symbols := make([]loader.Sym, elfobj.nsymtab) 555 556 for i := 1; i < elfobj.nsymtab; i++ { 557 var elfsym ElfSym 558 if err := readelfsym(newSym, lookup, l, arch, elfobj, i, &elfsym, 1, localSymVersion); err != nil { 559 return errorf("%s: malformed elf file: %v", pn, err) 560 } 561 symbols[i] = elfsym.sym 562 if elfsym.type_ != elf.STT_FUNC && elfsym.type_ != elf.STT_OBJECT && elfsym.type_ != elf.STT_NOTYPE && elfsym.type_ != elf.STT_COMMON { 563 continue 564 } 565 if elfsym.shndx == elf.SHN_COMMON || elfsym.type_ == elf.STT_COMMON { 566 sb := l.MakeSymbolUpdater(elfsym.sym) 567 if uint64(sb.Size()) < elfsym.size { 568 sb.SetSize(int64(elfsym.size)) 569 } 570 if sb.Type() == 0 || sb.Type() == sym.SXREF { 571 sb.SetType(sym.SNOPTRBSS) 572 } 573 continue 574 } 575 576 if uint(elfsym.shndx) >= elfobj.nsect || elfsym.shndx == 0 { 577 continue 578 } 579 580 // even when we pass needSym == 1 to readelfsym, it might still return nil to skip some unwanted symbols 581 if elfsym.sym == 0 { 582 continue 583 } 584 sect = &elfobj.sect[elfsym.shndx] 585 if sect.sym == 0 { 586 if strings.HasPrefix(elfsym.name, ".Linfo_string") { // clang does this 587 continue 588 } 589 590 if elfsym.name == "" && elfsym.type_ == 0 && sect.name == ".debug_str" { 591 // This reportedly happens with clang 3.7 on ARM. 592 // See issue 13139. 593 continue 594 } 595 596 if strings.HasPrefix(elfsym.name, "$d") && elfsym.type_ == 0 && sect.name == ".debug_frame" { 597 // "$d" is a marker, not a real symbol. 598 // This happens with gcc on ARM64. 599 // See https://sourceware.org/bugzilla/show_bug.cgi?id=21809 600 continue 601 } 602 603 if strings.HasPrefix(elfsym.name, ".LASF") { // gcc on s390x does this 604 continue 605 } 606 return errorf("%v: sym#%d (%s): ignoring symbol in section %d (type %d)", elfsym.sym, i, elfsym.name, elfsym.shndx, elfsym.type_) 607 } 608 609 s := elfsym.sym 610 if l.OuterSym(s) != 0 { 611 if l.AttrDuplicateOK(s) { 612 continue 613 } 614 return errorf("duplicate symbol reference: %s in both %s and %s", 615 l.SymName(s), l.SymName(l.OuterSym(s)), l.SymName(sect.sym)) 616 } 617 618 sectsb := l.MakeSymbolUpdater(sect.sym) 619 sb := l.MakeSymbolUpdater(s) 620 621 sb.SetType(sectsb.Type()) 622 sectsb.AddInteriorSym(s) 623 if !l.AttrCgoExportDynamic(s) { 624 sb.SetDynimplib("") // satisfy dynimport 625 } 626 sb.SetValue(int64(elfsym.value)) 627 sb.SetSize(int64(elfsym.size)) 628 if sectsb.Type() == sym.STEXT { 629 if l.AttrExternal(s) && !l.AttrDuplicateOK(s) { 630 return errorf("%s: duplicate symbol definition", sb.Name()) 631 } 632 l.SetAttrExternal(s, true) 633 } 634 635 if elf.Machine(elfobj.machine) == elf.EM_PPC64 { 636 flag := int(elfsym.other) >> 5 637 switch flag { 638 case 0: 639 // No local entry. R2 is preserved. 640 case 1: 641 // These require R2 be saved and restored by the caller. This isn't supported today. 642 return errorf("%s: unable to handle local entry type 1", sb.Name()) 643 case 7: 644 return errorf("%s: invalid sym.other 0x%x", sb.Name(), elfsym.other) 645 default: 646 l.SetSymLocalentry(s, 4<<uint(flag-2)) 647 } 648 } 649 } 650 651 // Sort outer lists by address, adding to textp. 652 // This keeps textp in increasing address order. 653 for i := uint(0); i < elfobj.nsect; i++ { 654 s := elfobj.sect[i].sym 655 if s == 0 { 656 continue 657 } 658 sb := l.MakeSymbolUpdater(s) 659 if l.SubSym(s) != 0 { 660 sb.SortSub() 661 } 662 if sb.Type() == sym.STEXT { 663 if l.AttrOnList(s) { 664 return errorf("symbol %s listed multiple times", 665 l.SymName(s)) 666 } 667 l.SetAttrOnList(s, true) 668 textp = append(textp, s) 669 for ss := l.SubSym(s); ss != 0; ss = l.SubSym(ss) { 670 if l.AttrOnList(ss) { 671 return errorf("symbol %s listed multiple times", 672 l.SymName(ss)) 673 } 674 l.SetAttrOnList(ss, true) 675 textp = append(textp, ss) 676 } 677 } 678 } 679 680 // load relocations 681 for i := uint(0); i < elfobj.nsect; i++ { 682 rsect := &elfobj.sect[i] 683 if rsect.type_ != elf.SHT_RELA && rsect.type_ != elf.SHT_REL { 684 continue 685 } 686 if rsect.info >= uint32(elfobj.nsect) || elfobj.sect[rsect.info].base == nil { 687 continue 688 } 689 sect = &elfobj.sect[rsect.info] 690 if err := elfmap(elfobj, rsect); err != nil { 691 return errorf("malformed elf file: %v", err) 692 } 693 rela := 0 694 if rsect.type_ == elf.SHT_RELA { 695 rela = 1 696 } 697 n := int(rsect.size / uint64(4+4*is64) / uint64(2+rela)) 698 p := rsect.base 699 sb := l.MakeSymbolUpdater(sect.sym) 700 for j := 0; j < n; j++ { 701 var add uint64 702 var symIdx int 703 var relocType uint64 704 var rOff int32 705 var rAdd int64 706 var rSym loader.Sym 707 708 if is64 != 0 { 709 // 64-bit rel/rela 710 rOff = int32(e.Uint64(p)) 711 712 p = p[8:] 713 switch arch.Family { 714 case sys.MIPS64: 715 // https://www.linux-mips.org/pub/linux/mips/doc/ABI/elf64-2.4.pdf 716 // The doc shows it's different with general Linux ELF 717 symIdx = int(e.Uint32(p)) 718 relocType = uint64(p[7]) 719 default: 720 info := e.Uint64(p) 721 relocType = info & 0xffffffff 722 symIdx = int(info >> 32) 723 } 724 p = p[8:] 725 if rela != 0 { 726 add = e.Uint64(p) 727 p = p[8:] 728 } 729 } else { 730 // 32-bit rel/rela 731 rOff = int32(e.Uint32(p)) 732 733 p = p[4:] 734 info := e.Uint32(p) 735 relocType = uint64(info & 0xff) 736 symIdx = int(info >> 8) 737 p = p[4:] 738 if rela != 0 { 739 add = uint64(e.Uint32(p)) 740 p = p[4:] 741 } 742 } 743 744 if relocType == 0 { // skip R_*_NONE relocation 745 j-- 746 n-- 747 continue 748 } 749 750 if symIdx == 0 { // absolute relocation, don't bother reading the null symbol 751 rSym = 0 752 } else { 753 var elfsym ElfSym 754 if err := readelfsym(newSym, lookup, l, arch, elfobj, int(symIdx), &elfsym, 0, 0); err != nil { 755 return errorf("malformed elf file: %v", err) 756 } 757 elfsym.sym = symbols[symIdx] 758 if elfsym.sym == 0 { 759 return errorf("malformed elf file: %s#%d: reloc of invalid sym #%d %s shndx=%d type=%d", l.SymName(sect.sym), j, int(symIdx), elfsym.name, elfsym.shndx, elfsym.type_) 760 } 761 762 rSym = elfsym.sym 763 } 764 765 rType := objabi.ElfRelocOffset + objabi.RelocType(relocType) 766 rSize, addendSize, err := relSize(arch, pn, uint32(relocType)) 767 if err != nil { 768 return nil, 0, err 769 } 770 if rela != 0 { 771 rAdd = int64(add) 772 } else { 773 // load addend from image 774 if rSize == 4 { 775 rAdd = int64(e.Uint32(sect.base[rOff:])) 776 } else if rSize == 8 { 777 rAdd = int64(e.Uint64(sect.base[rOff:])) 778 } else { 779 return errorf("invalid rela size %d", rSize) 780 } 781 } 782 783 if addendSize == 2 { 784 rAdd = int64(int16(rAdd)) 785 } 786 if addendSize == 4 { 787 rAdd = int64(int32(rAdd)) 788 } 789 790 r, _ := sb.AddRel(rType) 791 r.SetOff(rOff) 792 r.SetSiz(rSize) 793 r.SetSym(rSym) 794 r.SetAdd(rAdd) 795 } 796 797 sb.SortRelocs() // just in case 798 } 799 800 return textp, ehdrFlags, nil 801 } 802 803 func section(elfobj *ElfObj, name string) *ElfSect { 804 for i := 0; uint(i) < elfobj.nsect; i++ { 805 if elfobj.sect[i].name != "" && name != "" && elfobj.sect[i].name == name { 806 return &elfobj.sect[i] 807 } 808 } 809 return nil 810 } 811 812 func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) { 813 if sect.base != nil { 814 return nil 815 } 816 817 if sect.off+sect.size > uint64(elfobj.length) { 818 err = fmt.Errorf("elf section past end of file") 819 return err 820 } 821 822 elfobj.f.MustSeek(int64(uint64(elfobj.base)+sect.off), 0) 823 sect.base, sect.readOnlyMem, err = elfobj.f.Slice(uint64(sect.size)) 824 if err != nil { 825 return fmt.Errorf("short read: %v", err) 826 } 827 828 return nil 829 } 830 831 func readelfsym(newSym, lookup func(string, int) loader.Sym, l *loader.Loader, arch *sys.Arch, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) { 832 if i >= elfobj.nsymtab || i < 0 { 833 err = fmt.Errorf("invalid elf symbol index") 834 return err 835 } 836 837 if i == 0 { 838 return fmt.Errorf("readym: read null symbol!") 839 } 840 841 if elfobj.is64 != 0 { 842 b := new(elf.Sym64) 843 binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym64Size:(i+1)*elf.Sym64Size]), elfobj.e, b) 844 elfsym.name = cstring(elfobj.symstr.base[b.Name:]) 845 elfsym.value = b.Value 846 elfsym.size = b.Size 847 elfsym.shndx = elf.SectionIndex(b.Shndx) 848 elfsym.bind = elf.ST_BIND(b.Info) 849 elfsym.type_ = elf.ST_TYPE(b.Info) 850 elfsym.other = b.Other 851 } else { 852 b := new(elf.Sym32) 853 binary.Read(bytes.NewReader(elfobj.symtab.base[i*elf.Sym32Size:(i+1)*elf.Sym32Size]), elfobj.e, b) 854 elfsym.name = cstring(elfobj.symstr.base[b.Name:]) 855 elfsym.value = uint64(b.Value) 856 elfsym.size = uint64(b.Size) 857 elfsym.shndx = elf.SectionIndex(b.Shndx) 858 elfsym.bind = elf.ST_BIND(b.Info) 859 elfsym.type_ = elf.ST_TYPE(b.Info) 860 elfsym.other = b.Other 861 } 862 863 var s loader.Sym 864 865 if elfsym.name == "_GLOBAL_OFFSET_TABLE_" { 866 elfsym.name = ".got" 867 } 868 if elfsym.name == ".TOC." { 869 // Magic symbol on ppc64. Will be set to this object 870 // file's .got+0x8000. 871 elfsym.bind = elf.STB_LOCAL 872 } 873 874 switch elfsym.type_ { 875 case elf.STT_SECTION: 876 s = elfobj.sect[elfsym.shndx].sym 877 878 case elf.STT_OBJECT, elf.STT_FUNC, elf.STT_NOTYPE, elf.STT_COMMON: 879 switch elfsym.bind { 880 case elf.STB_GLOBAL: 881 if needSym != 0 { 882 s = lookup(elfsym.name, 0) 883 884 // for global scoped hidden symbols we should insert it into 885 // symbol hash table, but mark them as hidden. 886 // __i686.get_pc_thunk.bx is allowed to be duplicated, to 887 // workaround that we set dupok. 888 // TODO(minux): correctly handle __i686.get_pc_thunk.bx without 889 // set dupok generally. See https://golang.org/cl/5823055 890 // comment #5 for details. 891 if s != 0 && elfsym.other == 2 { 892 if !l.IsExternal(s) { 893 l.MakeSymbolUpdater(s) 894 } 895 l.SetAttrDuplicateOK(s, true) 896 l.SetAttrVisibilityHidden(s, true) 897 } 898 } 899 900 case elf.STB_LOCAL: 901 if (arch.Family == sys.ARM || arch.Family == sys.ARM64) && (strings.HasPrefix(elfsym.name, "$a") || strings.HasPrefix(elfsym.name, "$d") || strings.HasPrefix(elfsym.name, "$x")) { 902 // binutils for arm and arm64 generate these mapping 903 // symbols, ignore these 904 break 905 } 906 907 if elfsym.name == ".TOC." { 908 // We need to be able to look this up, 909 // so put it in the hash table. 910 if needSym != 0 { 911 s = lookup(elfsym.name, localSymVersion) 912 l.SetAttrVisibilityHidden(s, true) 913 } 914 break 915 } 916 917 if needSym != 0 { 918 // local names and hidden global names are unique 919 // and should only be referenced by their index, not name, so we 920 // don't bother to add them into the hash table 921 // FIXME: pass empty string here for name? This would 922 // reduce mem use, but also (possibly) make it harder 923 // to debug problems. 924 s = newSym(elfsym.name, localSymVersion) 925 l.SetAttrVisibilityHidden(s, true) 926 } 927 928 case elf.STB_WEAK: 929 if needSym != 0 { 930 s = lookup(elfsym.name, 0) 931 if elfsym.other == 2 { 932 l.SetAttrVisibilityHidden(s, true) 933 } 934 935 // Allow weak symbols to be duplicated when already defined. 936 if l.OuterSym(s) != 0 { 937 l.SetAttrDuplicateOK(s, true) 938 } 939 } 940 941 default: 942 err = fmt.Errorf("%s: invalid symbol binding %d", elfsym.name, elfsym.bind) 943 return err 944 } 945 } 946 947 if s != 0 && l.SymType(s) == 0 && elfsym.type_ != elf.STT_SECTION { 948 sb := l.MakeSymbolUpdater(s) 949 sb.SetType(sym.SXREF) 950 } 951 elfsym.sym = s 952 953 return nil 954 } 955 956 // Return the size of the relocated field, and the size of the addend as the first 957 // and second values. Note, the addend may be larger than the relocation field in 958 // some cases when a relocated value is split across multiple relocations. 959 func relSize(arch *sys.Arch, pn string, elftype uint32) (uint8, uint8, error) { 960 // TODO(mdempsky): Replace this with a struct-valued switch statement 961 // once golang.org/issue/15164 is fixed or found to not impair cmd/link 962 // performance. 963 964 const ( 965 AMD64 = uint32(sys.AMD64) 966 ARM = uint32(sys.ARM) 967 ARM64 = uint32(sys.ARM64) 968 I386 = uint32(sys.I386) 969 LOONG64 = uint32(sys.Loong64) 970 MIPS = uint32(sys.MIPS) 971 MIPS64 = uint32(sys.MIPS64) 972 PPC64 = uint32(sys.PPC64) 973 RISCV64 = uint32(sys.RISCV64) 974 S390X = uint32(sys.S390X) 975 ) 976 977 switch uint32(arch.Family) | elftype<<16 { 978 default: 979 return 0, 0, fmt.Errorf("%s: unknown relocation type %d; compiled without -fpic?", pn, elftype) 980 981 case MIPS | uint32(elf.R_MIPS_HI16)<<16, 982 MIPS | uint32(elf.R_MIPS_LO16)<<16, 983 MIPS | uint32(elf.R_MIPS_GOT16)<<16, 984 MIPS | uint32(elf.R_MIPS_GOT_HI16)<<16, 985 MIPS | uint32(elf.R_MIPS_GOT_LO16)<<16, 986 MIPS | uint32(elf.R_MIPS_GPREL16)<<16, 987 MIPS | uint32(elf.R_MIPS_GOT_PAGE)<<16, 988 MIPS | uint32(elf.R_MIPS_JALR)<<16, 989 MIPS | uint32(elf.R_MIPS_GOT_OFST)<<16, 990 MIPS64 | uint32(elf.R_MIPS_HI16)<<16, 991 MIPS64 | uint32(elf.R_MIPS_LO16)<<16, 992 MIPS64 | uint32(elf.R_MIPS_GOT16)<<16, 993 MIPS64 | uint32(elf.R_MIPS_GOT_HI16)<<16, 994 MIPS64 | uint32(elf.R_MIPS_GOT_LO16)<<16, 995 MIPS64 | uint32(elf.R_MIPS_GPREL16)<<16, 996 MIPS64 | uint32(elf.R_MIPS_GOT_PAGE)<<16, 997 MIPS64 | uint32(elf.R_MIPS_JALR)<<16, 998 MIPS64 | uint32(elf.R_MIPS_GOT_OFST)<<16, 999 MIPS64 | uint32(elf.R_MIPS_CALL16)<<16, 1000 MIPS64 | uint32(elf.R_MIPS_GPREL32)<<16, 1001 MIPS64 | uint32(elf.R_MIPS_64)<<16, 1002 MIPS64 | uint32(elf.R_MIPS_GOT_DISP)<<16: 1003 return 4, 4, nil 1004 1005 case LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_PCREL)<<16, 1006 LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_GPREL)<<16, 1007 LOONG64 | uint32(elf.R_LARCH_SOP_PUSH_ABSOLUTE)<<16, 1008 LOONG64 | uint32(elf.R_LARCH_MARK_LA)<<16, 1009 LOONG64 | uint32(elf.R_LARCH_SOP_POP_32_S_0_10_10_16_S2)<<16, 1010 LOONG64 | uint32(elf.R_LARCH_64)<<16, 1011 LOONG64 | uint32(elf.R_LARCH_MARK_PCREL)<<16, 1012 LOONG64 | uint32(elf.R_LARCH_32_PCREL)<<16: 1013 return 4, 4, nil 1014 1015 case S390X | uint32(elf.R_390_8)<<16: 1016 return 1, 1, nil 1017 1018 case PPC64 | uint32(elf.R_PPC64_TOC16)<<16, 1019 S390X | uint32(elf.R_390_16)<<16, 1020 S390X | uint32(elf.R_390_GOT16)<<16, 1021 S390X | uint32(elf.R_390_PC16)<<16, 1022 S390X | uint32(elf.R_390_PC16DBL)<<16, 1023 S390X | uint32(elf.R_390_PLT16DBL)<<16: 1024 return 2, 2, nil 1025 1026 case ARM | uint32(elf.R_ARM_ABS32)<<16, 1027 ARM | uint32(elf.R_ARM_GOT32)<<16, 1028 ARM | uint32(elf.R_ARM_PLT32)<<16, 1029 ARM | uint32(elf.R_ARM_GOTOFF)<<16, 1030 ARM | uint32(elf.R_ARM_GOTPC)<<16, 1031 ARM | uint32(elf.R_ARM_THM_PC22)<<16, 1032 ARM | uint32(elf.R_ARM_REL32)<<16, 1033 ARM | uint32(elf.R_ARM_CALL)<<16, 1034 ARM | uint32(elf.R_ARM_V4BX)<<16, 1035 ARM | uint32(elf.R_ARM_GOT_PREL)<<16, 1036 ARM | uint32(elf.R_ARM_PC24)<<16, 1037 ARM | uint32(elf.R_ARM_JUMP24)<<16, 1038 ARM64 | uint32(elf.R_AARCH64_CALL26)<<16, 1039 ARM64 | uint32(elf.R_AARCH64_ADR_GOT_PAGE)<<16, 1040 ARM64 | uint32(elf.R_AARCH64_LD64_GOT_LO12_NC)<<16, 1041 ARM64 | uint32(elf.R_AARCH64_ADR_PREL_PG_HI21)<<16, 1042 ARM64 | uint32(elf.R_AARCH64_ADD_ABS_LO12_NC)<<16, 1043 ARM64 | uint32(elf.R_AARCH64_LDST8_ABS_LO12_NC)<<16, 1044 ARM64 | uint32(elf.R_AARCH64_LDST16_ABS_LO12_NC)<<16, 1045 ARM64 | uint32(elf.R_AARCH64_LDST32_ABS_LO12_NC)<<16, 1046 ARM64 | uint32(elf.R_AARCH64_LDST64_ABS_LO12_NC)<<16, 1047 ARM64 | uint32(elf.R_AARCH64_LDST128_ABS_LO12_NC)<<16, 1048 ARM64 | uint32(elf.R_AARCH64_PREL32)<<16, 1049 ARM64 | uint32(elf.R_AARCH64_JUMP26)<<16, 1050 AMD64 | uint32(elf.R_X86_64_PC32)<<16, 1051 AMD64 | uint32(elf.R_X86_64_PLT32)<<16, 1052 AMD64 | uint32(elf.R_X86_64_GOTPCREL)<<16, 1053 AMD64 | uint32(elf.R_X86_64_GOTPCRELX)<<16, 1054 AMD64 | uint32(elf.R_X86_64_REX_GOTPCRELX)<<16, 1055 I386 | uint32(elf.R_386_32)<<16, 1056 I386 | uint32(elf.R_386_PC32)<<16, 1057 I386 | uint32(elf.R_386_GOT32)<<16, 1058 I386 | uint32(elf.R_386_PLT32)<<16, 1059 I386 | uint32(elf.R_386_GOTOFF)<<16, 1060 I386 | uint32(elf.R_386_GOTPC)<<16, 1061 I386 | uint32(elf.R_386_GOT32X)<<16, 1062 PPC64 | uint32(elf.R_PPC64_REL24)<<16, 1063 PPC64 | uint32(elf.R_PPC_REL32)<<16, 1064 S390X | uint32(elf.R_390_32)<<16, 1065 S390X | uint32(elf.R_390_PC32)<<16, 1066 S390X | uint32(elf.R_390_GOT32)<<16, 1067 S390X | uint32(elf.R_390_PLT32)<<16, 1068 S390X | uint32(elf.R_390_PC32DBL)<<16, 1069 S390X | uint32(elf.R_390_PLT32DBL)<<16, 1070 S390X | uint32(elf.R_390_GOTPCDBL)<<16, 1071 S390X | uint32(elf.R_390_GOTENT)<<16: 1072 return 4, 4, nil 1073 1074 case AMD64 | uint32(elf.R_X86_64_64)<<16, 1075 AMD64 | uint32(elf.R_X86_64_PC64)<<16, 1076 ARM64 | uint32(elf.R_AARCH64_ABS64)<<16, 1077 ARM64 | uint32(elf.R_AARCH64_PREL64)<<16, 1078 PPC64 | uint32(elf.R_PPC64_ADDR64)<<16, 1079 S390X | uint32(elf.R_390_GLOB_DAT)<<16, 1080 S390X | uint32(elf.R_390_RELATIVE)<<16, 1081 S390X | uint32(elf.R_390_GOTOFF)<<16, 1082 S390X | uint32(elf.R_390_GOTPC)<<16, 1083 S390X | uint32(elf.R_390_64)<<16, 1084 S390X | uint32(elf.R_390_PC64)<<16, 1085 S390X | uint32(elf.R_390_GOT64)<<16, 1086 S390X | uint32(elf.R_390_PLT64)<<16: 1087 return 8, 8, nil 1088 1089 case RISCV64 | uint32(elf.R_RISCV_SET6)<<16, 1090 RISCV64 | uint32(elf.R_RISCV_SUB6)<<16, 1091 RISCV64 | uint32(elf.R_RISCV_SET8)<<16, 1092 RISCV64 | uint32(elf.R_RISCV_SUB8)<<16: 1093 return 1, 1, nil 1094 1095 case RISCV64 | uint32(elf.R_RISCV_RVC_BRANCH)<<16, 1096 RISCV64 | uint32(elf.R_RISCV_RVC_JUMP)<<16, 1097 RISCV64 | uint32(elf.R_RISCV_SET16)<<16, 1098 RISCV64 | uint32(elf.R_RISCV_SUB16)<<16: 1099 return 2, 2, nil 1100 1101 case RISCV64 | uint32(elf.R_RISCV_32)<<16, 1102 RISCV64 | uint32(elf.R_RISCV_BRANCH)<<16, 1103 RISCV64 | uint32(elf.R_RISCV_HI20)<<16, 1104 RISCV64 | uint32(elf.R_RISCV_LO12_I)<<16, 1105 RISCV64 | uint32(elf.R_RISCV_LO12_S)<<16, 1106 RISCV64 | uint32(elf.R_RISCV_GOT_HI20)<<16, 1107 RISCV64 | uint32(elf.R_RISCV_PCREL_HI20)<<16, 1108 RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_I)<<16, 1109 RISCV64 | uint32(elf.R_RISCV_PCREL_LO12_S)<<16, 1110 RISCV64 | uint32(elf.R_RISCV_ADD32)<<16, 1111 RISCV64 | uint32(elf.R_RISCV_SET32)<<16, 1112 RISCV64 | uint32(elf.R_RISCV_SUB32)<<16, 1113 RISCV64 | uint32(elf.R_RISCV_32_PCREL)<<16, 1114 RISCV64 | uint32(elf.R_RISCV_RELAX)<<16: 1115 return 4, 4, nil 1116 1117 case RISCV64 | uint32(elf.R_RISCV_64)<<16, 1118 RISCV64 | uint32(elf.R_RISCV_CALL)<<16, 1119 RISCV64 | uint32(elf.R_RISCV_CALL_PLT)<<16: 1120 return 8, 8, nil 1121 1122 case PPC64 | uint32(elf.R_PPC64_TOC16_LO)<<16, 1123 PPC64 | uint32(elf.R_PPC64_TOC16_HI)<<16, 1124 PPC64 | uint32(elf.R_PPC64_TOC16_HA)<<16, 1125 PPC64 | uint32(elf.R_PPC64_TOC16_DS)<<16, 1126 PPC64 | uint32(elf.R_PPC64_TOC16_LO_DS)<<16, 1127 PPC64 | uint32(elf.R_PPC64_REL16_LO)<<16, 1128 PPC64 | uint32(elf.R_PPC64_REL16_HI)<<16, 1129 PPC64 | uint32(elf.R_PPC64_REL16_HA)<<16, 1130 PPC64 | uint32(elf.R_PPC64_PLT16_HA)<<16, 1131 PPC64 | uint32(elf.R_PPC64_PLT16_LO_DS)<<16: 1132 return 2, 4, nil 1133 1134 // PPC64 inline PLT sequence hint relocations (-fno-plt) 1135 // These are informational annotations to assist linker optimizations. 1136 case PPC64 | uint32(elf.R_PPC64_PLTSEQ)<<16, 1137 PPC64 | uint32(elf.R_PPC64_PLTCALL)<<16, 1138 PPC64 | uint32(elf.R_PPC64_PLTCALL_NOTOC)<<16, 1139 PPC64 | uint32(elf.R_PPC64_PLTSEQ_NOTOC)<<16: 1140 return 0, 0, nil 1141 1142 } 1143 } 1144 1145 func cstring(x []byte) string { 1146 i := bytes.IndexByte(x, '\x00') 1147 if i >= 0 { 1148 x = x[:i] 1149 } 1150 return string(x) 1151 }