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