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