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.
20 * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
21 * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
22 * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
23 * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
24 * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
25 * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
26 * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
27 * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
28 * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
30 * Copyright (c) 1996-1998 John D. Polstra. All rights reserved.
31 * Copyright (c) 2001 David E. O'Brien
32 * Portions Copyright 2009 The Go Authors. All rights reserved.
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
37 * 1. Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in the
41 * documentation and/or other materials provided with the distribution.
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * ELF definitions that are independent of architecture or word size.
62 * Note header. The ".note" section contains an array of notes. Each
63 * begins with this header, aligned to a word boundary. Immediately
64 * following the note header is n_namesz bytes of name, padded to the
65 * next word boundary. Then comes n_descsz bytes of descriptor, again
66 * padded to a word boundary. The values of n_namesz and n_descsz do
67 * not include the padding.
69 type Elf_Note struct {
112 ELFOSABI_MODESTO = 11
113 ELFOSABI_OPENBSD = 12
114 ELFOSABI_OPENVMS = 13
117 ELFOSABI_STANDALONE = 255
118 ELFOSABI_SYSV = ELFOSABI_NONE
119 ELFOSABI_MONTEREY = ELFOSABI_AIX
178 SHN_LORESERVE = 0xff00
186 SHN_HIRESERVE = 0xffff
201 SHT_PREINIT_ARRAY = 16
203 SHT_SYMTAB_SHNDX = 18
204 SHT_LOOS = 0x60000000
205 SHT_HIOS = 0x6fffffff
206 SHT_GNU_VERDEF = 0x6ffffffd
207 SHT_GNU_VERNEED = 0x6ffffffe
208 SHT_GNU_VERSYM = 0x6fffffff
209 SHT_LOPROC = 0x70000000
210 SHT_ARM_ATTRIBUTES = 0x70000003
211 SHT_HIPROC = 0x7fffffff
212 SHT_LOUSER = 0x80000000
213 SHT_HIUSER = 0xffffffff
220 SHF_LINK_ORDER = 0x80
221 SHF_OS_NONCONFORMING = 0x100
224 SHF_MASKOS = 0x0ff00000
225 SHF_MASKPROC = 0xf0000000
236 PT_LOPROC = 0x70000000
237 PT_HIPROC = 0x7fffffff
238 PT_GNU_STACK = 0x6474e551
239 PT_PAX_FLAGS = 0x65041580
243 PF_MASKOS = 0x0ff00000
244 PF_MASKPROC = 0xf0000000
277 DT_PREINIT_ARRAY = 32
278 DT_PREINIT_ARRAYSZ = 33
281 DT_LOPROC = 0x70000000
282 DT_HIPROC = 0x7fffffff
283 DT_VERNEED = 0x6ffffffe
284 DT_VERNEEDNUM = 0x6fffffff
285 DT_VERSYM = 0x6ffffff0
286 DT_PPC64_GLINK = DT_LOPROC + 0
287 DT_PPC64_OPT = DT_LOPROC + 3
292 DF_STATIC_TLS = 0x0010
321 /* For accessing the fields of r_info. */
323 /* For constructing r_info from field values. */
335 R_X86_64_GLOB_DAT = 6
336 R_X86_64_JMP_SLOT = 7
337 R_X86_64_RELATIVE = 8
338 R_X86_64_GOTPCREL = 9
345 R_X86_64_DTPMOD64 = 16
346 R_X86_64_DTPOFF64 = 17
347 R_X86_64_TPOFF64 = 18
350 R_X86_64_DTPOFF32 = 21
351 R_X86_64_GOTTPOFF = 22
352 R_X86_64_TPOFF32 = 23
354 R_X86_64_GOTOFF64 = 25
355 R_X86_64_GOTPC32 = 26
357 R_X86_64_GOTPCREL64 = 28
358 R_X86_64_GOTPC64 = 29
359 R_X86_64_GOTPLT64 = 30
360 R_X86_64_PLTOFF64 = 31
363 R_X86_64_GOTPC32_TLSDEC = 34
364 R_X86_64_TLSDESC_CALL = 35
365 R_X86_64_TLSDESC = 36
366 R_X86_64_IRELATIVE = 37
367 R_X86_64_PC32_BND = 40
368 R_X86_64_GOTPCRELX = 41
369 R_X86_64_REX_GOTPCRELX = 42
371 R_AARCH64_ABS64 = 257
372 R_AARCH64_ABS32 = 258
373 R_AARCH64_CALL26 = 283
374 R_AARCH64_ADR_PREL_PG_HI21 = 275
375 R_AARCH64_ADD_ABS_LO12_NC = 277
376 R_AARCH64_LDST8_ABS_LO12_NC = 278
377 R_AARCH64_LDST16_ABS_LO12_NC = 284
378 R_AARCH64_LDST32_ABS_LO12_NC = 285
379 R_AARCH64_LDST64_ABS_LO12_NC = 286
380 R_AARCH64_ADR_GOT_PAGE = 311
381 R_AARCH64_LD64_GOT_LO12_NC = 312
382 R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 = 541
383 R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 542
384 R_AARCH64_TLSLE_MOVW_TPREL_G0 = 547
399 R_ALPHA_OP_STORE = 13
401 R_ALPHA_OP_PRSHIFT = 15
403 R_ALPHA_GPRELHIGH = 17
404 R_ALPHA_GPRELLOW = 18
405 R_ALPHA_IMMED_GP_16 = 19
406 R_ALPHA_IMMED_GP_HI32 = 20
407 R_ALPHA_IMMED_SCN_HI32 = 21
408 R_ALPHA_IMMED_BR_HI32 = 22
409 R_ALPHA_IMMED_LO32 = 23
411 R_ALPHA_GLOB_DAT = 25
412 R_ALPHA_JMP_SLOT = 26
413 R_ALPHA_RELATIVE = 27
427 R_ARM_AMP_VCALL9 = 12
444 R_ARM_GNU_VTENTRY = 100
445 R_ARM_GNU_VTINHERIT = 101
449 R_ARM_THM_RPC22 = 251
473 R_386_TLS_GD_PUSH = 25
474 R_386_TLS_GD_CALL = 26
475 R_386_TLS_GD_POP = 27
476 R_386_TLS_LDM_32 = 28
477 R_386_TLS_LDM_PUSH = 29
478 R_386_TLS_LDM_CALL = 30
479 R_386_TLS_LDM_POP = 31
480 R_386_TLS_LDO_32 = 32
483 R_386_TLS_DTPMOD32 = 35
484 R_386_TLS_DTPOFF32 = 36
485 R_386_TLS_TPOFF32 = 37
486 R_386_TLS_GOTDESC = 39
487 R_386_TLS_DESC_CALL = 40
519 R_MIPS_CALL_HI16 = 30
520 R_MIPS_CALL_LO16 = 31
523 R_MIPS_ADD_IMMEDIATE = 34
527 R_MIPS_TLS_DTPMOD32 = 38
528 R_MIPS_TLS_DTPREL32 = 39
529 R_MIPS_TLS_DTPMOD64 = 40
530 R_MIPS_TLS_DTPREL64 = 41
533 R_MIPS_TLS_DTPREL_HI16 = 44
534 R_MIPS_TLS_DTPREL_LO16 = 45
535 R_MIPS_TLS_GOTTPREL = 46
536 R_MIPS_TLS_TPREL32 = 47
537 R_MIPS_TLS_TPREL64 = 48
538 R_MIPS_TLS_TPREL_HI16 = 49
539 R_MIPS_TLS_TPREL_LO16 = 50
549 R_PPC_ADDR14_BRTAKEN = 8
550 R_PPC_ADDR14_BRNTAKEN = 9
553 R_PPC_REL14_BRTAKEN = 12
554 R_PPC_REL14_BRNTAKEN = 13
575 R_PPC_SECTOFF_LO = 34
576 R_PPC_SECTOFF_HI = 35
577 R_PPC_SECTOFF_HA = 36
581 R_PPC_TPREL16_LO = 70
582 R_PPC_TPREL16_HI = 71
583 R_PPC_TPREL16_HA = 72
586 R_PPC_DTPREL16_LO = 75
587 R_PPC_DTPREL16_HI = 76
588 R_PPC_DTPREL16_HA = 77
590 R_PPC_GOT_TLSGD16 = 79
591 R_PPC_GOT_TLSGD16_LO = 80
592 R_PPC_GOT_TLSGD16_HI = 81
593 R_PPC_GOT_TLSGD16_HA = 82
594 R_PPC_GOT_TLSLD16 = 83
595 R_PPC_GOT_TLSLD16_LO = 84
596 R_PPC_GOT_TLSLD16_HI = 85
597 R_PPC_GOT_TLSLD16_HA = 86
598 R_PPC_GOT_TPREL16 = 87
599 R_PPC_GOT_TPREL16_LO = 88
600 R_PPC_GOT_TPREL16_HI = 89
601 R_PPC_GOT_TPREL16_HA = 90
602 R_PPC_EMB_NADDR32 = 101
603 R_PPC_EMB_NADDR16 = 102
604 R_PPC_EMB_NADDR16_LO = 103
605 R_PPC_EMB_NADDR16_HI = 104
606 R_PPC_EMB_NADDR16_HA = 105
607 R_PPC_EMB_SDAI16 = 106
608 R_PPC_EMB_SDA2I16 = 107
609 R_PPC_EMB_SDA2REL = 108
610 R_PPC_EMB_SDA21 = 109
611 R_PPC_EMB_MRKREF = 110
612 R_PPC_EMB_RELSEC16 = 111
613 R_PPC_EMB_RELST_LO = 112
614 R_PPC_EMB_RELST_HI = 113
615 R_PPC_EMB_RELST_HA = 114
616 R_PPC_EMB_BIT_FLD = 115
617 R_PPC_EMB_RELSDA = 116
619 R_PPC64_ADDR32 = R_PPC_ADDR32
620 R_PPC64_ADDR16_LO = R_PPC_ADDR16_LO
621 R_PPC64_ADDR16_HA = R_PPC_ADDR16_HA
622 R_PPC64_REL24 = R_PPC_REL24
623 R_PPC64_GOT16_HA = R_PPC_GOT16_HA
624 R_PPC64_JMP_SLOT = R_PPC_JMP_SLOT
625 R_PPC64_TPREL16 = R_PPC_TPREL16
628 R_PPC64_TOC16_LO = 48
629 R_PPC64_TOC16_HI = 49
630 R_PPC64_TOC16_HA = 50
631 R_PPC64_ADDR16_LO_DS = 57
632 R_PPC64_GOT16_LO_DS = 59
633 R_PPC64_TOC16_DS = 63
634 R_PPC64_TOC16_LO_DS = 64
636 R_PPC64_GOT_TPREL16_LO_DS = 88
637 R_PPC64_GOT_TPREL16_HA = 90
638 R_PPC64_REL16_LO = 250
639 R_PPC64_REL16_HI = 251
640 R_PPC64_REL16_HA = 252
662 R_SPARC_GLOB_DAT = 20
663 R_SPARC_JMP_SLOT = 21
664 R_SPARC_RELATIVE = 22
684 R_SPARC_GLOB_JMP = 42
695 R_SPARC_REGISTER = 53
733 R_390_GOTPLTOFF16 = 34
734 R_390_GOTPLTOFF32 = 35
735 R_390_GOTPLTOFF64 = 36
737 R_390_TLS_GDCALL = 38
738 R_390_TLS_LDCALL = 39
741 R_390_TLS_GOTIE12 = 42
742 R_390_TLS_GOTIE32 = 43
743 R_390_TLS_GOTIE64 = 44
753 R_390_TLS_DTPMOD = 54
754 R_390_TLS_DTPOFF = 55
759 R_390_TLS_GOTIE20 = 60
761 ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
765 * Symbol table entries.
768 /* For accessing the fields of st_info. */
770 /* For constructing st_info from field values. */
772 /* For accessing the fields of st_other. */
777 type ElfEhdr struct {
778 ident [EI_NIDENT]uint8
797 type ElfShdr struct {
815 type ElfPhdr struct {
826 /* For accessing the fields of r_info. */
828 /* For constructing r_info from field values. */
831 * Symbol table entries.
834 /* For accessing the fields of st_info. */
836 /* For constructing st_info from field values. */
838 /* For accessing the fields of st_other. */
841 * Go linker interface
858 * The interface uses the 64-bit structures always,
859 * to avoid code duplication. The writers know how to
860 * marshal a 32-bit representation from the 64-bit structure.
866 * Total amount of space to reserve at the start of the file
867 * for Header, PHeaders, SHeaders, and interp.
869 * On FreeBSD, cannot be larger than a page.
876 * We use the 64-bit data structures on both 32- and 64-bit machines
877 * in order to write the code just once. The 64-bit data structure is
878 * written in the 32-bit format on the 32-bit machines.
890 // Either ".rel" or ".rela" depending on which type of relocation the
891 // target platform uses.
901 type Elfstring struct {
906 var elfstr [100]Elfstring
913 Initialize the global variable that describes the ELF header. It will be updated as
914 we write section and prog headers.
919 if SysArch.InFamily(sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.S390X) {
925 switch SysArch.Family {
926 // 64-bit architectures
927 case sys.PPC64, sys.S390X:
928 if Ctxt.Arch.ByteOrder == binary.BigEndian {
929 ehdr.flags = 1 /* Version 1 ABI */
931 ehdr.flags = 2 /* Version 2 ABI */
934 case sys.AMD64, sys.ARM64, sys.MIPS64:
935 if SysArch.Family == sys.MIPS64 {
936 ehdr.flags = 0x20000000 /* MIPS 3 */
940 ehdr.phoff = ELF64HDRSIZE /* Must be be ELF64HDRSIZE: first PHdr must follow ELF header */
941 ehdr.shoff = ELF64HDRSIZE /* Will move as we add PHeaders */
942 ehdr.ehsize = ELF64HDRSIZE /* Must be ELF64HDRSIZE */
943 ehdr.phentsize = ELF64PHDRSIZE /* Must be ELF64PHDRSIZE */
944 ehdr.shentsize = ELF64SHDRSIZE /* Must be ELF64SHDRSIZE */
946 // we use EABI on both linux/arm and freebsd/arm.
947 // 32-bit architectures
949 // we use EABI on both linux/arm and freebsd/arm.
950 if HEADTYPE == obj.Hlinux || HEADTYPE == obj.Hfreebsd {
951 // We set a value here that makes no indication of which
952 // float ABI the object uses, because this is information
953 // used by the dynamic linker to compare executables and
954 // shared libraries -- so it only matters for cgo calls, and
955 // the information properly comes from the object files
956 // produced by the host C compiler. parseArmAttributes in
957 // ldelf.go reads that information and updates this field as
959 ehdr.flags = 0x5000002 // has entry point, Version5 EABI
963 ehdr.phoff = ELF32HDRSIZE
964 /* Must be be ELF32HDRSIZE: first PHdr must follow ELF header */
965 ehdr.shoff = ELF32HDRSIZE /* Will move as we add PHeaders */
966 ehdr.ehsize = ELF32HDRSIZE /* Must be ELF32HDRSIZE */
967 ehdr.phentsize = ELF32PHDRSIZE /* Must be ELF32PHDRSIZE */
968 ehdr.shentsize = ELF32SHDRSIZE /* Must be ELF32SHDRSIZE */
972 // Make sure PT_LOAD is aligned properly and
973 // that there is no gap,
974 // correct ELF loaders will do this implicitly,
975 // but buggy ELF loaders like the one in some
976 // versions of QEMU and UPX won't.
977 func fixElfPhdr(e *ElfPhdr) {
978 frag := int(e.vaddr & (e.align - 1))
980 e.off -= uint64(frag)
981 e.vaddr -= uint64(frag)
982 e.paddr -= uint64(frag)
983 e.filesz += uint64(frag)
984 e.memsz += uint64(frag)
987 func elf64phdr(e *ElfPhdr) {
988 if e.type_ == PT_LOAD {
992 Thearch.Lput(e.type_)
993 Thearch.Lput(e.flags)
995 Thearch.Vput(e.vaddr)
996 Thearch.Vput(e.paddr)
997 Thearch.Vput(e.filesz)
998 Thearch.Vput(e.memsz)
999 Thearch.Vput(e.align)
1002 func elf32phdr(e *ElfPhdr) {
1003 if e.type_ == PT_LOAD {
1007 Thearch.Lput(e.type_)
1008 Thearch.Lput(uint32(e.off))
1009 Thearch.Lput(uint32(e.vaddr))
1010 Thearch.Lput(uint32(e.paddr))
1011 Thearch.Lput(uint32(e.filesz))
1012 Thearch.Lput(uint32(e.memsz))
1013 Thearch.Lput(e.flags)
1014 Thearch.Lput(uint32(e.align))
1017 func elf64shdr(e *ElfShdr) {
1018 Thearch.Lput(e.name)
1019 Thearch.Lput(e.type_)
1020 Thearch.Vput(e.flags)
1021 Thearch.Vput(e.addr)
1023 Thearch.Vput(e.size)
1024 Thearch.Lput(e.link)
1025 Thearch.Lput(e.info)
1026 Thearch.Vput(e.addralign)
1027 Thearch.Vput(e.entsize)
1030 func elf32shdr(e *ElfShdr) {
1031 Thearch.Lput(e.name)
1032 Thearch.Lput(e.type_)
1033 Thearch.Lput(uint32(e.flags))
1034 Thearch.Lput(uint32(e.addr))
1035 Thearch.Lput(uint32(e.off))
1036 Thearch.Lput(uint32(e.size))
1037 Thearch.Lput(e.link)
1038 Thearch.Lput(e.info)
1039 Thearch.Lput(uint32(e.addralign))
1040 Thearch.Lput(uint32(e.entsize))
1043 func elfwriteshdrs() uint32 {
1045 for i := 0; i < int(ehdr.shnum); i++ {
1048 return uint32(ehdr.shnum) * ELF64SHDRSIZE
1051 for i := 0; i < int(ehdr.shnum); i++ {
1054 return uint32(ehdr.shnum) * ELF32SHDRSIZE
1057 func elfsetstring(s string, off int) {
1058 if nelfstr >= len(elfstr) {
1059 Diag("too many elf strings")
1063 elfstr[nelfstr].s = s
1064 elfstr[nelfstr].off = off
1068 func elfwritephdrs() uint32 {
1070 for i := 0; i < int(ehdr.phnum); i++ {
1073 return uint32(ehdr.phnum) * ELF64PHDRSIZE
1076 for i := 0; i < int(ehdr.phnum); i++ {
1079 return uint32(ehdr.phnum) * ELF32PHDRSIZE
1082 func newElfPhdr() *ElfPhdr {
1084 if ehdr.phnum >= NSECT {
1085 Diag("too many phdrs")
1087 phdr[ehdr.phnum] = e
1091 ehdr.shoff += ELF64PHDRSIZE
1093 ehdr.shoff += ELF32PHDRSIZE
1098 func newElfShdr(name int64) *ElfShdr {
1100 e.name = uint32(name)
1101 e.shnum = int(ehdr.shnum)
1102 if ehdr.shnum >= NSECT {
1103 Diag("too many shdrs")
1105 shdr[ehdr.shnum] = e
1112 func getElfEhdr() *ElfEhdr {
1116 func elf64writehdr() uint32 {
1117 for i := 0; i < EI_NIDENT; i++ {
1120 Thearch.Wput(ehdr.type_)
1121 Thearch.Wput(ehdr.machine)
1122 Thearch.Lput(ehdr.version)
1123 Thearch.Vput(ehdr.entry)
1124 Thearch.Vput(ehdr.phoff)
1125 Thearch.Vput(ehdr.shoff)
1126 Thearch.Lput(ehdr.flags)
1127 Thearch.Wput(ehdr.ehsize)
1128 Thearch.Wput(ehdr.phentsize)
1129 Thearch.Wput(ehdr.phnum)
1130 Thearch.Wput(ehdr.shentsize)
1131 Thearch.Wput(ehdr.shnum)
1132 Thearch.Wput(ehdr.shstrndx)
1136 func elf32writehdr() uint32 {
1137 for i := 0; i < EI_NIDENT; i++ {
1140 Thearch.Wput(ehdr.type_)
1141 Thearch.Wput(ehdr.machine)
1142 Thearch.Lput(ehdr.version)
1143 Thearch.Lput(uint32(ehdr.entry))
1144 Thearch.Lput(uint32(ehdr.phoff))
1145 Thearch.Lput(uint32(ehdr.shoff))
1146 Thearch.Lput(ehdr.flags)
1147 Thearch.Wput(ehdr.ehsize)
1148 Thearch.Wput(ehdr.phentsize)
1149 Thearch.Wput(ehdr.phnum)
1150 Thearch.Wput(ehdr.shentsize)
1151 Thearch.Wput(ehdr.shnum)
1152 Thearch.Wput(ehdr.shstrndx)
1156 func elfwritehdr() uint32 {
1158 return elf64writehdr()
1160 return elf32writehdr()
1163 /* Taken directly from the definition document for ELF64 */
1164 func elfhash(name string) uint32 {
1166 for i := 0; i < len(name); i++ {
1167 h = (h << 4) + uint32(name[i])
1168 if g := h & 0xf0000000; g != 0 {
1176 func Elfwritedynent(s *LSym, tag int, val uint64) {
1178 Adduint64(Ctxt, s, uint64(tag))
1179 Adduint64(Ctxt, s, val)
1181 Adduint32(Ctxt, s, uint32(tag))
1182 Adduint32(Ctxt, s, uint32(val))
1186 func elfwritedynentsym(s *LSym, tag int, t *LSym) {
1187 Elfwritedynentsymplus(s, tag, t, 0)
1190 func Elfwritedynentsymplus(s *LSym, tag int, t *LSym, add int64) {
1192 Adduint64(Ctxt, s, uint64(tag))
1194 Adduint32(Ctxt, s, uint32(tag))
1196 Addaddrplus(Ctxt, s, t, add)
1199 func elfwritedynentsymsize(s *LSym, tag int, t *LSym) {
1201 Adduint64(Ctxt, s, uint64(tag))
1203 Adduint32(Ctxt, s, uint32(tag))
1208 func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
1210 n := len(interp) + 1
1211 sh.addr = startva + resoff - uint64(n)
1212 sh.off = resoff - uint64(n)
1218 func elfwriteinterp() int {
1219 sh := elfshname(".interp")
1220 Cseek(int64(sh.off))
1221 coutbuf.WriteString(interp)
1226 func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int, alloc bool) int {
1227 n := 3*4 + uint64(sz) + resoff%4
1231 sh.flags = SHF_ALLOC
1234 sh.addr = startva + resoff - n
1236 sh.size = n - resoff%4
1241 func elfwritenotehdr(str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
1242 sh := elfshname(str)
1244 // Write Elf_Note header.
1245 Cseek(int64(sh.off))
1247 Thearch.Lput(namesz)
1248 Thearch.Lput(descsz)
1254 // NetBSD Signature (as per sys/exec_elf.h)
1256 ELF_NOTE_NETBSD_NAMESZ = 7
1257 ELF_NOTE_NETBSD_DESCSZ = 4
1258 ELF_NOTE_NETBSD_TAG = 1
1259 ELF_NOTE_NETBSD_VERSION = 599000000 /* NetBSD 5.99 */
1262 var ELF_NOTE_NETBSD_NAME = []byte("NetBSD\x00")
1264 func elfnetbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
1265 n := int(Rnd(ELF_NOTE_NETBSD_NAMESZ, 4) + Rnd(ELF_NOTE_NETBSD_DESCSZ, 4))
1266 return elfnote(sh, startva, resoff, n, true)
1269 func elfwritenetbsdsig() int {
1270 // Write Elf_Note header.
1271 sh := elfwritenotehdr(".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
1277 // Followed by NetBSD string and version.
1278 Cwrite(ELF_NOTE_NETBSD_NAME)
1281 Thearch.Lput(ELF_NOTE_NETBSD_VERSION)
1286 // OpenBSD Signature
1288 ELF_NOTE_OPENBSD_NAMESZ = 8
1289 ELF_NOTE_OPENBSD_DESCSZ = 4
1290 ELF_NOTE_OPENBSD_TAG = 1
1291 ELF_NOTE_OPENBSD_VERSION = 0
1294 var ELF_NOTE_OPENBSD_NAME = []byte("OpenBSD\x00")
1296 func elfopenbsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
1297 n := ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ
1298 return elfnote(sh, startva, resoff, n, true)
1301 func elfwriteopenbsdsig() int {
1302 // Write Elf_Note header.
1303 sh := elfwritenotehdr(".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
1309 // Followed by OpenBSD string and version.
1310 Cwrite(ELF_NOTE_OPENBSD_NAME)
1312 Thearch.Lput(ELF_NOTE_OPENBSD_VERSION)
1317 func addbuildinfo(val string) {
1318 if !strings.HasPrefix(val, "0x") {
1319 Exitf("-B argument must start with 0x: %s", val)
1326 if hex.DecodedLen(len(val)) > maxLen {
1327 Exitf("-B option too long (max %d digits): %s", maxLen, ov)
1330 b, err := hex.DecodeString(val)
1332 if err == hex.ErrLength {
1333 Exitf("-B argument must have even number of digits: %s", ov)
1335 if inv, ok := err.(hex.InvalidByteError); ok {
1336 Exitf("-B argument contains invalid hex digit %c: %s", byte(inv), ov)
1338 Exitf("-B argument contains invalid hex: %s", ov)
1346 ELF_NOTE_BUILDINFO_NAMESZ = 4
1347 ELF_NOTE_BUILDINFO_TAG = 3
1350 var ELF_NOTE_BUILDINFO_NAME = []byte("GNU\x00")
1352 func elfbuildinfo(sh *ElfShdr, startva uint64, resoff uint64) int {
1353 n := int(ELF_NOTE_BUILDINFO_NAMESZ + Rnd(int64(len(buildinfo)), 4))
1354 return elfnote(sh, startva, resoff, n, true)
1357 func elfgobuildid(sh *ElfShdr, startva uint64, resoff uint64) int {
1358 n := len(ELF_NOTE_GO_NAME) + int(Rnd(int64(len(buildid)), 4))
1359 return elfnote(sh, startva, resoff, n, true)
1362 func elfwritebuildinfo() int {
1363 sh := elfwritenotehdr(".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
1368 Cwrite(ELF_NOTE_BUILDINFO_NAME)
1370 var zero = make([]byte, 4)
1371 Cwrite(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))])
1376 func elfwritegobuildid() int {
1377 sh := elfwritenotehdr(".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(buildid)), ELF_NOTE_GOBUILDID_TAG)
1382 Cwrite(ELF_NOTE_GO_NAME)
1383 Cwrite([]byte(buildid))
1384 var zero = make([]byte, 4)
1385 Cwrite(zero[:int(Rnd(int64(len(buildid)), 4)-int64(len(buildid)))])
1390 // Go specific notes
1392 ELF_NOTE_GOPKGLIST_TAG = 1
1393 ELF_NOTE_GOABIHASH_TAG = 2
1394 ELF_NOTE_GODEPS_TAG = 3
1395 ELF_NOTE_GOBUILDID_TAG = 4
1398 var ELF_NOTE_GO_NAME = []byte("Go\x00\x00")
1402 type Elfaux struct {
1408 type Elflib struct {
1414 func addelflib(list **Elflib, file string, vers string) *Elfaux {
1417 for lib = *list; lib != nil; lib = lib.next {
1418 if lib.file == file {
1428 for aux := lib.aux; aux != nil; aux = aux.next {
1429 if aux.vers == vers {
1447 s := Linklookup(Ctxt, ".hash", 0)
1448 s.Type = obj.SELFROSECT
1449 s.Attr |= AttrReachable
1459 need := make([]*Elfaux, nsym)
1460 chain := make([]uint32, nsym)
1461 buckets := make([]uint32, nbucket)
1464 for _, sy := range Ctxt.Allsym {
1469 if sy.Dynimpvers != "" {
1470 need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib, sy.Dynimpvers)
1476 b = int(hc % uint32(nbucket))
1477 chain[sy.Dynid] = buckets[b]
1478 buckets[b] = uint32(sy.Dynid)
1481 // s390x (ELF64) hash table entries are 8 bytes
1482 if SysArch.Family == sys.S390X {
1483 Adduint64(Ctxt, s, uint64(nbucket))
1484 Adduint64(Ctxt, s, uint64(nsym))
1485 for i := 0; i < nbucket; i++ {
1486 Adduint64(Ctxt, s, uint64(buckets[i]))
1488 for i := 0; i < nsym; i++ {
1489 Adduint64(Ctxt, s, uint64(chain[i]))
1492 Adduint32(Ctxt, s, uint32(nbucket))
1493 Adduint32(Ctxt, s, uint32(nsym))
1494 for i := 0; i < nbucket; i++ {
1495 Adduint32(Ctxt, s, buckets[i])
1497 for i := 0; i < nsym; i++ {
1498 Adduint32(Ctxt, s, chain[i])
1503 dynstr := Linklookup(Ctxt, ".dynstr", 0)
1505 s = Linklookup(Ctxt, ".gnu.version_r", 0)
1510 for l := needlib; l != nil; l = l.next {
1514 Adduint16(Ctxt, s, 1) // table version
1516 for x = l.aux; x != nil; x = x.next {
1519 Adduint16(Ctxt, s, uint16(j)) // aux count
1520 Adduint32(Ctxt, s, uint32(Addstring(dynstr, l.file))) // file string offset
1521 Adduint32(Ctxt, s, 16) // offset from header to first aux
1523 Adduint32(Ctxt, s, 16+uint32(j)*16) // offset from this header to next
1525 Adduint32(Ctxt, s, 0)
1528 for x = l.aux; x != nil; x = x.next {
1533 Adduint32(Ctxt, s, elfhash(x.vers)) // hash
1534 Adduint16(Ctxt, s, 0) // flags
1535 Adduint16(Ctxt, s, uint16(x.num)) // other - index we refer to this by
1536 Adduint32(Ctxt, s, uint32(Addstring(dynstr, x.vers))) // version string offset
1538 Adduint32(Ctxt, s, 16) // offset from this aux to next
1540 Adduint32(Ctxt, s, 0)
1545 // version references
1546 s = Linklookup(Ctxt, ".gnu.version", 0)
1548 for i := 0; i < nsym; i++ {
1550 Adduint16(Ctxt, s, 0) // first entry - no symbol
1551 } else if need[i] == nil {
1552 Adduint16(Ctxt, s, 1) // global
1554 Adduint16(Ctxt, s, uint16(need[i].num))
1558 s = Linklookup(Ctxt, ".dynamic", 0)
1560 if elfverneed != 0 {
1561 elfwritedynentsym(s, DT_VERNEED, Linklookup(Ctxt, ".gnu.version_r", 0))
1562 Elfwritedynent(s, DT_VERNEEDNUM, uint64(nfile))
1563 elfwritedynentsym(s, DT_VERSYM, Linklookup(Ctxt, ".gnu.version", 0))
1566 sy := Linklookup(Ctxt, elfRelType+".plt", 0)
1568 if elfRelType == ".rela" {
1569 Elfwritedynent(s, DT_PLTREL, DT_RELA)
1571 Elfwritedynent(s, DT_PLTREL, DT_REL)
1573 elfwritedynentsymsize(s, DT_PLTRELSZ, sy)
1574 elfwritedynentsym(s, DT_JMPREL, sy)
1577 Elfwritedynent(s, DT_NULL, 0)
1580 func elfphload(seg *Segment) *ElfPhdr {
1592 ph.vaddr = seg.Vaddr
1593 ph.paddr = seg.Vaddr
1594 ph.memsz = seg.Length
1595 ph.off = seg.Fileoff
1596 ph.filesz = seg.Filelen
1597 ph.align = uint64(INITRND)
1602 func elfshname(name string) *ElfShdr {
1606 for i := 0; i < nelfstr; i++ {
1607 if name == elfstr[i].s {
1609 for i = 0; i < int(ehdr.shnum); i++ {
1611 if sh.name == uint32(off) {
1616 sh = newElfShdr(int64(off))
1621 Diag("cannot find elf name %s", name)
1626 func elfshalloc(sect *Section) *ElfShdr {
1627 sh := elfshname(sect.Name)
1632 func elfshbits(sect *Section) *ElfShdr {
1633 sh := elfshalloc(sect)
1634 // If this section has already been set up as a note, we assume type_ and
1635 // flags are already correct, but the other fields still need filling in.
1636 if sh.type_ == SHT_NOTE {
1637 if Linkmode != LinkExternal {
1638 // TODO(mwhudson): the approach here will work OK when
1639 // linking internally for notes that we want to be included
1640 // in a loadable segment (e.g. the abihash note) but not for
1641 // notes that we do not want to be mapped (e.g. the package
1642 // list note). The real fix is probably to define new values
1643 // for LSym.Type corresponding to mapped and unmapped notes
1644 // and handle them in dodata().
1645 Diag("sh.type_ == SHT_NOTE in elfshbits when linking internally")
1647 sh.addralign = uint64(sect.Align)
1648 sh.size = sect.Length
1649 sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
1656 if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
1657 sh.type_ = SHT_PROGBITS
1659 sh.type_ = SHT_NOBITS
1661 sh.flags = SHF_ALLOC
1662 if sect.Rwx&1 != 0 {
1663 sh.flags |= SHF_EXECINSTR
1665 if sect.Rwx&2 != 0 {
1666 sh.flags |= SHF_WRITE
1668 if sect.Name == ".tbss" {
1670 sh.type_ = SHT_NOBITS
1672 if strings.HasPrefix(sect.Name, ".debug") {
1676 if Linkmode != LinkExternal {
1677 sh.addr = sect.Vaddr
1679 sh.addralign = uint64(sect.Align)
1680 sh.size = sect.Length
1681 if sect.Name != ".tbss" {
1682 sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
1688 func elfshreloc(sect *Section) *ElfShdr {
1689 // If main section is SHT_NOBITS, nothing to relocate.
1690 // Also nothing to relocate in .shstrtab or notes.
1691 if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
1694 if sect.Name == ".shstrtab" || sect.Name == ".tbss" {
1697 if sect.Elfsect.type_ == SHT_NOTE {
1702 if elfRelType == ".rela" {
1708 sh := elfshname(elfRelType + sect.Name)
1709 sh.type_ = uint32(typ)
1710 sh.entsize = uint64(SysArch.RegSize) * 2
1711 if typ == SHT_RELA {
1712 sh.entsize += uint64(SysArch.RegSize)
1714 sh.link = uint32(elfshname(".symtab").shnum)
1715 sh.info = uint32(sect.Elfsect.shnum)
1716 sh.off = sect.Reloff
1717 sh.size = sect.Rellen
1718 sh.addralign = uint64(SysArch.RegSize)
1722 func elfrelocsect(sect *Section, syms []*LSym) {
1723 // If main section is SHT_NOBITS, nothing to relocate.
1724 // Also nothing to relocate in .shstrtab.
1725 if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
1728 if sect.Name == ".shstrtab" {
1732 sect.Reloff = uint64(Cpos())
1733 for i, s := range syms {
1734 if !s.Attr.Reachable() {
1737 if uint64(s.Value) >= sect.Vaddr {
1743 eaddr := int32(sect.Vaddr + sect.Length)
1744 for _, sym := range syms {
1745 if !sym.Attr.Reachable() {
1748 if sym.Value >= int64(eaddr) {
1753 for ri := 0; ri < len(sym.R); ri++ {
1759 Diag("missing xsym in relocation")
1762 if r.Xsym.ElfsymForReloc() == 0 {
1763 Diag("reloc %d to non-elf symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
1765 if Thearch.Elfreloc1(r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 {
1766 Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
1771 sect.Rellen = uint64(Cpos()) - sect.Reloff
1774 func Elfemitreloc() {
1779 elfrelocsect(Segtext.Sect, Ctxt.Textp)
1780 for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
1781 elfrelocsect(sect, datap)
1783 for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
1784 elfrelocsect(sect, datap)
1786 for sect := Segdata.Sect; sect != nil; sect = sect.Next {
1787 elfrelocsect(sect, datap)
1789 for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
1790 elfrelocsect(sect, list2slice(dwarfp))
1794 func addgonote(sectionName string, tag uint32, desc []byte) {
1795 s := Linklookup(Ctxt, sectionName, 0)
1796 s.Attr |= AttrReachable
1797 s.Type = obj.SELFROSECT
1799 Adduint32(Ctxt, s, uint32(len(ELF_NOTE_GO_NAME)))
1801 Adduint32(Ctxt, s, uint32(len(desc)))
1803 Adduint32(Ctxt, s, tag)
1805 s.P = append(s.P, ELF_NOTE_GO_NAME...)
1806 for len(s.P)%4 != 0 {
1807 s.P = append(s.P, 0)
1810 s.P = append(s.P, desc...)
1811 for len(s.P)%4 != 0 {
1812 s.P = append(s.P, 0)
1814 s.Size = int64(len(s.P))
1822 /* predefine strings we need for section headers */
1823 shstrtab := Linklookup(Ctxt, ".shstrtab", 0)
1825 shstrtab.Type = obj.SELFROSECT
1826 shstrtab.Attr |= AttrReachable
1828 Addstring(shstrtab, "")
1829 Addstring(shstrtab, ".text")
1830 Addstring(shstrtab, ".noptrdata")
1831 Addstring(shstrtab, ".data")
1832 Addstring(shstrtab, ".bss")
1833 Addstring(shstrtab, ".noptrbss")
1835 // generate .tbss section (except for OpenBSD where it's not supported)
1836 // for dynamic internal linker or external linking, so that various
1837 // binutils could correctly calculate PT_TLS size.
1838 // see https://golang.org/issue/5200.
1839 if HEADTYPE != obj.Hopenbsd {
1840 if Debug['d'] == 0 || Linkmode == LinkExternal {
1841 Addstring(shstrtab, ".tbss")
1844 if HEADTYPE == obj.Hnetbsd {
1845 Addstring(shstrtab, ".note.netbsd.ident")
1847 if HEADTYPE == obj.Hopenbsd {
1848 Addstring(shstrtab, ".note.openbsd.ident")
1850 if len(buildinfo) > 0 {
1851 Addstring(shstrtab, ".note.gnu.build-id")
1854 Addstring(shstrtab, ".note.go.buildid")
1856 Addstring(shstrtab, ".elfdata")
1857 Addstring(shstrtab, ".rodata")
1858 // See the comment about data.rel.ro.FOO section names in data.go.
1861 Addstring(shstrtab, ".data.rel.ro")
1862 relro_prefix = ".data.rel.ro"
1864 Addstring(shstrtab, relro_prefix+".typelink")
1865 Addstring(shstrtab, relro_prefix+".itablink")
1866 Addstring(shstrtab, relro_prefix+".gosymtab")
1867 Addstring(shstrtab, relro_prefix+".gopclntab")
1869 if Linkmode == LinkExternal {
1872 Addstring(shstrtab, elfRelType+".text")
1873 Addstring(shstrtab, elfRelType+".rodata")
1874 Addstring(shstrtab, elfRelType+relro_prefix+".typelink")
1875 Addstring(shstrtab, elfRelType+relro_prefix+".itablink")
1876 Addstring(shstrtab, elfRelType+relro_prefix+".gosymtab")
1877 Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
1878 Addstring(shstrtab, elfRelType+".noptrdata")
1879 Addstring(shstrtab, elfRelType+".data")
1881 Addstring(shstrtab, elfRelType+".data.rel.ro")
1884 // add a .note.GNU-stack section to mark the stack as non-executable
1885 Addstring(shstrtab, ".note.GNU-stack")
1887 if Buildmode == BuildmodeShared {
1888 Addstring(shstrtab, ".note.go.abihash")
1889 Addstring(shstrtab, ".note.go.pkg-list")
1890 Addstring(shstrtab, ".note.go.deps")
1894 hasinitarr := Linkshared
1896 /* shared library initializer */
1898 case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared:
1903 Addstring(shstrtab, ".init_array")
1904 Addstring(shstrtab, elfRelType+".init_array")
1907 if Debug['s'] == 0 {
1908 Addstring(shstrtab, ".symtab")
1909 Addstring(shstrtab, ".strtab")
1910 dwarfaddshstrings(shstrtab)
1913 Addstring(shstrtab, ".shstrtab")
1915 if Debug['d'] == 0 { /* -d suppresses dynamic loader format */
1916 Addstring(shstrtab, ".interp")
1917 Addstring(shstrtab, ".hash")
1918 Addstring(shstrtab, ".got")
1919 if SysArch.Family == sys.PPC64 {
1920 Addstring(shstrtab, ".glink")
1922 Addstring(shstrtab, ".got.plt")
1923 Addstring(shstrtab, ".dynamic")
1924 Addstring(shstrtab, ".dynsym")
1925 Addstring(shstrtab, ".dynstr")
1926 Addstring(shstrtab, elfRelType)
1927 Addstring(shstrtab, elfRelType+".plt")
1929 Addstring(shstrtab, ".plt")
1930 Addstring(shstrtab, ".gnu.version")
1931 Addstring(shstrtab, ".gnu.version_r")
1933 /* dynamic symbol table - first entry all zeros */
1934 s := Linklookup(Ctxt, ".dynsym", 0)
1936 s.Type = obj.SELFROSECT
1937 s.Attr |= AttrReachable
1939 s.Size += ELF64SYMSIZE
1941 s.Size += ELF32SYMSIZE
1944 /* dynamic string table */
1945 s = Linklookup(Ctxt, ".dynstr", 0)
1947 s.Type = obj.SELFROSECT
1948 s.Attr |= AttrReachable
1954 /* relocation table */
1955 s = Linklookup(Ctxt, elfRelType, 0)
1956 s.Attr |= AttrReachable
1957 s.Type = obj.SELFROSECT
1959 /* global offset table */
1960 s = Linklookup(Ctxt, ".got", 0)
1962 s.Attr |= AttrReachable
1963 s.Type = obj.SELFGOT // writable
1965 /* ppc64 glink resolver */
1966 if SysArch.Family == sys.PPC64 {
1967 s := Linklookup(Ctxt, ".glink", 0)
1968 s.Attr |= AttrReachable
1969 s.Type = obj.SELFRXSECT
1973 s = Linklookup(Ctxt, ".hash", 0)
1975 s.Attr |= AttrReachable
1976 s.Type = obj.SELFROSECT
1978 s = Linklookup(Ctxt, ".got.plt", 0)
1979 s.Attr |= AttrReachable
1980 s.Type = obj.SELFSECT // writable
1982 s = Linklookup(Ctxt, ".plt", 0)
1984 s.Attr |= AttrReachable
1985 if SysArch.Family == sys.PPC64 {
1986 // In the ppc64 ABI, .plt is a data section
1987 // written by the dynamic linker.
1988 s.Type = obj.SELFSECT
1990 s.Type = obj.SELFRXSECT
1993 Thearch.Elfsetupplt()
1995 s = Linklookup(Ctxt, elfRelType+".plt", 0)
1996 s.Attr |= AttrReachable
1997 s.Type = obj.SELFROSECT
1999 s = Linklookup(Ctxt, ".gnu.version", 0)
2000 s.Attr |= AttrReachable
2001 s.Type = obj.SELFROSECT
2003 s = Linklookup(Ctxt, ".gnu.version_r", 0)
2004 s.Attr |= AttrReachable
2005 s.Type = obj.SELFROSECT
2007 /* define dynamic elf table */
2008 s = Linklookup(Ctxt, ".dynamic", 0)
2010 s.Attr |= AttrReachable
2011 s.Type = obj.SELFSECT // writable
2016 elfwritedynentsym(s, DT_HASH, Linklookup(Ctxt, ".hash", 0))
2018 elfwritedynentsym(s, DT_SYMTAB, Linklookup(Ctxt, ".dynsym", 0))
2020 Elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE)
2022 Elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE)
2024 elfwritedynentsym(s, DT_STRTAB, Linklookup(Ctxt, ".dynstr", 0))
2025 elfwritedynentsymsize(s, DT_STRSZ, Linklookup(Ctxt, ".dynstr", 0))
2026 if elfRelType == ".rela" {
2027 elfwritedynentsym(s, DT_RELA, Linklookup(Ctxt, ".rela", 0))
2028 elfwritedynentsymsize(s, DT_RELASZ, Linklookup(Ctxt, ".rela", 0))
2029 Elfwritedynent(s, DT_RELAENT, ELF64RELASIZE)
2031 elfwritedynentsym(s, DT_REL, Linklookup(Ctxt, ".rel", 0))
2032 elfwritedynentsymsize(s, DT_RELSZ, Linklookup(Ctxt, ".rel", 0))
2033 Elfwritedynent(s, DT_RELENT, ELF32RELSIZE)
2036 if rpath.val != "" {
2037 Elfwritedynent(s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val)))
2040 if SysArch.Family == sys.PPC64 {
2041 elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".plt", 0))
2042 } else if SysArch.Family == sys.S390X {
2043 elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".got", 0))
2045 elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".got.plt", 0))
2048 if SysArch.Family == sys.PPC64 {
2049 Elfwritedynent(s, DT_PPC64_OPT, 0)
2052 // Solaris dynamic linker can't handle an empty .rela.plt if
2053 // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL,
2054 // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the
2055 // size of .rel(a).plt section.
2056 Elfwritedynent(s, DT_DEBUG, 0)
2059 if Buildmode == BuildmodeShared {
2060 // The go.link.abihashbytes symbol will be pointed at the appropriate
2061 // part of the .note.go.abihash section in data.go:func address().
2062 s := Linklookup(Ctxt, "go.link.abihashbytes", 0)
2064 s.Type = obj.SRODATA
2065 s.Attr |= AttrSpecial
2066 s.Attr |= AttrReachable
2067 s.Size = int64(sha1.Size)
2069 sort.Sort(byPkg(Ctxt.Library))
2071 for _, l := range Ctxt.Library {
2074 addgonote(".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{}))
2075 addgonote(".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, pkglistfornote)
2076 var deplist []string
2077 for _, shlib := range Ctxt.Shlibs {
2078 deplist = append(deplist, filepath.Base(shlib.Path))
2080 addgonote(".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n")))
2083 if Linkmode == LinkExternal && buildid != "" {
2084 addgonote(".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(buildid))
2088 // Do not write DT_NULL. elfdynhash will finish it.
2089 func shsym(sh *ElfShdr, s *LSym) {
2091 if sh.flags&SHF_ALLOC != 0 {
2092 sh.addr = uint64(addr)
2094 sh.off = uint64(datoff(addr))
2095 sh.size = uint64(s.Size)
2098 func phsh(ph *ElfPhdr, sh *ElfShdr) {
2104 ph.align = sh.addralign
2107 func Asmbelfsetup() {
2108 /* This null SHdr must appear before all others */
2111 for sect := Segtext.Sect; sect != nil; sect = sect.Next {
2114 for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
2117 for sect := Segdata.Sect; sect != nil; sect = sect.Next {
2120 for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
2125 func Asmbelf(symo int64) {
2127 switch SysArch.Family {
2129 Exitf("unknown architecture in asmbelf: %v", SysArch.Family)
2131 eh.machine = EM_MIPS
2135 eh.machine = EM_X86_64
2137 eh.machine = EM_AARCH64
2141 eh.machine = EM_PPC64
2143 eh.machine = EM_S390
2146 elfreserve := int64(ELFRESERVE)
2147 startva := INITTEXT - int64(HEADR)
2148 resoff := elfreserve
2152 if Linkmode == LinkExternal {
2153 /* skip program headers */
2158 if Buildmode == BuildmodeShared {
2159 sh := elfshname(".note.go.pkg-list")
2161 sh = elfshname(".note.go.abihash")
2163 sh.flags = SHF_ALLOC
2164 sh = elfshname(".note.go.deps")
2169 sh := elfshname(".note.go.buildid")
2171 sh.flags = SHF_ALLOC
2177 /* program header info */
2182 pph.off = uint64(eh.ehsize)
2183 pph.vaddr = uint64(INITTEXT) - uint64(HEADR) + pph.off
2184 pph.paddr = uint64(INITTEXT) - uint64(HEADR) + pph.off
2185 pph.align = uint64(INITRND)
2188 * PHDR must be in a loaded segment. Adjust the text
2189 * segment boundaries downwards to include it.
2190 * Except on NaCl where it must not be loaded.
2192 if HEADTYPE != obj.Hnacl {
2193 o := int64(Segtext.Vaddr - pph.vaddr)
2194 Segtext.Vaddr -= uint64(o)
2195 Segtext.Length += uint64(o)
2196 o = int64(Segtext.Fileoff - pph.off)
2197 Segtext.Fileoff -= uint64(o)
2198 Segtext.Filelen += uint64(o)
2201 if Debug['d'] == 0 { /* -d suppresses dynamic loader format */
2203 sh := elfshname(".interp")
2205 sh.type_ = SHT_PROGBITS
2206 sh.flags = SHF_ALLOC
2208 if interpreter == "" {
2211 interpreter = Thearch.Linuxdynld
2214 interpreter = Thearch.Freebsddynld
2217 interpreter = Thearch.Netbsddynld
2220 interpreter = Thearch.Openbsddynld
2222 case obj.Hdragonfly:
2223 interpreter = Thearch.Dragonflydynld
2226 interpreter = Thearch.Solarisdynld
2230 resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter))
2233 ph.type_ = PT_INTERP
2239 if HEADTYPE == obj.Hnetbsd || HEADTYPE == obj.Hopenbsd {
2243 sh = elfshname(".note.netbsd.ident")
2244 resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff)))
2247 sh = elfshname(".note.openbsd.ident")
2248 resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
2251 pnote = newElfPhdr()
2252 pnote.type_ = PT_NOTE
2257 if len(buildinfo) > 0 {
2258 sh := elfshname(".note.gnu.build-id")
2259 resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff)))
2262 pnote = newElfPhdr()
2263 pnote.type_ = PT_NOTE
2271 sh := elfshname(".note.go.buildid")
2272 resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff)))
2274 pnote := newElfPhdr()
2275 pnote.type_ = PT_NOTE
2280 // Additions to the reserved area must be above this line.
2283 if Segrodata.Sect != nil {
2284 elfphload(&Segrodata)
2288 /* Dynamic linking sections */
2289 if Debug['d'] == 0 {
2290 sh := elfshname(".dynsym")
2291 sh.type_ = SHT_DYNSYM
2292 sh.flags = SHF_ALLOC
2294 sh.entsize = ELF64SYMSIZE
2296 sh.entsize = ELF32SYMSIZE
2298 sh.addralign = uint64(SysArch.RegSize)
2299 sh.link = uint32(elfshname(".dynstr").shnum)
2301 // sh->info = index of first non-local symbol (number of local symbols)
2302 shsym(sh, Linklookup(Ctxt, ".dynsym", 0))
2304 sh = elfshname(".dynstr")
2305 sh.type_ = SHT_STRTAB
2306 sh.flags = SHF_ALLOC
2308 shsym(sh, Linklookup(Ctxt, ".dynstr", 0))
2310 if elfverneed != 0 {
2311 sh := elfshname(".gnu.version")
2312 sh.type_ = SHT_GNU_VERSYM
2313 sh.flags = SHF_ALLOC
2315 sh.link = uint32(elfshname(".dynsym").shnum)
2317 shsym(sh, Linklookup(Ctxt, ".gnu.version", 0))
2319 sh = elfshname(".gnu.version_r")
2320 sh.type_ = SHT_GNU_VERNEED
2321 sh.flags = SHF_ALLOC
2322 sh.addralign = uint64(SysArch.RegSize)
2323 sh.info = uint32(elfverneed)
2324 sh.link = uint32(elfshname(".dynstr").shnum)
2325 shsym(sh, Linklookup(Ctxt, ".gnu.version_r", 0))
2328 if elfRelType == ".rela" {
2329 sh := elfshname(".rela.plt")
2331 sh.flags = SHF_ALLOC
2332 sh.entsize = ELF64RELASIZE
2333 sh.addralign = uint64(SysArch.RegSize)
2334 sh.link = uint32(elfshname(".dynsym").shnum)
2335 sh.info = uint32(elfshname(".plt").shnum)
2336 shsym(sh, Linklookup(Ctxt, ".rela.plt", 0))
2338 sh = elfshname(".rela")
2340 sh.flags = SHF_ALLOC
2341 sh.entsize = ELF64RELASIZE
2343 sh.link = uint32(elfshname(".dynsym").shnum)
2344 shsym(sh, Linklookup(Ctxt, ".rela", 0))
2346 sh := elfshname(".rel.plt")
2348 sh.flags = SHF_ALLOC
2349 sh.entsize = ELF32RELSIZE
2351 sh.link = uint32(elfshname(".dynsym").shnum)
2352 shsym(sh, Linklookup(Ctxt, ".rel.plt", 0))
2354 sh = elfshname(".rel")
2356 sh.flags = SHF_ALLOC
2357 sh.entsize = ELF32RELSIZE
2359 sh.link = uint32(elfshname(".dynsym").shnum)
2360 shsym(sh, Linklookup(Ctxt, ".rel", 0))
2363 if eh.machine == EM_PPC64 {
2364 sh := elfshname(".glink")
2365 sh.type_ = SHT_PROGBITS
2366 sh.flags = SHF_ALLOC + SHF_EXECINSTR
2368 shsym(sh, Linklookup(Ctxt, ".glink", 0))
2371 sh = elfshname(".plt")
2372 sh.type_ = SHT_PROGBITS
2373 sh.flags = SHF_ALLOC + SHF_EXECINSTR
2374 if eh.machine == EM_X86_64 {
2376 } else if eh.machine == EM_S390 {
2378 } else if eh.machine == EM_PPC64 {
2379 // On ppc64, this is just a table of addresses
2380 // filled by the dynamic linker
2381 sh.type_ = SHT_NOBITS
2383 sh.flags = SHF_ALLOC + SHF_WRITE
2388 sh.addralign = sh.entsize
2389 shsym(sh, Linklookup(Ctxt, ".plt", 0))
2391 // On ppc64, .got comes from the input files, so don't
2392 // create it here, and .got.plt is not used.
2393 if eh.machine != EM_PPC64 {
2394 sh := elfshname(".got")
2395 sh.type_ = SHT_PROGBITS
2396 sh.flags = SHF_ALLOC + SHF_WRITE
2397 sh.entsize = uint64(SysArch.RegSize)
2398 sh.addralign = uint64(SysArch.RegSize)
2399 shsym(sh, Linklookup(Ctxt, ".got", 0))
2401 sh = elfshname(".got.plt")
2402 sh.type_ = SHT_PROGBITS
2403 sh.flags = SHF_ALLOC + SHF_WRITE
2404 sh.entsize = uint64(SysArch.RegSize)
2405 sh.addralign = uint64(SysArch.RegSize)
2406 shsym(sh, Linklookup(Ctxt, ".got.plt", 0))
2409 sh = elfshname(".hash")
2411 sh.flags = SHF_ALLOC
2413 sh.addralign = uint64(SysArch.RegSize)
2414 sh.link = uint32(elfshname(".dynsym").shnum)
2415 shsym(sh, Linklookup(Ctxt, ".hash", 0))
2417 /* sh and PT_DYNAMIC for .dynamic section */
2418 sh = elfshname(".dynamic")
2420 sh.type_ = SHT_DYNAMIC
2421 sh.flags = SHF_ALLOC + SHF_WRITE
2422 sh.entsize = 2 * uint64(SysArch.RegSize)
2423 sh.addralign = uint64(SysArch.RegSize)
2424 sh.link = uint32(elfshname(".dynstr").shnum)
2425 shsym(sh, Linklookup(Ctxt, ".dynamic", 0))
2427 ph.type_ = PT_DYNAMIC
2428 ph.flags = PF_R + PF_W
2432 * Thread-local storage segment (really just size).
2434 // Do not emit PT_TLS for OpenBSD since ld.so(1) does
2435 // not currently support it. This is handled
2436 // appropriately in runtime/cgo.
2437 if HEADTYPE != obj.Hopenbsd {
2438 tlssize := uint64(0)
2439 for sect := Segdata.Sect; sect != nil; sect = sect.Next {
2440 if sect.Name == ".tbss" {
2441 tlssize = sect.Length
2449 ph.align = uint64(SysArch.RegSize)
2454 if HEADTYPE == obj.Hlinux {
2456 ph.type_ = PT_GNU_STACK
2457 ph.flags = PF_W + PF_R
2458 ph.align = uint64(SysArch.RegSize)
2461 ph.type_ = PT_PAX_FLAGS
2462 ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled
2463 ph.align = uint64(SysArch.RegSize)
2467 sh := elfshname(".shstrtab")
2468 sh.type_ = SHT_STRTAB
2470 shsym(sh, Linklookup(Ctxt, ".shstrtab", 0))
2471 eh.shstrndx = uint16(sh.shnum)
2473 // put these sections early in the list
2474 if Debug['s'] == 0 {
2475 elfshname(".symtab")
2476 elfshname(".strtab")
2479 for sect := Segtext.Sect; sect != nil; sect = sect.Next {
2482 for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
2485 for sect := Segdata.Sect; sect != nil; sect = sect.Next {
2488 for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
2492 if Linkmode == LinkExternal {
2493 for sect := Segtext.Sect; sect != nil; sect = sect.Next {
2496 for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
2499 for sect := Segdata.Sect; sect != nil; sect = sect.Next {
2502 for s := dwarfp; s != nil; s = s.Next {
2503 if len(s.R) > 0 || s.Type == obj.SDWARFINFO {
2506 if s.Type == obj.SDWARFINFO {
2510 // add a .note.GNU-stack section to mark the stack as non-executable
2511 sh := elfshname(".note.GNU-stack")
2513 sh.type_ = SHT_PROGBITS
2518 if Debug['s'] == 0 {
2519 sh := elfshname(".symtab")
2520 sh.type_ = SHT_SYMTAB
2521 sh.off = uint64(symo)
2522 sh.size = uint64(Symsize)
2523 sh.addralign = uint64(SysArch.RegSize)
2524 sh.entsize = 8 + 2*uint64(SysArch.RegSize)
2525 sh.link = uint32(elfshname(".strtab").shnum)
2526 sh.info = uint32(elfglobalsymndx)
2528 sh = elfshname(".strtab")
2529 sh.type_ = SHT_STRTAB
2530 sh.off = uint64(symo) + uint64(Symsize)
2531 sh.size = uint64(len(Elfstrdat))
2536 eh.ident[EI_MAG0] = '\177'
2538 eh.ident[EI_MAG1] = 'E'
2539 eh.ident[EI_MAG2] = 'L'
2540 eh.ident[EI_MAG3] = 'F'
2541 if HEADTYPE == obj.Hfreebsd {
2542 eh.ident[EI_OSABI] = ELFOSABI_FREEBSD
2543 } else if HEADTYPE == obj.Hnetbsd {
2544 eh.ident[EI_OSABI] = ELFOSABI_NETBSD
2545 } else if HEADTYPE == obj.Hopenbsd {
2546 eh.ident[EI_OSABI] = ELFOSABI_OPENBSD
2547 } else if HEADTYPE == obj.Hdragonfly {
2548 eh.ident[EI_OSABI] = ELFOSABI_NONE
2551 eh.ident[EI_CLASS] = ELFCLASS64
2553 eh.ident[EI_CLASS] = ELFCLASS32
2555 if Ctxt.Arch.ByteOrder == binary.BigEndian {
2556 eh.ident[EI_DATA] = ELFDATA2MSB
2558 eh.ident[EI_DATA] = ELFDATA2LSB
2560 eh.ident[EI_VERSION] = EV_CURRENT
2562 if Linkmode == LinkExternal {
2568 if Linkmode != LinkExternal {
2569 eh.entry = uint64(Entryvalue())
2572 eh.version = EV_CURRENT
2575 pph.filesz = uint64(eh.phnum) * uint64(eh.phentsize)
2576 pph.memsz = pph.filesz
2581 a += int64(elfwritehdr())
2582 a += int64(elfwritephdrs())
2583 a += int64(elfwriteshdrs())
2584 if Debug['d'] == 0 {
2585 a += int64(elfwriteinterp())
2587 if Linkmode != LinkExternal {
2588 if HEADTYPE == obj.Hnetbsd {
2589 a += int64(elfwritenetbsdsig())
2591 if HEADTYPE == obj.Hopenbsd {
2592 a += int64(elfwriteopenbsdsig())
2594 if len(buildinfo) > 0 {
2595 a += int64(elfwritebuildinfo())
2598 a += int64(elfwritegobuildid())
2603 Diag("ELFRESERVE too small: %d > %d", a, elfreserve)
2607 func Elfadddynsym(ctxt *Link, s *LSym) {
2609 s.Dynid = int32(Nelfsym)
2612 d := Linklookup(ctxt, ".dynsym", 0)
2615 Adduint32(ctxt, d, uint32(Addstring(Linklookup(ctxt, ".dynstr", 0), name)))
2618 t := STB_GLOBAL << 4
2620 if s.Attr.CgoExport() && s.Type&obj.SMASK == obj.STEXT {
2625 Adduint8(ctxt, d, uint8(t))
2628 Adduint8(ctxt, d, 0)
2630 /* section where symbol is defined */
2631 if s.Type == obj.SDYNIMPORT {
2632 Adduint16(ctxt, d, SHN_UNDEF)
2634 Adduint16(ctxt, d, 1)
2638 if s.Type == obj.SDYNIMPORT {
2639 Adduint64(ctxt, d, 0)
2644 /* size of object */
2645 Adduint64(ctxt, d, uint64(s.Size))
2647 if SysArch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
2648 Elfwritedynent(Linklookup(ctxt, ".dynamic", 0), DT_NEEDED, uint64(Addstring(Linklookup(ctxt, ".dynstr", 0), s.Dynimplib)))
2651 s.Dynid = int32(Nelfsym)
2654 d := Linklookup(ctxt, ".dynsym", 0)
2659 Adduint32(ctxt, d, uint32(Addstring(Linklookup(ctxt, ".dynstr", 0), name)))
2662 if s.Type == obj.SDYNIMPORT {
2663 Adduint32(ctxt, d, 0)
2669 Adduint32(ctxt, d, 0)
2672 t := STB_GLOBAL << 4
2674 // TODO(mwhudson): presumably the behaviour should actually be the same on both arm and 386.
2675 if SysArch.Family == sys.I386 && s.Attr.CgoExport() && s.Type&obj.SMASK == obj.STEXT {
2677 } else if SysArch.Family == sys.ARM && s.Attr.CgoExportDynamic() && s.Type&obj.SMASK == obj.STEXT {
2682 Adduint8(ctxt, d, uint8(t))
2683 Adduint8(ctxt, d, 0)
2686 if s.Type == obj.SDYNIMPORT {
2687 Adduint16(ctxt, d, SHN_UNDEF)
2689 Adduint16(ctxt, d, 1)
2694 func ELF32_R_SYM(info uint32) uint32 {
2698 func ELF32_R_TYPE(info uint32) uint32 {
2699 return uint32(uint8(info))
2702 func ELF32_R_INFO(sym uint32, type_ uint32) uint32 {
2703 return sym<<8 | type_
2706 func ELF32_ST_BIND(info uint8) uint8 {
2710 func ELF32_ST_TYPE(info uint8) uint8 {
2714 func ELF32_ST_INFO(bind uint8, type_ uint8) uint8 {
2715 return bind<<4 | type_&0xf
2718 func ELF32_ST_VISIBILITY(oth uint8) uint8 {
2722 func ELF64_R_SYM(info uint64) uint32 {
2723 return uint32(info >> 32)
2726 func ELF64_R_TYPE(info uint64) uint32 {
2730 func ELF64_R_INFO(sym uint32, type_ uint32) uint64 {
2731 return uint64(sym)<<32 | uint64(type_)
2734 func ELF64_ST_BIND(info uint8) uint8 {
2738 func ELF64_ST_TYPE(info uint8) uint8 {
2742 func ELF64_ST_INFO(bind uint8, type_ uint8) uint8 {
2743 return bind<<4 | type_&0xf
2746 func ELF64_ST_VISIBILITY(oth uint8) uint8 {