github.com/jonasi/go@v0.0.0-20150930005915-e78e654c1de0/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_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 if sect.Name != ".tbss" || goos == "android" { 1512 sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr 1513 } 1514 1515 return sh 1516 } 1517 1518 func elfshreloc(sect *Section) *ElfShdr { 1519 // If main section is SHT_NOBITS, nothing to relocate. 1520 // Also nothing to relocate in .shstrtab or notes. 1521 if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen { 1522 return nil 1523 } 1524 if sect.Name == ".shstrtab" || sect.Name == ".tbss" { 1525 return nil 1526 } 1527 if sect.Elfsect.type_ == SHT_NOTE { 1528 return nil 1529 } 1530 1531 var prefix string 1532 var typ int 1533 switch Thearch.Thechar { 1534 case '6', '7', '9': 1535 prefix = ".rela" 1536 typ = SHT_RELA 1537 default: 1538 prefix = ".rel" 1539 typ = SHT_REL 1540 } 1541 1542 buf := fmt.Sprintf("%s%s", prefix, sect.Name) 1543 sh := elfshname(buf) 1544 sh.type_ = uint32(typ) 1545 sh.entsize = uint64(Thearch.Regsize) * 2 1546 if typ == SHT_RELA { 1547 sh.entsize += uint64(Thearch.Regsize) 1548 } 1549 sh.link = uint32(elfshname(".symtab").shnum) 1550 sh.info = uint32(sect.Elfsect.shnum) 1551 sh.off = sect.Reloff 1552 sh.size = sect.Rellen 1553 sh.addralign = uint64(Thearch.Regsize) 1554 return sh 1555 } 1556 1557 func elfrelocsect(sect *Section, first *LSym) { 1558 // If main section is SHT_NOBITS, nothing to relocate. 1559 // Also nothing to relocate in .shstrtab. 1560 if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen { 1561 return 1562 } 1563 if sect.Name == ".shstrtab" { 1564 return 1565 } 1566 1567 sect.Reloff = uint64(Cpos()) 1568 var sym *LSym 1569 for sym = first; sym != nil; sym = sym.Next { 1570 if !sym.Reachable { 1571 continue 1572 } 1573 if uint64(sym.Value) >= sect.Vaddr { 1574 break 1575 } 1576 } 1577 1578 eaddr := int32(sect.Vaddr + sect.Length) 1579 var r *Reloc 1580 var ri int 1581 for ; sym != nil; sym = sym.Next { 1582 if !sym.Reachable { 1583 continue 1584 } 1585 if sym.Value >= int64(eaddr) { 1586 break 1587 } 1588 Ctxt.Cursym = sym 1589 1590 for ri = 0; ri < len(sym.R); ri++ { 1591 r = &sym.R[ri] 1592 if r.Done != 0 { 1593 continue 1594 } 1595 if r.Xsym == nil { 1596 Diag("missing xsym in relocation") 1597 continue 1598 } 1599 1600 if r.Xsym.Elfsym == 0 { 1601 Diag("reloc %d to non-elf symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type) 1602 } 1603 if Thearch.Elfreloc1(r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 { 1604 Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name) 1605 } 1606 } 1607 } 1608 1609 sect.Rellen = uint64(Cpos()) - sect.Reloff 1610 } 1611 1612 func Elfemitreloc() { 1613 for Cpos()&7 != 0 { 1614 Cput(0) 1615 } 1616 1617 elfrelocsect(Segtext.Sect, Ctxt.Textp) 1618 for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next { 1619 elfrelocsect(sect, datap) 1620 } 1621 for sect := Segrodata.Sect; sect != nil; sect = sect.Next { 1622 elfrelocsect(sect, datap) 1623 } 1624 for sect := Segdata.Sect; sect != nil; sect = sect.Next { 1625 elfrelocsect(sect, datap) 1626 } 1627 } 1628 1629 func addgonote(sectionName string, tag uint32, desc []byte) { 1630 s := Linklookup(Ctxt, sectionName, 0) 1631 s.Reachable = true 1632 s.Type = obj.SELFROSECT 1633 // namesz 1634 Adduint32(Ctxt, s, uint32(len(ELF_NOTE_GO_NAME))) 1635 // descsz 1636 Adduint32(Ctxt, s, uint32(len(desc))) 1637 // tag 1638 Adduint32(Ctxt, s, tag) 1639 // name + padding 1640 s.P = append(s.P, ELF_NOTE_GO_NAME...) 1641 for len(s.P)%4 != 0 { 1642 s.P = append(s.P, 0) 1643 } 1644 // desc + padding 1645 s.P = append(s.P, desc...) 1646 for len(s.P)%4 != 0 { 1647 s.P = append(s.P, 0) 1648 } 1649 s.Size = int64(len(s.P)) 1650 } 1651 1652 func doelf() { 1653 if !Iself { 1654 return 1655 } 1656 1657 /* predefine strings we need for section headers */ 1658 shstrtab := Linklookup(Ctxt, ".shstrtab", 0) 1659 1660 shstrtab.Type = obj.SELFROSECT 1661 shstrtab.Reachable = true 1662 1663 Addstring(shstrtab, "") 1664 Addstring(shstrtab, ".text") 1665 Addstring(shstrtab, ".noptrdata") 1666 Addstring(shstrtab, ".data") 1667 Addstring(shstrtab, ".bss") 1668 Addstring(shstrtab, ".noptrbss") 1669 1670 // generate .tbss section (except for OpenBSD where it's not supported) 1671 // for dynamic internal linker or external linking, so that various 1672 // binutils could correctly calculate PT_TLS size. 1673 // see https://golang.org/issue/5200. 1674 if HEADTYPE != obj.Hopenbsd { 1675 if Debug['d'] == 0 || Linkmode == LinkExternal { 1676 Addstring(shstrtab, ".tbss") 1677 } 1678 } 1679 if HEADTYPE == obj.Hnetbsd { 1680 Addstring(shstrtab, ".note.netbsd.ident") 1681 } 1682 if HEADTYPE == obj.Hopenbsd { 1683 Addstring(shstrtab, ".note.openbsd.ident") 1684 } 1685 if len(buildinfo) > 0 { 1686 Addstring(shstrtab, ".note.gnu.build-id") 1687 } 1688 if buildid != "" { 1689 Addstring(shstrtab, ".note.go.buildid") 1690 } 1691 Addstring(shstrtab, ".elfdata") 1692 Addstring(shstrtab, ".rodata") 1693 if Buildmode == BuildmodeShared || Buildmode == BuildmodeCShared { 1694 Addstring(shstrtab, ".data.rel.ro") 1695 } 1696 // See the comment about data.rel.ro.FOO section names in data.go. 1697 relro_prefix := "" 1698 1699 if UseRelro() { 1700 relro_prefix = ".data.rel.ro" 1701 } 1702 Addstring(shstrtab, relro_prefix+".typelink") 1703 Addstring(shstrtab, relro_prefix+".gosymtab") 1704 Addstring(shstrtab, relro_prefix+".gopclntab") 1705 1706 if Linkmode == LinkExternal { 1707 Debug['d'] = 1 1708 1709 switch Thearch.Thechar { 1710 case '6', '7', '9': 1711 Addstring(shstrtab, ".rela.text") 1712 Addstring(shstrtab, ".rela.rodata") 1713 Addstring(shstrtab, ".rela"+relro_prefix+".typelink") 1714 Addstring(shstrtab, ".rela"+relro_prefix+".gosymtab") 1715 Addstring(shstrtab, ".rela"+relro_prefix+".gopclntab") 1716 Addstring(shstrtab, ".rela.noptrdata") 1717 Addstring(shstrtab, ".rela.data") 1718 if UseRelro() { 1719 Addstring(shstrtab, ".rela.data.rel.ro") 1720 } 1721 1722 default: 1723 Addstring(shstrtab, ".rel.text") 1724 Addstring(shstrtab, ".rel.rodata") 1725 Addstring(shstrtab, ".rel"+relro_prefix+".typelink") 1726 Addstring(shstrtab, ".rel"+relro_prefix+".gosymtab") 1727 Addstring(shstrtab, ".rel"+relro_prefix+".gopclntab") 1728 Addstring(shstrtab, ".rel.noptrdata") 1729 Addstring(shstrtab, ".rel.data") 1730 if UseRelro() { 1731 Addstring(shstrtab, ".rel.data.rel.ro") 1732 } 1733 } 1734 1735 // add a .note.GNU-stack section to mark the stack as non-executable 1736 Addstring(shstrtab, ".note.GNU-stack") 1737 1738 if Buildmode == BuildmodeShared { 1739 Addstring(shstrtab, ".note.go.abihash") 1740 Addstring(shstrtab, ".note.go.pkg-list") 1741 Addstring(shstrtab, ".note.go.deps") 1742 } 1743 } 1744 1745 hasinitarr := Linkshared 1746 1747 /* shared library initializer */ 1748 switch Buildmode { 1749 case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared: 1750 hasinitarr = true 1751 } 1752 1753 if hasinitarr { 1754 Addstring(shstrtab, ".init_array") 1755 switch Thearch.Thechar { 1756 case '6', '7', '9': 1757 Addstring(shstrtab, ".rela.init_array") 1758 default: 1759 Addstring(shstrtab, ".rel.init_array") 1760 } 1761 } 1762 1763 if Debug['s'] == 0 { 1764 Addstring(shstrtab, ".symtab") 1765 Addstring(shstrtab, ".strtab") 1766 dwarfaddshstrings(shstrtab) 1767 } 1768 1769 Addstring(shstrtab, ".shstrtab") 1770 1771 if Debug['d'] == 0 { /* -d suppresses dynamic loader format */ 1772 Addstring(shstrtab, ".interp") 1773 Addstring(shstrtab, ".hash") 1774 Addstring(shstrtab, ".got") 1775 if Thearch.Thechar == '9' { 1776 Addstring(shstrtab, ".glink") 1777 } 1778 Addstring(shstrtab, ".got.plt") 1779 Addstring(shstrtab, ".dynamic") 1780 Addstring(shstrtab, ".dynsym") 1781 Addstring(shstrtab, ".dynstr") 1782 switch Thearch.Thechar { 1783 case '6', '7', '9': 1784 Addstring(shstrtab, ".rela") 1785 Addstring(shstrtab, ".rela.plt") 1786 default: 1787 Addstring(shstrtab, ".rel") 1788 Addstring(shstrtab, ".rel.plt") 1789 } 1790 1791 Addstring(shstrtab, ".plt") 1792 Addstring(shstrtab, ".gnu.version") 1793 Addstring(shstrtab, ".gnu.version_r") 1794 1795 /* dynamic symbol table - first entry all zeros */ 1796 s := Linklookup(Ctxt, ".dynsym", 0) 1797 1798 s.Type = obj.SELFROSECT 1799 s.Reachable = true 1800 switch Thearch.Thechar { 1801 case '6', '7', '9': 1802 s.Size += ELF64SYMSIZE 1803 default: 1804 s.Size += ELF32SYMSIZE 1805 } 1806 1807 /* dynamic string table */ 1808 s = Linklookup(Ctxt, ".dynstr", 0) 1809 1810 s.Type = obj.SELFROSECT 1811 s.Reachable = true 1812 if s.Size == 0 { 1813 Addstring(s, "") 1814 } 1815 dynstr := s 1816 1817 /* relocation table */ 1818 switch Thearch.Thechar { 1819 case '6', '7', '9': 1820 s = Linklookup(Ctxt, ".rela", 0) 1821 default: 1822 s = Linklookup(Ctxt, ".rel", 0) 1823 } 1824 s.Reachable = true 1825 s.Type = obj.SELFROSECT 1826 1827 /* global offset table */ 1828 s = Linklookup(Ctxt, ".got", 0) 1829 1830 s.Reachable = true 1831 s.Type = obj.SELFGOT // writable 1832 1833 /* ppc64 glink resolver */ 1834 if Thearch.Thechar == '9' { 1835 s := Linklookup(Ctxt, ".glink", 0) 1836 s.Reachable = true 1837 s.Type = obj.SELFRXSECT 1838 } 1839 1840 /* hash */ 1841 s = Linklookup(Ctxt, ".hash", 0) 1842 1843 s.Reachable = true 1844 s.Type = obj.SELFROSECT 1845 1846 s = Linklookup(Ctxt, ".got.plt", 0) 1847 s.Reachable = true 1848 s.Type = obj.SELFSECT // writable 1849 1850 s = Linklookup(Ctxt, ".plt", 0) 1851 1852 s.Reachable = true 1853 if Thearch.Thechar == '9' { 1854 // In the ppc64 ABI, .plt is a data section 1855 // written by the dynamic linker. 1856 s.Type = obj.SELFSECT 1857 } else { 1858 s.Type = obj.SELFRXSECT 1859 } 1860 1861 Thearch.Elfsetupplt() 1862 1863 switch Thearch.Thechar { 1864 case '6', '7', '9': 1865 s = Linklookup(Ctxt, ".rela.plt", 0) 1866 default: 1867 s = Linklookup(Ctxt, ".rel.plt", 0) 1868 } 1869 s.Reachable = true 1870 s.Type = obj.SELFROSECT 1871 1872 s = Linklookup(Ctxt, ".gnu.version", 0) 1873 s.Reachable = true 1874 s.Type = obj.SELFROSECT 1875 1876 s = Linklookup(Ctxt, ".gnu.version_r", 0) 1877 s.Reachable = true 1878 s.Type = obj.SELFROSECT 1879 1880 /* define dynamic elf table */ 1881 s = Linklookup(Ctxt, ".dynamic", 0) 1882 1883 s.Reachable = true 1884 s.Type = obj.SELFSECT // writable 1885 1886 /* 1887 * .dynamic table 1888 */ 1889 elfwritedynentsym(s, DT_HASH, Linklookup(Ctxt, ".hash", 0)) 1890 1891 elfwritedynentsym(s, DT_SYMTAB, Linklookup(Ctxt, ".dynsym", 0)) 1892 switch Thearch.Thechar { 1893 case '6', '7', '9': 1894 Elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE) 1895 default: 1896 Elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE) 1897 } 1898 elfwritedynentsym(s, DT_STRTAB, Linklookup(Ctxt, ".dynstr", 0)) 1899 elfwritedynentsymsize(s, DT_STRSZ, Linklookup(Ctxt, ".dynstr", 0)) 1900 switch Thearch.Thechar { 1901 case '6', '7', '9': 1902 elfwritedynentsym(s, DT_RELA, Linklookup(Ctxt, ".rela", 0)) 1903 elfwritedynentsymsize(s, DT_RELASZ, Linklookup(Ctxt, ".rela", 0)) 1904 Elfwritedynent(s, DT_RELAENT, ELF64RELASIZE) 1905 default: 1906 elfwritedynentsym(s, DT_REL, Linklookup(Ctxt, ".rel", 0)) 1907 elfwritedynentsymsize(s, DT_RELSZ, Linklookup(Ctxt, ".rel", 0)) 1908 Elfwritedynent(s, DT_RELENT, ELF32RELSIZE) 1909 } 1910 1911 if rpath.val != "" { 1912 Elfwritedynent(s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val))) 1913 } 1914 1915 if Thearch.Thechar == '9' { 1916 elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".plt", 0)) 1917 } else { 1918 elfwritedynentsym(s, DT_PLTGOT, Linklookup(Ctxt, ".got.plt", 0)) 1919 } 1920 1921 if Thearch.Thechar == '9' { 1922 Elfwritedynent(s, DT_PPC64_OPT, 0) 1923 } 1924 1925 // Solaris dynamic linker can't handle an empty .rela.plt if 1926 // DT_JMPREL is emitted so we have to defer generation of DT_PLTREL, 1927 // DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the 1928 // size of .rel(a).plt section. 1929 Elfwritedynent(s, DT_DEBUG, 0) 1930 } 1931 1932 if Buildmode == BuildmodeShared { 1933 // The go.link.abihashbytes symbol will be pointed at the appropriate 1934 // part of the .note.go.abihash section in data.go:func address(). 1935 s := Linklookup(Ctxt, "go.link.abihashbytes", 0) 1936 s.Local = true 1937 s.Type = obj.SRODATA 1938 s.Special = 1 1939 s.Reachable = true 1940 s.Size = int64(sha1.Size) 1941 1942 sort.Sort(byPkg(Ctxt.Library)) 1943 h := sha1.New() 1944 for _, l := range Ctxt.Library { 1945 h.Write(l.hash) 1946 } 1947 addgonote(".note.go.abihash", ELF_NOTE_GOABIHASH_TAG, h.Sum([]byte{})) 1948 addgonote(".note.go.pkg-list", ELF_NOTE_GOPKGLIST_TAG, []byte(pkglistfornote)) 1949 var deplist []string 1950 for _, shlib := range Ctxt.Shlibs { 1951 deplist = append(deplist, filepath.Base(shlib.Path)) 1952 } 1953 addgonote(".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n"))) 1954 } 1955 1956 if Linkmode == LinkExternal && buildid != "" { 1957 addgonote(".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(buildid)) 1958 } 1959 } 1960 1961 // Do not write DT_NULL. elfdynhash will finish it. 1962 func shsym(sh *ElfShdr, s *LSym) { 1963 addr := Symaddr(s) 1964 if sh.flags&SHF_ALLOC != 0 { 1965 sh.addr = uint64(addr) 1966 } 1967 sh.off = uint64(datoff(addr)) 1968 sh.size = uint64(s.Size) 1969 } 1970 1971 func phsh(ph *ElfPhdr, sh *ElfShdr) { 1972 ph.vaddr = sh.addr 1973 ph.paddr = ph.vaddr 1974 ph.off = sh.off 1975 ph.filesz = sh.size 1976 ph.memsz = sh.size 1977 ph.align = sh.addralign 1978 } 1979 1980 func Asmbelfsetup() { 1981 /* This null SHdr must appear before all others */ 1982 elfshname("") 1983 1984 for sect := Segtext.Sect; sect != nil; sect = sect.Next { 1985 elfshalloc(sect) 1986 } 1987 for sect := Segrodata.Sect; sect != nil; sect = sect.Next { 1988 elfshalloc(sect) 1989 } 1990 for sect := Segdata.Sect; sect != nil; sect = sect.Next { 1991 elfshalloc(sect) 1992 } 1993 } 1994 1995 func Asmbelf(symo int64) { 1996 eh := getElfEhdr() 1997 switch Thearch.Thechar { 1998 default: 1999 Exitf("unknown architecture in asmbelf: %v", Thearch.Thechar) 2000 case '5': 2001 eh.machine = EM_ARM 2002 case '6': 2003 eh.machine = EM_X86_64 2004 case '7': 2005 eh.machine = EM_AARCH64 2006 case '8': 2007 eh.machine = EM_386 2008 case '9': 2009 eh.machine = EM_PPC64 2010 } 2011 2012 elfreserve := int64(ELFRESERVE) 2013 startva := INITTEXT - int64(HEADR) 2014 resoff := elfreserve 2015 2016 var pph *ElfPhdr 2017 var pnote *ElfPhdr 2018 if Linkmode == LinkExternal { 2019 /* skip program headers */ 2020 eh.phoff = 0 2021 2022 eh.phentsize = 0 2023 2024 if Buildmode == BuildmodeShared { 2025 sh := elfshname(".note.go.pkg-list") 2026 sh.type_ = SHT_NOTE 2027 sh = elfshname(".note.go.abihash") 2028 sh.type_ = SHT_NOTE 2029 sh.flags = SHF_ALLOC 2030 sh = elfshname(".note.go.deps") 2031 sh.type_ = SHT_NOTE 2032 } 2033 2034 if buildid != "" { 2035 sh := elfshname(".note.go.buildid") 2036 sh.type_ = SHT_NOTE 2037 sh.flags = SHF_ALLOC 2038 } 2039 2040 goto elfobj 2041 } 2042 2043 /* program header info */ 2044 pph = newElfPhdr() 2045 2046 pph.type_ = PT_PHDR 2047 pph.flags = PF_R 2048 pph.off = uint64(eh.ehsize) 2049 pph.vaddr = uint64(INITTEXT) - uint64(HEADR) + pph.off 2050 pph.paddr = uint64(INITTEXT) - uint64(HEADR) + pph.off 2051 pph.align = uint64(INITRND) 2052 2053 /* 2054 * PHDR must be in a loaded segment. Adjust the text 2055 * segment boundaries downwards to include it. 2056 * Except on NaCl where it must not be loaded. 2057 */ 2058 if HEADTYPE != obj.Hnacl { 2059 o := int64(Segtext.Vaddr - pph.vaddr) 2060 Segtext.Vaddr -= uint64(o) 2061 Segtext.Length += uint64(o) 2062 o = int64(Segtext.Fileoff - pph.off) 2063 Segtext.Fileoff -= uint64(o) 2064 Segtext.Filelen += uint64(o) 2065 } 2066 2067 if Debug['d'] == 0 { /* -d suppresses dynamic loader format */ 2068 /* interpreter */ 2069 sh := elfshname(".interp") 2070 2071 sh.type_ = SHT_PROGBITS 2072 sh.flags = SHF_ALLOC 2073 sh.addralign = 1 2074 if interpreter == "" { 2075 switch HEADTYPE { 2076 case obj.Hlinux: 2077 interpreter = Thearch.Linuxdynld 2078 2079 case obj.Hfreebsd: 2080 interpreter = Thearch.Freebsddynld 2081 2082 case obj.Hnetbsd: 2083 interpreter = Thearch.Netbsddynld 2084 2085 case obj.Hopenbsd: 2086 interpreter = Thearch.Openbsddynld 2087 2088 case obj.Hdragonfly: 2089 interpreter = Thearch.Dragonflydynld 2090 2091 case obj.Hsolaris: 2092 interpreter = Thearch.Solarisdynld 2093 } 2094 } 2095 2096 resoff -= int64(elfinterp(sh, uint64(startva), uint64(resoff), interpreter)) 2097 2098 ph := newElfPhdr() 2099 ph.type_ = PT_INTERP 2100 ph.flags = PF_R 2101 phsh(ph, sh) 2102 } 2103 2104 pnote = nil 2105 if HEADTYPE == obj.Hnetbsd || HEADTYPE == obj.Hopenbsd { 2106 var sh *ElfShdr 2107 switch HEADTYPE { 2108 case obj.Hnetbsd: 2109 sh = elfshname(".note.netbsd.ident") 2110 resoff -= int64(elfnetbsdsig(sh, uint64(startva), uint64(resoff))) 2111 2112 case obj.Hopenbsd: 2113 sh = elfshname(".note.openbsd.ident") 2114 resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff))) 2115 } 2116 2117 pnote = newElfPhdr() 2118 pnote.type_ = PT_NOTE 2119 pnote.flags = PF_R 2120 phsh(pnote, sh) 2121 } 2122 2123 if len(buildinfo) > 0 { 2124 sh := elfshname(".note.gnu.build-id") 2125 resoff -= int64(elfbuildinfo(sh, uint64(startva), uint64(resoff))) 2126 2127 if pnote == nil { 2128 pnote = newElfPhdr() 2129 pnote.type_ = PT_NOTE 2130 pnote.flags = PF_R 2131 } 2132 2133 phsh(pnote, sh) 2134 } 2135 2136 if buildid != "" { 2137 sh := elfshname(".note.go.buildid") 2138 resoff -= int64(elfgobuildid(sh, uint64(startva), uint64(resoff))) 2139 2140 pnote := newElfPhdr() 2141 pnote.type_ = PT_NOTE 2142 pnote.flags = PF_R 2143 phsh(pnote, sh) 2144 } 2145 2146 // Additions to the reserved area must be above this line. 2147 2148 elfphload(&Segtext) 2149 if Segrodata.Sect != nil { 2150 elfphload(&Segrodata) 2151 } 2152 elfphload(&Segdata) 2153 2154 /* Dynamic linking sections */ 2155 if Debug['d'] == 0 { 2156 sh := elfshname(".dynsym") 2157 sh.type_ = SHT_DYNSYM 2158 sh.flags = SHF_ALLOC 2159 if elf64 { 2160 sh.entsize = ELF64SYMSIZE 2161 } else { 2162 sh.entsize = ELF32SYMSIZE 2163 } 2164 sh.addralign = uint64(Thearch.Regsize) 2165 sh.link = uint32(elfshname(".dynstr").shnum) 2166 2167 // sh->info = index of first non-local symbol (number of local symbols) 2168 shsym(sh, Linklookup(Ctxt, ".dynsym", 0)) 2169 2170 sh = elfshname(".dynstr") 2171 sh.type_ = SHT_STRTAB 2172 sh.flags = SHF_ALLOC 2173 sh.addralign = 1 2174 shsym(sh, Linklookup(Ctxt, ".dynstr", 0)) 2175 2176 if elfverneed != 0 { 2177 sh := elfshname(".gnu.version") 2178 sh.type_ = SHT_GNU_VERSYM 2179 sh.flags = SHF_ALLOC 2180 sh.addralign = 2 2181 sh.link = uint32(elfshname(".dynsym").shnum) 2182 sh.entsize = 2 2183 shsym(sh, Linklookup(Ctxt, ".gnu.version", 0)) 2184 2185 sh = elfshname(".gnu.version_r") 2186 sh.type_ = SHT_GNU_VERNEED 2187 sh.flags = SHF_ALLOC 2188 sh.addralign = uint64(Thearch.Regsize) 2189 sh.info = uint32(elfverneed) 2190 sh.link = uint32(elfshname(".dynstr").shnum) 2191 shsym(sh, Linklookup(Ctxt, ".gnu.version_r", 0)) 2192 } 2193 2194 switch eh.machine { 2195 case EM_X86_64, EM_PPC64, EM_AARCH64: 2196 sh := elfshname(".rela.plt") 2197 sh.type_ = SHT_RELA 2198 sh.flags = SHF_ALLOC 2199 sh.entsize = ELF64RELASIZE 2200 sh.addralign = uint64(Thearch.Regsize) 2201 sh.link = uint32(elfshname(".dynsym").shnum) 2202 sh.info = uint32(elfshname(".plt").shnum) 2203 shsym(sh, Linklookup(Ctxt, ".rela.plt", 0)) 2204 2205 sh = elfshname(".rela") 2206 sh.type_ = SHT_RELA 2207 sh.flags = SHF_ALLOC 2208 sh.entsize = ELF64RELASIZE 2209 sh.addralign = 8 2210 sh.link = uint32(elfshname(".dynsym").shnum) 2211 shsym(sh, Linklookup(Ctxt, ".rela", 0)) 2212 2213 default: 2214 sh := elfshname(".rel.plt") 2215 sh.type_ = SHT_REL 2216 sh.flags = SHF_ALLOC 2217 sh.entsize = ELF32RELSIZE 2218 sh.addralign = 4 2219 sh.link = uint32(elfshname(".dynsym").shnum) 2220 shsym(sh, Linklookup(Ctxt, ".rel.plt", 0)) 2221 2222 sh = elfshname(".rel") 2223 sh.type_ = SHT_REL 2224 sh.flags = SHF_ALLOC 2225 sh.entsize = ELF32RELSIZE 2226 sh.addralign = 4 2227 sh.link = uint32(elfshname(".dynsym").shnum) 2228 shsym(sh, Linklookup(Ctxt, ".rel", 0)) 2229 } 2230 2231 if eh.machine == EM_PPC64 { 2232 sh := elfshname(".glink") 2233 sh.type_ = SHT_PROGBITS 2234 sh.flags = SHF_ALLOC + SHF_EXECINSTR 2235 sh.addralign = 4 2236 shsym(sh, Linklookup(Ctxt, ".glink", 0)) 2237 } 2238 2239 sh = elfshname(".plt") 2240 sh.type_ = SHT_PROGBITS 2241 sh.flags = SHF_ALLOC + SHF_EXECINSTR 2242 if eh.machine == EM_X86_64 { 2243 sh.entsize = 16 2244 } else if eh.machine == EM_PPC64 { 2245 // On ppc64, this is just a table of addresses 2246 // filled by the dynamic linker 2247 sh.type_ = SHT_NOBITS 2248 2249 sh.flags = SHF_ALLOC + SHF_WRITE 2250 sh.entsize = 8 2251 } else { 2252 sh.entsize = 4 2253 } 2254 sh.addralign = sh.entsize 2255 shsym(sh, Linklookup(Ctxt, ".plt", 0)) 2256 2257 // On ppc64, .got comes from the input files, so don't 2258 // create it here, and .got.plt is not used. 2259 if eh.machine != EM_PPC64 { 2260 sh := elfshname(".got") 2261 sh.type_ = SHT_PROGBITS 2262 sh.flags = SHF_ALLOC + SHF_WRITE 2263 sh.entsize = uint64(Thearch.Regsize) 2264 sh.addralign = uint64(Thearch.Regsize) 2265 shsym(sh, Linklookup(Ctxt, ".got", 0)) 2266 2267 sh = elfshname(".got.plt") 2268 sh.type_ = SHT_PROGBITS 2269 sh.flags = SHF_ALLOC + SHF_WRITE 2270 sh.entsize = uint64(Thearch.Regsize) 2271 sh.addralign = uint64(Thearch.Regsize) 2272 shsym(sh, Linklookup(Ctxt, ".got.plt", 0)) 2273 } 2274 2275 sh = elfshname(".hash") 2276 sh.type_ = SHT_HASH 2277 sh.flags = SHF_ALLOC 2278 sh.entsize = 4 2279 sh.addralign = uint64(Thearch.Regsize) 2280 sh.link = uint32(elfshname(".dynsym").shnum) 2281 shsym(sh, Linklookup(Ctxt, ".hash", 0)) 2282 2283 /* sh and PT_DYNAMIC for .dynamic section */ 2284 sh = elfshname(".dynamic") 2285 2286 sh.type_ = SHT_DYNAMIC 2287 sh.flags = SHF_ALLOC + SHF_WRITE 2288 sh.entsize = 2 * uint64(Thearch.Regsize) 2289 sh.addralign = uint64(Thearch.Regsize) 2290 sh.link = uint32(elfshname(".dynstr").shnum) 2291 shsym(sh, Linklookup(Ctxt, ".dynamic", 0)) 2292 ph := newElfPhdr() 2293 ph.type_ = PT_DYNAMIC 2294 ph.flags = PF_R + PF_W 2295 phsh(ph, sh) 2296 2297 /* 2298 * Thread-local storage segment (really just size). 2299 */ 2300 // Do not emit PT_TLS for OpenBSD since ld.so(1) does 2301 // not currently support it. This is handled 2302 // appropriately in runtime/cgo. 2303 if HEADTYPE != obj.Hopenbsd { 2304 tlssize := uint64(0) 2305 for sect := Segdata.Sect; sect != nil; sect = sect.Next { 2306 if sect.Name == ".tbss" { 2307 tlssize = sect.Length 2308 } 2309 } 2310 if tlssize != 0 { 2311 ph := newElfPhdr() 2312 ph.type_ = PT_TLS 2313 ph.flags = PF_R 2314 ph.memsz = tlssize 2315 ph.align = uint64(Thearch.Regsize) 2316 } 2317 } 2318 } 2319 2320 if HEADTYPE == obj.Hlinux { 2321 ph := newElfPhdr() 2322 ph.type_ = PT_GNU_STACK 2323 ph.flags = PF_W + PF_R 2324 ph.align = uint64(Thearch.Regsize) 2325 2326 ph = newElfPhdr() 2327 ph.type_ = PT_PAX_FLAGS 2328 ph.flags = 0x2a00 // mprotect, randexec, emutramp disabled 2329 ph.align = uint64(Thearch.Regsize) 2330 } 2331 2332 elfobj: 2333 sh := elfshname(".shstrtab") 2334 sh.type_ = SHT_STRTAB 2335 sh.addralign = 1 2336 shsym(sh, Linklookup(Ctxt, ".shstrtab", 0)) 2337 eh.shstrndx = uint16(sh.shnum) 2338 2339 // put these sections early in the list 2340 if Debug['s'] == 0 { 2341 elfshname(".symtab") 2342 elfshname(".strtab") 2343 } 2344 2345 for sect := Segtext.Sect; sect != nil; sect = sect.Next { 2346 elfshbits(sect) 2347 } 2348 for sect := Segrodata.Sect; sect != nil; sect = sect.Next { 2349 elfshbits(sect) 2350 } 2351 for sect := Segdata.Sect; sect != nil; sect = sect.Next { 2352 elfshbits(sect) 2353 } 2354 2355 if Linkmode == LinkExternal { 2356 for sect := Segtext.Sect; sect != nil; sect = sect.Next { 2357 elfshreloc(sect) 2358 } 2359 for sect := Segrodata.Sect; sect != nil; sect = sect.Next { 2360 elfshreloc(sect) 2361 } 2362 for sect := Segdata.Sect; sect != nil; sect = sect.Next { 2363 elfshreloc(sect) 2364 } 2365 2366 // add a .note.GNU-stack section to mark the stack as non-executable 2367 sh := elfshname(".note.GNU-stack") 2368 2369 sh.type_ = SHT_PROGBITS 2370 sh.addralign = 1 2371 sh.flags = 0 2372 } 2373 2374 if Debug['s'] == 0 { 2375 sh := elfshname(".symtab") 2376 sh.type_ = SHT_SYMTAB 2377 sh.off = uint64(symo) 2378 sh.size = uint64(Symsize) 2379 sh.addralign = uint64(Thearch.Regsize) 2380 sh.entsize = 8 + 2*uint64(Thearch.Regsize) 2381 sh.link = uint32(elfshname(".strtab").shnum) 2382 sh.info = uint32(elfglobalsymndx) 2383 2384 sh = elfshname(".strtab") 2385 sh.type_ = SHT_STRTAB 2386 sh.off = uint64(symo) + uint64(Symsize) 2387 sh.size = uint64(len(Elfstrdat)) 2388 sh.addralign = 1 2389 2390 dwarfaddelfheaders() 2391 } 2392 2393 /* Main header */ 2394 eh.ident[EI_MAG0] = '\177' 2395 2396 eh.ident[EI_MAG1] = 'E' 2397 eh.ident[EI_MAG2] = 'L' 2398 eh.ident[EI_MAG3] = 'F' 2399 if HEADTYPE == obj.Hfreebsd { 2400 eh.ident[EI_OSABI] = ELFOSABI_FREEBSD 2401 } else if HEADTYPE == obj.Hnetbsd { 2402 eh.ident[EI_OSABI] = ELFOSABI_NETBSD 2403 } else if HEADTYPE == obj.Hopenbsd { 2404 eh.ident[EI_OSABI] = ELFOSABI_OPENBSD 2405 } else if HEADTYPE == obj.Hdragonfly { 2406 eh.ident[EI_OSABI] = ELFOSABI_NONE 2407 } 2408 if elf64 { 2409 eh.ident[EI_CLASS] = ELFCLASS64 2410 } else { 2411 eh.ident[EI_CLASS] = ELFCLASS32 2412 } 2413 if Ctxt.Arch.ByteOrder == binary.BigEndian { 2414 eh.ident[EI_DATA] = ELFDATA2MSB 2415 } else { 2416 eh.ident[EI_DATA] = ELFDATA2LSB 2417 } 2418 eh.ident[EI_VERSION] = EV_CURRENT 2419 2420 if Linkmode == LinkExternal { 2421 eh.type_ = ET_REL 2422 } else { 2423 eh.type_ = ET_EXEC 2424 } 2425 2426 if Linkmode != LinkExternal { 2427 eh.entry = uint64(Entryvalue()) 2428 } 2429 2430 eh.version = EV_CURRENT 2431 2432 if pph != nil { 2433 pph.filesz = uint64(eh.phnum) * uint64(eh.phentsize) 2434 pph.memsz = pph.filesz 2435 } 2436 2437 Cseek(0) 2438 a := int64(0) 2439 a += int64(elfwritehdr()) 2440 a += int64(elfwritephdrs()) 2441 a += int64(elfwriteshdrs()) 2442 if Debug['d'] == 0 { 2443 a += int64(elfwriteinterp()) 2444 } 2445 if Linkmode != LinkExternal { 2446 if HEADTYPE == obj.Hnetbsd { 2447 a += int64(elfwritenetbsdsig()) 2448 } 2449 if HEADTYPE == obj.Hopenbsd { 2450 a += int64(elfwriteopenbsdsig()) 2451 } 2452 if len(buildinfo) > 0 { 2453 a += int64(elfwritebuildinfo()) 2454 } 2455 if buildid != "" { 2456 a += int64(elfwritegobuildid()) 2457 } 2458 } 2459 2460 if a > elfreserve { 2461 Diag("ELFRESERVE too small: %d > %d", a, elfreserve) 2462 } 2463 } 2464 2465 func Elfadddynsym(ctxt *Link, s *LSym) { 2466 if elf64 { 2467 s.Dynid = int32(Nelfsym) 2468 Nelfsym++ 2469 2470 d := Linklookup(ctxt, ".dynsym", 0) 2471 2472 name := s.Extname 2473 Adduint32(ctxt, d, uint32(Addstring(Linklookup(ctxt, ".dynstr", 0), name))) 2474 2475 /* type */ 2476 t := STB_GLOBAL << 4 2477 2478 if s.Cgoexport != 0 && s.Type&obj.SMASK == obj.STEXT { 2479 t |= STT_FUNC 2480 } else { 2481 t |= STT_OBJECT 2482 } 2483 Adduint8(ctxt, d, uint8(t)) 2484 2485 /* reserved */ 2486 Adduint8(ctxt, d, 0) 2487 2488 /* section where symbol is defined */ 2489 if s.Type == obj.SDYNIMPORT { 2490 Adduint16(ctxt, d, SHN_UNDEF) 2491 } else { 2492 Adduint16(ctxt, d, 1) 2493 } 2494 2495 /* value */ 2496 if s.Type == obj.SDYNIMPORT { 2497 Adduint64(ctxt, d, 0) 2498 } else { 2499 Addaddr(ctxt, d, s) 2500 } 2501 2502 /* size of object */ 2503 Adduint64(ctxt, d, uint64(s.Size)) 2504 2505 if Thearch.Thechar == '6' && s.Cgoexport&CgoExportDynamic == 0 && s.Dynimplib != "" && !seenlib[s.Dynimplib] { 2506 Elfwritedynent(Linklookup(ctxt, ".dynamic", 0), DT_NEEDED, uint64(Addstring(Linklookup(ctxt, ".dynstr", 0), s.Dynimplib))) 2507 } 2508 } else { 2509 s.Dynid = int32(Nelfsym) 2510 Nelfsym++ 2511 2512 d := Linklookup(ctxt, ".dynsym", 0) 2513 2514 /* name */ 2515 name := s.Extname 2516 2517 Adduint32(ctxt, d, uint32(Addstring(Linklookup(ctxt, ".dynstr", 0), name))) 2518 2519 /* value */ 2520 if s.Type == obj.SDYNIMPORT { 2521 Adduint32(ctxt, d, 0) 2522 } else { 2523 Addaddr(ctxt, d, s) 2524 } 2525 2526 /* size */ 2527 Adduint32(ctxt, d, 0) 2528 2529 /* type */ 2530 t := STB_GLOBAL << 4 2531 2532 // TODO(mwhudson): presumably the behaviour should actually be the same on both arm and 386. 2533 if Thearch.Thechar == '8' && s.Cgoexport != 0 && s.Type&obj.SMASK == obj.STEXT { 2534 t |= STT_FUNC 2535 } else if Thearch.Thechar == '5' && s.Cgoexport&CgoExportDynamic != 0 && s.Type&obj.SMASK == obj.STEXT { 2536 t |= STT_FUNC 2537 } else { 2538 t |= STT_OBJECT 2539 } 2540 Adduint8(ctxt, d, uint8(t)) 2541 Adduint8(ctxt, d, 0) 2542 2543 /* shndx */ 2544 if s.Type == obj.SDYNIMPORT { 2545 Adduint16(ctxt, d, SHN_UNDEF) 2546 } else { 2547 Adduint16(ctxt, d, 1) 2548 } 2549 } 2550 } 2551 2552 func ELF32_R_SYM(info uint32) uint32 { 2553 return info >> 8 2554 } 2555 2556 func ELF32_R_TYPE(info uint32) uint32 { 2557 return uint32(uint8(info)) 2558 } 2559 2560 func ELF32_R_INFO(sym uint32, type_ uint32) uint32 { 2561 return sym<<8 | type_ 2562 } 2563 2564 func ELF32_ST_BIND(info uint8) uint8 { 2565 return info >> 4 2566 } 2567 2568 func ELF32_ST_TYPE(info uint8) uint8 { 2569 return info & 0xf 2570 } 2571 2572 func ELF32_ST_INFO(bind uint8, type_ uint8) uint8 { 2573 return bind<<4 | type_&0xf 2574 } 2575 2576 func ELF32_ST_VISIBILITY(oth uint8) uint8 { 2577 return oth & 3 2578 } 2579 2580 func ELF64_R_SYM(info uint64) uint32 { 2581 return uint32(info >> 32) 2582 } 2583 2584 func ELF64_R_TYPE(info uint64) uint32 { 2585 return uint32(info) 2586 } 2587 2588 func ELF64_R_INFO(sym uint32, type_ uint32) uint64 { 2589 return uint64(sym)<<32 | uint64(type_) 2590 } 2591 2592 func ELF64_ST_BIND(info uint8) uint8 { 2593 return info >> 4 2594 } 2595 2596 func ELF64_ST_TYPE(info uint8) uint8 { 2597 return info & 0xf 2598 } 2599 2600 func ELF64_ST_INFO(bind uint8, type_ uint8) uint8 { 2601 return bind<<4 | type_&0xf 2602 } 2603 2604 func ELF64_ST_VISIBILITY(oth uint8) uint8 { 2605 return oth & 3 2606 }