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