github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/link/internal/ld/elf.go (about) 1 // Copyright 2009 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 ld 6 7 import ( 8 "github.com/gagliardetto/golang-go/cmd/internal/objabi" 9 "github.com/gagliardetto/golang-go/cmd/internal/sys" 10 "github.com/gagliardetto/golang-go/cmd/link/internal/sym" 11 "crypto/sha1" 12 "encoding/binary" 13 "encoding/hex" 14 "io" 15 "path/filepath" 16 "sort" 17 "strings" 18 ) 19 20 /* 21 * Derived from: 22 * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $ 23 * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $ 24 * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $ 25 * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $ 26 * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $ 27 * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $ 28 * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $ 29 * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $ 30 * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $ 31 * 32 * Copyright (c) 1996-1998 John D. Polstra. All rights reserved. 33 * Copyright (c) 2001 David E. O'Brien 34 * Portions Copyright 2009 The Go Authors. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 * SUCH DAMAGE. 56 * 57 */ 58 59 /* 60 * ELF definitions that are independent of architecture or word size. 61 */ 62 63 /* 64 * Note header. The ".note" section contains an array of notes. Each 65 * begins with this header, aligned to a word boundary. Immediately 66 * following the note header is n_namesz bytes of name, padded to the 67 * next word boundary. Then comes n_descsz bytes of descriptor, again 68 * padded to a word boundary. The values of n_namesz and n_descsz do 69 * not include the padding. 70 */ 71 type elfNote struct { 72 nNamesz uint32 73 nDescsz uint32 74 nType uint32 75 } 76 77 const ( 78 EI_MAG0 = 0 79 EI_MAG1 = 1 80 EI_MAG2 = 2 81 EI_MAG3 = 3 82 EI_CLASS = 4 83 EI_DATA = 5 84 EI_VERSION = 6 85 EI_OSABI = 7 86 EI_ABIVERSION = 8 87 OLD_EI_BRAND = 8 88 EI_PAD = 9 89 EI_NIDENT = 16 90 ELFMAG0 = 0x7f 91 ELFMAG1 = 'E' 92 ELFMAG2 = 'L' 93 ELFMAG3 = 'F' 94 SELFMAG = 4 95 EV_NONE = 0 96 EV_CURRENT = 1 97 ELFCLASSNONE = 0 98 ELFCLASS32 = 1 99 ELFCLASS64 = 2 100 ELFDATANONE = 0 101 ELFDATA2LSB = 1 102 ELFDATA2MSB = 2 103 ELFOSABI_NONE = 0 104 ELFOSABI_HPUX = 1 105 ELFOSABI_NETBSD = 2 106 ELFOSABI_LINUX = 3 107 ELFOSABI_HURD = 4 108 ELFOSABI_86OPEN = 5 109 ELFOSABI_SOLARIS = 6 110 ELFOSABI_AIX = 7 111 ELFOSABI_IRIX = 8 112 ELFOSABI_FREEBSD = 9 113 ELFOSABI_TRU64 = 10 114 ELFOSABI_MODESTO = 11 115 ELFOSABI_OPENBSD = 12 116 ELFOSABI_OPENVMS = 13 117 ELFOSABI_NSK = 14 118 ELFOSABI_ARM = 97 119 ELFOSABI_STANDALONE = 255 120 ELFOSABI_SYSV = ELFOSABI_NONE 121 ELFOSABI_MONTEREY = ELFOSABI_AIX 122 ET_NONE = 0 123 ET_REL = 1 124 ET_EXEC = 2 125 ET_DYN = 3 126 ET_CORE = 4 127 ET_LOOS = 0xfe00 128 ET_HIOS = 0xfeff 129 ET_LOPROC = 0xff00 130 ET_HIPROC = 0xffff 131 EM_NONE = 0 132 EM_M32 = 1 133 EM_SPARC = 2 134 EM_386 = 3 135 EM_68K = 4 136 EM_88K = 5 137 EM_860 = 7 138 EM_MIPS = 8 139 EM_S370 = 9 140 EM_MIPS_RS3_LE = 10 141 EM_PARISC = 15 142 EM_VPP500 = 17 143 EM_SPARC32PLUS = 18 144 EM_960 = 19 145 EM_PPC = 20 146 EM_PPC64 = 21 147 EM_S390 = 22 148 EM_V800 = 36 149 EM_FR20 = 37 150 EM_RH32 = 38 151 EM_RCE = 39 152 EM_ARM = 40 153 EM_SH = 42 154 EM_SPARCV9 = 43 155 EM_TRICORE = 44 156 EM_ARC = 45 157 EM_H8_300 = 46 158 EM_H8_300H = 47 159 EM_H8S = 48 160 EM_H8_500 = 49 161 EM_IA_64 = 50 162 EM_MIPS_X = 51 163 EM_COLDFIRE = 52 164 EM_68HC12 = 53 165 EM_MMA = 54 166 EM_PCP = 55 167 EM_NCPU = 56 168 EM_NDR1 = 57 169 EM_STARCORE = 58 170 EM_ME16 = 59 171 EM_ST100 = 60 172 EM_TINYJ = 61 173 EM_X86_64 = 62 174 EM_AARCH64 = 183 175 EM_486 = 6 176 EM_MIPS_RS4_BE = 10 177 EM_ALPHA_STD = 41 178 EM_ALPHA = 0x9026 179 EM_RISCV = 243 180 SHN_UNDEF = 0 181 SHN_LORESERVE = 0xff00 182 SHN_LOPROC = 0xff00 183 SHN_HIPROC = 0xff1f 184 SHN_LOOS = 0xff20 185 SHN_HIOS = 0xff3f 186 SHN_ABS = 0xfff1 187 SHN_COMMON = 0xfff2 188 SHN_XINDEX = 0xffff 189 SHN_HIRESERVE = 0xffff 190 SHT_NULL = 0 191 SHT_PROGBITS = 1 192 SHT_SYMTAB = 2 193 SHT_STRTAB = 3 194 SHT_RELA = 4 195 SHT_HASH = 5 196 SHT_DYNAMIC = 6 197 SHT_NOTE = 7 198 SHT_NOBITS = 8 199 SHT_REL = 9 200 SHT_SHLIB = 10 201 SHT_DYNSYM = 11 202 SHT_INIT_ARRAY = 14 203 SHT_FINI_ARRAY = 15 204 SHT_PREINIT_ARRAY = 16 205 SHT_GROUP = 17 206 SHT_SYMTAB_SHNDX = 18 207 SHT_LOOS = 0x60000000 208 SHT_HIOS = 0x6fffffff 209 SHT_GNU_VERDEF = 0x6ffffffd 210 SHT_GNU_VERNEED = 0x6ffffffe 211 SHT_GNU_VERSYM = 0x6fffffff 212 SHT_LOPROC = 0x70000000 213 SHT_ARM_ATTRIBUTES = 0x70000003 214 SHT_HIPROC = 0x7fffffff 215 SHT_LOUSER = 0x80000000 216 SHT_HIUSER = 0xffffffff 217 SHF_WRITE = 0x1 218 SHF_ALLOC = 0x2 219 SHF_EXECINSTR = 0x4 220 SHF_MERGE = 0x10 221 SHF_STRINGS = 0x20 222 SHF_INFO_LINK = 0x40 223 SHF_LINK_ORDER = 0x80 224 SHF_OS_NONCONFORMING = 0x100 225 SHF_GROUP = 0x200 226 SHF_TLS = 0x400 227 SHF_MASKOS = 0x0ff00000 228 SHF_MASKPROC = 0xf0000000 229 PT_NULL = 0 230 PT_LOAD = 1 231 PT_DYNAMIC = 2 232 PT_INTERP = 3 233 PT_NOTE = 4 234 PT_SHLIB = 5 235 PT_PHDR = 6 236 PT_TLS = 7 237 PT_LOOS = 0x60000000 238 PT_HIOS = 0x6fffffff 239 PT_LOPROC = 0x70000000 240 PT_HIPROC = 0x7fffffff 241 PT_GNU_STACK = 0x6474e551 242 PT_GNU_RELRO = 0x6474e552 243 PT_PAX_FLAGS = 0x65041580 244 PT_SUNWSTACK = 0x6ffffffb 245 PF_X = 0x1 246 PF_W = 0x2 247 PF_R = 0x4 248 PF_MASKOS = 0x0ff00000 249 PF_MASKPROC = 0xf0000000 250 DT_NULL = 0 251 DT_NEEDED = 1 252 DT_PLTRELSZ = 2 253 DT_PLTGOT = 3 254 DT_HASH = 4 255 DT_STRTAB = 5 256 DT_SYMTAB = 6 257 DT_RELA = 7 258 DT_RELASZ = 8 259 DT_RELAENT = 9 260 DT_STRSZ = 10 261 DT_SYMENT = 11 262 DT_INIT = 12 263 DT_FINI = 13 264 DT_SONAME = 14 265 DT_RPATH = 15 266 DT_SYMBOLIC = 16 267 DT_REL = 17 268 DT_RELSZ = 18 269 DT_RELENT = 19 270 DT_PLTREL = 20 271 DT_DEBUG = 21 272 DT_TEXTREL = 22 273 DT_JMPREL = 23 274 DT_BIND_NOW = 24 275 DT_INIT_ARRAY = 25 276 DT_FINI_ARRAY = 26 277 DT_INIT_ARRAYSZ = 27 278 DT_FINI_ARRAYSZ = 28 279 DT_RUNPATH = 29 280 DT_FLAGS = 30 281 DT_ENCODING = 32 282 DT_PREINIT_ARRAY = 32 283 DT_PREINIT_ARRAYSZ = 33 284 DT_LOOS = 0x6000000d 285 DT_HIOS = 0x6ffff000 286 DT_LOPROC = 0x70000000 287 DT_HIPROC = 0x7fffffff 288 DT_VERNEED = 0x6ffffffe 289 DT_VERNEEDNUM = 0x6fffffff 290 DT_VERSYM = 0x6ffffff0 291 DT_PPC64_GLINK = DT_LOPROC + 0 292 DT_PPC64_OPT = DT_LOPROC + 3 293 DF_ORIGIN = 0x0001 294 DF_SYMBOLIC = 0x0002 295 DF_TEXTREL = 0x0004 296 DF_BIND_NOW = 0x0008 297 DF_STATIC_TLS = 0x0010 298 NT_PRSTATUS = 1 299 NT_FPREGSET = 2 300 NT_PRPSINFO = 3 301 STB_LOCAL = 0 302 STB_GLOBAL = 1 303 STB_WEAK = 2 304 STB_LOOS = 10 305 STB_HIOS = 12 306 STB_LOPROC = 13 307 STB_HIPROC = 15 308 STT_NOTYPE = 0 309 STT_OBJECT = 1 310 STT_FUNC = 2 311 STT_SECTION = 3 312 STT_FILE = 4 313 STT_COMMON = 5 314 STT_TLS = 6 315 STT_LOOS = 10 316 STT_HIOS = 12 317 STT_LOPROC = 13 318 STT_HIPROC = 15 319 STV_DEFAULT = 0x0 320 STV_INTERNAL = 0x1 321 STV_HIDDEN = 0x2 322 STV_PROTECTED = 0x3 323 STN_UNDEF = 0 324 ) 325 326 /* For accessing the fields of r_info. */ 327 328 /* For constructing r_info from field values. */ 329 330 /* 331 * Relocation types. 332 */ 333 const ( 334 ARM_MAGIC_TRAMP_NUMBER = 0x5c000003 335 ) 336 337 /* 338 * Symbol table entries. 339 */ 340 341 /* For accessing the fields of st_info. */ 342 343 /* For constructing st_info from field values. */ 344 345 /* For accessing the fields of st_other. */ 346 347 /* 348 * ELF header. 349 */ 350 type ElfEhdr struct { 351 ident [EI_NIDENT]uint8 352 type_ uint16 353 machine uint16 354 version uint32 355 entry uint64 356 phoff uint64 357 shoff uint64 358 flags uint32 359 ehsize uint16 360 phentsize uint16 361 phnum uint16 362 shentsize uint16 363 shnum uint16 364 shstrndx uint16 365 } 366 367 /* 368 * Section header. 369 */ 370 type ElfShdr struct { 371 name uint32 372 type_ uint32 373 flags uint64 374 addr uint64 375 off uint64 376 size uint64 377 link uint32 378 info uint32 379 addralign uint64 380 entsize uint64 381 shnum int 382 } 383 384 /* 385 * Program header. 386 */ 387 type ElfPhdr struct { 388 type_ uint32 389 flags uint32 390 off uint64 391 vaddr uint64 392 paddr uint64 393 filesz uint64 394 memsz uint64 395 align uint64 396 } 397 398 /* For accessing the fields of r_info. */ 399 400 /* For constructing r_info from field values. */ 401 402 /* 403 * Symbol table entries. 404 */ 405 406 /* For accessing the fields of st_info. */ 407 408 /* For constructing st_info from field values. */ 409 410 /* For accessing the fields of st_other. */ 411 412 /* 413 * Go linker interface 414 */ 415 const ( 416 ELF64HDRSIZE = 64 417 ELF64PHDRSIZE = 56 418 ELF64SHDRSIZE = 64 419 ELF64RELSIZE = 16 420 ELF64RELASIZE = 24 421 ELF64SYMSIZE = 24 422 ELF32HDRSIZE = 52 423 ELF32PHDRSIZE = 32 424 ELF32SHDRSIZE = 40 425 ELF32SYMSIZE = 16 426 ELF32RELSIZE = 8 427 ) 428 429 /* 430 * The interface uses the 64-bit structures always, 431 * to avoid code duplication. The writers know how to 432 * marshal a 32-bit representation from the 64-bit structure. 433 */ 434 435 var Elfstrdat []byte 436 437 /* 438 * Total amount of space to reserve at the start of the file 439 * for Header, PHeaders, SHeaders, and interp. 440 * May waste some. 441 * On FreeBSD, cannot be larger than a page. 442 */ 443 const ( 444 ELFRESERVE = 4096 445 ) 446 447 /* 448 * We use the 64-bit data structures on both 32- and 64-bit machines 449 * in order to write the code just once. The 64-bit data structure is 450 * written in the 32-bit format on the 32-bit machines. 451 */ 452 const ( 453 NSECT = 400 454 ) 455 456 var ( 457 Nelfsym = 1 458 459 elf64 bool 460 // Either ".rel" or ".rela" depending on which type of relocation the 461 // target platform uses. 462 elfRelType string 463 464 ehdr ElfEhdr 465 phdr [NSECT]*ElfPhdr 466 shdr [NSECT]*ElfShdr 467 468 interp string 469 ) 470 471 type Elfstring struct { 472 s string 473 off int 474 } 475 476 var elfstr [100]Elfstring 477 478 var nelfstr int 479 480 var buildinfo []byte 481 482 /* 483 Initialize the global variable that describes the ELF header. It will be updated as 484 we write section and prog headers. 485 */ 486 func Elfinit(ctxt *Link) { 487 ctxt.IsELF = true 488 489 if ctxt.Arch.InFamily(sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X) { 490 elfRelType = ".rela" 491 } else { 492 elfRelType = ".rel" 493 } 494 495 switch ctxt.Arch.Family { 496 // 64-bit architectures 497 case sys.PPC64, sys.S390X: 498 if ctxt.Arch.ByteOrder == binary.BigEndian { 499 ehdr.flags = 1 /* Version 1 ABI */ 500 } else { 501 ehdr.flags = 2 /* Version 2 ABI */ 502 } 503 fallthrough 504 case sys.AMD64, sys.ARM64, sys.MIPS64, sys.RISCV64: 505 if ctxt.Arch.Family == sys.MIPS64 { 506 ehdr.flags = 0x20000004 /* MIPS 3 CPIC */ 507 } 508 elf64 = true 509 510 ehdr.phoff = ELF64HDRSIZE /* Must be ELF64HDRSIZE: first PHdr must follow ELF header */ 511 ehdr.shoff = ELF64HDRSIZE /* Will move as we add PHeaders */ 512 ehdr.ehsize = ELF64HDRSIZE /* Must be ELF64HDRSIZE */ 513 ehdr.phentsize = ELF64PHDRSIZE /* Must be ELF64PHDRSIZE */ 514 ehdr.shentsize = ELF64SHDRSIZE /* Must be ELF64SHDRSIZE */ 515 516 // 32-bit architectures 517 case sys.ARM, sys.MIPS: 518 if ctxt.Arch.Family == sys.ARM { 519 // we use EABI on linux/arm, freebsd/arm, netbsd/arm. 520 if ctxt.HeadType == objabi.Hlinux || ctxt.HeadType == objabi.Hfreebsd || ctxt.HeadType == objabi.Hnetbsd { 521 // We set a value here that makes no indication of which 522 // float ABI the object uses, because this is information 523 // used by the dynamic linker to compare executables and 524 // shared libraries -- so it only matters for cgo calls, and 525 // the information properly comes from the object files 526 // produced by the host C compiler. parseArmAttributes in 527 // ldelf.go reads that information and updates this field as 528 // appropriate. 529 ehdr.flags = 0x5000002 // has entry point, Version5 EABI 530 } 531 } else if ctxt.Arch.Family == sys.MIPS { 532 ehdr.flags = 0x50001004 /* MIPS 32 CPIC O32*/ 533 } 534 fallthrough 535 default: 536 ehdr.phoff = ELF32HDRSIZE 537 /* Must be ELF32HDRSIZE: first PHdr must follow ELF header */ 538 ehdr.shoff = ELF32HDRSIZE /* Will move as we add PHeaders */ 539 ehdr.ehsize = ELF32HDRSIZE /* Must be ELF32HDRSIZE */ 540 ehdr.phentsize = ELF32PHDRSIZE /* Must be ELF32PHDRSIZE */ 541 ehdr.shentsize = ELF32SHDRSIZE /* Must be ELF32SHDRSIZE */ 542 } 543 } 544 545 // Make sure PT_LOAD is aligned properly and 546 // that there is no gap, 547 // correct ELF loaders will do this implicitly, 548 // but buggy ELF loaders like the one in some 549 // versions of QEMU and UPX won't. 550 func fixElfPhdr(e *ElfPhdr) { 551 frag := int(e.vaddr & (e.align - 1)) 552 553 e.off -= uint64(frag) 554 e.vaddr -= uint64(frag) 555 e.paddr -= uint64(frag) 556 e.filesz += uint64(frag) 557 e.memsz += uint64(frag) 558 } 559 560 func elf64phdr(out *OutBuf, e *ElfPhdr) { 561 if e.type_ == PT_LOAD { 562 fixElfPhdr(e) 563 } 564 565 out.Write32(e.type_) 566 out.Write32(e.flags) 567 out.Write64(e.off) 568 out.Write64(e.vaddr) 569 out.Write64(e.paddr) 570 out.Write64(e.filesz) 571 out.Write64(e.memsz) 572 out.Write64(e.align) 573 } 574 575 func elf32phdr(out *OutBuf, e *ElfPhdr) { 576 if e.type_ == PT_LOAD { 577 fixElfPhdr(e) 578 } 579 580 out.Write32(e.type_) 581 out.Write32(uint32(e.off)) 582 out.Write32(uint32(e.vaddr)) 583 out.Write32(uint32(e.paddr)) 584 out.Write32(uint32(e.filesz)) 585 out.Write32(uint32(e.memsz)) 586 out.Write32(e.flags) 587 out.Write32(uint32(e.align)) 588 } 589 590 func elf64shdr(out *OutBuf, e *ElfShdr) { 591 out.Write32(e.name) 592 out.Write32(e.type_) 593 out.Write64(e.flags) 594 out.Write64(e.addr) 595 out.Write64(e.off) 596 out.Write64(e.size) 597 out.Write32(e.link) 598 out.Write32(e.info) 599 out.Write64(e.addralign) 600 out.Write64(e.entsize) 601 } 602 603 func elf32shdr(out *OutBuf, e *ElfShdr) { 604 out.Write32(e.name) 605 out.Write32(e.type_) 606 out.Write32(uint32(e.flags)) 607 out.Write32(uint32(e.addr)) 608 out.Write32(uint32(e.off)) 609 out.Write32(uint32(e.size)) 610 out.Write32(e.link) 611 out.Write32(e.info) 612 out.Write32(uint32(e.addralign)) 613 out.Write32(uint32(e.entsize)) 614 } 615 616 func elfwriteshdrs(out *OutBuf) uint32 { 617 if elf64 { 618 for i := 0; i < int(ehdr.shnum); i++ { 619 elf64shdr(out, shdr[i]) 620 } 621 return uint32(ehdr.shnum) * ELF64SHDRSIZE 622 } 623 624 for i := 0; i < int(ehdr.shnum); i++ { 625 elf32shdr(out, shdr[i]) 626 } 627 return uint32(ehdr.shnum) * ELF32SHDRSIZE 628 } 629 630 func elfsetstring(s *sym.Symbol, str string, off int) { 631 if nelfstr >= len(elfstr) { 632 Errorf(s, "too many elf strings") 633 errorexit() 634 } 635 636 elfstr[nelfstr].s = str 637 elfstr[nelfstr].off = off 638 nelfstr++ 639 } 640 641 func elfwritephdrs(out *OutBuf) uint32 { 642 if elf64 { 643 for i := 0; i < int(ehdr.phnum); i++ { 644 elf64phdr(out, phdr[i]) 645 } 646 return uint32(ehdr.phnum) * ELF64PHDRSIZE 647 } 648 649 for i := 0; i < int(ehdr.phnum); i++ { 650 elf32phdr(out, phdr[i]) 651 } 652 return uint32(ehdr.phnum) * ELF32PHDRSIZE 653 } 654 655 func newElfPhdr() *ElfPhdr { 656 e := new(ElfPhdr) 657 if ehdr.phnum >= NSECT { 658 Errorf(nil, "too many phdrs") 659 } else { 660 phdr[ehdr.phnum] = e 661 ehdr.phnum++ 662 } 663 if elf64 { 664 ehdr.shoff += ELF64PHDRSIZE 665 } else { 666 ehdr.shoff += ELF32PHDRSIZE 667 } 668 return e 669 } 670 671 func newElfShdr(name int64) *ElfShdr { 672 e := new(ElfShdr) 673 e.name = uint32(name) 674 e.shnum = int(ehdr.shnum) 675 if ehdr.shnum >= NSECT { 676 Errorf(nil, "too many shdrs") 677 } else { 678 shdr[ehdr.shnum] = e 679 ehdr.shnum++ 680 } 681 682 return e 683 } 684 685 func getElfEhdr() *ElfEhdr { 686 return &ehdr 687 } 688 689 func elf64writehdr(out *OutBuf) uint32 { 690 out.Write(ehdr.ident[:]) 691 out.Write16(ehdr.type_) 692 out.Write16(ehdr.machine) 693 out.Write32(ehdr.version) 694 out.Write64(ehdr.entry) 695 out.Write64(ehdr.phoff) 696 out.Write64(ehdr.shoff) 697 out.Write32(ehdr.flags) 698 out.Write16(ehdr.ehsize) 699 out.Write16(ehdr.phentsize) 700 out.Write16(ehdr.phnum) 701 out.Write16(ehdr.shentsize) 702 out.Write16(ehdr.shnum) 703 out.Write16(ehdr.shstrndx) 704 return ELF64HDRSIZE 705 } 706 707 func elf32writehdr(out *OutBuf) uint32 { 708 out.Write(ehdr.ident[:]) 709 out.Write16(ehdr.type_) 710 out.Write16(ehdr.machine) 711 out.Write32(ehdr.version) 712 out.Write32(uint32(ehdr.entry)) 713 out.Write32(uint32(ehdr.phoff)) 714 out.Write32(uint32(ehdr.shoff)) 715 out.Write32(ehdr.flags) 716 out.Write16(ehdr.ehsize) 717 out.Write16(ehdr.phentsize) 718 out.Write16(ehdr.phnum) 719 out.Write16(ehdr.shentsize) 720 out.Write16(ehdr.shnum) 721 out.Write16(ehdr.shstrndx) 722 return ELF32HDRSIZE 723 } 724 725 func elfwritehdr(out *OutBuf) uint32 { 726 if elf64 { 727 return elf64writehdr(out) 728 } 729 return elf32writehdr(out) 730 } 731 732 /* Taken directly from the definition document for ELF64 */ 733 func elfhash(name string) uint32 { 734 var h uint32 735 for i := 0; i < len(name); i++ { 736 h = (h << 4) + uint32(name[i]) 737 if g := h & 0xf0000000; g != 0 { 738 h ^= g >> 24 739 } 740 h &= 0x0fffffff 741 } 742 return h 743 } 744 745 func Elfwritedynent(ctxt *Link, s *sym.Symbol, tag int, val uint64) { 746 if elf64 { 747 s.AddUint64(ctxt.Arch, uint64(tag)) 748 s.AddUint64(ctxt.Arch, val) 749 } else { 750 s.AddUint32(ctxt.Arch, uint32(tag)) 751 s.AddUint32(ctxt.Arch, uint32(val)) 752 } 753 } 754 755 func elfwritedynentsym(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) { 756 Elfwritedynentsymplus(ctxt, s, tag, t, 0) 757 } 758 759 func Elfwritedynentsymplus(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol, add int64) { 760 if elf64 { 761 s.AddUint64(ctxt.Arch, uint64(tag)) 762 } else { 763 s.AddUint32(ctxt.Arch, uint32(tag)) 764 } 765 s.AddAddrPlus(ctxt.Arch, t, add) 766 } 767 768 func elfwritedynentsymsize(ctxt *Link, s *sym.Symbol, tag int, t *sym.Symbol) { 769 if elf64 { 770 s.AddUint64(ctxt.Arch, uint64(tag)) 771 } else { 772 s.AddUint32(ctxt.Arch, uint32(tag)) 773 } 774 s.AddSize(ctxt.Arch, t) 775 } 776 777 func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int { 778 interp = p 779 n := len(interp) + 1 780 sh.addr = startva + resoff - uint64(n) 781 sh.off = resoff - uint64(n) 782 sh.size = uint64(n) 783 784 return n 785 } 786 787 func elfwriteinterp(out *OutBuf) int { 788 sh := elfshname(".interp") 789 out.SeekSet(int64(sh.off)) 790 out.WriteString(interp) 791 out.Write8(0) 792 return int(sh.size) 793 } 794 795 func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int) int { 796 n := 3*4 + uint64(sz) + resoff%4 797 798 sh.type_ = SHT_NOTE 799 sh.flags = SHF_ALLOC 800 sh.addralign = 4 801 sh.addr = startva + resoff - n 802 sh.off = resoff - n 803 sh.size = n - resoff%4 804 805 return int(n) 806 } 807 808 func elfwritenotehdr(out *OutBuf, str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr { 809 sh := elfshname(str) 810 811 // Write Elf_Note header. 812 out.SeekSet(int64(sh.off)) 813 814 out.Write32(namesz) 815 out.Write32(descsz) 816 out.Write32(tag) 817 818 return sh 819 } 820 821 // NetBSD Signature (as per sys/exec_elf.h) 822 const ( 823 ELF_NOTE_NETBSD_NAMESZ = 7 824 ELF_NOTE_NETBSD_DESCSZ = 4 825 ELF_NOTE_NETBSD_TAG = 1 826 ELF_NOTE_NETBSD_VERSION = 599000000 /* NetBSD 5.99 */ 827 ) 828 829 var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00") 830 831 func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int { 832 n := int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4)) 833 return elfnote(sh, startva, resoff, n) 834 } 835 836 func elfwritenetbsdsig(out *OutBuf) int { 837 // Write Elf_Note header. 838 sh := elfwritenotehdr(out, ".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG) 839 840 if sh == nil { 841 return 0 842 } 843 844 // Followed by NetBSD string and version. 845 out.Write(ELF_NOTE_NETBSD_NAME) 846 out.Write8(0) 847 out.Write32(ELF_NOTE_NETBSD_VERSION) 848 849 return int(sh.size) 850 } 851 852 // OpenBSD Signature 853 const ( 854 ELF_NOTE_OPENBSD_NAMESZ = 8 855 ELF_NOTE_OPENBSD_DESCSZ = 4 856 ELF_NOTE_OPENBSD_TAG = 1 857 ELF_NOTE_OPENBSD_VERSION = 0 858 ) 859 860 var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00") 861 862 func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int { 863 n := ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ 864 return elfnote(sh, startva, resoff, n) 865 } 866 867 func elfwriteopenbsdsig(out *OutBuf) int { 868 // Write Elf_Note header. 869 sh := elfwritenotehdr(out, ".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG) 870 871 if sh == nil { 872 return 0 873 } 874 875 // Followed by OpenBSD string and version. 876 out.Write(ELF_NOTE_OPENBSD_NAME) 877 878 out.Write32(ELF_NOTE_OPENBSD_VERSION) 879 880 return int(sh.size) 881 } 882 883 func addbuildinfo(val string) { 884 if !strings.HasPrefix(val, "0x") { 885 Exitf("-B argument must start with 0x: %s", val) 886 } 887 888 ov := val 889 val = val[2:] 890 891 const maxLen = 32 892 if hex.DecodedLen(len(val)) > maxLen { 893 Exitf("-B option too long (max %d digits): %s", maxLen, ov) 894 } 895 896 b, err := hex.DecodeString(val) 897 if err != nil { 898 if err == hex.ErrLength { 899 Exitf("-B argument must have even number of digits: %s", ov) 900 } 901 if inv, ok := err.(hex.InvalidByteError); ok { 902 Exitf("-B argument contains invalid hex digit %c: %s", byte(inv), ov) 903 } 904 Exitf("-B argument contains invalid hex: %s", ov) 905 } 906 907 buildinfo = b 908 } 909 910 // Build info note 911 const ( 912 ELF_NOTE_BUILDINFO_NAMESZ = 4 913 ELF_NOTE_BUILDINFO_TAG = 3 914 ) 915 916 var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00") 917 918 func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int { 919 n := int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4)) 920 return elfnote(sh, startva, resoff, n) 921 } 922 923 func elfgobuildid(sh *ElfShdr, startva uint64, resoff uint64) int { 924 n := len(ELF_NOTE_GO_NAME) + int(Rnd(int64(len(*flagBuildid)), 4)) 925 return elfnote(sh, startva, resoff, n) 926 } 927 928 func elfwritebuildinfo(out *OutBuf) int { 929 sh := elfwritenotehdr(out, ".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG) 930 if sh == nil { 931 return 0 932 } 933 934 out.Write(ELF_NOTE_BUILDINFO_NAME) 935 out.Write(buildinfo) 936 var zero = make([]byte, 4) 937 out.Write(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))]) 938 939 return int(sh.size) 940 } 941 942 func elfwritegobuildid(out *OutBuf) int { 943 sh := elfwritenotehdr(out, ".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(*flagBuildid)), ELF_NOTE_GOBUILDID_TAG) 944 if sh == nil { 945 return 0 946 } 947 948 out.Write(ELF_NOTE_GO_NAME) 949 out.Write([]byte(*flagBuildid)) 950 var zero = make([]byte, 4) 951 out.Write(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))]) 952 953 return int(sh.size) 954 } 955 956 // Go specific notes 957 const ( 958 ELF_NOTE_GOPKGLIST_TAG = 1 959 ELF_NOTE_GOABIHASH_TAG = 2 960 ELF_NOTE_GODEPS_TAG = 3 961 ELF_NOTE_GOBUILDID_TAG = 4 962 ) 963 964 var ELF_NOTE_GO_NAME = []byte("Go\x00\x00") 965 966 var elfverneed int 967 968 type Elfaux struct { 969 next *Elfaux 970 num int 971 vers string 972 } 973 974 type Elflib struct { 975 next *Elflib 976 aux *Elfaux 977 file string 978 } 979 980 func addelflib(list **Elflib, file string, vers string) *Elfaux { 981 var lib *Elflib 982 983 for lib = *list; lib != nil; lib = lib.next { 984 if lib.file == file { 985 goto havelib 986 } 987 } 988 lib = new(Elflib) 989 lib.next = *list 990 lib.file = file 991 *list = lib 992 993 havelib: 994 for aux := lib.aux; aux != nil; aux = aux.next { 995 if aux.vers == vers { 996 return aux 997 } 998 } 999 aux := new(Elfaux) 1000 aux.next = lib.aux 1001 aux.vers = vers 1002 lib.aux = aux 1003 1004 return aux 1005 } 1006 1007 func elfdynhash(ctxt *Link) { 1008 if !ctxt.IsELF { 1009 return 1010 } 1011 1012 nsym := Nelfsym 1013 s := ctxt.Syms.Lookup(".hash", 0) 1014 s.Type = sym.SELFROSECT 1015 s.Attr |= sym.AttrReachable 1016 1017 i := nsym 1018 nbucket := 1 1019 for i > 0 { 1020 nbucket++ 1021 i >>= 1 1022 } 1023 1024 var needlib *Elflib 1025 need := make([]*Elfaux, nsym) 1026 chain := make([]uint32, nsym) 1027 buckets := make([]uint32, nbucket) 1028 1029 for _, sy := range ctxt.Syms.Allsym { 1030 if sy.Dynid <= 0 { 1031 continue 1032 } 1033 1034 if sy.Dynimpvers() != "" { 1035 need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib(), sy.Dynimpvers()) 1036 } 1037 1038 name := sy.Extname() 1039 hc := elfhash(name) 1040 1041 b := hc % uint32(nbucket) 1042 chain[sy.Dynid] = buckets[b] 1043 buckets[b] = uint32(sy.Dynid) 1044 } 1045 1046 // s390x (ELF64) hash table entries are 8 bytes 1047 if ctxt.Arch.Family == sys.S390X { 1048 s.AddUint64(ctxt.Arch, uint64(nbucket)) 1049 s.AddUint64(ctxt.Arch, uint64(nsym)) 1050 for i := 0; i < nbucket; i++ { 1051 s.AddUint64(ctxt.Arch, uint64(buckets[i])) 1052 } 1053 for i := 0; i < nsym; i++ { 1054 s.AddUint64(ctxt.Arch, uint64(chain[i])) 1055 } 1056 } else { 1057 s.AddUint32(ctxt.Arch, uint32(nbucket)) 1058 s.AddUint32(ctxt.Arch, uint32(nsym)) 1059 for i := 0; i < nbucket; i++ { 1060 s.AddUint32(ctxt.Arch, buckets[i]) 1061 } 1062 for i := 0; i < nsym; i++ { 1063 s.AddUint32(ctxt.Arch, chain[i]) 1064 } 1065 } 1066 1067 // version symbols 1068 dynstr := ctxt.Syms.Lookup(".dynstr", 0) 1069 1070 s = ctxt.Syms.Lookup(".gnu.version_r", 0) 1071 i = 2 1072 nfile := 0 1073 for l := needlib; l != nil; l = l.next { 1074 nfile++ 1075 1076 // header 1077 s.AddUint16(ctxt.Arch, 1) // table version 1078 j := 0 1079 for x := l.aux; x != nil; x = x.next { 1080 j++ 1081 } 1082 s.AddUint16(ctxt.Arch, uint16(j)) // aux count 1083 s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, l.file))) // file string offset 1084 s.AddUint32(ctxt.Arch, 16) // offset from header to first aux 1085 if l.next != nil { 1086 s.AddUint32(ctxt.Arch, 16+uint32(j)*16) // offset from this header to next 1087 } else { 1088 s.AddUint32(ctxt.Arch, 0) 1089 } 1090 1091 for x := l.aux; x != nil; x = x.next { 1092 x.num = i 1093 i++ 1094 1095 // aux struct 1096 s.AddUint32(ctxt.Arch, elfhash(x.vers)) // hash 1097 s.AddUint16(ctxt.Arch, 0) // flags 1098 s.AddUint16(ctxt.Arch, uint16(x.num)) // other - index we refer to this by 1099 s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, x.vers))) // version string offset 1100 if x.next != nil { 1101 s.AddUint32(ctxt.Arch, 16) // offset from this aux to next 1102 } else { 1103 s.AddUint32(ctxt.Arch, 0) 1104 } 1105 } 1106 } 1107 1108 // version references 1109 s = ctxt.Syms.Lookup(".gnu.version", 0) 1110 1111 for i := 0; i < nsym; i++ { 1112 if i == 0 { 1113 s.AddUint16(ctxt.Arch, 0) // first entry - no symbol 1114 } else if need[i] == nil { 1115 s.AddUint16(ctxt.Arch, 1) // global 1116 } else { 1117 s.AddUint16(ctxt.Arch, uint16(need[i].num)) 1118 } 1119 } 1120 1121 s = ctxt.Syms.Lookup(".dynamic", 0) 1122 elfverneed = nfile 1123 if elfverneed != 0 { 1124 elfwritedynentsym(ctxt, s, DT_VERNEED, ctxt.Syms.Lookup(".gnu.version_r", 0)) 1125 Elfwritedynent(ctxt, s, DT_VERNEEDNUM, uint64(nfile)) 1126 elfwritedynentsym(ctxt, s, DT_VERSYM, ctxt.Syms.Lookup(".gnu.version", 0)) 1127 } 1128 1129 sy := ctxt.Syms.Lookup(elfRelType+".plt", 0) 1130 if sy.Size > 0 { 1131 if elfRelType == ".rela" { 1132 Elfwritedynent(ctxt, s, DT_PLTREL, DT_RELA) 1133 } else { 1134 Elfwritedynent(ctxt, s, DT_PLTREL, DT_REL) 1135 } 1136 elfwritedynentsymsize(ctxt, s, DT_PLTRELSZ, sy) 1137 elfwritedynentsym(ctxt, s, DT_JMPREL, sy) 1138 } 1139 1140 Elfwritedynent(ctxt, s, DT_NULL, 0) 1141 } 1142 1143 func elfphload(seg *sym.Segment) *ElfPhdr { 1144 ph := newElfPhdr() 1145 ph.type_ = PT_LOAD 1146 if seg.Rwx&4 != 0 { 1147 ph.flags |= PF_R 1148 } 1149 if seg.Rwx&2 != 0 { 1150 ph.flags |= PF_W 1151 } 1152 if seg.Rwx&1 != 0 { 1153 ph.flags |= PF_X 1154 } 1155 ph.vaddr = seg.Vaddr 1156 ph.paddr = seg.Vaddr 1157 ph.memsz = seg.Length 1158 ph.off = seg.Fileoff 1159 ph.filesz = seg.Filelen 1160 ph.align = uint64(*FlagRound) 1161 1162 return ph 1163 } 1164 1165 func elfphrelro(seg *sym.Segment) { 1166 ph := newElfPhdr() 1167 ph.type_ = PT_GNU_RELRO 1168 ph.vaddr = seg.Vaddr 1169 ph.paddr = seg.Vaddr 1170 ph.memsz = seg.Length 1171 ph.off = seg.Fileoff 1172 ph.filesz = seg.Filelen 1173 ph.align = uint64(*FlagRound) 1174 } 1175 1176 func elfshname(name string) *ElfShdr { 1177 for i := 0; i < nelfstr; i++ { 1178 if name != elfstr[i].s { 1179 continue 1180 } 1181 off := elfstr[i].off 1182 for i = 0; i < int(ehdr.shnum); i++ { 1183 sh := shdr[i] 1184 if sh.name == uint32(off) { 1185 return sh 1186 } 1187 } 1188 return newElfShdr(int64(off)) 1189 } 1190 Exitf("cannot find elf name %s", name) 1191 return nil 1192 } 1193 1194 // Create an ElfShdr for the section with name. 1195 // Create a duplicate if one already exists with that name 1196 func elfshnamedup(name string) *ElfShdr { 1197 for i := 0; i < nelfstr; i++ { 1198 if name == elfstr[i].s { 1199 off := elfstr[i].off 1200 return newElfShdr(int64(off)) 1201 } 1202 } 1203 1204 Errorf(nil, "cannot find elf name %s", name) 1205 errorexit() 1206 return nil 1207 } 1208 1209 func elfshalloc(sect *sym.Section) *ElfShdr { 1210 sh := elfshname(sect.Name) 1211 sect.Elfsect = sh 1212 return sh 1213 } 1214 1215 func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr { 1216 var sh *ElfShdr 1217 1218 if sect.Name == ".text" { 1219 if sect.Elfsect == nil { 1220 sect.Elfsect = elfshnamedup(sect.Name) 1221 } 1222 sh = sect.Elfsect.(*ElfShdr) 1223 } else { 1224 sh = elfshalloc(sect) 1225 } 1226 1227 // If this section has already been set up as a note, we assume type_ and 1228 // flags are already correct, but the other fields still need filling in. 1229 if sh.type_ == SHT_NOTE { 1230 if linkmode != LinkExternal { 1231 // TODO(mwhudson): the approach here will work OK when 1232 // linking internally for notes that we want to be included 1233 // in a loadable segment (e.g. the abihash note) but not for 1234 // notes that we do not want to be mapped (e.g. the package 1235 // list note). The real fix is probably to define new values 1236 // for Symbol.Type corresponding to mapped and unmapped notes 1237 // and handle them in dodata(). 1238 Errorf(nil, "sh.type_ == SHT_NOTE in elfshbits when linking internally") 1239 } 1240 sh.addralign = uint64(sect.Align) 1241 sh.size = sect.Length 1242 sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr 1243 return sh 1244 } 1245 if sh.type_ > 0 { 1246 return sh 1247 } 1248 1249 if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen { 1250 sh.type_ = SHT_PROGBITS 1251 } else { 1252 sh.type_ = SHT_NOBITS 1253 } 1254 sh.flags = SHF_ALLOC 1255 if sect.Rwx&1 != 0 { 1256 sh.flags |= SHF_EXECINSTR 1257 } 1258 if sect.Rwx&2 != 0 { 1259 sh.flags |= SHF_WRITE 1260 } 1261 if sect.Name == ".tbss" { 1262 sh.flags |= SHF_TLS 1263 sh.type_ = SHT_NOBITS 1264 } 1265 if strings.HasPrefix(sect.Name, ".debug") || strings.HasPrefix(sect.Name, ".zdebug") { 1266 sh.flags = 0 1267 } 1268 1269 if linkmode != LinkExternal { 1270 sh.addr = sect.Vaddr 1271 } 1272 sh.addralign = uint64(sect.Align) 1273 sh.size = sect.Length 1274 if sect.Name != ".tbss" { 1275 sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr 1276 } 1277 1278 return sh 1279 } 1280 1281 func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr { 1282 // If main section is SHT_NOBITS, nothing to relocate. 1283 // Also nothing to relocate in .shstrtab or notes. 1284 if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen { 1285 return nil 1286 } 1287 if sect.Name == ".shstrtab" || sect.Name == ".tbss" { 1288 return nil 1289 } 1290 if sect.Elfsect.(*ElfShdr).type_ == SHT_NOTE { 1291 return nil 1292 } 1293 1294 typ := SHT_REL 1295 if elfRelType == ".rela" { 1296 typ = SHT_RELA 1297 } 1298 1299 sh := elfshname(elfRelType + sect.Name) 1300 // There could be multiple text sections but each needs 1301 // its own .rela.text. 1302 1303 if sect.Name == ".text" { 1304 if sh.info != 0 && sh.info != uint32(sect.Elfsect.(*ElfShdr).shnum) { 1305 sh = elfshnamedup(elfRelType + sect.Name) 1306 } 1307 } 1308 1309 sh.type_ = uint32(typ) 1310 sh.entsize = uint64(arch.RegSize) * 2 1311 if typ == SHT_RELA { 1312 sh.entsize += uint64(arch.RegSize) 1313 } 1314 sh.link = uint32(elfshname(".symtab").shnum) 1315 sh.info = uint32(sect.Elfsect.(*ElfShdr).shnum) 1316 sh.off = sect.Reloff 1317 sh.size = sect.Rellen 1318 sh.addralign = uint64(arch.RegSize) 1319 return sh 1320 } 1321 1322 func elfrelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) { 1323 // If main section is SHT_NOBITS, nothing to relocate. 1324 // Also nothing to relocate in .shstrtab. 1325 if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen { 1326 return 1327 } 1328 if sect.Name == ".shstrtab" { 1329 return 1330 } 1331 1332 sect.Reloff = uint64(ctxt.Out.Offset()) 1333 for i, s := range syms { 1334 if !s.Attr.Reachable() { 1335 continue 1336 } 1337 if uint64(s.Value) >= sect.Vaddr { 1338 syms = syms[i:] 1339 break 1340 } 1341 } 1342 1343 eaddr := int32(sect.Vaddr + sect.Length) 1344 for _, s := range syms { 1345 if !s.Attr.Reachable() { 1346 continue 1347 } 1348 if s.Value >= int64(eaddr) { 1349 break 1350 } 1351 for ri := range s.R { 1352 r := &s.R[ri] 1353 if r.Done { 1354 continue 1355 } 1356 if r.Xsym == nil { 1357 Errorf(s, "missing xsym in relocation %#v %#v", r.Sym.Name, s) 1358 continue 1359 } 1360 if r.Xsym.ElfsymForReloc() == 0 { 1361 Errorf(s, "reloc %d (%s) to non-elf symbol %s (outer=%s) %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Sym.Name, r.Xsym.Name, r.Sym.Type, r.Sym.Type) 1362 } 1363 if !r.Xsym.Attr.Reachable() { 1364 Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name) 1365 } 1366 if !thearch.Elfreloc1(ctxt, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) { 1367 Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name) 1368 } 1369 } 1370 } 1371 1372 sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff 1373 } 1374 1375 func Elfemitreloc(ctxt *Link) { 1376 for ctxt.Out.Offset()&7 != 0 { 1377 ctxt.Out.Write8(0) 1378 } 1379 1380 for _, sect := range Segtext.Sections { 1381 if sect.Name == ".text" { 1382 elfrelocsect(ctxt, sect, ctxt.Textp) 1383 } else { 1384 elfrelocsect(ctxt, sect, datap) 1385 } 1386 } 1387 1388 for _, sect := range Segrodata.Sections { 1389 elfrelocsect(ctxt, sect, datap) 1390 } 1391 for _, sect := range Segrelrodata.Sections { 1392 elfrelocsect(ctxt, sect, datap) 1393 } 1394 for _, sect := range Segdata.Sections { 1395 elfrelocsect(ctxt, sect, datap) 1396 } 1397 for _, sect := range Segdwarf.Sections { 1398 elfrelocsect(ctxt, sect, dwarfp) 1399 } 1400 } 1401 1402 func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) { 1403 s := ctxt.Syms.Lookup(sectionName, 0) 1404 s.Attr |= sym.AttrReachable 1405 s.Type = sym.SELFROSECT 1406 // namesz 1407 s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME))) 1408 // descsz 1409 s.AddUint32(ctxt.Arch, uint32(len(desc))) 1410 // tag 1411 s.AddUint32(ctxt.Arch, tag) 1412 // name + padding 1413 s.P = append(s.P, ELF_NOTE_GO_NAME...) 1414 for len(s.P)%4 != 0 { 1415 s.P = append(s.P, 0) 1416 } 1417 // desc + padding 1418 s.P = append(s.P, desc...) 1419 for len(s.P)%4 != 0 { 1420 s.P = append(s.P, 0) 1421 } 1422 s.Size = int64(len(s.P)) 1423 s.Align = 4 1424 } 1425 1426 func (ctxt *Link) doelf() { 1427 if !ctxt.IsELF { 1428 return 1429 } 1430 1431 /* predefine strings we need for section headers */ 1432 shstrtab := ctxt.Syms.Lookup(".shstrtab", 0) 1433 1434 shstrtab.Type = sym.SELFROSECT 1435 shstrtab.Attr |= sym.AttrReachable 1436 1437 Addstring(shstrtab, "") 1438 Addstring(shstrtab, ".text") 1439 Addstring(shstrtab, ".noptrdata") 1440 Addstring(shstrtab, ".data") 1441 Addstring(shstrtab, ".bss") 1442 Addstring(shstrtab, ".noptrbss") 1443 Addstring(shstrtab, "__libfuzzer_extra_counters") 1444 Addstring(shstrtab, ".go.buildinfo") 1445 1446 // generate .tbss section for dynamic internal linker or external 1447 // linking, so that various binutils could correctly calculate 1448 // PT_TLS size. See https://golang.org/issue/5200. 1449 if !*FlagD || ctxt.LinkMode == LinkExternal { 1450 Addstring(shstrtab, ".tbss") 1451 } 1452 if ctxt.HeadType == objabi.Hnetbsd { 1453 Addstring(shstrtab, ".note.netbsd.ident") 1454 } 1455 if ctxt.HeadType == objabi.Hopenbsd { 1456 Addstring(shstrtab, ".note.openbsd.ident") 1457 } 1458 if len(buildinfo) > 0 { 1459 Addstring(shstrtab, ".note.gnu.build-id") 1460 } 1461 if *flagBuildid != "" { 1462 Addstring(shstrtab, ".note.go.buildid") 1463 } 1464 Addstring(shstrtab, ".elfdata") 1465 Addstring(shstrtab, ".rodata") 1466 // See the comment about data.rel.ro.FOO section names in data.go. 1467 relro_prefix := "" 1468 if ctxt.UseRelro() { 1469 Addstring(shstrtab, ".data.rel.ro") 1470 relro_prefix = ".data.rel.ro" 1471 } 1472 Addstring(shstrtab, relro_prefix+".typelink") 1473 Addstring(shstrtab, relro_prefix+".itablink") 1474 Addstring(shstrtab, relro_prefix+".gosymtab") 1475 Addstring(shstrtab, relro_prefix+".gopclntab") 1476 1477 if ctxt.LinkMode == LinkExternal { 1478 *FlagD = true 1479 1480 Addstring(shstrtab, elfRelType+".text") 1481 Addstring(shstrtab, elfRelType+".rodata") 1482 Addstring(shstrtab, elfRelType+relro_prefix+".typelink") 1483 Addstring(shstrtab, elfRelType+relro_prefix+".itablink") 1484 Addstring(shstrtab, elfRelType+relro_prefix+".gosymtab") 1485 Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab") 1486 Addstring(shstrtab, elfRelType+".noptrdata") 1487 Addstring(shstrtab, elfRelType+".data") 1488 if ctxt.UseRelro() { 1489 Addstring(shstrtab, elfRelType+".data.rel.ro") 1490 } 1491 Addstring(shstrtab, elfRelType+".go.buildinfo") 1492 1493 // add a .note.GNU-stack section to mark the stack as non-executable 1494 Addstring(shstrtab, ".note.GNU-stack") 1495 1496 if ctxt.BuildMode == BuildModeShared { 1497 Addstring(shstrtab, ".note.go.abihash") 1498 Addstring(shstrtab, ".note.go.pkg-list") 1499 Addstring(shstrtab, ".note.go.deps") 1500 } 1501 } 1502 1503 hasinitarr := ctxt.linkShared 1504 1505 /* shared library initializer */ 1506 switch ctxt.BuildMode { 1507 case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin: 1508 hasinitarr = true 1509 } 1510 1511 if hasinitarr { 1512 Addstring(shstrtab, ".init_array") 1513 Addstring(shstrtab, elfRelType+".init_array") 1514 } 1515 1516 if !*FlagS { 1517 Addstring(shstrtab, ".symtab") 1518 Addstring(shstrtab, ".strtab") 1519 dwarfaddshstrings(ctxt, shstrtab) 1520 } 1521 1522 Addstring(shstrtab, ".shstrtab") 1523 1524 if !*FlagD { /* -d suppresses dynamic loader format */ 1525 Addstring(shstrtab, ".interp") 1526 Addstring(shstrtab, ".hash") 1527 Addstring(shstrtab, ".got") 1528 if ctxt.Arch.Family == sys.PPC64 { 1529 Addstring(shstrtab, ".glink") 1530 } 1531 Addstring(shstrtab, ".got.plt") 1532 Addstring(shstrtab, ".dynamic") 1533 Addstring(shstrtab, ".dynsym") 1534 Addstring(shstrtab, ".dynstr") 1535 Addstring(shstrtab, elfRelType) 1536 Addstring(shstrtab, elfRelType+".plt") 1537 1538 Addstring(shstrtab, ".plt") 1539 Addstring(shstrtab, ".gnu.version") 1540 Addstring(shstrtab, ".gnu.version_r") 1541 1542 /* dynamic symbol table - first entry all zeros */ 1543 s := ctxt.Syms.Lookup(".dynsym", 0) 1544 1545 s.Type = sym.SELFROSECT 1546 s.Attr |= sym.AttrReachable 1547 if elf64 { 1548 s.Size += ELF64SYMSIZE 1549 } else { 1550 s.Size += ELF32SYMSIZE 1551 } 1552 1553 /* dynamic string table */ 1554 s = ctxt.Syms.Lookup(".dynstr", 0) 1555 1556 s.Type = sym.SELFROSECT 1557 s.Attr |= sym.AttrReachable 1558 if s.Size == 0 { 1559 Addstring(s, "") 1560 } 1561 dynstr := s 1562 1563 /* relocation table */ 1564 s = ctxt.Syms.Lookup(elfRelType, 0) 1565 s.Attr |= sym.AttrReachable 1566 s.Type = sym.SELFROSECT 1567 1568 /* global offset table */ 1569 s = ctxt.Syms.Lookup(".got", 0) 1570 1571 s.Attr |= sym.AttrReachable 1572 s.Type = sym.SELFGOT // writable 1573 1574 /* ppc64 glink resolver */ 1575 if ctxt.Arch.Family == sys.PPC64 { 1576 s := ctxt.Syms.Lookup(".glink", 0) 1577 s.Attr |= sym.AttrReachable 1578 s.Type = sym.SELFRXSECT 1579 } 1580 1581 /* hash */ 1582 s = ctxt.Syms.Lookup(".hash", 0) 1583 1584 s.Attr |= sym.AttrReachable 1585 s.Type = sym.SELFROSECT 1586 1587 s = ctxt.Syms.Lookup(".got.plt", 0) 1588 s.Attr |= sym.AttrReachable 1589 s.Type = sym.SELFSECT // writable 1590 1591 s = ctxt.Syms.Lookup(".plt", 0) 1592 1593 s.Attr |= sym.AttrReachable 1594 if ctxt.Arch.Family == sys.PPC64 { 1595 // In the ppc64 ABI, .plt is a data section 1596 // written by the dynamic linker. 1597 s.Type = sym.SELFSECT 1598 } else { 1599 s.Type = sym.SELFRXSECT 1600 } 1601 1602 thearch.Elfsetupplt(ctxt) 1603 1604 s = ctxt.Syms.Lookup(elfRelType+".plt", 0) 1605 s.Attr |= sym.AttrReachable 1606 s.Type = sym.SELFROSECT 1607 1608 s = ctxt.Syms.Lookup(".gnu.version", 0) 1609 s.Attr |= sym.AttrReachable 1610 s.Type = sym.SELFROSECT 1611 1612 s = ctxt.Syms.Lookup(".gnu.version_r", 0) 1613 s.Attr |= sym.AttrReachable 1614 s.Type = sym.SELFROSECT 1615 1616 /* define dynamic elf table */ 1617 s = ctxt.Syms.Lookup(".dynamic", 0) 1618 1619 s.Attr |= sym.AttrReachable 1620 s.Type = sym.SELFSECT // writable 1621 1622 /* 1623 * .dynamic table 1624 */ 1625 elfwritedynentsym(ctxt, s, DT_HASH, ctxt.Syms.Lookup(".hash", 0)) 1626 1627 elfwritedynentsym(ctxt, s, DT_SYMTAB, ctxt.Syms.Lookup(".dynsym", 0)) 1628 if elf64 { 1629 Elfwritedynent(ctxt, s, DT_SYMENT, ELF64SYMSIZE) 1630 } else { 1631 Elfwritedynent(ctxt, s, DT_SYMENT, ELF32SYMSIZE) 1632 } 1633 elfwritedynentsym(ctxt, s, DT_STRTAB, ctxt.Syms.Lookup(".dynstr", 0)) 1634 elfwritedynentsymsize(ctxt, s, DT_STRSZ, ctxt.Syms.Lookup(".dynstr", 0)) 1635 if elfRelType == ".rela" { 1636 elfwritedynentsym(ctxt, s, DT_RELA, ctxt.Syms.Lookup(".rela", 0)) 1637 elfwritedynentsymsize(ctxt, s, DT_RELASZ, ctxt.Syms.Lookup(".rela", 0)) 1638 Elfwritedynent(ctxt, s, DT_RELAENT, ELF64RELASIZE) 1639 } else { 1640 elfwritedynentsym(ctxt, s, DT_REL, ctxt.Syms.Lookup(".rel", 0)) 1641 elfwritedynentsymsize(ctxt, s, DT_RELSZ, ctxt.Syms.Lookup(".rel", 0)) 1642 Elfwritedynent(ctxt, s, DT_RELENT, ELF32RELSIZE) 1643 } 1644 1645 if rpath.val != "" { 1646 Elfwritedynent(ctxt, s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val))) 1647 } 1648 1649 if ctxt.Arch.Family == sys.PPC64 { 1650 elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".plt", 0)) 1651 } else if ctxt.Arch.Family == sys.S390X { 1652 elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got", 0)) 1653 } else { 1654 elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got.plt", 0)) 1655 } 1656 1657 if ctxt.Arch.Family == sys.PPC64 { 1658 Elfwritedynent(ctxt, s, DT_PPC64_OPT, 0) 1659 } 1660 1661 // Solaris dynamic linker can't handle an empty .rela.plt if 1662 // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL, 1663 // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the 1664 // size of .rel(a).plt section. 1665 Elfwritedynent(ctxt, s, DT_DEBUG, 0) 1666 } 1667 1668 if ctxt.BuildMode == BuildModeShared { 1669 // The go.link.abihashbytes symbol will be pointed at the appropriate 1670 // part of the .note.go.abihash section in data.go:func address(). 1671 s := ctxt.Syms.Lookup("go.link.abihashbytes", 0) 1672 s.Attr |= sym.AttrLocal 1673 s.Type = sym.SRODATA 1674 s.Attr |= sym.AttrSpecial 1675 s.Attr |= sym.AttrReachable 1676 s.Size = int64(sha1.Size) 1677 1678 sort.Sort(byPkg(ctxt.Library)) 1679 h := sha1.New() 1680 for _, l := range ctxt.Library { 1681 io.WriteString(h, l.Hash) 1682 } 1683 addgonote(ctxt, ".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{})) 1684 addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote) 1685 var deplist []string 1686 for _, shlib := range ctxt.Shlibs { 1687 deplist = append(deplist, filepath.Base(shlib.Path)) 1688 } 1689 addgonote(ctxt, ".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n"))) 1690 } 1691 1692 if ctxt.LinkMode == LinkExternal && *flagBuildid != "" { 1693 addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(*flagBuildid)) 1694 } 1695 } 1696 1697 // Do not write DT_NULL. elfdynhash will finish it. 1698 func shsym(sh *ElfShdr, s *sym.Symbol) { 1699 addr := Symaddr(s) 1700 if sh.flags&SHF_ALLOC != 0 { 1701 sh.addr = uint64(addr) 1702 } 1703 sh.off = uint64(datoff(s, addr)) 1704 sh.size = uint64(s.Size) 1705 } 1706 1707 func phsh(ph *ElfPhdr, sh *ElfShdr) { 1708 ph.vaddr = sh.addr 1709 ph.paddr = ph.vaddr 1710 ph.off = sh.off 1711 ph.filesz = sh.size 1712 ph.memsz = sh.size 1713 ph.align = sh.addralign 1714 } 1715 1716 func Asmbelfsetup() { 1717 /* This null SHdr must appear before all others */ 1718 elfshname("") 1719 1720 for _, sect := range Segtext.Sections { 1721 // There could be multiple .text sections. Instead check the Elfsect 1722 // field to determine if already has an ElfShdr and if not, create one. 1723 if sect.Name == ".text" { 1724 if sect.Elfsect == nil { 1725 sect.Elfsect = elfshnamedup(sect.Name) 1726 } 1727 } else { 1728 elfshalloc(sect) 1729 } 1730 } 1731 for _, sect := range Segrodata.Sections { 1732 elfshalloc(sect) 1733 } 1734 for _, sect := range Segrelrodata.Sections { 1735 elfshalloc(sect) 1736 } 1737 for _, sect := range Segdata.Sections { 1738 elfshalloc(sect) 1739 } 1740 for _, sect := range Segdwarf.Sections { 1741 elfshalloc(sect) 1742 } 1743 } 1744 1745 func Asmbelf(ctxt *Link, symo int64) { 1746 eh := getElfEhdr() 1747 switch ctxt.Arch.Family { 1748 default: 1749 Exitf("unknown architecture in asmbelf: %v", ctxt.Arch.Family) 1750 case sys.MIPS, sys.MIPS64: 1751 eh.machine = EM_MIPS 1752 case sys.ARM: 1753 eh.machine = EM_ARM 1754 case sys.AMD64: 1755 eh.machine = EM_X86_64 1756 case sys.ARM64: 1757 eh.machine = EM_AARCH64 1758 case sys.I386: 1759 eh.machine = EM_386 1760 case sys.PPC64: 1761 eh.machine = EM_PPC64 1762 case sys.RISCV64: 1763 eh.machine = EM_RISCV 1764 case sys.S390X: 1765 eh.machine = EM_S390 1766 } 1767 1768 elfreserve := int64(ELFRESERVE) 1769 1770 numtext := int64(0) 1771 for _, sect := range Segtext.Sections { 1772 if sect.Name == ".text" { 1773 numtext++ 1774 } 1775 } 1776 1777 // If there are multiple text sections, extra space is needed 1778 // in the elfreserve for the additional .text and .rela.text 1779 // section headers. It can handle 4 extra now. Headers are 1780 // 64 bytes. 1781 1782 if numtext > 4 { 1783 elfreserve += elfreserve + numtext*64*2 1784 } 1785 1786 startva := *FlagTextAddr - int64(HEADR) 1787 resoff := elfreserve 1788 1789 var pph *ElfPhdr 1790 var pnote *ElfPhdr 1791 if ctxt.LinkMode == LinkExternal { 1792 /* skip program headers */ 1793 eh.phoff = 0 1794 1795 eh.phentsize = 0 1796 1797 if ctxt.BuildMode == BuildModeShared { 1798 sh := elfshname(".note.go.pkg-list") 1799 sh.type_ = SHT_NOTE 1800 sh = elfshname(".note.go.abihash") 1801 sh.type_ = SHT_NOTE 1802 sh.flags = SHF_ALLOC 1803 sh = elfshname(".note.go.deps") 1804 sh.type_ = SHT_NOTE 1805 } 1806 1807 if *flagBuildid != "" { 1808 sh := elfshname(".note.go.buildid") 1809 sh.type_ = SHT_NOTE 1810 sh.flags = SHF_ALLOC 1811 } 1812 1813 goto elfobj 1814 } 1815 1816 /* program header info */ 1817 pph = newElfPhdr() 1818 1819 pph.type_ = PT_PHDR 1820 pph.flags = PF_R 1821 pph.off = uint64(eh.ehsize) 1822 pph.vaddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off 1823 pph.paddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off 1824 pph.align = uint64(*FlagRound) 1825 1826 /* 1827 * PHDR must be in a loaded segment. Adjust the text 1828 * segment boundaries downwards to include it. 1829 */ 1830 { 1831 o := int64(Segtext.Vaddr - pph.vaddr) 1832 Segtext.Vaddr -= uint64(o) 1833 Segtext.Length += uint64(o) 1834 o = int64(Segtext.Fileoff - pph.off) 1835 Segtext.Fileoff -= uint64(o) 1836 Segtext.Filelen += uint64(o) 1837 } 1838 1839 if !*FlagD { /* -d suppresses dynamic loader format */ 1840 /* interpreter */ 1841 sh := elfshname(".interp") 1842 1843 sh.type_ = SHT_PROGBITS 1844 sh.flags = SHF_ALLOC 1845 sh.addralign = 1 1846 1847 if interpreter == "" && objabi.GO_LDSO != "" { 1848 interpreter = objabi.GO_LDSO 1849 } 1850 1851 if interpreter == "" { 1852 switch ctxt.HeadType { 1853 case objabi.Hlinux: 1854 interpreter = thearch.Linuxdynld 1855 1856 case objabi.Hfreebsd: 1857 interpreter = thearch.Freebsddynld 1858 1859 case objabi.Hnetbsd: 1860 interpreter = thearch.Netbsddynld 1861 1862 case objabi.Hopenbsd: 1863 interpreter = thearch.Openbsddynld 1864 1865 case objabi.Hdragonfly: 1866 interpreter = thearch.Dragonflydynld 1867 1868 case objabi.Hsolaris: 1869 interpreter = thearch.Solarisdynld 1870 } 1871 } 1872 1873 resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter)) 1874 1875 ph := newElfPhdr() 1876 ph.type_ = PT_INTERP 1877 ph.flags = PF_R 1878 phsh(ph, sh) 1879 } 1880 1881 pnote = nil 1882 if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd { 1883 var sh *ElfShdr 1884 switch ctxt.HeadType { 1885 case objabi.Hnetbsd: 1886 sh = elfshname(".note.netbsd.ident") 1887 resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff))) 1888 1889 case objabi.Hopenbsd: 1890 sh = elfshname(".note.openbsd.ident") 1891 resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff))) 1892 } 1893 1894 pnote = newElfPhdr() 1895 pnote.type_ = PT_NOTE 1896 pnote.flags = PF_R 1897 phsh(pnote, sh) 1898 } 1899 1900 if len(buildinfo) > 0 { 1901 sh := elfshname(".note.gnu.build-id") 1902 resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff))) 1903 1904 if pnote == nil { 1905 pnote = newElfPhdr() 1906 pnote.type_ = PT_NOTE 1907 pnote.flags = PF_R 1908 } 1909 1910 phsh(pnote, sh) 1911 } 1912 1913 if *flagBuildid != "" { 1914 sh := elfshname(".note.go.buildid") 1915 resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff))) 1916 1917 pnote := newElfPhdr() 1918 pnote.type_ = PT_NOTE 1919 pnote.flags = PF_R 1920 phsh(pnote, sh) 1921 } 1922 1923 // Additions to the reserved area must be above this line. 1924 1925 elfphload(&Segtext) 1926 if len(Segrodata.Sections) > 0 { 1927 elfphload(&Segrodata) 1928 } 1929 if len(Segrelrodata.Sections) > 0 { 1930 elfphload(&Segrelrodata) 1931 elfphrelro(&Segrelrodata) 1932 } 1933 elfphload(&Segdata) 1934 1935 /* Dynamic linking sections */ 1936 if !*FlagD { 1937 sh := elfshname(".dynsym") 1938 sh.type_ = SHT_DYNSYM 1939 sh.flags = SHF_ALLOC 1940 if elf64 { 1941 sh.entsize = ELF64SYMSIZE 1942 } else { 1943 sh.entsize = ELF32SYMSIZE 1944 } 1945 sh.addralign = uint64(ctxt.Arch.RegSize) 1946 sh.link = uint32(elfshname(".dynstr").shnum) 1947 1948 // sh.info is the index of first non-local symbol (number of local symbols) 1949 s := ctxt.Syms.Lookup(".dynsym", 0) 1950 i := uint32(0) 1951 for sub := s; sub != nil; sub = sub.Sub { 1952 i++ 1953 if !sub.Attr.Local() { 1954 break 1955 } 1956 } 1957 sh.info = i 1958 shsym(sh, s) 1959 1960 sh = elfshname(".dynstr") 1961 sh.type_ = SHT_STRTAB 1962 sh.flags = SHF_ALLOC 1963 sh.addralign = 1 1964 shsym(sh, ctxt.Syms.Lookup(".dynstr", 0)) 1965 1966 if elfverneed != 0 { 1967 sh := elfshname(".gnu.version") 1968 sh.type_ = SHT_GNU_VERSYM 1969 sh.flags = SHF_ALLOC 1970 sh.addralign = 2 1971 sh.link = uint32(elfshname(".dynsym").shnum) 1972 sh.entsize = 2 1973 shsym(sh, ctxt.Syms.Lookup(".gnu.version", 0)) 1974 1975 sh = elfshname(".gnu.version_r") 1976 sh.type_ = SHT_GNU_VERNEED 1977 sh.flags = SHF_ALLOC 1978 sh.addralign = uint64(ctxt.Arch.RegSize) 1979 sh.info = uint32(elfverneed) 1980 sh.link = uint32(elfshname(".dynstr").shnum) 1981 shsym(sh, ctxt.Syms.Lookup(".gnu.version_r", 0)) 1982 } 1983 1984 if elfRelType == ".rela" { 1985 sh := elfshname(".rela.plt") 1986 sh.type_ = SHT_RELA 1987 sh.flags = SHF_ALLOC 1988 sh.entsize = ELF64RELASIZE 1989 sh.addralign = uint64(ctxt.Arch.RegSize) 1990 sh.link = uint32(elfshname(".dynsym").shnum) 1991 sh.info = uint32(elfshname(".plt").shnum) 1992 shsym(sh, ctxt.Syms.Lookup(".rela.plt", 0)) 1993 1994 sh = elfshname(".rela") 1995 sh.type_ = SHT_RELA 1996 sh.flags = SHF_ALLOC 1997 sh.entsize = ELF64RELASIZE 1998 sh.addralign = 8 1999 sh.link = uint32(elfshname(".dynsym").shnum) 2000 shsym(sh, ctxt.Syms.Lookup(".rela", 0)) 2001 } else { 2002 sh := elfshname(".rel.plt") 2003 sh.type_ = SHT_REL 2004 sh.flags = SHF_ALLOC 2005 sh.entsize = ELF32RELSIZE 2006 sh.addralign = 4 2007 sh.link = uint32(elfshname(".dynsym").shnum) 2008 shsym(sh, ctxt.Syms.Lookup(".rel.plt", 0)) 2009 2010 sh = elfshname(".rel") 2011 sh.type_ = SHT_REL 2012 sh.flags = SHF_ALLOC 2013 sh.entsize = ELF32RELSIZE 2014 sh.addralign = 4 2015 sh.link = uint32(elfshname(".dynsym").shnum) 2016 shsym(sh, ctxt.Syms.Lookup(".rel", 0)) 2017 } 2018 2019 if eh.machine == EM_PPC64 { 2020 sh := elfshname(".glink") 2021 sh.type_ = SHT_PROGBITS 2022 sh.flags = SHF_ALLOC + SHF_EXECINSTR 2023 sh.addralign = 4 2024 shsym(sh, ctxt.Syms.Lookup(".glink", 0)) 2025 } 2026 2027 sh = elfshname(".plt") 2028 sh.type_ = SHT_PROGBITS 2029 sh.flags = SHF_ALLOC + SHF_EXECINSTR 2030 if eh.machine == EM_X86_64 { 2031 sh.entsize = 16 2032 } else if eh.machine == EM_S390 { 2033 sh.entsize = 32 2034 } else if eh.machine == EM_PPC64 { 2035 // On ppc64, this is just a table of addresses 2036 // filled by the dynamic linker 2037 sh.type_ = SHT_NOBITS 2038 2039 sh.flags = SHF_ALLOC + SHF_WRITE 2040 sh.entsize = 8 2041 } else { 2042 sh.entsize = 4 2043 } 2044 sh.addralign = sh.entsize 2045 shsym(sh, ctxt.Syms.Lookup(".plt", 0)) 2046 2047 // On ppc64, .got comes from the input files, so don't 2048 // create it here, and .got.plt is not used. 2049 if eh.machine != EM_PPC64 { 2050 sh := elfshname(".got") 2051 sh.type_ = SHT_PROGBITS 2052 sh.flags = SHF_ALLOC + SHF_WRITE 2053 sh.entsize = uint64(ctxt.Arch.RegSize) 2054 sh.addralign = uint64(ctxt.Arch.RegSize) 2055 shsym(sh, ctxt.Syms.Lookup(".got", 0)) 2056 2057 sh = elfshname(".got.plt") 2058 sh.type_ = SHT_PROGBITS 2059 sh.flags = SHF_ALLOC + SHF_WRITE 2060 sh.entsize = uint64(ctxt.Arch.RegSize) 2061 sh.addralign = uint64(ctxt.Arch.RegSize) 2062 shsym(sh, ctxt.Syms.Lookup(".got.plt", 0)) 2063 } 2064 2065 sh = elfshname(".hash") 2066 sh.type_ = SHT_HASH 2067 sh.flags = SHF_ALLOC 2068 sh.entsize = 4 2069 sh.addralign = uint64(ctxt.Arch.RegSize) 2070 sh.link = uint32(elfshname(".dynsym").shnum) 2071 shsym(sh, ctxt.Syms.Lookup(".hash", 0)) 2072 2073 /* sh and PT_DYNAMIC for .dynamic section */ 2074 sh = elfshname(".dynamic") 2075 2076 sh.type_ = SHT_DYNAMIC 2077 sh.flags = SHF_ALLOC + SHF_WRITE 2078 sh.entsize = 2 * uint64(ctxt.Arch.RegSize) 2079 sh.addralign = uint64(ctxt.Arch.RegSize) 2080 sh.link = uint32(elfshname(".dynstr").shnum) 2081 shsym(sh, ctxt.Syms.Lookup(".dynamic", 0)) 2082 ph := newElfPhdr() 2083 ph.type_ = PT_DYNAMIC 2084 ph.flags = PF_R + PF_W 2085 phsh(ph, sh) 2086 2087 /* 2088 * Thread-local storage segment (really just size). 2089 */ 2090 tlssize := uint64(0) 2091 for _, sect := range Segdata.Sections { 2092 if sect.Name == ".tbss" { 2093 tlssize = sect.Length 2094 } 2095 } 2096 if tlssize != 0 { 2097 ph := newElfPhdr() 2098 ph.type_ = PT_TLS 2099 ph.flags = PF_R 2100 ph.memsz = tlssize 2101 ph.align = uint64(ctxt.Arch.RegSize) 2102 } 2103 } 2104 2105 if ctxt.HeadType == objabi.Hlinux { 2106 ph := newElfPhdr() 2107 ph.type_ = PT_GNU_STACK 2108 ph.flags = PF_W + PF_R 2109 ph.align = uint64(ctxt.Arch.RegSize) 2110 2111 ph = newElfPhdr() 2112 ph.type_ = PT_PAX_FLAGS 2113 ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled 2114 ph.align = uint64(ctxt.Arch.RegSize) 2115 } else if ctxt.HeadType == objabi.Hsolaris { 2116 ph := newElfPhdr() 2117 ph.type_ = PT_SUNWSTACK 2118 ph.flags = PF_W + PF_R 2119 } 2120 2121 elfobj: 2122 sh := elfshname(".shstrtab") 2123 sh.type_ = SHT_STRTAB 2124 sh.addralign = 1 2125 shsym(sh, ctxt.Syms.Lookup(".shstrtab", 0)) 2126 eh.shstrndx = uint16(sh.shnum) 2127 2128 // put these sections early in the list 2129 if !*FlagS { 2130 elfshname(".symtab") 2131 elfshname(".strtab") 2132 } 2133 2134 for _, sect := range Segtext.Sections { 2135 elfshbits(ctxt.LinkMode, sect) 2136 } 2137 for _, sect := range Segrodata.Sections { 2138 elfshbits(ctxt.LinkMode, sect) 2139 } 2140 for _, sect := range Segrelrodata.Sections { 2141 elfshbits(ctxt.LinkMode, sect) 2142 } 2143 for _, sect := range Segdata.Sections { 2144 elfshbits(ctxt.LinkMode, sect) 2145 } 2146 for _, sect := range Segdwarf.Sections { 2147 elfshbits(ctxt.LinkMode, sect) 2148 } 2149 2150 if ctxt.LinkMode == LinkExternal { 2151 for _, sect := range Segtext.Sections { 2152 elfshreloc(ctxt.Arch, sect) 2153 } 2154 for _, sect := range Segrodata.Sections { 2155 elfshreloc(ctxt.Arch, sect) 2156 } 2157 for _, sect := range Segrelrodata.Sections { 2158 elfshreloc(ctxt.Arch, sect) 2159 } 2160 for _, sect := range Segdata.Sections { 2161 elfshreloc(ctxt.Arch, sect) 2162 } 2163 for _, s := range dwarfp { 2164 if len(s.R) > 0 || s.Type == sym.SDWARFINFO || s.Type == sym.SDWARFLOC { 2165 elfshreloc(ctxt.Arch, s.Sect) 2166 } 2167 } 2168 // add a .note.GNU-stack section to mark the stack as non-executable 2169 sh := elfshname(".note.GNU-stack") 2170 2171 sh.type_ = SHT_PROGBITS 2172 sh.addralign = 1 2173 sh.flags = 0 2174 } 2175 2176 if !*FlagS { 2177 sh := elfshname(".symtab") 2178 sh.type_ = SHT_SYMTAB 2179 sh.off = uint64(symo) 2180 sh.size = uint64(Symsize) 2181 sh.addralign = uint64(ctxt.Arch.RegSize) 2182 sh.entsize = 8 + 2*uint64(ctxt.Arch.RegSize) 2183 sh.link = uint32(elfshname(".strtab").shnum) 2184 sh.info = uint32(elfglobalsymndx) 2185 2186 sh = elfshname(".strtab") 2187 sh.type_ = SHT_STRTAB 2188 sh.off = uint64(symo) + uint64(Symsize) 2189 sh.size = uint64(len(Elfstrdat)) 2190 sh.addralign = 1 2191 } 2192 2193 /* Main header */ 2194 eh.ident[EI_MAG0] = '\177' 2195 2196 eh.ident[EI_MAG1] = 'E' 2197 eh.ident[EI_MAG2] = 'L' 2198 eh.ident[EI_MAG3] = 'F' 2199 if ctxt.HeadType == objabi.Hfreebsd { 2200 eh.ident[EI_OSABI] = ELFOSABI_FREEBSD 2201 } else if ctxt.HeadType == objabi.Hnetbsd { 2202 eh.ident[EI_OSABI] = ELFOSABI_NETBSD 2203 } else if ctxt.HeadType == objabi.Hopenbsd { 2204 eh.ident[EI_OSABI] = ELFOSABI_OPENBSD 2205 } else if ctxt.HeadType == objabi.Hdragonfly { 2206 eh.ident[EI_OSABI] = ELFOSABI_NONE 2207 } 2208 if elf64 { 2209 eh.ident[EI_CLASS] = ELFCLASS64 2210 } else { 2211 eh.ident[EI_CLASS] = ELFCLASS32 2212 } 2213 if ctxt.Arch.ByteOrder == binary.BigEndian { 2214 eh.ident[EI_DATA] = ELFDATA2MSB 2215 } else { 2216 eh.ident[EI_DATA] = ELFDATA2LSB 2217 } 2218 eh.ident[EI_VERSION] = EV_CURRENT 2219 2220 if ctxt.LinkMode == LinkExternal { 2221 eh.type_ = ET_REL 2222 } else if ctxt.BuildMode == BuildModePIE { 2223 eh.type_ = ET_DYN 2224 } else { 2225 eh.type_ = ET_EXEC 2226 } 2227 2228 if ctxt.LinkMode != LinkExternal { 2229 eh.entry = uint64(Entryvalue(ctxt)) 2230 } 2231 2232 eh.version = EV_CURRENT 2233 2234 if pph != nil { 2235 pph.filesz = uint64(eh.phnum) * uint64(eh.phentsize) 2236 pph.memsz = pph.filesz 2237 } 2238 2239 ctxt.Out.SeekSet(0) 2240 a := int64(0) 2241 a += int64(elfwritehdr(ctxt.Out)) 2242 a += int64(elfwritephdrs(ctxt.Out)) 2243 a += int64(elfwriteshdrs(ctxt.Out)) 2244 if !*FlagD { 2245 a += int64(elfwriteinterp(ctxt.Out)) 2246 } 2247 if ctxt.LinkMode != LinkExternal { 2248 if ctxt.HeadType == objabi.Hnetbsd { 2249 a += int64(elfwritenetbsdsig(ctxt.Out)) 2250 } 2251 if ctxt.HeadType == objabi.Hopenbsd { 2252 a += int64(elfwriteopenbsdsig(ctxt.Out)) 2253 } 2254 if len(buildinfo) > 0 { 2255 a += int64(elfwritebuildinfo(ctxt.Out)) 2256 } 2257 if *flagBuildid != "" { 2258 a += int64(elfwritegobuildid(ctxt.Out)) 2259 } 2260 } 2261 2262 if a > elfreserve { 2263 Errorf(nil, "ELFRESERVE too small: %d > %d with %d text sections", a, elfreserve, numtext) 2264 } 2265 } 2266 2267 func elfadddynsym(ctxt *Link, s *sym.Symbol) { 2268 if elf64 { 2269 s.Dynid = int32(Nelfsym) 2270 Nelfsym++ 2271 2272 d := ctxt.Syms.Lookup(".dynsym", 0) 2273 2274 name := s.Extname() 2275 d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name))) 2276 2277 /* type */ 2278 t := STB_GLOBAL << 4 2279 2280 if s.Attr.CgoExport() && s.Type == sym.STEXT { 2281 t |= STT_FUNC 2282 } else { 2283 t |= STT_OBJECT 2284 } 2285 d.AddUint8(uint8(t)) 2286 2287 /* reserved */ 2288 d.AddUint8(0) 2289 2290 /* section where symbol is defined */ 2291 if s.Type == sym.SDYNIMPORT { 2292 d.AddUint16(ctxt.Arch, SHN_UNDEF) 2293 } else { 2294 d.AddUint16(ctxt.Arch, 1) 2295 } 2296 2297 /* value */ 2298 if s.Type == sym.SDYNIMPORT { 2299 d.AddUint64(ctxt.Arch, 0) 2300 } else { 2301 d.AddAddr(ctxt.Arch, s) 2302 } 2303 2304 /* size of object */ 2305 d.AddUint64(ctxt.Arch, uint64(s.Size)) 2306 2307 if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib() != "" && !seenlib[s.Dynimplib()] { 2308 Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib()))) 2309 } 2310 } else { 2311 s.Dynid = int32(Nelfsym) 2312 Nelfsym++ 2313 2314 d := ctxt.Syms.Lookup(".dynsym", 0) 2315 2316 /* name */ 2317 name := s.Extname() 2318 2319 d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name))) 2320 2321 /* value */ 2322 if s.Type == sym.SDYNIMPORT { 2323 d.AddUint32(ctxt.Arch, 0) 2324 } else { 2325 d.AddAddr(ctxt.Arch, s) 2326 } 2327 2328 /* size of object */ 2329 d.AddUint32(ctxt.Arch, uint32(s.Size)) 2330 2331 /* type */ 2332 t := STB_GLOBAL << 4 2333 2334 // TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386. 2335 if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type == sym.STEXT { 2336 t |= STT_FUNC 2337 } else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type == sym.STEXT { 2338 t |= STT_FUNC 2339 } else { 2340 t |= STT_OBJECT 2341 } 2342 d.AddUint8(uint8(t)) 2343 d.AddUint8(0) 2344 2345 /* shndx */ 2346 if s.Type == sym.SDYNIMPORT { 2347 d.AddUint16(ctxt.Arch, SHN_UNDEF) 2348 } else { 2349 d.AddUint16(ctxt.Arch, 1) 2350 } 2351 } 2352 } 2353 2354 func ELF32_R_SYM(info uint32) uint32 { 2355 return info >> 8 2356 } 2357 2358 func ELF32_R_TYPE(info uint32) uint32 { 2359 return uint32(uint8(info)) 2360 } 2361 2362 func ELF32_R_INFO(sym uint32, type_ uint32) uint32 { 2363 return sym<<8 | type_ 2364 } 2365 2366 func ELF32_ST_BIND(info uint8) uint8 { 2367 return info >> 4 2368 } 2369 2370 func ELF32_ST_TYPE(info uint8) uint8 { 2371 return info & 0xf 2372 } 2373 2374 func ELF32_ST_INFO(bind uint8, type_ uint8) uint8 { 2375 return bind<<4 | type_&0xf 2376 } 2377 2378 func ELF32_ST_VISIBILITY(oth uint8) uint8 { 2379 return oth & 3 2380 } 2381 2382 func ELF64_R_SYM(info uint64) uint32 { 2383 return uint32(info >> 32) 2384 } 2385 2386 func ELF64_R_TYPE(info uint64) uint32 { 2387 return uint32(info) 2388 } 2389 2390 func ELF64_R_INFO(sym uint32, type_ uint32) uint64 { 2391 return uint64(sym)<<32 | uint64(type_) 2392 } 2393 2394 func ELF64_ST_BIND(info uint8) uint8 { 2395 return info >> 4 2396 } 2397 2398 func ELF64_ST_TYPE(info uint8) uint8 { 2399 return info & 0xf 2400 } 2401 2402 func ELF64_ST_INFO(bind uint8, type_ uint8) uint8 { 2403 return bind<<4 | type_&0xf 2404 } 2405 2406 func ELF64_ST_VISIBILITY(oth uint8) uint8 { 2407 return oth & 3 2408 }