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