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 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 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, alloc bool) int { 795 n := 3*4 + uint64(sz) + resoff%4 796 797 sh.type_ = SHT_NOTE 798 if alloc { 799 sh.flags = SHF_ALLOC 800 } 801 sh.addralign = 4 802 sh.addr = startva + resoff - n 803 sh.off = resoff - n 804 sh.size = n - resoff%4 805 806 return int(n) 807 } 808 809 func elfwritenotehdr(out *OutBuf, str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr { 810 sh := elfshname(str) 811 812 // Write Elf_Note header. 813 out.SeekSet(int64(sh.off)) 814 815 out.Write32(namesz) 816 out.Write32(descsz) 817 out.Write32(tag) 818 819 return sh 820 } 821 822 // NetBSD Signature (as per sys/exec_elf.h) 823 const ( 824 ELF_NOTE_NETBSD_NAMESZ = 7 825 ELF_NOTE_NETBSD_DESCSZ = 4 826 ELF_NOTE_NETBSD_TAG = 1 827 ELF_NOTE_NETBSD_VERSION = 599000000 /* NetBSD 5.99 */ 828 ) 829 830 var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00") 831 832 func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int { 833 n := int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4)) 834 return elfnote(sh, startva, resoff, n, true) 835 } 836 837 func elfwritenetbsdsig(out *OutBuf) int { 838 // Write Elf_Note header. 839 sh := elfwritenotehdr(out, ".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG) 840 841 if sh == nil { 842 return 0 843 } 844 845 // Followed by NetBSD string and version. 846 out.Write(ELF_NOTE_NETBSD_NAME) 847 out.Write8(0) 848 out.Write32(ELF_NOTE_NETBSD_VERSION) 849 850 return int(sh.size) 851 } 852 853 // OpenBSD Signature 854 const ( 855 ELF_NOTE_OPENBSD_NAMESZ = 8 856 ELF_NOTE_OPENBSD_DESCSZ = 4 857 ELF_NOTE_OPENBSD_TAG = 1 858 ELF_NOTE_OPENBSD_VERSION = 0 859 ) 860 861 var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00") 862 863 func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int { 864 n := ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ 865 return elfnote(sh, startva, resoff, n, true) 866 } 867 868 func elfwriteopenbsdsig(out *OutBuf) int { 869 // Write Elf_Note header. 870 sh := elfwritenotehdr(out, ".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG) 871 872 if sh == nil { 873 return 0 874 } 875 876 // Followed by OpenBSD string and version. 877 out.Write(ELF_NOTE_OPENBSD_NAME) 878 879 out.Write32(ELF_NOTE_OPENBSD_VERSION) 880 881 return int(sh.size) 882 } 883 884 func addbuildinfo(val string) { 885 if !strings.HasPrefix(val, "0x") { 886 Exitf("-B argument must start with 0x: %s", val) 887 } 888 889 ov := val 890 val = val[2:] 891 892 const maxLen = 32 893 if hex.DecodedLen(len(val)) > maxLen { 894 Exitf("-B option too long (max %d digits): %s", maxLen, ov) 895 } 896 897 b, err := hex.DecodeString(val) 898 if err != nil { 899 if err == hex.ErrLength { 900 Exitf("-B argument must have even number of digits: %s", ov) 901 } 902 if inv, ok := err.(hex.InvalidByteError); ok { 903 Exitf("-B argument contains invalid hex digit %c: %s", byte(inv), ov) 904 } 905 Exitf("-B argument contains invalid hex: %s", ov) 906 } 907 908 buildinfo = b 909 } 910 911 // Build info note 912 const ( 913 ELF_NOTE_BUILDINFO_NAMESZ = 4 914 ELF_NOTE_BUILDINFO_TAG = 3 915 ) 916 917 var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00") 918 919 func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int { 920 n := int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4)) 921 return elfnote(sh, startva, resoff, n, true) 922 } 923 924 func elfgobuildid(sh *ElfShdr, startva uint64, resoff uint64) int { 925 n := len(ELF_NOTE_GO_NAME) + int(Rnd(int64(len(*flagBuildid)), 4)) 926 return elfnote(sh, startva, resoff, n, true) 927 } 928 929 func elfwritebuildinfo(out *OutBuf) int { 930 sh := elfwritenotehdr(out, ".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG) 931 if sh == nil { 932 return 0 933 } 934 935 out.Write(ELF_NOTE_BUILDINFO_NAME) 936 out.Write(buildinfo) 937 var zero = make([]byte, 4) 938 out.Write(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))]) 939 940 return int(sh.size) 941 } 942 943 func elfwritegobuildid(out *OutBuf) int { 944 sh := elfwritenotehdr(out, ".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(*flagBuildid)), ELF_NOTE_GOBUILDID_TAG) 945 if sh == nil { 946 return 0 947 } 948 949 out.Write(ELF_NOTE_GO_NAME) 950 out.Write([]byte(*flagBuildid)) 951 var zero = make([]byte, 4) 952 out.Write(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))]) 953 954 return int(sh.size) 955 } 956 957 // Go specific notes 958 const ( 959 ELF_NOTE_GOPKGLIST_TAG = 1 960 ELF_NOTE_GOABIHASH_TAG = 2 961 ELF_NOTE_GODEPS_TAG = 3 962 ELF_NOTE_GOBUILDID_TAG = 4 963 ) 964 965 var ELF_NOTE_GO_NAME = []byte("Go\x00\x00") 966 967 var elfverneed int 968 969 type Elfaux struct { 970 next *Elfaux 971 num int 972 vers string 973 } 974 975 type Elflib struct { 976 next *Elflib 977 aux *Elfaux 978 file string 979 } 980 981 func addelflib(list **Elflib, file string, vers string) *Elfaux { 982 var lib *Elflib 983 984 for lib = *list; lib != nil; lib = lib.next { 985 if lib.file == file { 986 goto havelib 987 } 988 } 989 lib = new(Elflib) 990 lib.next = *list 991 lib.file = file 992 *list = lib 993 994 havelib: 995 for aux := lib.aux; aux != nil; aux = aux.next { 996 if aux.vers == vers { 997 return aux 998 } 999 } 1000 aux := new(Elfaux) 1001 aux.next = lib.aux 1002 aux.vers = vers 1003 lib.aux = aux 1004 1005 return aux 1006 } 1007 1008 func elfdynhash(ctxt *Link) { 1009 if !ctxt.IsELF { 1010 return 1011 } 1012 1013 nsym := Nelfsym 1014 s := ctxt.Syms.Lookup(".hash", 0) 1015 s.Type = sym.SELFROSECT 1016 s.Attr |= sym.AttrReachable 1017 1018 i := nsym 1019 nbucket := 1 1020 for i > 0 { 1021 nbucket++ 1022 i >>= 1 1023 } 1024 1025 var needlib *Elflib 1026 need := make([]*Elfaux, nsym) 1027 chain := make([]uint32, nsym) 1028 buckets := make([]uint32, nbucket) 1029 1030 for _, sy := range ctxt.Syms.Allsym { 1031 if sy.Dynid <= 0 { 1032 continue 1033 } 1034 1035 if sy.Dynimpvers != "" { 1036 need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib, sy.Dynimpvers) 1037 } 1038 1039 name := sy.Extname 1040 hc := elfhash(name) 1041 1042 b := hc % uint32(nbucket) 1043 chain[sy.Dynid] = buckets[b] 1044 buckets[b] = uint32(sy.Dynid) 1045 } 1046 1047 // s390x (ELF64) hash table entries are 8 bytes 1048 if ctxt.Arch.Family == sys.S390X { 1049 s.AddUint64(ctxt.Arch, uint64(nbucket)) 1050 s.AddUint64(ctxt.Arch, uint64(nsym)) 1051 for i := 0; i < nbucket; i++ { 1052 s.AddUint64(ctxt.Arch, uint64(buckets[i])) 1053 } 1054 for i := 0; i < nsym; i++ { 1055 s.AddUint64(ctxt.Arch, uint64(chain[i])) 1056 } 1057 } else { 1058 s.AddUint32(ctxt.Arch, uint32(nbucket)) 1059 s.AddUint32(ctxt.Arch, uint32(nsym)) 1060 for i := 0; i < nbucket; i++ { 1061 s.AddUint32(ctxt.Arch, buckets[i]) 1062 } 1063 for i := 0; i < nsym; i++ { 1064 s.AddUint32(ctxt.Arch, chain[i]) 1065 } 1066 } 1067 1068 // version symbols 1069 dynstr := ctxt.Syms.Lookup(".dynstr", 0) 1070 1071 s = ctxt.Syms.Lookup(".gnu.version_r", 0) 1072 i = 2 1073 nfile := 0 1074 for l := needlib; l != nil; l = l.next { 1075 nfile++ 1076 1077 // header 1078 s.AddUint16(ctxt.Arch, 1) // table version 1079 j := 0 1080 for x := l.aux; x != nil; x = x.next { 1081 j++ 1082 } 1083 s.AddUint16(ctxt.Arch, uint16(j)) // aux count 1084 s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, l.file))) // file string offset 1085 s.AddUint32(ctxt.Arch, 16) // offset from header to first aux 1086 if l.next != nil { 1087 s.AddUint32(ctxt.Arch, 16+uint32(j)*16) // offset from this header to next 1088 } else { 1089 s.AddUint32(ctxt.Arch, 0) 1090 } 1091 1092 for x := l.aux; x != nil; x = x.next { 1093 x.num = i 1094 i++ 1095 1096 // aux struct 1097 s.AddUint32(ctxt.Arch, elfhash(x.vers)) // hash 1098 s.AddUint16(ctxt.Arch, 0) // flags 1099 s.AddUint16(ctxt.Arch, uint16(x.num)) // other - index we refer to this by 1100 s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, x.vers))) // version string offset 1101 if x.next != nil { 1102 s.AddUint32(ctxt.Arch, 16) // offset from this aux to next 1103 } else { 1104 s.AddUint32(ctxt.Arch, 0) 1105 } 1106 } 1107 } 1108 1109 // version references 1110 s = ctxt.Syms.Lookup(".gnu.version", 0) 1111 1112 for i := 0; i < nsym; i++ { 1113 if i == 0 { 1114 s.AddUint16(ctxt.Arch, 0) // first entry - no symbol 1115 } else if need[i] == nil { 1116 s.AddUint16(ctxt.Arch, 1) // global 1117 } else { 1118 s.AddUint16(ctxt.Arch, uint16(need[i].num)) 1119 } 1120 } 1121 1122 s = ctxt.Syms.Lookup(".dynamic", 0) 1123 elfverneed = nfile 1124 if elfverneed != 0 { 1125 elfwritedynentsym(ctxt, s, DT_VERNEED, ctxt.Syms.Lookup(".gnu.version_r", 0)) 1126 Elfwritedynent(ctxt, s, DT_VERNEEDNUM, uint64(nfile)) 1127 elfwritedynentsym(ctxt, s, DT_VERSYM, ctxt.Syms.Lookup(".gnu.version", 0)) 1128 } 1129 1130 sy := ctxt.Syms.Lookup(elfRelType+".plt", 0) 1131 if sy.Size > 0 { 1132 if elfRelType == ".rela" { 1133 Elfwritedynent(ctxt, s, DT_PLTREL, DT_RELA) 1134 } else { 1135 Elfwritedynent(ctxt, s, DT_PLTREL, DT_REL) 1136 } 1137 elfwritedynentsymsize(ctxt, s, DT_PLTRELSZ, sy) 1138 elfwritedynentsym(ctxt, s, DT_JMPREL, sy) 1139 } 1140 1141 Elfwritedynent(ctxt, s, DT_NULL, 0) 1142 } 1143 1144 func elfphload(seg *sym.Segment) *ElfPhdr { 1145 ph := newElfPhdr() 1146 ph.type_ = PT_LOAD 1147 if seg.Rwx&4 != 0 { 1148 ph.flags |= PF_R 1149 } 1150 if seg.Rwx&2 != 0 { 1151 ph.flags |= PF_W 1152 } 1153 if seg.Rwx&1 != 0 { 1154 ph.flags |= PF_X 1155 } 1156 ph.vaddr = seg.Vaddr 1157 ph.paddr = seg.Vaddr 1158 ph.memsz = seg.Length 1159 ph.off = seg.Fileoff 1160 ph.filesz = seg.Filelen 1161 ph.align = uint64(*FlagRound) 1162 1163 return ph 1164 } 1165 1166 func elfphrelro(seg *sym.Segment) { 1167 ph := newElfPhdr() 1168 ph.type_ = PT_GNU_RELRO 1169 ph.vaddr = seg.Vaddr 1170 ph.paddr = seg.Vaddr 1171 ph.memsz = seg.Length 1172 ph.off = seg.Fileoff 1173 ph.filesz = seg.Filelen 1174 ph.align = uint64(*FlagRound) 1175 } 1176 1177 func elfshname(name string) *ElfShdr { 1178 for i := 0; i < nelfstr; i++ { 1179 if name != elfstr[i].s { 1180 continue 1181 } 1182 off := elfstr[i].off 1183 for i = 0; i < int(ehdr.shnum); i++ { 1184 sh := shdr[i] 1185 if sh.name == uint32(off) { 1186 return sh 1187 } 1188 } 1189 return newElfShdr(int64(off)) 1190 } 1191 Exitf("cannot find elf name %s", name) 1192 return nil 1193 } 1194 1195 // Create an ElfShdr for the section with name. 1196 // Create a duplicate if one already exists with that name 1197 func elfshnamedup(name string) *ElfShdr { 1198 for i := 0; i < nelfstr; i++ { 1199 if name == elfstr[i].s { 1200 off := elfstr[i].off 1201 return newElfShdr(int64(off)) 1202 } 1203 } 1204 1205 Errorf(nil, "cannot find elf name %s", name) 1206 errorexit() 1207 return nil 1208 } 1209 1210 func elfshalloc(sect *sym.Section) *ElfShdr { 1211 sh := elfshname(sect.Name) 1212 sect.Elfsect = sh 1213 return sh 1214 } 1215 1216 func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr { 1217 var sh *ElfShdr 1218 1219 if sect.Name == ".text" { 1220 if sect.Elfsect == nil { 1221 sect.Elfsect = elfshnamedup(sect.Name) 1222 } 1223 sh = sect.Elfsect.(*ElfShdr) 1224 } else { 1225 sh = elfshalloc(sect) 1226 } 1227 1228 // If this section has already been set up as a note, we assume type_ and 1229 // flags are already correct, but the other fields still need filling in. 1230 if sh.type_ == SHT_NOTE { 1231 if linkmode != LinkExternal { 1232 // TODO(mwhudson): the approach here will work OK when 1233 // linking internally for notes that we want to be included 1234 // in a loadable segment (e.g. the abihash note) but not for 1235 // notes that we do not want to be mapped (e.g. the package 1236 // list note). The real fix is probably to define new values 1237 // for Symbol.Type corresponding to mapped and unmapped notes 1238 // and handle them in dodata(). 1239 Errorf(nil, "sh.type_ == SHT_NOTE in elfshbits when linking internally") 1240 } 1241 sh.addralign = uint64(sect.Align) 1242 sh.size = sect.Length 1243 sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr 1244 return sh 1245 } 1246 if sh.type_ > 0 { 1247 return sh 1248 } 1249 1250 if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen { 1251 sh.type_ = SHT_PROGBITS 1252 } else { 1253 sh.type_ = SHT_NOBITS 1254 } 1255 sh.flags = SHF_ALLOC 1256 if sect.Rwx&1 != 0 { 1257 sh.flags |= SHF_EXECINSTR 1258 } 1259 if sect.Rwx&2 != 0 { 1260 sh.flags |= SHF_WRITE 1261 } 1262 if sect.Name == ".tbss" { 1263 sh.flags |= SHF_TLS 1264 sh.type_ = SHT_NOBITS 1265 } 1266 if strings.HasPrefix(sect.Name, ".debug") { 1267 sh.flags = 0 1268 } 1269 1270 if linkmode != LinkExternal { 1271 sh.addr = sect.Vaddr 1272 } 1273 sh.addralign = uint64(sect.Align) 1274 sh.size = sect.Length 1275 if sect.Name != ".tbss" { 1276 sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr 1277 } 1278 1279 return sh 1280 } 1281 1282 func elfshreloc(arch *sys.Arch, sect *sym.Section) *ElfShdr { 1283 // If main section is SHT_NOBITS, nothing to relocate. 1284 // Also nothing to relocate in .shstrtab or notes. 1285 if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen { 1286 return nil 1287 } 1288 if sect.Name == ".shstrtab" || sect.Name == ".tbss" { 1289 return nil 1290 } 1291 if sect.Elfsect.(*ElfShdr).type_ == SHT_NOTE { 1292 return nil 1293 } 1294 1295 var typ int 1296 if elfRelType == ".rela" { 1297 typ = SHT_RELA 1298 } else { 1299 typ = SHT_REL 1300 } 1301 1302 sh := elfshname(elfRelType + sect.Name) 1303 // There could be multiple text sections but each needs 1304 // its own .rela.text. 1305 1306 if sect.Name == ".text" { 1307 if sh.info != 0 && sh.info != uint32(sect.Elfsect.(*ElfShdr).shnum) { 1308 sh = elfshnamedup(elfRelType + sect.Name) 1309 } 1310 } 1311 1312 sh.type_ = uint32(typ) 1313 sh.entsize = uint64(arch.RegSize) * 2 1314 if typ == SHT_RELA { 1315 sh.entsize += uint64(arch.RegSize) 1316 } 1317 sh.link = uint32(elfshname(".symtab").shnum) 1318 sh.info = uint32(sect.Elfsect.(*ElfShdr).shnum) 1319 sh.off = sect.Reloff 1320 sh.size = sect.Rellen 1321 sh.addralign = uint64(arch.RegSize) 1322 return sh 1323 } 1324 1325 func elfrelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) { 1326 // If main section is SHT_NOBITS, nothing to relocate. 1327 // Also nothing to relocate in .shstrtab. 1328 if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen { 1329 return 1330 } 1331 if sect.Name == ".shstrtab" { 1332 return 1333 } 1334 1335 sect.Reloff = uint64(ctxt.Out.Offset()) 1336 for i, s := range syms { 1337 if !s.Attr.Reachable() { 1338 continue 1339 } 1340 if uint64(s.Value) >= sect.Vaddr { 1341 syms = syms[i:] 1342 break 1343 } 1344 } 1345 1346 eaddr := int32(sect.Vaddr + sect.Length) 1347 for _, s := range syms { 1348 if !s.Attr.Reachable() { 1349 continue 1350 } 1351 if s.Value >= int64(eaddr) { 1352 break 1353 } 1354 for ri := 0; ri < len(s.R); ri++ { 1355 r := &s.R[ri] 1356 if r.Done { 1357 continue 1358 } 1359 if r.Xsym == nil { 1360 Errorf(s, "missing xsym in relocation %#v %#v", r.Sym.Name, s) 1361 continue 1362 } 1363 if r.Xsym.ElfsymForReloc() == 0 { 1364 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) 1365 } 1366 if !r.Xsym.Attr.Reachable() { 1367 Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name) 1368 } 1369 if !Thearch.Elfreloc1(ctxt, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) { 1370 Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name) 1371 } 1372 } 1373 } 1374 1375 sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff 1376 } 1377 1378 func Elfemitreloc(ctxt *Link) { 1379 for ctxt.Out.Offset()&7 != 0 { 1380 ctxt.Out.Write8(0) 1381 } 1382 1383 for _, sect := range Segtext.Sections { 1384 if sect.Name == ".text" { 1385 elfrelocsect(ctxt, sect, ctxt.Textp) 1386 } else { 1387 elfrelocsect(ctxt, sect, datap) 1388 } 1389 } 1390 1391 for _, sect := range Segrodata.Sections { 1392 elfrelocsect(ctxt, sect, datap) 1393 } 1394 for _, sect := range Segrelrodata.Sections { 1395 elfrelocsect(ctxt, sect, datap) 1396 } 1397 for _, sect := range Segdata.Sections { 1398 elfrelocsect(ctxt, sect, datap) 1399 } 1400 for _, sect := range Segdwarf.Sections { 1401 elfrelocsect(ctxt, sect, dwarfp) 1402 } 1403 } 1404 1405 func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) { 1406 s := ctxt.Syms.Lookup(sectionName, 0) 1407 s.Attr |= sym.AttrReachable 1408 s.Type = sym.SELFROSECT 1409 // namesz 1410 s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME))) 1411 // descsz 1412 s.AddUint32(ctxt.Arch, uint32(len(desc))) 1413 // tag 1414 s.AddUint32(ctxt.Arch, tag) 1415 // name + padding 1416 s.P = append(s.P, ELF_NOTE_GO_NAME...) 1417 for len(s.P)%4 != 0 { 1418 s.P = append(s.P, 0) 1419 } 1420 // desc + padding 1421 s.P = append(s.P, desc...) 1422 for len(s.P)%4 != 0 { 1423 s.P = append(s.P, 0) 1424 } 1425 s.Size = int64(len(s.P)) 1426 s.Align = 4 1427 } 1428 1429 func (ctxt *Link) doelf() { 1430 if !ctxt.IsELF { 1431 return 1432 } 1433 1434 /* predefine strings we need for section headers */ 1435 shstrtab := ctxt.Syms.Lookup(".shstrtab", 0) 1436 1437 shstrtab.Type = sym.SELFROSECT 1438 shstrtab.Attr |= sym.AttrReachable 1439 1440 Addstring(shstrtab, "") 1441 Addstring(shstrtab, ".text") 1442 Addstring(shstrtab, ".noptrdata") 1443 Addstring(shstrtab, ".data") 1444 Addstring(shstrtab, ".bss") 1445 Addstring(shstrtab, ".noptrbss") 1446 1447 // generate .tbss section for dynamic internal linker or external 1448 // linking, so that various binutils could correctly calculate 1449 // PT_TLS size. See https://golang.org/issue/5200. 1450 if !*FlagD || ctxt.LinkMode == LinkExternal { 1451 Addstring(shstrtab, ".tbss") 1452 } 1453 if ctxt.HeadType == objabi.Hnetbsd { 1454 Addstring(shstrtab, ".note.netbsd.ident") 1455 } 1456 if ctxt.HeadType == objabi.Hopenbsd { 1457 Addstring(shstrtab, ".note.openbsd.ident") 1458 } 1459 if len(buildinfo) > 0 { 1460 Addstring(shstrtab, ".note.gnu.build-id") 1461 } 1462 if *flagBuildid != "" { 1463 Addstring(shstrtab, ".note.go.buildid") 1464 } 1465 Addstring(shstrtab, ".elfdata") 1466 Addstring(shstrtab, ".rodata") 1467 // See the comment about data.rel.ro.FOO section names in data.go. 1468 relro_prefix := "" 1469 if ctxt.UseRelro() { 1470 Addstring(shstrtab, ".data.rel.ro") 1471 relro_prefix = ".data.rel.ro" 1472 } 1473 Addstring(shstrtab, relro_prefix+".typelink") 1474 Addstring(shstrtab, relro_prefix+".itablink") 1475 Addstring(shstrtab, relro_prefix+".gosymtab") 1476 Addstring(shstrtab, relro_prefix+".gopclntab") 1477 1478 if ctxt.LinkMode == LinkExternal { 1479 *FlagD = true 1480 1481 Addstring(shstrtab, elfRelType+".text") 1482 Addstring(shstrtab, elfRelType+".rodata") 1483 Addstring(shstrtab, elfRelType+relro_prefix+".typelink") 1484 Addstring(shstrtab, elfRelType+relro_prefix+".itablink") 1485 Addstring(shstrtab, elfRelType+relro_prefix+".gosymtab") 1486 Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab") 1487 Addstring(shstrtab, elfRelType+".noptrdata") 1488 Addstring(shstrtab, elfRelType+".data") 1489 if ctxt.UseRelro() { 1490 Addstring(shstrtab, elfRelType+".data.rel.ro") 1491 } 1492 1493 // add a .note.GNU-stack section to mark the stack as non-executable 1494 Addstring(shstrtab, ".note.GNU-stack") 1495 1496 if ctxt.BuildMode == BuildModeShared { 1497 Addstring(shstrtab, ".note.go.abihash") 1498 Addstring(shstrtab, ".note.go.pkg-list") 1499 Addstring(shstrtab, ".note.go.deps") 1500 } 1501 } 1502 1503 hasinitarr := ctxt.linkShared 1504 1505 /* shared library initializer */ 1506 switch ctxt.BuildMode { 1507 case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin: 1508 hasinitarr = true 1509 } 1510 1511 if hasinitarr { 1512 Addstring(shstrtab, ".init_array") 1513 Addstring(shstrtab, elfRelType+".init_array") 1514 } 1515 1516 if !*FlagS { 1517 Addstring(shstrtab, ".symtab") 1518 Addstring(shstrtab, ".strtab") 1519 dwarfaddshstrings(ctxt, shstrtab) 1520 } 1521 1522 Addstring(shstrtab, ".shstrtab") 1523 1524 if !*FlagD { /* -d suppresses dynamic loader format */ 1525 Addstring(shstrtab, ".interp") 1526 Addstring(shstrtab, ".hash") 1527 Addstring(shstrtab, ".got") 1528 if ctxt.Arch.Family == sys.PPC64 { 1529 Addstring(shstrtab, ".glink") 1530 } 1531 Addstring(shstrtab, ".got.plt") 1532 Addstring(shstrtab, ".dynamic") 1533 Addstring(shstrtab, ".dynsym") 1534 Addstring(shstrtab, ".dynstr") 1535 Addstring(shstrtab, elfRelType) 1536 Addstring(shstrtab, elfRelType+".plt") 1537 1538 Addstring(shstrtab, ".plt") 1539 Addstring(shstrtab, ".gnu.version") 1540 Addstring(shstrtab, ".gnu.version_r") 1541 1542 /* dynamic symbol table - first entry all zeros */ 1543 s := ctxt.Syms.Lookup(".dynsym", 0) 1544 1545 s.Type = sym.SELFROSECT 1546 s.Attr |= sym.AttrReachable 1547 if elf64 { 1548 s.Size += ELF64SYMSIZE 1549 } else { 1550 s.Size += ELF32SYMSIZE 1551 } 1552 1553 /* dynamic string table */ 1554 s = ctxt.Syms.Lookup(".dynstr", 0) 1555 1556 s.Type = sym.SELFROSECT 1557 s.Attr |= sym.AttrReachable 1558 if s.Size == 0 { 1559 Addstring(s, "") 1560 } 1561 dynstr := s 1562 1563 /* relocation table */ 1564 s = ctxt.Syms.Lookup(elfRelType, 0) 1565 s.Attr |= sym.AttrReachable 1566 s.Type = sym.SELFROSECT 1567 1568 /* global offset table */ 1569 s = ctxt.Syms.Lookup(".got", 0) 1570 1571 s.Attr |= sym.AttrReachable 1572 s.Type = sym.SELFGOT // writable 1573 1574 /* ppc64 glink resolver */ 1575 if ctxt.Arch.Family == sys.PPC64 { 1576 s := ctxt.Syms.Lookup(".glink", 0) 1577 s.Attr |= sym.AttrReachable 1578 s.Type = sym.SELFRXSECT 1579 } 1580 1581 /* hash */ 1582 s = ctxt.Syms.Lookup(".hash", 0) 1583 1584 s.Attr |= sym.AttrReachable 1585 s.Type = sym.SELFROSECT 1586 1587 s = ctxt.Syms.Lookup(".got.plt", 0) 1588 s.Attr |= sym.AttrReachable 1589 s.Type = sym.SELFSECT // writable 1590 1591 s = ctxt.Syms.Lookup(".plt", 0) 1592 1593 s.Attr |= sym.AttrReachable 1594 if ctxt.Arch.Family == sys.PPC64 { 1595 // In the ppc64 ABI, .plt is a data section 1596 // written by the dynamic linker. 1597 s.Type = sym.SELFSECT 1598 } else { 1599 s.Type = sym.SELFRXSECT 1600 } 1601 1602 Thearch.Elfsetupplt(ctxt) 1603 1604 s = ctxt.Syms.Lookup(elfRelType+".plt", 0) 1605 s.Attr |= sym.AttrReachable 1606 s.Type = sym.SELFROSECT 1607 1608 s = ctxt.Syms.Lookup(".gnu.version", 0) 1609 s.Attr |= sym.AttrReachable 1610 s.Type = sym.SELFROSECT 1611 1612 s = ctxt.Syms.Lookup(".gnu.version_r", 0) 1613 s.Attr |= sym.AttrReachable 1614 s.Type = sym.SELFROSECT 1615 1616 /* define dynamic elf table */ 1617 s = ctxt.Syms.Lookup(".dynamic", 0) 1618 1619 s.Attr |= sym.AttrReachable 1620 s.Type = sym.SELFSECT // writable 1621 1622 /* 1623 * .dynamic table 1624 */ 1625 elfwritedynentsym(ctxt, s, DT_HASH, ctxt.Syms.Lookup(".hash", 0)) 1626 1627 elfwritedynentsym(ctxt, s, DT_SYMTAB, ctxt.Syms.Lookup(".dynsym", 0)) 1628 if elf64 { 1629 Elfwritedynent(ctxt, s, DT_SYMENT, ELF64SYMSIZE) 1630 } else { 1631 Elfwritedynent(ctxt, s, DT_SYMENT, ELF32SYMSIZE) 1632 } 1633 elfwritedynentsym(ctxt, s, DT_STRTAB, ctxt.Syms.Lookup(".dynstr", 0)) 1634 elfwritedynentsymsize(ctxt, s, DT_STRSZ, ctxt.Syms.Lookup(".dynstr", 0)) 1635 if elfRelType == ".rela" { 1636 elfwritedynentsym(ctxt, s, DT_RELA, ctxt.Syms.Lookup(".rela", 0)) 1637 elfwritedynentsymsize(ctxt, s, DT_RELASZ, ctxt.Syms.Lookup(".rela", 0)) 1638 Elfwritedynent(ctxt, s, DT_RELAENT, ELF64RELASIZE) 1639 } else { 1640 elfwritedynentsym(ctxt, s, DT_REL, ctxt.Syms.Lookup(".rel", 0)) 1641 elfwritedynentsymsize(ctxt, s, DT_RELSZ, ctxt.Syms.Lookup(".rel", 0)) 1642 Elfwritedynent(ctxt, s, DT_RELENT, ELF32RELSIZE) 1643 } 1644 1645 if rpath.val != "" { 1646 Elfwritedynent(ctxt, s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val))) 1647 } 1648 1649 if ctxt.Arch.Family == sys.PPC64 { 1650 elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".plt", 0)) 1651 } else if ctxt.Arch.Family == sys.S390X { 1652 elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got", 0)) 1653 } else { 1654 elfwritedynentsym(ctxt, s, DT_PLTGOT, ctxt.Syms.Lookup(".got.plt", 0)) 1655 } 1656 1657 if ctxt.Arch.Family == sys.PPC64 { 1658 Elfwritedynent(ctxt, s, DT_PPC64_OPT, 0) 1659 } 1660 1661 // Solaris dynamic linker can't handle an empty .rela.plt if 1662 // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL, 1663 // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the 1664 // size of .rel(a).plt section. 1665 Elfwritedynent(ctxt, s, DT_DEBUG, 0) 1666 } 1667 1668 if ctxt.BuildMode == BuildModeShared { 1669 // The go.link.abihashbytes symbol will be pointed at the appropriate 1670 // part of the .note.go.abihash section in data.go:func address(). 1671 s := ctxt.Syms.Lookup("go.link.abihashbytes", 0) 1672 s.Attr |= sym.AttrLocal 1673 s.Type = sym.SRODATA 1674 s.Attr |= sym.AttrSpecial 1675 s.Attr |= sym.AttrReachable 1676 s.Size = int64(sha1.Size) 1677 1678 sort.Sort(byPkg(ctxt.Library)) 1679 h := sha1.New() 1680 for _, l := range ctxt.Library { 1681 io.WriteString(h, l.Hash) 1682 } 1683 addgonote(ctxt, ".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{})) 1684 addgonote(ctxt, ".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote) 1685 var deplist []string 1686 for _, shlib := range ctxt.Shlibs { 1687 deplist = append(deplist, filepath.Base(shlib.Path)) 1688 } 1689 addgonote(ctxt, ".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n"))) 1690 } 1691 1692 if ctxt.LinkMode == LinkExternal && *flagBuildid != "" { 1693 addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(*flagBuildid)) 1694 } 1695 } 1696 1697 // Do not write DT_NULL. elfdynhash will finish it. 1698 func shsym(sh *ElfShdr, s *sym.Symbol) { 1699 addr := Symaddr(s) 1700 if sh.flags&SHF_ALLOC != 0 { 1701 sh.addr = uint64(addr) 1702 } 1703 sh.off = uint64(datoff(s, addr)) 1704 sh.size = uint64(s.Size) 1705 } 1706 1707 func phsh(ph *ElfPhdr, sh *ElfShdr) { 1708 ph.vaddr = sh.addr 1709 ph.paddr = ph.vaddr 1710 ph.off = sh.off 1711 ph.filesz = sh.size 1712 ph.memsz = sh.size 1713 ph.align = sh.addralign 1714 } 1715 1716 func Asmbelfsetup() { 1717 /* This null SHdr must appear before all others */ 1718 elfshname("") 1719 1720 for _, sect := range Segtext.Sections { 1721 // There could be multiple .text sections. Instead check the Elfsect 1722 // field to determine if already has an ElfShdr and if not, create one. 1723 if sect.Name == ".text" { 1724 if sect.Elfsect == nil { 1725 sect.Elfsect = elfshnamedup(sect.Name) 1726 } 1727 } else { 1728 elfshalloc(sect) 1729 } 1730 } 1731 for _, sect := range Segrodata.Sections { 1732 elfshalloc(sect) 1733 } 1734 for _, sect := range Segrelrodata.Sections { 1735 elfshalloc(sect) 1736 } 1737 for _, sect := range Segdata.Sections { 1738 elfshalloc(sect) 1739 } 1740 for _, sect := range Segdwarf.Sections { 1741 elfshalloc(sect) 1742 } 1743 } 1744 1745 func Asmbelf(ctxt *Link, symo int64) { 1746 eh := getElfEhdr() 1747 switch ctxt.Arch.Family { 1748 default: 1749 Exitf("unknown architecture in asmbelf: %v", ctxt.Arch.Family) 1750 case sys.MIPS, sys.MIPS64: 1751 eh.machine = EM_MIPS 1752 case sys.ARM: 1753 eh.machine = EM_ARM 1754 case sys.AMD64: 1755 eh.machine = EM_X86_64 1756 case sys.ARM64: 1757 eh.machine = EM_AARCH64 1758 case sys.I386: 1759 eh.machine = EM_386 1760 case sys.PPC64: 1761 eh.machine = EM_PPC64 1762 case sys.S390X: 1763 eh.machine = EM_S390 1764 } 1765 1766 elfreserve := int64(ELFRESERVE) 1767 1768 numtext := int64(0) 1769 for _, sect := range Segtext.Sections { 1770 if sect.Name == ".text" { 1771 numtext++ 1772 } 1773 } 1774 1775 // If there are multiple text sections, extra space is needed 1776 // in the elfreserve for the additional .text and .rela.text 1777 // section headers. It can handle 4 extra now. Headers are 1778 // 64 bytes. 1779 1780 if numtext > 4 { 1781 elfreserve += elfreserve + numtext*64*2 1782 } 1783 1784 startva := *FlagTextAddr - int64(HEADR) 1785 resoff := elfreserve 1786 1787 var pph *ElfPhdr 1788 var pnote *ElfPhdr 1789 if ctxt.LinkMode == LinkExternal { 1790 /* skip program headers */ 1791 eh.phoff = 0 1792 1793 eh.phentsize = 0 1794 1795 if ctxt.BuildMode == BuildModeShared { 1796 sh := elfshname(".note.go.pkg-list") 1797 sh.type_ = SHT_NOTE 1798 sh = elfshname(".note.go.abihash") 1799 sh.type_ = SHT_NOTE 1800 sh.flags = SHF_ALLOC 1801 sh = elfshname(".note.go.deps") 1802 sh.type_ = SHT_NOTE 1803 } 1804 1805 if *flagBuildid != "" { 1806 sh := elfshname(".note.go.buildid") 1807 sh.type_ = SHT_NOTE 1808 sh.flags = SHF_ALLOC 1809 } 1810 1811 goto elfobj 1812 } 1813 1814 /* program header info */ 1815 pph = newElfPhdr() 1816 1817 pph.type_ = PT_PHDR 1818 pph.flags = PF_R 1819 pph.off = uint64(eh.ehsize) 1820 pph.vaddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off 1821 pph.paddr = uint64(*FlagTextAddr) - uint64(HEADR) + pph.off 1822 pph.align = uint64(*FlagRound) 1823 1824 /* 1825 * PHDR must be in a loaded segment. Adjust the text 1826 * segment boundaries downwards to include it. 1827 * Except on NaCl where it must not be loaded. 1828 */ 1829 if ctxt.HeadType != objabi.Hnacl { 1830 o := int64(Segtext.Vaddr - pph.vaddr) 1831 Segtext.Vaddr -= uint64(o) 1832 Segtext.Length += uint64(o) 1833 o = int64(Segtext.Fileoff - pph.off) 1834 Segtext.Fileoff -= uint64(o) 1835 Segtext.Filelen += uint64(o) 1836 } 1837 1838 if !*FlagD { /* -d suppresses dynamic loader format */ 1839 /* interpreter */ 1840 sh := elfshname(".interp") 1841 1842 sh.type_ = SHT_PROGBITS 1843 sh.flags = SHF_ALLOC 1844 sh.addralign = 1 1845 if interpreter == "" { 1846 switch ctxt.HeadType { 1847 case objabi.Hlinux: 1848 interpreter = Thearch.Linuxdynld 1849 1850 case objabi.Hfreebsd: 1851 interpreter = Thearch.Freebsddynld 1852 1853 case objabi.Hnetbsd: 1854 interpreter = Thearch.Netbsddynld 1855 1856 case objabi.Hopenbsd: 1857 interpreter = Thearch.Openbsddynld 1858 1859 case objabi.Hdragonfly: 1860 interpreter = Thearch.Dragonflydynld 1861 1862 case objabi.Hsolaris: 1863 interpreter = Thearch.Solarisdynld 1864 } 1865 } 1866 1867 resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter)) 1868 1869 ph := newElfPhdr() 1870 ph.type_ = PT_INTERP 1871 ph.flags = PF_R 1872 phsh(ph, sh) 1873 } 1874 1875 pnote = nil 1876 if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd { 1877 var sh *ElfShdr 1878 switch ctxt.HeadType { 1879 case objabi.Hnetbsd: 1880 sh = elfshname(".note.netbsd.ident") 1881 resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff))) 1882 1883 case objabi.Hopenbsd: 1884 sh = elfshname(".note.openbsd.ident") 1885 resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff))) 1886 } 1887 1888 pnote = newElfPhdr() 1889 pnote.type_ = PT_NOTE 1890 pnote.flags = PF_R 1891 phsh(pnote, sh) 1892 } 1893 1894 if len(buildinfo) > 0 { 1895 sh := elfshname(".note.gnu.build-id") 1896 resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff))) 1897 1898 if pnote == nil { 1899 pnote = newElfPhdr() 1900 pnote.type_ = PT_NOTE 1901 pnote.flags = PF_R 1902 } 1903 1904 phsh(pnote, sh) 1905 } 1906 1907 if *flagBuildid != "" { 1908 sh := elfshname(".note.go.buildid") 1909 resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff))) 1910 1911 pnote := newElfPhdr() 1912 pnote.type_ = PT_NOTE 1913 pnote.flags = PF_R 1914 phsh(pnote, sh) 1915 } 1916 1917 // Additions to the reserved area must be above this line. 1918 1919 elfphload(&Segtext) 1920 if len(Segrodata.Sections) > 0 { 1921 elfphload(&Segrodata) 1922 } 1923 if len(Segrelrodata.Sections) > 0 { 1924 elfphload(&Segrelrodata) 1925 elfphrelro(&Segrelrodata) 1926 } 1927 elfphload(&Segdata) 1928 1929 /* Dynamic linking sections */ 1930 if !*FlagD { 1931 sh := elfshname(".dynsym") 1932 sh.type_ = SHT_DYNSYM 1933 sh.flags = SHF_ALLOC 1934 if elf64 { 1935 sh.entsize = ELF64SYMSIZE 1936 } else { 1937 sh.entsize = ELF32SYMSIZE 1938 } 1939 sh.addralign = uint64(ctxt.Arch.RegSize) 1940 sh.link = uint32(elfshname(".dynstr").shnum) 1941 1942 // sh->info = index of first non-local symbol (number of local symbols) 1943 shsym(sh, ctxt.Syms.Lookup(".dynsym", 0)) 1944 1945 sh = elfshname(".dynstr") 1946 sh.type_ = SHT_STRTAB 1947 sh.flags = SHF_ALLOC 1948 sh.addralign = 1 1949 shsym(sh, ctxt.Syms.Lookup(".dynstr", 0)) 1950 1951 if elfverneed != 0 { 1952 sh := elfshname(".gnu.version") 1953 sh.type_ = SHT_GNU_VERSYM 1954 sh.flags = SHF_ALLOC 1955 sh.addralign = 2 1956 sh.link = uint32(elfshname(".dynsym").shnum) 1957 sh.entsize = 2 1958 shsym(sh, ctxt.Syms.Lookup(".gnu.version", 0)) 1959 1960 sh = elfshname(".gnu.version_r") 1961 sh.type_ = SHT_GNU_VERNEED 1962 sh.flags = SHF_ALLOC 1963 sh.addralign = uint64(ctxt.Arch.RegSize) 1964 sh.info = uint32(elfverneed) 1965 sh.link = uint32(elfshname(".dynstr").shnum) 1966 shsym(sh, ctxt.Syms.Lookup(".gnu.version_r", 0)) 1967 } 1968 1969 if elfRelType == ".rela" { 1970 sh := elfshname(".rela.plt") 1971 sh.type_ = SHT_RELA 1972 sh.flags = SHF_ALLOC 1973 sh.entsize = ELF64RELASIZE 1974 sh.addralign = uint64(ctxt.Arch.RegSize) 1975 sh.link = uint32(elfshname(".dynsym").shnum) 1976 sh.info = uint32(elfshname(".plt").shnum) 1977 shsym(sh, ctxt.Syms.Lookup(".rela.plt", 0)) 1978 1979 sh = elfshname(".rela") 1980 sh.type_ = SHT_RELA 1981 sh.flags = SHF_ALLOC 1982 sh.entsize = ELF64RELASIZE 1983 sh.addralign = 8 1984 sh.link = uint32(elfshname(".dynsym").shnum) 1985 shsym(sh, ctxt.Syms.Lookup(".rela", 0)) 1986 } else { 1987 sh := elfshname(".rel.plt") 1988 sh.type_ = SHT_REL 1989 sh.flags = SHF_ALLOC 1990 sh.entsize = ELF32RELSIZE 1991 sh.addralign = 4 1992 sh.link = uint32(elfshname(".dynsym").shnum) 1993 shsym(sh, ctxt.Syms.Lookup(".rel.plt", 0)) 1994 1995 sh = elfshname(".rel") 1996 sh.type_ = SHT_REL 1997 sh.flags = SHF_ALLOC 1998 sh.entsize = ELF32RELSIZE 1999 sh.addralign = 4 2000 sh.link = uint32(elfshname(".dynsym").shnum) 2001 shsym(sh, ctxt.Syms.Lookup(".rel", 0)) 2002 } 2003 2004 if eh.machine == EM_PPC64 { 2005 sh := elfshname(".glink") 2006 sh.type_ = SHT_PROGBITS 2007 sh.flags = SHF_ALLOC + SHF_EXECINSTR 2008 sh.addralign = 4 2009 shsym(sh, ctxt.Syms.Lookup(".glink", 0)) 2010 } 2011 2012 sh = elfshname(".plt") 2013 sh.type_ = SHT_PROGBITS 2014 sh.flags = SHF_ALLOC + SHF_EXECINSTR 2015 if eh.machine == EM_X86_64 { 2016 sh.entsize = 16 2017 } else if eh.machine == EM_S390 { 2018 sh.entsize = 32 2019 } else if eh.machine == EM_PPC64 { 2020 // On ppc64, this is just a table of addresses 2021 // filled by the dynamic linker 2022 sh.type_ = SHT_NOBITS 2023 2024 sh.flags = SHF_ALLOC + SHF_WRITE 2025 sh.entsize = 8 2026 } else { 2027 sh.entsize = 4 2028 } 2029 sh.addralign = sh.entsize 2030 shsym(sh, ctxt.Syms.Lookup(".plt", 0)) 2031 2032 // On ppc64, .got comes from the input files, so don't 2033 // create it here, and .got.plt is not used. 2034 if eh.machine != EM_PPC64 { 2035 sh := elfshname(".got") 2036 sh.type_ = SHT_PROGBITS 2037 sh.flags = SHF_ALLOC + SHF_WRITE 2038 sh.entsize = uint64(ctxt.Arch.RegSize) 2039 sh.addralign = uint64(ctxt.Arch.RegSize) 2040 shsym(sh, ctxt.Syms.Lookup(".got", 0)) 2041 2042 sh = elfshname(".got.plt") 2043 sh.type_ = SHT_PROGBITS 2044 sh.flags = SHF_ALLOC + SHF_WRITE 2045 sh.entsize = uint64(ctxt.Arch.RegSize) 2046 sh.addralign = uint64(ctxt.Arch.RegSize) 2047 shsym(sh, ctxt.Syms.Lookup(".got.plt", 0)) 2048 } 2049 2050 sh = elfshname(".hash") 2051 sh.type_ = SHT_HASH 2052 sh.flags = SHF_ALLOC 2053 sh.entsize = 4 2054 sh.addralign = uint64(ctxt.Arch.RegSize) 2055 sh.link = uint32(elfshname(".dynsym").shnum) 2056 shsym(sh, ctxt.Syms.Lookup(".hash", 0)) 2057 2058 /* sh and PT_DYNAMIC for .dynamic section */ 2059 sh = elfshname(".dynamic") 2060 2061 sh.type_ = SHT_DYNAMIC 2062 sh.flags = SHF_ALLOC + SHF_WRITE 2063 sh.entsize = 2 * uint64(ctxt.Arch.RegSize) 2064 sh.addralign = uint64(ctxt.Arch.RegSize) 2065 sh.link = uint32(elfshname(".dynstr").shnum) 2066 shsym(sh, ctxt.Syms.Lookup(".dynamic", 0)) 2067 ph := newElfPhdr() 2068 ph.type_ = PT_DYNAMIC 2069 ph.flags = PF_R + PF_W 2070 phsh(ph, sh) 2071 2072 /* 2073 * Thread-local storage segment (really just size). 2074 */ 2075 tlssize := uint64(0) 2076 for _, sect := range Segdata.Sections { 2077 if sect.Name == ".tbss" { 2078 tlssize = sect.Length 2079 } 2080 } 2081 if tlssize != 0 { 2082 ph := newElfPhdr() 2083 ph.type_ = PT_TLS 2084 ph.flags = PF_R 2085 ph.memsz = tlssize 2086 ph.align = uint64(ctxt.Arch.RegSize) 2087 } 2088 } 2089 2090 if ctxt.HeadType == objabi.Hlinux { 2091 ph := newElfPhdr() 2092 ph.type_ = PT_GNU_STACK 2093 ph.flags = PF_W + PF_R 2094 ph.align = uint64(ctxt.Arch.RegSize) 2095 2096 ph = newElfPhdr() 2097 ph.type_ = PT_PAX_FLAGS 2098 ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled 2099 ph.align = uint64(ctxt.Arch.RegSize) 2100 } else if ctxt.HeadType == objabi.Hsolaris { 2101 ph := newElfPhdr() 2102 ph.type_ = PT_SUNWSTACK 2103 ph.flags = PF_W + PF_R 2104 } 2105 2106 elfobj: 2107 sh := elfshname(".shstrtab") 2108 sh.type_ = SHT_STRTAB 2109 sh.addralign = 1 2110 shsym(sh, ctxt.Syms.Lookup(".shstrtab", 0)) 2111 eh.shstrndx = uint16(sh.shnum) 2112 2113 // put these sections early in the list 2114 if !*FlagS { 2115 elfshname(".symtab") 2116 elfshname(".strtab") 2117 } 2118 2119 for _, sect := range Segtext.Sections { 2120 elfshbits(ctxt.LinkMode, sect) 2121 } 2122 for _, sect := range Segrodata.Sections { 2123 elfshbits(ctxt.LinkMode, sect) 2124 } 2125 for _, sect := range Segrelrodata.Sections { 2126 elfshbits(ctxt.LinkMode, sect) 2127 } 2128 for _, sect := range Segdata.Sections { 2129 elfshbits(ctxt.LinkMode, sect) 2130 } 2131 for _, sect := range Segdwarf.Sections { 2132 elfshbits(ctxt.LinkMode, sect) 2133 } 2134 2135 if ctxt.LinkMode == LinkExternal { 2136 for _, sect := range Segtext.Sections { 2137 elfshreloc(ctxt.Arch, sect) 2138 } 2139 for _, sect := range Segrodata.Sections { 2140 elfshreloc(ctxt.Arch, sect) 2141 } 2142 for _, sect := range Segrelrodata.Sections { 2143 elfshreloc(ctxt.Arch, sect) 2144 } 2145 for _, sect := range Segdata.Sections { 2146 elfshreloc(ctxt.Arch, sect) 2147 } 2148 for _, s := range dwarfp { 2149 if len(s.R) > 0 || s.Type == sym.SDWARFINFO || s.Type == sym.SDWARFLOC { 2150 elfshreloc(ctxt.Arch, s.Sect) 2151 } 2152 } 2153 // add a .note.GNU-stack section to mark the stack as non-executable 2154 sh := elfshname(".note.GNU-stack") 2155 2156 sh.type_ = SHT_PROGBITS 2157 sh.addralign = 1 2158 sh.flags = 0 2159 } 2160 2161 if !*FlagS { 2162 sh := elfshname(".symtab") 2163 sh.type_ = SHT_SYMTAB 2164 sh.off = uint64(symo) 2165 sh.size = uint64(Symsize) 2166 sh.addralign = uint64(ctxt.Arch.RegSize) 2167 sh.entsize = 8 + 2*uint64(ctxt.Arch.RegSize) 2168 sh.link = uint32(elfshname(".strtab").shnum) 2169 sh.info = uint32(elfglobalsymndx) 2170 2171 sh = elfshname(".strtab") 2172 sh.type_ = SHT_STRTAB 2173 sh.off = uint64(symo) + uint64(Symsize) 2174 sh.size = uint64(len(Elfstrdat)) 2175 sh.addralign = 1 2176 } 2177 2178 /* Main header */ 2179 eh.ident[EI_MAG0] = '\177' 2180 2181 eh.ident[EI_MAG1] = 'E' 2182 eh.ident[EI_MAG2] = 'L' 2183 eh.ident[EI_MAG3] = 'F' 2184 if ctxt.HeadType == objabi.Hfreebsd { 2185 eh.ident[EI_OSABI] = ELFOSABI_FREEBSD 2186 } else if ctxt.HeadType == objabi.Hnetbsd { 2187 eh.ident[EI_OSABI] = ELFOSABI_NETBSD 2188 } else if ctxt.HeadType == objabi.Hopenbsd { 2189 eh.ident[EI_OSABI] = ELFOSABI_OPENBSD 2190 } else if ctxt.HeadType == objabi.Hdragonfly { 2191 eh.ident[EI_OSABI] = ELFOSABI_NONE 2192 } 2193 if elf64 { 2194 eh.ident[EI_CLASS] = ELFCLASS64 2195 } else { 2196 eh.ident[EI_CLASS] = ELFCLASS32 2197 } 2198 if ctxt.Arch.ByteOrder == binary.BigEndian { 2199 eh.ident[EI_DATA] = ELFDATA2MSB 2200 } else { 2201 eh.ident[EI_DATA] = ELFDATA2LSB 2202 } 2203 eh.ident[EI_VERSION] = EV_CURRENT 2204 2205 if ctxt.LinkMode == LinkExternal { 2206 eh.type_ = ET_REL 2207 } else if ctxt.BuildMode == BuildModePIE { 2208 eh.type_ = ET_DYN 2209 } else { 2210 eh.type_ = ET_EXEC 2211 } 2212 2213 if ctxt.LinkMode != LinkExternal { 2214 eh.entry = uint64(Entryvalue(ctxt)) 2215 } 2216 2217 eh.version = EV_CURRENT 2218 2219 if pph != nil { 2220 pph.filesz = uint64(eh.phnum) * uint64(eh.phentsize) 2221 pph.memsz = pph.filesz 2222 } 2223 2224 ctxt.Out.SeekSet(0) 2225 a := int64(0) 2226 a += int64(elfwritehdr(ctxt.Out)) 2227 a += int64(elfwritephdrs(ctxt.Out)) 2228 a += int64(elfwriteshdrs(ctxt.Out)) 2229 if !*FlagD { 2230 a += int64(elfwriteinterp(ctxt.Out)) 2231 } 2232 if ctxt.LinkMode != LinkExternal { 2233 if ctxt.HeadType == objabi.Hnetbsd { 2234 a += int64(elfwritenetbsdsig(ctxt.Out)) 2235 } 2236 if ctxt.HeadType == objabi.Hopenbsd { 2237 a += int64(elfwriteopenbsdsig(ctxt.Out)) 2238 } 2239 if len(buildinfo) > 0 { 2240 a += int64(elfwritebuildinfo(ctxt.Out)) 2241 } 2242 if *flagBuildid != "" { 2243 a += int64(elfwritegobuildid(ctxt.Out)) 2244 } 2245 } 2246 2247 if a > elfreserve { 2248 Errorf(nil, "ELFRESERVE too small: %d > %d with %d text sections", a, elfreserve, numtext) 2249 } 2250 } 2251 2252 func elfadddynsym(ctxt *Link, s *sym.Symbol) { 2253 if elf64 { 2254 s.Dynid = int32(Nelfsym) 2255 Nelfsym++ 2256 2257 d := ctxt.Syms.Lookup(".dynsym", 0) 2258 2259 name := s.Extname 2260 d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name))) 2261 2262 /* type */ 2263 t := STB_GLOBAL << 4 2264 2265 if s.Attr.CgoExport() && s.Type == sym.STEXT { 2266 t |= STT_FUNC 2267 } else { 2268 t |= STT_OBJECT 2269 } 2270 d.AddUint8(uint8(t)) 2271 2272 /* reserved */ 2273 d.AddUint8(0) 2274 2275 /* section where symbol is defined */ 2276 if s.Type == sym.SDYNIMPORT { 2277 d.AddUint16(ctxt.Arch, SHN_UNDEF) 2278 } else { 2279 d.AddUint16(ctxt.Arch, 1) 2280 } 2281 2282 /* value */ 2283 if s.Type == sym.SDYNIMPORT { 2284 d.AddUint64(ctxt.Arch, 0) 2285 } else { 2286 d.AddAddr(ctxt.Arch, s) 2287 } 2288 2289 /* size of object */ 2290 d.AddUint64(ctxt.Arch, uint64(s.Size)) 2291 2292 if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] { 2293 Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib))) 2294 } 2295 } else { 2296 s.Dynid = int32(Nelfsym) 2297 Nelfsym++ 2298 2299 d := ctxt.Syms.Lookup(".dynsym", 0) 2300 2301 /* name */ 2302 name := s.Extname 2303 2304 d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name))) 2305 2306 /* value */ 2307 if s.Type == sym.SDYNIMPORT { 2308 d.AddUint32(ctxt.Arch, 0) 2309 } else { 2310 d.AddAddr(ctxt.Arch, s) 2311 } 2312 2313 /* size of object */ 2314 d.AddUint32(ctxt.Arch, uint32(s.Size)) 2315 2316 /* type */ 2317 t := STB_GLOBAL << 4 2318 2319 // TODO(mwhudson): presumably the behavior should actually be the same on both arm and 386. 2320 if ctxt.Arch.Family == sys.I386 && s.Attr.CgoExport() && s.Type == sym.STEXT { 2321 t |= STT_FUNC 2322 } else if ctxt.Arch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type == sym.STEXT { 2323 t |= STT_FUNC 2324 } else { 2325 t |= STT_OBJECT 2326 } 2327 d.AddUint8(uint8(t)) 2328 d.AddUint8(0) 2329 2330 /* shndx */ 2331 if s.Type == sym.SDYNIMPORT { 2332 d.AddUint16(ctxt.Arch, SHN_UNDEF) 2333 } else { 2334 d.AddUint16(ctxt.Arch, 1) 2335 } 2336 } 2337 } 2338 2339 func ELF32_R_SYM(info uint32) uint32 { 2340 return info >> 8 2341 } 2342 2343 func ELF32_R_TYPE(info uint32) uint32 { 2344 return uint32(uint8(info)) 2345 } 2346 2347 func ELF32_R_INFO(sym uint32, type_ uint32) uint32 { 2348 return sym<<8 | type_ 2349 } 2350 2351 func ELF32_ST_BIND(info uint8) uint8 { 2352 return info >> 4 2353 } 2354 2355 func ELF32_ST_TYPE(info uint8) uint8 { 2356 return info & 0xf 2357 } 2358 2359 func ELF32_ST_INFO(bind uint8, type_ uint8) uint8 { 2360 return bind<<4 | type_&0xf 2361 } 2362 2363 func ELF32_ST_VISIBILITY(oth uint8) uint8 { 2364 return oth & 3 2365 } 2366 2367 func ELF64_R_SYM(info uint64) uint32 { 2368 return uint32(info >> 32) 2369 } 2370 2371 func ELF64_R_TYPE(info uint64) uint32 { 2372 return uint32(info) 2373 } 2374 2375 func ELF64_R_INFO(sym uint32, type_ uint32) uint64 { 2376 return uint64(sym)<<32 | uint64(type_) 2377 } 2378 2379 func ELF64_ST_BIND(info uint8) uint8 { 2380 return info >> 4 2381 } 2382 2383 func ELF64_ST_TYPE(info uint8) uint8 { 2384 return info & 0xf 2385 } 2386 2387 func ELF64_ST_INFO(bind uint8, type_ uint8) uint8 { 2388 return bind<<4 | type_&0xf 2389 } 2390 2391 func ELF64_ST_VISIBILITY(oth uint8) uint8 { 2392 return oth & 3 2393 } 2394