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