1 1.1 christos /* X86-64 specific support for ELF 2 1.10 christos Copyright (C) 2000-2025 Free Software Foundation, Inc. 3 1.1 christos Contributed by Jan Hubicka <jh (at) suse.cz>. 4 1.1 christos 5 1.1 christos This file is part of BFD, the Binary File Descriptor library. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program; if not, write to the Free Software 19 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 1.1 christos MA 02110-1301, USA. */ 21 1.1 christos 22 1.6 christos #include "elfxx-x86.h" 23 1.1 christos #include "dwarf2.h" 24 1.1 christos #include "libiberty.h" 25 1.9 christos #include "sframe.h" 26 1.1 christos 27 1.3 christos #include "opcode/i386.h" 28 1.1 christos 29 1.1 christos #ifdef CORE_HEADER 30 1.1 christos #include <stdarg.h> 31 1.1 christos #include CORE_HEADER 32 1.1 christos #endif 33 1.1 christos 34 1.1 christos /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */ 35 1.1 christos #define MINUS_ONE (~ (bfd_vma) 0) 36 1.1 christos 37 1.1 christos /* Since both 32-bit and 64-bit x86-64 encode relocation type in the 38 1.1 christos identical manner, we use ELF32_R_TYPE instead of ELF64_R_TYPE to get 39 1.1 christos relocation type. We also use ELF_ST_TYPE instead of ELF64_ST_TYPE 40 1.1 christos since they are the same. */ 41 1.1 christos 42 1.1 christos /* The relocation "howto" table. Order of fields: 43 1.1 christos type, rightshift, size, bitsize, pc_relative, bitpos, complain_on_overflow, 44 1.1 christos special_function, name, partial_inplace, src_mask, dst_mask, pcrel_offset. */ 45 1.1 christos static reloc_howto_type x86_64_elf_howto_table[] = 46 1.1 christos { 47 1.8 christos HOWTO(R_X86_64_NONE, 0, 0, 0, false, 0, complain_overflow_dont, 48 1.8 christos bfd_elf_generic_reloc, "R_X86_64_NONE", false, 0, 0x00000000, 49 1.8 christos false), 50 1.8 christos HOWTO(R_X86_64_64, 0, 8, 64, false, 0, complain_overflow_dont, 51 1.8 christos bfd_elf_generic_reloc, "R_X86_64_64", false, 0, MINUS_ONE, 52 1.8 christos false), 53 1.8 christos HOWTO(R_X86_64_PC32, 0, 4, 32, true, 0, complain_overflow_signed, 54 1.8 christos bfd_elf_generic_reloc, "R_X86_64_PC32", false, 0, 0xffffffff, 55 1.8 christos true), 56 1.8 christos HOWTO(R_X86_64_GOT32, 0, 4, 32, false, 0, complain_overflow_signed, 57 1.8 christos bfd_elf_generic_reloc, "R_X86_64_GOT32", false, 0, 0xffffffff, 58 1.8 christos false), 59 1.8 christos HOWTO(R_X86_64_PLT32, 0, 4, 32, true, 0, complain_overflow_signed, 60 1.8 christos bfd_elf_generic_reloc, "R_X86_64_PLT32", false, 0, 0xffffffff, 61 1.8 christos true), 62 1.8 christos HOWTO(R_X86_64_COPY, 0, 4, 32, false, 0, complain_overflow_bitfield, 63 1.8 christos bfd_elf_generic_reloc, "R_X86_64_COPY", false, 0, 0xffffffff, 64 1.8 christos false), 65 1.8 christos HOWTO(R_X86_64_GLOB_DAT, 0, 8, 64, false, 0, complain_overflow_dont, 66 1.8 christos bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", false, 0, MINUS_ONE, 67 1.8 christos false), 68 1.8 christos HOWTO(R_X86_64_JUMP_SLOT, 0, 8, 64, false, 0, complain_overflow_dont, 69 1.8 christos bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", false, 0, MINUS_ONE, 70 1.8 christos false), 71 1.8 christos HOWTO(R_X86_64_RELATIVE, 0, 8, 64, false, 0, complain_overflow_dont, 72 1.8 christos bfd_elf_generic_reloc, "R_X86_64_RELATIVE", false, 0, MINUS_ONE, 73 1.8 christos false), 74 1.8 christos HOWTO(R_X86_64_GOTPCREL, 0, 4, 32, true, 0, complain_overflow_signed, 75 1.8 christos bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", false, 0, 0xffffffff, 76 1.8 christos true), 77 1.8 christos HOWTO(R_X86_64_32, 0, 4, 32, false, 0, complain_overflow_unsigned, 78 1.8 christos bfd_elf_generic_reloc, "R_X86_64_32", false, 0, 0xffffffff, 79 1.8 christos false), 80 1.8 christos HOWTO(R_X86_64_32S, 0, 4, 32, false, 0, complain_overflow_signed, 81 1.8 christos bfd_elf_generic_reloc, "R_X86_64_32S", false, 0, 0xffffffff, 82 1.8 christos false), 83 1.8 christos HOWTO(R_X86_64_16, 0, 2, 16, false, 0, complain_overflow_bitfield, 84 1.8 christos bfd_elf_generic_reloc, "R_X86_64_16", false, 0, 0xffff, false), 85 1.8 christos HOWTO(R_X86_64_PC16, 0, 2, 16, true, 0, complain_overflow_bitfield, 86 1.8 christos bfd_elf_generic_reloc, "R_X86_64_PC16", false, 0, 0xffff, true), 87 1.8 christos HOWTO(R_X86_64_8, 0, 1, 8, false, 0, complain_overflow_bitfield, 88 1.8 christos bfd_elf_generic_reloc, "R_X86_64_8", false, 0, 0xff, false), 89 1.8 christos HOWTO(R_X86_64_PC8, 0, 1, 8, true, 0, complain_overflow_signed, 90 1.8 christos bfd_elf_generic_reloc, "R_X86_64_PC8", false, 0, 0xff, true), 91 1.8 christos HOWTO(R_X86_64_DTPMOD64, 0, 8, 64, false, 0, complain_overflow_dont, 92 1.8 christos bfd_elf_generic_reloc, "R_X86_64_DTPMOD64", false, 0, MINUS_ONE, 93 1.8 christos false), 94 1.8 christos HOWTO(R_X86_64_DTPOFF64, 0, 8, 64, false, 0, complain_overflow_dont, 95 1.8 christos bfd_elf_generic_reloc, "R_X86_64_DTPOFF64", false, 0, MINUS_ONE, 96 1.8 christos false), 97 1.8 christos HOWTO(R_X86_64_TPOFF64, 0, 8, 64, false, 0, complain_overflow_dont, 98 1.8 christos bfd_elf_generic_reloc, "R_X86_64_TPOFF64", false, 0, MINUS_ONE, 99 1.8 christos false), 100 1.8 christos HOWTO(R_X86_64_TLSGD, 0, 4, 32, true, 0, complain_overflow_signed, 101 1.8 christos bfd_elf_generic_reloc, "R_X86_64_TLSGD", false, 0, 0xffffffff, 102 1.8 christos true), 103 1.8 christos HOWTO(R_X86_64_TLSLD, 0, 4, 32, true, 0, complain_overflow_signed, 104 1.8 christos bfd_elf_generic_reloc, "R_X86_64_TLSLD", false, 0, 0xffffffff, 105 1.8 christos true), 106 1.8 christos HOWTO(R_X86_64_DTPOFF32, 0, 4, 32, false, 0, complain_overflow_signed, 107 1.8 christos bfd_elf_generic_reloc, "R_X86_64_DTPOFF32", false, 0, 0xffffffff, 108 1.8 christos false), 109 1.8 christos HOWTO(R_X86_64_GOTTPOFF, 0, 4, 32, true, 0, complain_overflow_signed, 110 1.8 christos bfd_elf_generic_reloc, "R_X86_64_GOTTPOFF", false, 0, 0xffffffff, 111 1.8 christos true), 112 1.8 christos HOWTO(R_X86_64_TPOFF32, 0, 4, 32, false, 0, complain_overflow_signed, 113 1.8 christos bfd_elf_generic_reloc, "R_X86_64_TPOFF32", false, 0, 0xffffffff, 114 1.8 christos false), 115 1.8 christos HOWTO(R_X86_64_PC64, 0, 8, 64, true, 0, complain_overflow_dont, 116 1.8 christos bfd_elf_generic_reloc, "R_X86_64_PC64", false, 0, MINUS_ONE, 117 1.8 christos true), 118 1.8 christos HOWTO(R_X86_64_GOTOFF64, 0, 8, 64, false, 0, complain_overflow_dont, 119 1.8 christos bfd_elf_generic_reloc, "R_X86_64_GOTOFF64", false, 0, MINUS_ONE, 120 1.8 christos false), 121 1.8 christos HOWTO(R_X86_64_GOTPC32, 0, 4, 32, true, 0, complain_overflow_signed, 122 1.8 christos bfd_elf_generic_reloc, "R_X86_64_GOTPC32", false, 0, 0xffffffff, 123 1.8 christos true), 124 1.8 christos HOWTO(R_X86_64_GOT64, 0, 8, 64, false, 0, complain_overflow_signed, 125 1.8 christos bfd_elf_generic_reloc, "R_X86_64_GOT64", false, 0, MINUS_ONE, 126 1.8 christos false), 127 1.8 christos HOWTO(R_X86_64_GOTPCREL64, 0, 8, 64, true, 0, complain_overflow_signed, 128 1.8 christos bfd_elf_generic_reloc, "R_X86_64_GOTPCREL64", false, 0, MINUS_ONE, 129 1.8 christos true), 130 1.8 christos HOWTO(R_X86_64_GOTPC64, 0, 8, 64, true, 0, complain_overflow_signed, 131 1.8 christos bfd_elf_generic_reloc, "R_X86_64_GOTPC64", false, 0, MINUS_ONE, 132 1.8 christos true), 133 1.8 christos HOWTO(R_X86_64_GOTPLT64, 0, 8, 64, false, 0, complain_overflow_signed, 134 1.8 christos bfd_elf_generic_reloc, "R_X86_64_GOTPLT64", false, 0, MINUS_ONE, 135 1.8 christos false), 136 1.8 christos HOWTO(R_X86_64_PLTOFF64, 0, 8, 64, false, 0, complain_overflow_signed, 137 1.8 christos bfd_elf_generic_reloc, "R_X86_64_PLTOFF64", false, 0, MINUS_ONE, 138 1.8 christos false), 139 1.8 christos HOWTO(R_X86_64_SIZE32, 0, 4, 32, false, 0, complain_overflow_unsigned, 140 1.8 christos bfd_elf_generic_reloc, "R_X86_64_SIZE32", false, 0, 0xffffffff, 141 1.8 christos false), 142 1.8 christos HOWTO(R_X86_64_SIZE64, 0, 8, 64, false, 0, complain_overflow_dont, 143 1.8 christos bfd_elf_generic_reloc, "R_X86_64_SIZE64", false, 0, MINUS_ONE, 144 1.8 christos false), 145 1.8 christos HOWTO(R_X86_64_GOTPC32_TLSDESC, 0, 4, 32, true, 0, 146 1.1 christos complain_overflow_bitfield, bfd_elf_generic_reloc, 147 1.8 christos "R_X86_64_GOTPC32_TLSDESC", false, 0, 0xffffffff, true), 148 1.8 christos HOWTO(R_X86_64_TLSDESC_CALL, 0, 0, 0, false, 0, 149 1.1 christos complain_overflow_dont, bfd_elf_generic_reloc, 150 1.1 christos "R_X86_64_TLSDESC_CALL", 151 1.8 christos false, 0, 0, false), 152 1.8 christos HOWTO(R_X86_64_TLSDESC, 0, 8, 64, false, 0, 153 1.8 christos complain_overflow_dont, bfd_elf_generic_reloc, 154 1.8 christos "R_X86_64_TLSDESC", false, 0, MINUS_ONE, false), 155 1.8 christos HOWTO(R_X86_64_IRELATIVE, 0, 8, 64, false, 0, complain_overflow_dont, 156 1.8 christos bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", false, 0, MINUS_ONE, 157 1.8 christos false), 158 1.8 christos HOWTO(R_X86_64_RELATIVE64, 0, 8, 64, false, 0, complain_overflow_dont, 159 1.8 christos bfd_elf_generic_reloc, "R_X86_64_RELATIVE64", false, 0, MINUS_ONE, 160 1.8 christos false), 161 1.8 christos HOWTO(R_X86_64_PC32_BND, 0, 4, 32, true, 0, complain_overflow_signed, 162 1.8 christos bfd_elf_generic_reloc, "R_X86_64_PC32_BND", false, 0, 0xffffffff, 163 1.8 christos true), 164 1.8 christos HOWTO(R_X86_64_PLT32_BND, 0, 4, 32, true, 0, complain_overflow_signed, 165 1.8 christos bfd_elf_generic_reloc, "R_X86_64_PLT32_BND", false, 0, 0xffffffff, 166 1.8 christos true), 167 1.8 christos HOWTO(R_X86_64_GOTPCRELX, 0, 4, 32, true, 0, complain_overflow_signed, 168 1.8 christos bfd_elf_generic_reloc, "R_X86_64_GOTPCRELX", false, 0, 0xffffffff, 169 1.8 christos true), 170 1.8 christos HOWTO(R_X86_64_REX_GOTPCRELX, 0, 4, 32, true, 0, complain_overflow_signed, 171 1.8 christos bfd_elf_generic_reloc, "R_X86_64_REX_GOTPCRELX", false, 0, 0xffffffff, 172 1.8 christos true), 173 1.9 christos HOWTO(R_X86_64_CODE_4_GOTPCRELX, 0, 4, 32, true, 0, complain_overflow_signed, 174 1.9 christos bfd_elf_generic_reloc, "R_X86_64_CODE_4_GOTPCRELX", false, 0, 0xffffffff, 175 1.9 christos true), 176 1.9 christos HOWTO(R_X86_64_CODE_4_GOTTPOFF, 0, 4, 32, true, 0, complain_overflow_signed, 177 1.9 christos bfd_elf_generic_reloc, "R_X86_64_CODE_4_GOTTPOFF", false, 0, 0xffffffff, 178 1.9 christos true), 179 1.9 christos HOWTO(R_X86_64_CODE_4_GOTPC32_TLSDESC, 0, 4, 32, true, 0, 180 1.9 christos complain_overflow_bitfield, bfd_elf_generic_reloc, 181 1.9 christos "R_X86_64_CODE_4_GOTPC32_TLSDESC", false, 0, 0xffffffff, true), 182 1.10 christos HOWTO(R_X86_64_CODE_5_GOTPCRELX, 0, 4, 32, true, 0, 183 1.10 christos complain_overflow_signed, bfd_elf_generic_reloc, 184 1.10 christos "R_X86_64_CODE_5_GOTPCRELX", false, 0, 0xffffffff, true), 185 1.10 christos HOWTO(R_X86_64_CODE_5_GOTTPOFF, 0, 4, 32, true, 0, 186 1.10 christos complain_overflow_signed, bfd_elf_generic_reloc, 187 1.10 christos "R_X86_64_CODE_5_GOTTPOFF", false, 0, 0xffffffff, true), 188 1.10 christos HOWTO(R_X86_64_CODE_5_GOTPC32_TLSDESC, 0, 4, 32, true, 0, 189 1.10 christos complain_overflow_bitfield, bfd_elf_generic_reloc, 190 1.10 christos "R_X86_64_CODE_5_GOTPC32_TLSDESC", false, 0, 0xffffffff, true), 191 1.10 christos HOWTO(R_X86_64_CODE_6_GOTPCRELX, 0, 4, 32, true, 0, 192 1.10 christos complain_overflow_signed, bfd_elf_generic_reloc, 193 1.10 christos "R_X86_64_CODE_6_GOTPCRELX", false, 0, 0xffffffff, true), 194 1.10 christos HOWTO(R_X86_64_CODE_6_GOTTPOFF, 0, 4, 32, true, 0, 195 1.10 christos complain_overflow_signed, bfd_elf_generic_reloc, 196 1.10 christos "R_X86_64_CODE_6_GOTTPOFF", false, 0, 0xffffffff, true), 197 1.10 christos HOWTO(R_X86_64_CODE_6_GOTPC32_TLSDESC, 0, 4, 32, true, 0, 198 1.10 christos complain_overflow_bitfield, bfd_elf_generic_reloc, 199 1.10 christos "R_X86_64_CODE_6_GOTPC32_TLSDESC", false, 0, 0xffffffff, true), 200 1.1 christos 201 1.1 christos /* We have a gap in the reloc numbers here. 202 1.1 christos R_X86_64_standard counts the number up to this point, and 203 1.1 christos R_X86_64_vt_offset is the value to subtract from a reloc type of 204 1.1 christos R_X86_64_GNU_VT* to form an index into this table. */ 205 1.10 christos #define R_X86_64_standard (R_X86_64_CODE_6_GOTPC32_TLSDESC + 1) 206 1.1 christos #define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard) 207 1.1 christos 208 1.1 christos /* GNU extension to record C++ vtable hierarchy. */ 209 1.8 christos HOWTO (R_X86_64_GNU_VTINHERIT, 0, 8, 0, false, 0, complain_overflow_dont, 210 1.8 christos NULL, "R_X86_64_GNU_VTINHERIT", false, 0, 0, false), 211 1.1 christos 212 1.1 christos /* GNU extension to record C++ vtable member usage. */ 213 1.8 christos HOWTO (R_X86_64_GNU_VTENTRY, 0, 8, 0, false, 0, complain_overflow_dont, 214 1.8 christos _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", false, 0, 0, 215 1.8 christos false), 216 1.1 christos 217 1.1 christos /* Use complain_overflow_bitfield on R_X86_64_32 for x32. */ 218 1.8 christos HOWTO(R_X86_64_32, 0, 4, 32, false, 0, complain_overflow_bitfield, 219 1.8 christos bfd_elf_generic_reloc, "R_X86_64_32", false, 0, 0xffffffff, 220 1.8 christos false) 221 1.1 christos }; 222 1.1 christos 223 1.1 christos /* Map BFD relocs to the x86_64 elf relocs. */ 224 1.1 christos struct elf_reloc_map 225 1.1 christos { 226 1.1 christos bfd_reloc_code_real_type bfd_reloc_val; 227 1.1 christos unsigned char elf_reloc_val; 228 1.1 christos }; 229 1.1 christos 230 1.1 christos static const struct elf_reloc_map x86_64_reloc_map[] = 231 1.1 christos { 232 1.1 christos { BFD_RELOC_NONE, R_X86_64_NONE, }, 233 1.1 christos { BFD_RELOC_64, R_X86_64_64, }, 234 1.1 christos { BFD_RELOC_32_PCREL, R_X86_64_PC32, }, 235 1.1 christos { BFD_RELOC_X86_64_GOT32, R_X86_64_GOT32,}, 236 1.1 christos { BFD_RELOC_X86_64_PLT32, R_X86_64_PLT32,}, 237 1.1 christos { BFD_RELOC_X86_64_COPY, R_X86_64_COPY, }, 238 1.1 christos { BFD_RELOC_X86_64_GLOB_DAT, R_X86_64_GLOB_DAT, }, 239 1.1 christos { BFD_RELOC_X86_64_JUMP_SLOT, R_X86_64_JUMP_SLOT, }, 240 1.1 christos { BFD_RELOC_X86_64_RELATIVE, R_X86_64_RELATIVE, }, 241 1.1 christos { BFD_RELOC_X86_64_GOTPCREL, R_X86_64_GOTPCREL, }, 242 1.1 christos { BFD_RELOC_32, R_X86_64_32, }, 243 1.1 christos { BFD_RELOC_X86_64_32S, R_X86_64_32S, }, 244 1.1 christos { BFD_RELOC_16, R_X86_64_16, }, 245 1.1 christos { BFD_RELOC_16_PCREL, R_X86_64_PC16, }, 246 1.1 christos { BFD_RELOC_8, R_X86_64_8, }, 247 1.1 christos { BFD_RELOC_8_PCREL, R_X86_64_PC8, }, 248 1.1 christos { BFD_RELOC_X86_64_DTPMOD64, R_X86_64_DTPMOD64, }, 249 1.1 christos { BFD_RELOC_X86_64_DTPOFF64, R_X86_64_DTPOFF64, }, 250 1.1 christos { BFD_RELOC_X86_64_TPOFF64, R_X86_64_TPOFF64, }, 251 1.1 christos { BFD_RELOC_X86_64_TLSGD, R_X86_64_TLSGD, }, 252 1.1 christos { BFD_RELOC_X86_64_TLSLD, R_X86_64_TLSLD, }, 253 1.1 christos { BFD_RELOC_X86_64_DTPOFF32, R_X86_64_DTPOFF32, }, 254 1.1 christos { BFD_RELOC_X86_64_GOTTPOFF, R_X86_64_GOTTPOFF, }, 255 1.1 christos { BFD_RELOC_X86_64_TPOFF32, R_X86_64_TPOFF32, }, 256 1.1 christos { BFD_RELOC_64_PCREL, R_X86_64_PC64, }, 257 1.1 christos { BFD_RELOC_X86_64_GOTOFF64, R_X86_64_GOTOFF64, }, 258 1.1 christos { BFD_RELOC_X86_64_GOTPC32, R_X86_64_GOTPC32, }, 259 1.1 christos { BFD_RELOC_X86_64_GOT64, R_X86_64_GOT64, }, 260 1.1 christos { BFD_RELOC_X86_64_GOTPCREL64,R_X86_64_GOTPCREL64, }, 261 1.1 christos { BFD_RELOC_X86_64_GOTPC64, R_X86_64_GOTPC64, }, 262 1.1 christos { BFD_RELOC_X86_64_GOTPLT64, R_X86_64_GOTPLT64, }, 263 1.1 christos { BFD_RELOC_X86_64_PLTOFF64, R_X86_64_PLTOFF64, }, 264 1.3 christos { BFD_RELOC_SIZE32, R_X86_64_SIZE32, }, 265 1.3 christos { BFD_RELOC_SIZE64, R_X86_64_SIZE64, }, 266 1.1 christos { BFD_RELOC_X86_64_GOTPC32_TLSDESC, R_X86_64_GOTPC32_TLSDESC, }, 267 1.1 christos { BFD_RELOC_X86_64_TLSDESC_CALL, R_X86_64_TLSDESC_CALL, }, 268 1.1 christos { BFD_RELOC_X86_64_TLSDESC, R_X86_64_TLSDESC, }, 269 1.1 christos { BFD_RELOC_X86_64_IRELATIVE, R_X86_64_IRELATIVE, }, 270 1.3 christos { BFD_RELOC_X86_64_PC32_BND, R_X86_64_PC32_BND, }, 271 1.3 christos { BFD_RELOC_X86_64_PLT32_BND, R_X86_64_PLT32_BND, }, 272 1.3 christos { BFD_RELOC_X86_64_GOTPCRELX, R_X86_64_GOTPCRELX, }, 273 1.3 christos { BFD_RELOC_X86_64_REX_GOTPCRELX, R_X86_64_REX_GOTPCRELX, }, 274 1.9 christos { BFD_RELOC_X86_64_CODE_4_GOTPCRELX, R_X86_64_CODE_4_GOTPCRELX, }, 275 1.9 christos { BFD_RELOC_X86_64_CODE_4_GOTTPOFF, R_X86_64_CODE_4_GOTTPOFF, }, 276 1.9 christos { BFD_RELOC_X86_64_CODE_4_GOTPC32_TLSDESC, R_X86_64_CODE_4_GOTPC32_TLSDESC, }, 277 1.10 christos { BFD_RELOC_X86_64_CODE_5_GOTPCRELX, R_X86_64_CODE_5_GOTPCRELX, }, 278 1.10 christos { BFD_RELOC_X86_64_CODE_5_GOTTPOFF, R_X86_64_CODE_5_GOTTPOFF, }, 279 1.10 christos { BFD_RELOC_X86_64_CODE_5_GOTPC32_TLSDESC, R_X86_64_CODE_5_GOTPC32_TLSDESC, }, 280 1.10 christos { BFD_RELOC_X86_64_CODE_6_GOTPCRELX, R_X86_64_CODE_6_GOTPCRELX, }, 281 1.10 christos { BFD_RELOC_X86_64_CODE_6_GOTTPOFF, R_X86_64_CODE_6_GOTTPOFF, }, 282 1.10 christos { BFD_RELOC_X86_64_CODE_6_GOTPC32_TLSDESC, R_X86_64_CODE_6_GOTPC32_TLSDESC, }, 283 1.1 christos { BFD_RELOC_VTABLE_INHERIT, R_X86_64_GNU_VTINHERIT, }, 284 1.1 christos { BFD_RELOC_VTABLE_ENTRY, R_X86_64_GNU_VTENTRY, }, 285 1.1 christos }; 286 1.1 christos 287 1.1 christos static reloc_howto_type * 288 1.1 christos elf_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type) 289 1.1 christos { 290 1.1 christos unsigned i; 291 1.1 christos 292 1.1 christos if (r_type == (unsigned int) R_X86_64_32) 293 1.1 christos { 294 1.1 christos if (ABI_64_P (abfd)) 295 1.1 christos i = r_type; 296 1.1 christos else 297 1.1 christos i = ARRAY_SIZE (x86_64_elf_howto_table) - 1; 298 1.1 christos } 299 1.1 christos else if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT 300 1.1 christos || r_type >= (unsigned int) R_X86_64_max) 301 1.1 christos { 302 1.1 christos if (r_type >= (unsigned int) R_X86_64_standard) 303 1.1 christos { 304 1.6 christos /* xgettext:c-format */ 305 1.6 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 306 1.6 christos abfd, r_type); 307 1.6 christos bfd_set_error (bfd_error_bad_value); 308 1.6 christos return NULL; 309 1.1 christos } 310 1.1 christos i = r_type; 311 1.1 christos } 312 1.1 christos else 313 1.1 christos i = r_type - (unsigned int) R_X86_64_vt_offset; 314 1.1 christos BFD_ASSERT (x86_64_elf_howto_table[i].type == r_type); 315 1.1 christos return &x86_64_elf_howto_table[i]; 316 1.1 christos } 317 1.1 christos 318 1.1 christos /* Given a BFD reloc type, return a HOWTO structure. */ 319 1.1 christos static reloc_howto_type * 320 1.1 christos elf_x86_64_reloc_type_lookup (bfd *abfd, 321 1.1 christos bfd_reloc_code_real_type code) 322 1.1 christos { 323 1.1 christos unsigned int i; 324 1.1 christos 325 1.1 christos for (i = 0; i < sizeof (x86_64_reloc_map) / sizeof (struct elf_reloc_map); 326 1.1 christos i++) 327 1.1 christos { 328 1.1 christos if (x86_64_reloc_map[i].bfd_reloc_val == code) 329 1.1 christos return elf_x86_64_rtype_to_howto (abfd, 330 1.1 christos x86_64_reloc_map[i].elf_reloc_val); 331 1.1 christos } 332 1.3 christos return NULL; 333 1.1 christos } 334 1.1 christos 335 1.1 christos static reloc_howto_type * 336 1.1 christos elf_x86_64_reloc_name_lookup (bfd *abfd, 337 1.1 christos const char *r_name) 338 1.1 christos { 339 1.1 christos unsigned int i; 340 1.1 christos 341 1.1 christos if (!ABI_64_P (abfd) && strcasecmp (r_name, "R_X86_64_32") == 0) 342 1.1 christos { 343 1.1 christos /* Get x32 R_X86_64_32. */ 344 1.1 christos reloc_howto_type *reloc 345 1.1 christos = &x86_64_elf_howto_table[ARRAY_SIZE (x86_64_elf_howto_table) - 1]; 346 1.1 christos BFD_ASSERT (reloc->type == (unsigned int) R_X86_64_32); 347 1.1 christos return reloc; 348 1.1 christos } 349 1.1 christos 350 1.1 christos for (i = 0; i < ARRAY_SIZE (x86_64_elf_howto_table); i++) 351 1.1 christos if (x86_64_elf_howto_table[i].name != NULL 352 1.1 christos && strcasecmp (x86_64_elf_howto_table[i].name, r_name) == 0) 353 1.1 christos return &x86_64_elf_howto_table[i]; 354 1.1 christos 355 1.1 christos return NULL; 356 1.1 christos } 357 1.1 christos 358 1.1 christos /* Given an x86_64 ELF reloc type, fill in an arelent structure. */ 359 1.1 christos 360 1.8 christos static bool 361 1.6 christos elf_x86_64_info_to_howto (bfd *abfd, arelent *cache_ptr, 362 1.1 christos Elf_Internal_Rela *dst) 363 1.1 christos { 364 1.1 christos unsigned r_type; 365 1.1 christos 366 1.1 christos r_type = ELF32_R_TYPE (dst->r_info); 367 1.1 christos cache_ptr->howto = elf_x86_64_rtype_to_howto (abfd, r_type); 368 1.6 christos if (cache_ptr->howto == NULL) 369 1.8 christos return false; 370 1.6 christos BFD_ASSERT (r_type == cache_ptr->howto->type || cache_ptr->howto->type == R_X86_64_NONE); 371 1.8 christos return true; 372 1.1 christos } 373 1.1 christos 374 1.1 christos /* Support for core dump NOTE sections. */ 376 1.1 christos static bool 377 1.1 christos elf_x86_64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) 378 1.1 christos { 379 1.1 christos int offset; 380 1.1 christos size_t size; 381 1.1 christos 382 1.1 christos switch (note->descsz) 383 1.1 christos { 384 1.8 christos default: 385 1.1 christos return false; 386 1.1 christos 387 1.1 christos case 296: /* sizeof(istruct elf_prstatus) on Linux/x32 */ 388 1.3 christos /* pr_cursig */ 389 1.1 christos elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12); 390 1.1 christos 391 1.3 christos /* pr_pid */ 392 1.1 christos elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24); 393 1.1 christos 394 1.1 christos /* pr_reg */ 395 1.1 christos offset = 72; 396 1.1 christos size = 216; 397 1.1 christos 398 1.1 christos break; 399 1.1 christos 400 1.1 christos case 336: /* sizeof(istruct elf_prstatus) on Linux/x86_64 */ 401 1.3 christos /* pr_cursig */ 402 1.1 christos elf_tdata (abfd)->core->signal 403 1.1 christos = bfd_get_16 (abfd, note->descdata + 12); 404 1.1 christos 405 1.3 christos /* pr_pid */ 406 1.1 christos elf_tdata (abfd)->core->lwpid 407 1.1 christos = bfd_get_32 (abfd, note->descdata + 32); 408 1.1 christos 409 1.1 christos /* pr_reg */ 410 1.1 christos offset = 112; 411 1.1 christos size = 216; 412 1.1 christos 413 1.1 christos break; 414 1.1 christos } 415 1.1 christos 416 1.1 christos /* Make a ".reg/999" section. */ 417 1.1 christos return _bfd_elfcore_make_pseudosection (abfd, ".reg", 418 1.1 christos size, note->descpos + offset); 419 1.1 christos } 420 1.8 christos 421 1.1 christos static bool 422 1.1 christos elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) 423 1.1 christos { 424 1.1 christos switch (note->descsz) 425 1.1 christos { 426 1.8 christos default: 427 1.1 christos return false; 428 1.9 christos 429 1.9 christos case 124: 430 1.3 christos /* sizeof (struct elf_external_linux_prpsinfo32_ugid16). */ 431 1.1 christos elf_tdata (abfd)->core->pid 432 1.3 christos = bfd_get_32 (abfd, note->descdata + 12); 433 1.1 christos elf_tdata (abfd)->core->program 434 1.3 christos = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16); 435 1.1 christos elf_tdata (abfd)->core->command 436 1.1 christos = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80); 437 1.1 christos break; 438 1.9 christos 439 1.9 christos case 128: 440 1.9 christos /* sizeof (struct elf_external_linux_prpsinfo32_ugid32). */ 441 1.9 christos elf_tdata (abfd)->core->pid 442 1.9 christos = bfd_get_32 (abfd, note->descdata + 12); 443 1.9 christos elf_tdata (abfd)->core->program 444 1.9 christos = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16); 445 1.9 christos elf_tdata (abfd)->core->command 446 1.9 christos = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80); 447 1.9 christos break; 448 1.9 christos 449 1.9 christos case 136: 450 1.3 christos /* sizeof (struct elf_prpsinfo) on Linux/x86_64. */ 451 1.1 christos elf_tdata (abfd)->core->pid 452 1.3 christos = bfd_get_32 (abfd, note->descdata + 24); 453 1.1 christos elf_tdata (abfd)->core->program 454 1.3 christos = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16); 455 1.1 christos elf_tdata (abfd)->core->command 456 1.1 christos = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80); 457 1.1 christos } 458 1.1 christos 459 1.1 christos /* Note that for some reason, a spurious space is tacked 460 1.1 christos onto the end of the args in some (at least one anyway) 461 1.1 christos implementations, so strip it off if it exists. */ 462 1.1 christos 463 1.3 christos { 464 1.1 christos char *command = elf_tdata (abfd)->core->command; 465 1.1 christos int n = strlen (command); 466 1.1 christos 467 1.1 christos if (0 < n && command[n - 1] == ' ') 468 1.1 christos command[n - 1] = '\0'; 469 1.1 christos } 470 1.8 christos 471 1.1 christos return true; 472 1.1 christos } 473 1.1 christos 474 1.6 christos #ifdef CORE_HEADER 475 1.6 christos # if GCC_VERSION >= 8000 476 1.6 christos # pragma GCC diagnostic push 477 1.6 christos # pragma GCC diagnostic ignored "-Wstringop-truncation" 478 1.1 christos # endif 479 1.1 christos static char * 480 1.1 christos elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz, 481 1.1 christos int note_type, ...) 482 1.1 christos { 483 1.1 christos const struct elf_backend_data *bed = get_elf_backend_data (abfd); 484 1.1 christos va_list ap; 485 1.1 christos const char *fname, *psargs; 486 1.1 christos long pid; 487 1.1 christos int cursig; 488 1.1 christos const void *gregs; 489 1.1 christos 490 1.1 christos switch (note_type) 491 1.1 christos { 492 1.1 christos default: 493 1.1 christos return NULL; 494 1.1 christos 495 1.1 christos case NT_PRPSINFO: 496 1.1 christos va_start (ap, note_type); 497 1.1 christos fname = va_arg (ap, const char *); 498 1.1 christos psargs = va_arg (ap, const char *); 499 1.1 christos va_end (ap); 500 1.1 christos 501 1.1 christos if (bed->s->elfclass == ELFCLASS32) 502 1.1 christos { 503 1.1 christos prpsinfo32_t data; 504 1.1 christos memset (&data, 0, sizeof (data)); 505 1.1 christos strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); 506 1.1 christos strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); 507 1.1 christos return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, 508 1.1 christos &data, sizeof (data)); 509 1.1 christos } 510 1.1 christos else 511 1.3 christos { 512 1.1 christos prpsinfo64_t data; 513 1.1 christos memset (&data, 0, sizeof (data)); 514 1.1 christos strncpy (data.pr_fname, fname, sizeof (data.pr_fname)); 515 1.1 christos strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs)); 516 1.1 christos return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, 517 1.1 christos &data, sizeof (data)); 518 1.1 christos } 519 1.1 christos /* NOTREACHED */ 520 1.1 christos 521 1.1 christos case NT_PRSTATUS: 522 1.1 christos va_start (ap, note_type); 523 1.1 christos pid = va_arg (ap, long); 524 1.1 christos cursig = va_arg (ap, int); 525 1.1 christos gregs = va_arg (ap, const void *); 526 1.1 christos va_end (ap); 527 1.1 christos 528 1.1 christos if (bed->s->elfclass == ELFCLASS32) 529 1.1 christos { 530 1.1 christos if (bed->elf_machine_code == EM_X86_64) 531 1.1 christos { 532 1.1 christos prstatusx32_t prstat; 533 1.1 christos memset (&prstat, 0, sizeof (prstat)); 534 1.1 christos prstat.pr_pid = pid; 535 1.1 christos prstat.pr_cursig = cursig; 536 1.1 christos memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); 537 1.1 christos return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, 538 1.1 christos &prstat, sizeof (prstat)); 539 1.1 christos } 540 1.1 christos else 541 1.1 christos { 542 1.1 christos prstatus32_t prstat; 543 1.1 christos memset (&prstat, 0, sizeof (prstat)); 544 1.1 christos prstat.pr_pid = pid; 545 1.1 christos prstat.pr_cursig = cursig; 546 1.1 christos memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); 547 1.1 christos return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, 548 1.1 christos &prstat, sizeof (prstat)); 549 1.1 christos } 550 1.1 christos } 551 1.1 christos else 552 1.3 christos { 553 1.1 christos prstatus64_t prstat; 554 1.1 christos memset (&prstat, 0, sizeof (prstat)); 555 1.1 christos prstat.pr_pid = pid; 556 1.1 christos prstat.pr_cursig = cursig; 557 1.1 christos memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg)); 558 1.1 christos return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type, 559 1.1 christos &prstat, sizeof (prstat)); 560 1.1 christos } 561 1.1 christos } 562 1.1 christos /* NOTREACHED */ 563 1.6 christos } 564 1.6 christos # if GCC_VERSION >= 8000 565 1.6 christos # pragma GCC diagnostic pop 566 1.1 christos # endif 567 1.1 christos #endif 568 1.1 christos 569 1.1 christos /* Functions for the x86-64 ELF linker. */ 571 1.1 christos 572 1.6 christos /* The size in bytes of an entry in the global offset table. */ 573 1.1 christos 574 1.6 christos #define GOT_ENTRY_SIZE 8 575 1.1 christos 576 1.6 christos /* The size in bytes of an entry in the lazy procedure linkage table. */ 577 1.1 christos 578 1.6 christos #define LAZY_PLT_ENTRY_SIZE 16 579 1.6 christos 580 1.1 christos /* The size in bytes of an entry in the non-lazy procedure linkage 581 1.6 christos table. */ 582 1.1 christos 583 1.6 christos #define NON_LAZY_PLT_ENTRY_SIZE 8 584 1.6 christos 585 1.6 christos /* The first entry in a lazy procedure linkage table looks like this. 586 1.1 christos See the SVR4 ABI i386 supplement and the x86-64 ABI to see how this 587 1.6 christos works. */ 588 1.1 christos 589 1.1 christos static const bfd_byte elf_x86_64_lazy_plt0_entry[LAZY_PLT_ENTRY_SIZE] = 590 1.1 christos { 591 1.1 christos 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */ 592 1.1 christos 0xff, 0x25, 16, 0, 0, 0, /* jmpq *GOT+16(%rip) */ 593 1.1 christos 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */ 594 1.6 christos }; 595 1.1 christos 596 1.6 christos /* Subsequent entries in a lazy procedure linkage table look like this. */ 597 1.1 christos 598 1.1 christos static const bfd_byte elf_x86_64_lazy_plt_entry[LAZY_PLT_ENTRY_SIZE] = 599 1.1 christos { 600 1.1 christos 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */ 601 1.1 christos 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */ 602 1.1 christos 0x68, /* pushq immediate */ 603 1.1 christos 0, 0, 0, 0, /* replaced with index into relocation table. */ 604 1.1 christos 0xe9, /* jmp relative */ 605 1.1 christos 0, 0, 0, 0 /* replaced with offset to start of .plt0. */ 606 1.6 christos }; 607 1.3 christos 608 1.3 christos /* The first entry in a lazy procedure linkage table with BND prefix 609 1.6 christos like this. */ 610 1.3 christos 611 1.6 christos static const bfd_byte elf_x86_64_lazy_bnd_plt0_entry[LAZY_PLT_ENTRY_SIZE] = 612 1.3 christos { 613 1.6 christos 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */ 614 1.3 christos 0xf2, 0xff, 0x25, 16, 0, 0, 0, /* bnd jmpq *GOT+16(%rip) */ 615 1.3 christos 0x0f, 0x1f, 0 /* nopl (%rax) */ 616 1.6 christos }; 617 1.6 christos 618 1.3 christos /* Subsequent entries for branches with BND prefx in a lazy procedure 619 1.6 christos linkage table look like this. */ 620 1.3 christos 621 1.6 christos static const bfd_byte elf_x86_64_lazy_bnd_plt_entry[LAZY_PLT_ENTRY_SIZE] = 622 1.6 christos { 623 1.6 christos 0x68, 0, 0, 0, 0, /* pushq immediate */ 624 1.6 christos 0xf2, 0xe9, 0, 0, 0, 0, /* bnd jmpq relative */ 625 1.6 christos 0x0f, 0x1f, 0x44, 0, 0 /* nopl 0(%rax,%rax,1) */ 626 1.6 christos }; 627 1.6 christos 628 1.6 christos /* The first entry in the IBT-enabled lazy procedure linkage table is the 629 1.6 christos the same as the lazy PLT with BND prefix so that bound registers are 630 1.6 christos preserved when control is passed to dynamic linker. Subsequent 631 1.6 christos entries for a IBT-enabled lazy procedure linkage table look like 632 1.10 christos this. */ 633 1.6 christos 634 1.6 christos static const bfd_byte elf_x86_64_lazy_bnd_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] = 635 1.6 christos { 636 1.6 christos 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */ 637 1.6 christos 0x68, 0, 0, 0, 0, /* pushq immediate */ 638 1.6 christos 0xf2, 0xe9, 0, 0, 0, 0, /* bnd jmpq relative */ 639 1.6 christos 0x90 /* nop */ 640 1.10 christos }; 641 1.6 christos 642 1.10 christos /* The first entry in the IBT-enabled lazy procedure linkage table 643 1.6 christos is the same as the normal lazy PLT. Subsequent entries for an 644 1.10 christos IBT-enabled lazy procedure linkage table look like this. */ 645 1.6 christos 646 1.6 christos static const bfd_byte elf_x86_64_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] = 647 1.6 christos { 648 1.6 christos 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */ 649 1.6 christos 0x68, 0, 0, 0, 0, /* pushq immediate */ 650 1.3 christos 0xe9, 0, 0, 0, 0, /* jmpq relative */ 651 1.3 christos 0x66, 0x90 /* xchg %ax,%ax */ 652 1.6 christos }; 653 1.3 christos 654 1.6 christos /* Entries in the non-lazey procedure linkage table look like this. */ 655 1.3 christos 656 1.6 christos static const bfd_byte elf_x86_64_non_lazy_plt_entry[NON_LAZY_PLT_ENTRY_SIZE] = 657 1.6 christos { 658 1.6 christos 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */ 659 1.3 christos 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */ 660 1.3 christos 0x66, 0x90 /* xchg %ax,%ax */ 661 1.6 christos }; 662 1.6 christos 663 1.3 christos /* Entries for branches with BND prefix in the non-lazey procedure 664 1.6 christos linkage table look like this. */ 665 1.3 christos 666 1.6 christos static const bfd_byte elf_x86_64_non_lazy_bnd_plt_entry[NON_LAZY_PLT_ENTRY_SIZE] = 667 1.6 christos { 668 1.6 christos 0xf2, 0xff, 0x25, /* bnd jmpq *name@GOTPC(%rip) */ 669 1.6 christos 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */ 670 1.6 christos 0x90 /* nop */ 671 1.10 christos }; 672 1.10 christos 673 1.10 christos /* Entries for IBT-enabled branches with BND prefix in the non-lazey 674 1.6 christos procedure linkage table look like this. They have the same size as 675 1.10 christos the lazy PLT entry. */ 676 1.6 christos 677 1.6 christos static const bfd_byte elf_x86_64_non_lazy_bnd_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] = 678 1.6 christos { 679 1.6 christos 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */ 680 1.6 christos 0xf2, 0xff, 0x25, /* bnd jmpq *name@GOTPC(%rip) */ 681 1.3 christos 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */ 682 1.3 christos 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopl 0x0(%rax,%rax,1) */ 683 1.10 christos }; 684 1.6 christos 685 1.6 christos /* Entries for branches with IBT-enabled in the non-lazey procedure 686 1.6 christos linkage table look like this. They have the same size as the lazy 687 1.10 christos PLT entry. */ 688 1.6 christos 689 1.6 christos static const bfd_byte elf_x86_64_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] = 690 1.6 christos { 691 1.6 christos 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */ 692 1.6 christos 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */ 693 1.6 christos 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */ 694 1.3 christos 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */ 695 1.6 christos }; 696 1.6 christos 697 1.3 christos /* The TLSDESC entry in a lazy procedure linkage table. */ 698 1.6 christos static const bfd_byte elf_x86_64_tlsdesc_plt_entry[LAZY_PLT_ENTRY_SIZE] = 699 1.6 christos { 700 1.6 christos 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */ 701 1.3 christos 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */ 702 1.3 christos 0xff, 0x25, 16, 0, 0, 0 /* jmpq *GOT+TDG(%rip) */ 703 1.6 christos }; 704 1.1 christos 705 1.6 christos /* .eh_frame covering the lazy .plt section. */ 706 1.1 christos 707 1.1 christos static const bfd_byte elf_x86_64_eh_frame_lazy_plt[] = 708 1.1 christos { 709 1.1 christos PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */ 710 1.1 christos 0, 0, 0, 0, /* CIE ID */ 711 1.1 christos 1, /* CIE version */ 712 1.1 christos 'z', 'R', 0, /* Augmentation string */ 713 1.1 christos 1, /* Code alignment factor */ 714 1.1 christos 0x78, /* Data alignment factor */ 715 1.1 christos 16, /* Return address column */ 716 1.1 christos 1, /* Augmentation size */ 717 1.1 christos DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */ 718 1.1 christos DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */ 719 1.1 christos DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */ 720 1.1 christos DW_CFA_nop, DW_CFA_nop, 721 1.1 christos 722 1.1 christos PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */ 723 1.1 christos PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */ 724 1.1 christos 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */ 725 1.1 christos 0, 0, 0, 0, /* .plt size goes here */ 726 1.1 christos 0, /* Augmentation size */ 727 1.1 christos DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */ 728 1.1 christos DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */ 729 1.1 christos DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */ 730 1.1 christos DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */ 731 1.1 christos DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */ 732 1.1 christos 11, /* Block length */ 733 1.1 christos DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */ 734 1.1 christos DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */ 735 1.1 christos DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge, 736 1.1 christos DW_OP_lit3, DW_OP_shl, DW_OP_plus, 737 1.1 christos DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop 738 1.6 christos }; 739 1.1 christos 740 1.6 christos /* .eh_frame covering the lazy BND .plt section. */ 741 1.1 christos 742 1.6 christos static const bfd_byte elf_x86_64_eh_frame_lazy_bnd_plt[] = 743 1.6 christos { 744 1.6 christos PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */ 745 1.6 christos 0, 0, 0, 0, /* CIE ID */ 746 1.6 christos 1, /* CIE version */ 747 1.6 christos 'z', 'R', 0, /* Augmentation string */ 748 1.6 christos 1, /* Code alignment factor */ 749 1.6 christos 0x78, /* Data alignment factor */ 750 1.6 christos 16, /* Return address column */ 751 1.6 christos 1, /* Augmentation size */ 752 1.6 christos DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */ 753 1.6 christos DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */ 754 1.1 christos DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */ 755 1.6 christos DW_CFA_nop, DW_CFA_nop, 756 1.6 christos 757 1.6 christos PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */ 758 1.6 christos PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */ 759 1.6 christos 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */ 760 1.6 christos 0, 0, 0, 0, /* .plt size goes here */ 761 1.6 christos 0, /* Augmentation size */ 762 1.6 christos DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */ 763 1.6 christos DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */ 764 1.6 christos DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */ 765 1.6 christos DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */ 766 1.6 christos DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */ 767 1.6 christos 11, /* Block length */ 768 1.6 christos DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */ 769 1.6 christos DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */ 770 1.6 christos DW_OP_lit15, DW_OP_and, DW_OP_lit5, DW_OP_ge, 771 1.6 christos DW_OP_lit3, DW_OP_shl, DW_OP_plus, 772 1.1 christos DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop 773 1.10 christos }; 774 1.10 christos 775 1.1 christos /* .eh_frame covering the lazy .plt section with IBT-enabled and BND 776 1.10 christos prefix. */ 777 1.6 christos 778 1.6 christos static const bfd_byte elf_x86_64_eh_frame_lazy_bnd_ibt_plt[] = 779 1.6 christos { 780 1.6 christos PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */ 781 1.6 christos 0, 0, 0, 0, /* CIE ID */ 782 1.6 christos 1, /* CIE version */ 783 1.6 christos 'z', 'R', 0, /* Augmentation string */ 784 1.6 christos 1, /* Code alignment factor */ 785 1.6 christos 0x78, /* Data alignment factor */ 786 1.6 christos 16, /* Return address column */ 787 1.6 christos 1, /* Augmentation size */ 788 1.6 christos DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */ 789 1.6 christos DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */ 790 1.1 christos DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */ 791 1.6 christos DW_CFA_nop, DW_CFA_nop, 792 1.6 christos 793 1.6 christos PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */ 794 1.6 christos PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */ 795 1.6 christos 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */ 796 1.6 christos 0, 0, 0, 0, /* .plt size goes here */ 797 1.6 christos 0, /* Augmentation size */ 798 1.6 christos DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */ 799 1.6 christos DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */ 800 1.6 christos DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */ 801 1.6 christos DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */ 802 1.6 christos DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */ 803 1.6 christos 11, /* Block length */ 804 1.6 christos DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */ 805 1.6 christos DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */ 806 1.6 christos DW_OP_lit15, DW_OP_and, DW_OP_lit10, DW_OP_ge, 807 1.6 christos DW_OP_lit3, DW_OP_shl, DW_OP_plus, 808 1.1 christos DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop 809 1.10 christos }; 810 1.1 christos 811 1.10 christos /* .eh_frame covering the lazy .plt section with IBT-enabled. */ 812 1.6 christos 813 1.6 christos static const bfd_byte elf_x86_64_eh_frame_lazy_ibt_plt[] = 814 1.6 christos { 815 1.6 christos PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */ 816 1.6 christos 0, 0, 0, 0, /* CIE ID */ 817 1.6 christos 1, /* CIE version */ 818 1.6 christos 'z', 'R', 0, /* Augmentation string */ 819 1.6 christos 1, /* Code alignment factor */ 820 1.6 christos 0x78, /* Data alignment factor */ 821 1.6 christos 16, /* Return address column */ 822 1.6 christos 1, /* Augmentation size */ 823 1.6 christos DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */ 824 1.6 christos DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */ 825 1.1 christos DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */ 826 1.6 christos DW_CFA_nop, DW_CFA_nop, 827 1.6 christos 828 1.6 christos PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */ 829 1.6 christos PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */ 830 1.6 christos 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */ 831 1.6 christos 0, 0, 0, 0, /* .plt size goes here */ 832 1.6 christos 0, /* Augmentation size */ 833 1.6 christos DW_CFA_def_cfa_offset, 16, /* DW_CFA_def_cfa_offset: 16 */ 834 1.6 christos DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */ 835 1.6 christos DW_CFA_def_cfa_offset, 24, /* DW_CFA_def_cfa_offset: 24 */ 836 1.6 christos DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */ 837 1.6 christos DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */ 838 1.6 christos 11, /* Block length */ 839 1.6 christos DW_OP_breg7, 8, /* DW_OP_breg7 (rsp): 8 */ 840 1.6 christos DW_OP_breg16, 0, /* DW_OP_breg16 (rip): 0 */ 841 1.6 christos DW_OP_lit15, DW_OP_and, DW_OP_lit9, DW_OP_ge, 842 1.1 christos DW_OP_lit3, DW_OP_shl, DW_OP_plus, 843 1.1 christos DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop 844 1.6 christos }; 845 1.3 christos 846 1.6 christos /* .eh_frame covering the non-lazy .plt section. */ 847 1.6 christos 848 1.6 christos static const bfd_byte elf_x86_64_eh_frame_non_lazy_plt[] = 849 1.6 christos { 850 1.6 christos #define PLT_GOT_FDE_LENGTH 20 851 1.6 christos PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */ 852 1.6 christos 0, 0, 0, 0, /* CIE ID */ 853 1.6 christos 1, /* CIE version */ 854 1.6 christos 'z', 'R', 0, /* Augmentation string */ 855 1.6 christos 1, /* Code alignment factor */ 856 1.6 christos 0x78, /* Data alignment factor */ 857 1.6 christos 16, /* Return address column */ 858 1.6 christos 1, /* Augmentation size */ 859 1.6 christos DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */ 860 1.6 christos DW_CFA_def_cfa, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */ 861 1.1 christos DW_CFA_offset + 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */ 862 1.6 christos DW_CFA_nop, DW_CFA_nop, 863 1.6 christos 864 1.6 christos PLT_GOT_FDE_LENGTH, 0, 0, 0, /* FDE length */ 865 1.6 christos PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */ 866 1.6 christos 0, 0, 0, 0, /* the start of non-lazy .plt goes here */ 867 1.6 christos 0, 0, 0, 0, /* non-lazy .plt size goes here */ 868 1.6 christos 0, /* Augmentation size */ 869 1.6 christos DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, 870 1.1 christos DW_CFA_nop, DW_CFA_nop, DW_CFA_nop 871 1.9 christos }; 872 1.9 christos 873 1.9 christos /* .sframe FRE covering the .plt section entry. */ 874 1.9 christos static const sframe_frame_row_entry elf_x86_64_sframe_plt0_fre1 = 875 1.9 christos { 876 1.9 christos 0, /* SFrame FRE start address. */ 877 1.9 christos {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */ 878 1.9 christos SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ 879 1.9 christos }; 880 1.9 christos 881 1.9 christos /* .sframe FRE covering the .plt section entry. */ 882 1.9 christos static const sframe_frame_row_entry elf_x86_64_sframe_plt0_fre2 = 883 1.9 christos { 884 1.9 christos 6, /* SFrame FRE start address. */ 885 1.9 christos {24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */ 886 1.9 christos SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ 887 1.9 christos }; 888 1.9 christos 889 1.9 christos /* .sframe FRE covering the .plt section entry. */ 890 1.9 christos static const sframe_frame_row_entry elf_x86_64_sframe_pltn_fre1 = 891 1.9 christos { 892 1.9 christos 0, /* SFrame FRE start address. */ 893 1.9 christos {8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */ 894 1.9 christos SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ 895 1.9 christos }; 896 1.9 christos 897 1.9 christos /* .sframe FRE covering the .plt section entry. */ 898 1.9 christos static const sframe_frame_row_entry elf_x86_64_sframe_pltn_fre2 = 899 1.9 christos { 900 1.9 christos 11, /* SFrame FRE start address. */ 901 1.9 christos {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */ 902 1.9 christos SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ 903 1.10 christos }; 904 1.10 christos 905 1.10 christos /* .sframe FRE covering the .plt section entry for IBT. */ 906 1.10 christos static const sframe_frame_row_entry elf_x86_64_sframe_ibt_pltn_fre2 = 907 1.10 christos { 908 1.10 christos 9, /* SFrame FRE start address. */ 909 1.10 christos {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */ 910 1.10 christos SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ 911 1.9 christos }; 912 1.9 christos 913 1.9 christos /* .sframe FRE covering the second .plt section entry. */ 914 1.9 christos static const sframe_frame_row_entry elf_x86_64_sframe_sec_pltn_fre1 = 915 1.9 christos { 916 1.9 christos 0, /* SFrame FRE start address. */ 917 1.9 christos {8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */ 918 1.9 christos SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ 919 1.10 christos }; 920 1.10 christos 921 1.10 christos /* .sframe FRE covering the .plt.got section entry. */ 922 1.10 christos static const sframe_frame_row_entry elf_x86_64_sframe_pltgot_fre1 = 923 1.10 christos { 924 1.10 christos 0, /* SFrame FRE start address. */ 925 1.10 christos {16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* 12 bytes. */ 926 1.10 christos SFRAME_V1_FRE_INFO (SFRAME_BASE_REG_SP, 1, SFRAME_FRE_OFFSET_1B) /* FRE info. */ 927 1.10 christos }; 928 1.9 christos 929 1.9 christos /* SFrame helper object for non-lazy PLT. */ 930 1.9 christos static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_plt = 931 1.9 christos { 932 1.9 christos LAZY_PLT_ENTRY_SIZE, 933 1.9 christos 2, /* Number of FREs for PLT0. */ 934 1.9 christos /* Array of SFrame FREs for plt0. */ 935 1.9 christos { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 }, 936 1.9 christos LAZY_PLT_ENTRY_SIZE, 937 1.10 christos 1, /* Number of FREs for PLTn. */ 938 1.10 christos /* Array of SFrame FREs for plt. */ 939 1.10 christos { &elf_x86_64_sframe_sec_pltn_fre1 }, 940 1.10 christos 0, 941 1.10 christos 0, /* There is no second PLT necessary. */ 942 1.10 christos { }, 943 1.10 christos NON_LAZY_PLT_ENTRY_SIZE, 944 1.10 christos 1, /* Number of FREs for PLT GOT. */ 945 1.10 christos /* Array of SFrame FREs for PLT GOT. */ 946 1.10 christos { &elf_x86_64_sframe_pltgot_fre1 }, 947 1.10 christos }; 948 1.10 christos 949 1.10 christos /* SFrame helper object for non-lazy IBT enabled PLT. */ 950 1.10 christos static const struct elf_x86_sframe_plt elf_x86_64_sframe_non_lazy_ibt_plt = 951 1.10 christos { 952 1.10 christos LAZY_PLT_ENTRY_SIZE, 953 1.10 christos 2, /* Number of FREs for PLT0. */ 954 1.10 christos /* Array of SFrame FREs for plt0. */ 955 1.10 christos { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 }, 956 1.10 christos LAZY_PLT_ENTRY_SIZE, 957 1.10 christos 1, /* Number of FREs for PLTn. */ 958 1.9 christos /* Array of SFrame FREs for plt. */ 959 1.9 christos { &elf_x86_64_sframe_sec_pltn_fre1 }, 960 1.10 christos 0, 961 1.10 christos 0, /* There is no second PLT necessary. */ 962 1.10 christos { }, 963 1.10 christos LAZY_PLT_ENTRY_SIZE, 964 1.10 christos 1, /* Number of FREs for PLT GOT. */ 965 1.9 christos /* Array of SFrame FREs for PLT GOT. */ 966 1.9 christos { &elf_x86_64_sframe_pltgot_fre1 }, 967 1.10 christos }; 968 1.9 christos 969 1.9 christos /* SFrame helper object for lazy PLT. */ 970 1.9 christos static const struct elf_x86_sframe_plt elf_x86_64_sframe_plt = 971 1.9 christos { 972 1.9 christos LAZY_PLT_ENTRY_SIZE, 973 1.9 christos 2, /* Number of FREs for PLT0. */ 974 1.9 christos /* Array of SFrame FREs for plt0. */ 975 1.9 christos { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 }, 976 1.9 christos LAZY_PLT_ENTRY_SIZE, 977 1.9 christos 2, /* Number of FREs for PLTn. */ 978 1.9 christos /* Array of SFrame FREs for plt. */ 979 1.10 christos { &elf_x86_64_sframe_pltn_fre1, &elf_x86_64_sframe_pltn_fre2 }, 980 1.10 christos NON_LAZY_PLT_ENTRY_SIZE, 981 1.10 christos 1, /* Number of FREs for second PLT. */ 982 1.10 christos /* Array of SFrame FREs for second PLT. */ 983 1.10 christos { &elf_x86_64_sframe_sec_pltn_fre1 }, 984 1.10 christos NON_LAZY_PLT_ENTRY_SIZE, 985 1.10 christos 1, /* Number of FREs for PLT GOT. */ 986 1.10 christos /* Array of SFrame FREs for PLT GOT. */ 987 1.10 christos { &elf_x86_64_sframe_pltgot_fre1 }, 988 1.10 christos }; 989 1.10 christos 990 1.10 christos /* SFrame helper object for lazy PLT with IBT. */ 991 1.10 christos static const struct elf_x86_sframe_plt elf_x86_64_sframe_ibt_plt = 992 1.10 christos { 993 1.10 christos LAZY_PLT_ENTRY_SIZE, 994 1.10 christos 2, /* Number of FREs for PLT0. */ 995 1.10 christos /* Array of SFrame FREs for plt0. */ 996 1.10 christos { &elf_x86_64_sframe_plt0_fre1, &elf_x86_64_sframe_plt0_fre2 }, 997 1.10 christos LAZY_PLT_ENTRY_SIZE, 998 1.10 christos 2, /* Number of FREs for PLTn. */ 999 1.10 christos /* Array of SFrame FREs for plt. */ 1000 1.10 christos { &elf_x86_64_sframe_pltn_fre1, &elf_x86_64_sframe_ibt_pltn_fre2 }, 1001 1.10 christos LAZY_PLT_ENTRY_SIZE, 1002 1.10 christos 1, /* Number of FREs for second PLT. */ 1003 1.10 christos /* Array of SFrame FREs for second plt. */ 1004 1.10 christos { &elf_x86_64_sframe_sec_pltn_fre1 }, 1005 1.10 christos LAZY_PLT_ENTRY_SIZE, 1006 1.10 christos 1, /* Number of FREs for PLT GOT. */ 1007 1.9 christos /* Array of SFrame FREs for PLT GOT. */ 1008 1.9 christos { &elf_x86_64_sframe_pltgot_fre1 }, 1009 1.1 christos }; 1010 1.6 christos 1011 1.1 christos /* These are the standard parameters. */ 1012 1.6 christos static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_plt = 1013 1.6 christos { 1014 1.6 christos elf_x86_64_lazy_plt0_entry, /* plt0_entry */ 1015 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */ 1016 1.6 christos elf_x86_64_lazy_plt_entry, /* plt_entry */ 1017 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 1018 1.6 christos elf_x86_64_tlsdesc_plt_entry, /* plt_tlsdesc_entry */ 1019 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt_tlsdesc_entry_size */ 1020 1.6 christos 6, /* plt_tlsdesc_got1_offset */ 1021 1.6 christos 12, /* plt_tlsdesc_got2_offset */ 1022 1.6 christos 10, /* plt_tlsdesc_got1_insn_end */ 1023 1.6 christos 16, /* plt_tlsdesc_got2_insn_end */ 1024 1.6 christos 2, /* plt0_got1_offset */ 1025 1.6 christos 8, /* plt0_got2_offset */ 1026 1.6 christos 12, /* plt0_got2_insn_end */ 1027 1.6 christos 2, /* plt_got_offset */ 1028 1.6 christos 7, /* plt_reloc_offset */ 1029 1.6 christos 12, /* plt_plt_offset */ 1030 1.6 christos 6, /* plt_got_insn_size */ 1031 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt_plt_insn_end */ 1032 1.6 christos 6, /* plt_lazy_offset */ 1033 1.6 christos elf_x86_64_lazy_plt0_entry, /* pic_plt0_entry */ 1034 1.6 christos elf_x86_64_lazy_plt_entry, /* pic_plt_entry */ 1035 1.1 christos elf_x86_64_eh_frame_lazy_plt, /* eh_frame_plt */ 1036 1.1 christos sizeof (elf_x86_64_eh_frame_lazy_plt) /* eh_frame_plt_size */ 1037 1.6 christos }; 1038 1.3 christos 1039 1.6 christos static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_plt = 1040 1.6 christos { 1041 1.6 christos elf_x86_64_non_lazy_plt_entry, /* plt_entry */ 1042 1.6 christos elf_x86_64_non_lazy_plt_entry, /* pic_plt_entry */ 1043 1.6 christos NON_LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 1044 1.6 christos 2, /* plt_got_offset */ 1045 1.6 christos 6, /* plt_got_insn_size */ 1046 1.3 christos elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */ 1047 1.3 christos sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */ 1048 1.6 christos }; 1049 1.6 christos 1050 1.6 christos static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_bnd_plt = 1051 1.6 christos { 1052 1.6 christos elf_x86_64_lazy_bnd_plt0_entry, /* plt0_entry */ 1053 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */ 1054 1.6 christos elf_x86_64_lazy_bnd_plt_entry, /* plt_entry */ 1055 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 1056 1.6 christos elf_x86_64_tlsdesc_plt_entry, /* plt_tlsdesc_entry */ 1057 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt_tlsdesc_entry_size */ 1058 1.6 christos 6, /* plt_tlsdesc_got1_offset */ 1059 1.6 christos 12, /* plt_tlsdesc_got2_offset */ 1060 1.6 christos 10, /* plt_tlsdesc_got1_insn_end */ 1061 1.6 christos 16, /* plt_tlsdesc_got2_insn_end */ 1062 1.6 christos 2, /* plt0_got1_offset */ 1063 1.6 christos 1+8, /* plt0_got2_offset */ 1064 1.6 christos 1+12, /* plt0_got2_insn_end */ 1065 1.6 christos 1+2, /* plt_got_offset */ 1066 1.6 christos 1, /* plt_reloc_offset */ 1067 1.6 christos 7, /* plt_plt_offset */ 1068 1.6 christos 1+6, /* plt_got_insn_size */ 1069 1.6 christos 11, /* plt_plt_insn_end */ 1070 1.6 christos 0, /* plt_lazy_offset */ 1071 1.6 christos elf_x86_64_lazy_bnd_plt0_entry, /* pic_plt0_entry */ 1072 1.6 christos elf_x86_64_lazy_bnd_plt_entry, /* pic_plt_entry */ 1073 1.6 christos elf_x86_64_eh_frame_lazy_bnd_plt, /* eh_frame_plt */ 1074 1.1 christos sizeof (elf_x86_64_eh_frame_lazy_bnd_plt) /* eh_frame_plt_size */ 1075 1.6 christos }; 1076 1.6 christos 1077 1.6 christos static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_plt = 1078 1.6 christos { 1079 1.6 christos elf_x86_64_non_lazy_bnd_plt_entry, /* plt_entry */ 1080 1.6 christos elf_x86_64_non_lazy_bnd_plt_entry, /* pic_plt_entry */ 1081 1.6 christos NON_LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 1082 1.6 christos 1+2, /* plt_got_offset */ 1083 1.6 christos 1+6, /* plt_got_insn_size */ 1084 1.6 christos elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */ 1085 1.1 christos sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */ 1086 1.10 christos }; 1087 1.6 christos 1088 1.6 christos static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_bnd_ibt_plt = 1089 1.6 christos { 1090 1.10 christos elf_x86_64_lazy_bnd_plt0_entry, /* plt0_entry */ 1091 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */ 1092 1.6 christos elf_x86_64_lazy_bnd_ibt_plt_entry, /* plt_entry */ 1093 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 1094 1.6 christos elf_x86_64_tlsdesc_plt_entry, /* plt_tlsdesc_entry */ 1095 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt_tlsdesc_entry_size */ 1096 1.6 christos 6, /* plt_tlsdesc_got1_offset */ 1097 1.6 christos 12, /* plt_tlsdesc_got2_offset */ 1098 1.6 christos 10, /* plt_tlsdesc_got1_insn_end */ 1099 1.6 christos 16, /* plt_tlsdesc_got2_insn_end */ 1100 1.6 christos 2, /* plt0_got1_offset */ 1101 1.6 christos 1+8, /* plt0_got2_offset */ 1102 1.6 christos 1+12, /* plt0_got2_insn_end */ 1103 1.6 christos 4+1+2, /* plt_got_offset */ 1104 1.6 christos 4+1, /* plt_reloc_offset */ 1105 1.6 christos 4+1+6, /* plt_plt_offset */ 1106 1.6 christos 4+1+6, /* plt_got_insn_size */ 1107 1.6 christos 4+1+5+5, /* plt_plt_insn_end */ 1108 1.10 christos 0, /* plt_lazy_offset */ 1109 1.10 christos elf_x86_64_lazy_bnd_plt0_entry, /* pic_plt0_entry */ 1110 1.10 christos elf_x86_64_lazy_bnd_ibt_plt_entry, /* pic_plt_entry */ 1111 1.6 christos elf_x86_64_eh_frame_lazy_bnd_ibt_plt, /* eh_frame_plt */ 1112 1.1 christos sizeof (elf_x86_64_eh_frame_lazy_bnd_ibt_plt) /* eh_frame_plt_size */ 1113 1.10 christos }; 1114 1.6 christos 1115 1.6 christos static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_ibt_plt = 1116 1.6 christos { 1117 1.10 christos elf_x86_64_lazy_plt0_entry, /* plt0_entry */ 1118 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt0_entry_size */ 1119 1.6 christos elf_x86_64_lazy_ibt_plt_entry, /* plt_entry */ 1120 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 1121 1.6 christos elf_x86_64_tlsdesc_plt_entry, /* plt_tlsdesc_entry */ 1122 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt_tlsdesc_entry_size */ 1123 1.6 christos 6, /* plt_tlsdesc_got1_offset */ 1124 1.6 christos 12, /* plt_tlsdesc_got2_offset */ 1125 1.6 christos 10, /* plt_tlsdesc_got1_insn_end */ 1126 1.6 christos 16, /* plt_tlsdesc_got2_insn_end */ 1127 1.6 christos 2, /* plt0_got1_offset */ 1128 1.6 christos 8, /* plt0_got2_offset */ 1129 1.6 christos 12, /* plt0_got2_insn_end */ 1130 1.6 christos 4+2, /* plt_got_offset */ 1131 1.6 christos 4+1, /* plt_reloc_offset */ 1132 1.6 christos 4+6, /* plt_plt_offset */ 1133 1.6 christos 4+6, /* plt_got_insn_size */ 1134 1.6 christos 4+5+5, /* plt_plt_insn_end */ 1135 1.10 christos 0, /* plt_lazy_offset */ 1136 1.10 christos elf_x86_64_lazy_plt0_entry, /* pic_plt0_entry */ 1137 1.10 christos elf_x86_64_lazy_ibt_plt_entry, /* pic_plt_entry */ 1138 1.6 christos elf_x86_64_eh_frame_lazy_ibt_plt, /* eh_frame_plt */ 1139 1.1 christos sizeof (elf_x86_64_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */ 1140 1.10 christos }; 1141 1.6 christos 1142 1.10 christos static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_ibt_plt = 1143 1.10 christos { 1144 1.6 christos elf_x86_64_non_lazy_bnd_ibt_plt_entry, /* plt_entry */ 1145 1.6 christos elf_x86_64_non_lazy_bnd_ibt_plt_entry, /* pic_plt_entry */ 1146 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 1147 1.6 christos 4+1+2, /* plt_got_offset */ 1148 1.6 christos 4+1+6, /* plt_got_insn_size */ 1149 1.6 christos elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */ 1150 1.1 christos sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */ 1151 1.10 christos }; 1152 1.6 christos 1153 1.10 christos static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_ibt_plt = 1154 1.10 christos { 1155 1.6 christos elf_x86_64_non_lazy_ibt_plt_entry, /* plt_entry */ 1156 1.6 christos elf_x86_64_non_lazy_ibt_plt_entry, /* pic_plt_entry */ 1157 1.6 christos LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */ 1158 1.6 christos 4+2, /* plt_got_offset */ 1159 1.6 christos 4+6, /* plt_got_insn_size */ 1160 1.6 christos elf_x86_64_eh_frame_non_lazy_plt, /* eh_frame_plt */ 1161 1.1 christos sizeof (elf_x86_64_eh_frame_non_lazy_plt) /* eh_frame_plt_size */ 1162 1.8 christos }; 1163 1.6 christos 1164 1.1 christos static bool 1165 1.6 christos elf64_x86_64_elf_object_p (bfd *abfd) 1166 1.6 christos { 1167 1.8 christos /* Set the right machine number for an x86-64 elf64 file. */ 1168 1.1 christos bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64); 1169 1.1 christos return true; 1170 1.8 christos } 1171 1.6 christos 1172 1.1 christos static bool 1173 1.6 christos elf32_x86_64_elf_object_p (bfd *abfd) 1174 1.6 christos { 1175 1.8 christos /* Set the right machine number for an x86-64 elf32 file. */ 1176 1.1 christos bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x64_32); 1177 1.1 christos return true; 1178 1.6 christos } 1179 1.6 christos 1180 1.1 christos /* Return TRUE if the TLS access code sequence support transition 1181 1.10 christos from R_TYPE. */ 1182 1.6 christos 1183 1.6 christos static enum elf_x86_tls_error_type 1184 1.6 christos elf_x86_64_check_tls_transition (bfd *abfd, 1185 1.6 christos struct bfd_link_info *info, 1186 1.6 christos asection *sec, 1187 1.6 christos bfd_byte *contents, 1188 1.6 christos Elf_Internal_Shdr *symtab_hdr, 1189 1.6 christos struct elf_link_hash_entry **sym_hashes, 1190 1.6 christos unsigned int r_type, 1191 1.1 christos const Elf_Internal_Rela *rel, 1192 1.6 christos const Elf_Internal_Rela *relend) 1193 1.6 christos { 1194 1.8 christos unsigned int val; 1195 1.6 christos unsigned long r_symndx; 1196 1.6 christos bool largepic = false; 1197 1.6 christos struct elf_link_hash_entry *h; 1198 1.6 christos bfd_vma offset; 1199 1.8 christos struct elf_x86_link_hash_table *htab; 1200 1.1 christos bfd_byte *call; 1201 1.6 christos bool indirect_call; 1202 1.6 christos 1203 1.6 christos htab = elf_x86_hash_table (info, X86_64_ELF_DATA); 1204 1.1 christos offset = rel->r_offset; 1205 1.6 christos switch (r_type) 1206 1.6 christos { 1207 1.6 christos case R_X86_64_TLSGD: 1208 1.10 christos case R_X86_64_TLSLD: 1209 1.1 christos if ((rel + 1) >= relend) 1210 1.6 christos return elf_x86_tls_error_yes; 1211 1.6 christos 1212 1.6 christos if (r_type == R_X86_64_TLSGD) 1213 1.6 christos { 1214 1.6 christos /* Check transition from GD access model. For 64bit, only 1215 1.6 christos .byte 0x66; leaq foo@tlsgd(%rip), %rdi 1216 1.6 christos .word 0x6666; rex64; call __tls_get_addr@PLT 1217 1.6 christos or 1218 1.6 christos .byte 0x66; leaq foo@tlsgd(%rip), %rdi 1219 1.6 christos .byte 0x66; rex64 1220 1.6 christos call *__tls_get_addr@GOTPCREL(%rip) 1221 1.6 christos which may be converted to 1222 1.6 christos addr32 call __tls_get_addr 1223 1.6 christos can transit to different access model. For 32bit, only 1224 1.6 christos leaq foo@tlsgd(%rip), %rdi 1225 1.6 christos .word 0x6666; rex64; call __tls_get_addr@PLT 1226 1.6 christos or 1227 1.6 christos leaq foo@tlsgd(%rip), %rdi 1228 1.6 christos .byte 0x66; rex64 1229 1.6 christos call *__tls_get_addr@GOTPCREL(%rip) 1230 1.6 christos which may be converted to 1231 1.6 christos addr32 call __tls_get_addr 1232 1.6 christos can transit to different access model. For largepic, 1233 1.6 christos we also support: 1234 1.6 christos leaq foo@tlsgd(%rip), %rdi 1235 1.6 christos movabsq $__tls_get_addr@pltoff, %rax 1236 1.6 christos addq $r15, %rax 1237 1.6 christos call *%rax 1238 1.6 christos or 1239 1.6 christos leaq foo@tlsgd(%rip), %rdi 1240 1.6 christos movabsq $__tls_get_addr@pltoff, %rax 1241 1.1 christos addq $rbx, %rax 1242 1.6 christos call *%rax */ 1243 1.1 christos 1244 1.6 christos static const unsigned char leaq[] = { 0x66, 0x48, 0x8d, 0x3d }; 1245 1.10 christos 1246 1.1 christos if ((offset + 12) > sec->size) 1247 1.6 christos return elf_x86_tls_error_yes; 1248 1.6 christos 1249 1.6 christos call = contents + offset + 4; 1250 1.6 christos if (call[0] != 0x66 1251 1.6 christos || !((call[1] == 0x48 1252 1.6 christos && call[2] == 0xff 1253 1.6 christos && call[3] == 0x15) 1254 1.6 christos || (call[1] == 0x48 1255 1.6 christos && call[2] == 0x67 1256 1.5 christos && call[3] == 0xe8) 1257 1.5 christos || (call[1] == 0x66 1258 1.3 christos && call[2] == 0x48 1259 1.3 christos && call[3] == 0xe8))) 1260 1.3 christos { 1261 1.3 christos if (!ABI_64_P (abfd) 1262 1.5 christos || (offset + 19) > sec->size 1263 1.5 christos || offset < 3 1264 1.5 christos || memcmp (call - 7, leaq + 1, 3) != 0 1265 1.5 christos || memcmp (call, "\x48\xb8", 2) != 0 1266 1.5 christos || call[11] != 0x01 1267 1.5 christos || call[13] != 0xff 1268 1.5 christos || call[14] != 0xd0 1269 1.10 christos || !((call[10] == 0x48 && call[12] == 0xd8) 1270 1.8 christos || (call[10] == 0x4c && call[12] == 0xf8))) 1271 1.3 christos return elf_x86_tls_error_yes; 1272 1.3 christos largepic = true; 1273 1.1 christos } 1274 1.1 christos else if (ABI_64_P (abfd)) 1275 1.1 christos { 1276 1.10 christos if (offset < 4 1277 1.1 christos || memcmp (contents + offset - 4, leaq, 4) != 0) 1278 1.1 christos return elf_x86_tls_error_yes; 1279 1.1 christos } 1280 1.1 christos else 1281 1.1 christos { 1282 1.10 christos if (offset < 3 1283 1.1 christos || memcmp (contents + offset - 3, leaq + 1, 3) != 0) 1284 1.5 christos return elf_x86_tls_error_yes; 1285 1.1 christos } 1286 1.1 christos indirect_call = call[2] == 0xff; 1287 1.1 christos } 1288 1.1 christos else 1289 1.1 christos { 1290 1.5 christos /* Check transition from LD access model. Only 1291 1.6 christos leaq foo@tlsld(%rip), %rdi; 1292 1.5 christos call __tls_get_addr@PLT 1293 1.5 christos or 1294 1.5 christos leaq foo@tlsld(%rip), %rdi; 1295 1.5 christos call *__tls_get_addr@GOTPCREL(%rip) 1296 1.3 christos which may be converted to 1297 1.3 christos addr32 call __tls_get_addr 1298 1.6 christos can transit to different access model. For largepic 1299 1.6 christos we also support: 1300 1.6 christos leaq foo@tlsld(%rip), %rdi 1301 1.6 christos movabsq $__tls_get_addr@pltoff, %rax 1302 1.5 christos addq $r15, %rax 1303 1.6 christos call *%rax 1304 1.6 christos or 1305 1.6 christos leaq foo@tlsld(%rip), %rdi 1306 1.6 christos movabsq $__tls_get_addr@pltoff, %rax 1307 1.1 christos addq $rbx, %rax 1308 1.1 christos call *%rax */ 1309 1.1 christos 1310 1.1 christos static const unsigned char lea[] = { 0x48, 0x8d, 0x3d }; 1311 1.10 christos 1312 1.1 christos if (offset < 3 || (offset + 9) > sec->size) 1313 1.3 christos return elf_x86_tls_error_yes; 1314 1.10 christos 1315 1.3 christos if (memcmp (contents + offset - 3, lea, 3) != 0) 1316 1.5 christos return elf_x86_tls_error_yes; 1317 1.5 christos 1318 1.5 christos call = contents + offset + 4; 1319 1.5 christos if (!(call[0] == 0xe8 1320 1.3 christos || (call[0] == 0xff && call[1] == 0x15) 1321 1.3 christos || (call[0] == 0x67 && call[1] == 0xe8))) 1322 1.3 christos { 1323 1.5 christos if (!ABI_64_P (abfd) 1324 1.5 christos || (offset + 19) > sec->size 1325 1.5 christos || memcmp (call, "\x48\xb8", 2) != 0 1326 1.5 christos || call[11] != 0x01 1327 1.5 christos || call[13] != 0xff 1328 1.5 christos || call[14] != 0xd0 1329 1.10 christos || !((call[10] == 0x48 && call[12] == 0xd8) 1330 1.8 christos || (call[10] == 0x4c && call[12] == 0xf8))) 1331 1.3 christos return elf_x86_tls_error_yes; 1332 1.5 christos largepic = true; 1333 1.1 christos } 1334 1.1 christos indirect_call = call[0] == 0xff; 1335 1.1 christos } 1336 1.1 christos 1337 1.10 christos r_symndx = htab->r_sym (rel[1].r_info); 1338 1.1 christos if (r_symndx < symtab_hdr->sh_info) 1339 1.1 christos return elf_x86_tls_error_yes; 1340 1.6 christos 1341 1.6 christos h = sym_hashes[r_symndx - symtab_hdr->sh_info]; 1342 1.10 christos if (h == NULL 1343 1.6 christos || !((struct elf_x86_link_hash_entry *) h)->tls_get_addr) 1344 1.5 christos return elf_x86_tls_error_yes; 1345 1.6 christos else 1346 1.6 christos { 1347 1.6 christos r_type = (ELF32_R_TYPE (rel[1].r_info) 1348 1.10 christos & ~R_X86_64_converted_reloc_bit); 1349 1.10 christos if (largepic) 1350 1.10 christos return (r_type == R_X86_64_PLTOFF64 1351 1.6 christos ? elf_x86_tls_error_none 1352 1.10 christos : elf_x86_tls_error_yes); 1353 1.10 christos else if (indirect_call) 1354 1.10 christos return ((r_type == R_X86_64_GOTPCRELX 1355 1.10 christos || r_type == R_X86_64_GOTPCREL) 1356 1.6 christos ? elf_x86_tls_error_none 1357 1.10 christos : elf_x86_tls_error_yes); 1358 1.10 christos else 1359 1.10 christos return ((r_type == R_X86_64_PC32 1360 1.10 christos || r_type == R_X86_64_PLT32) 1361 1.5 christos ? elf_x86_tls_error_none 1362 1.5 christos : elf_x86_tls_error_yes); 1363 1.9 christos } 1364 1.9 christos 1365 1.9 christos case R_X86_64_CODE_4_GOTTPOFF: 1366 1.9 christos /* Check transition from IE access model: 1367 1.10 christos mov foo@gottpoff(%rip), %reg 1368 1.10 christos add foo@gottpoff(%rip), %reg 1369 1.10 christos where reg is one of r16 to r31. 1370 1.10 christos For x32 also: 1371 1.9 christos movrs foo@gottpoff(%rip), %reg 1372 1.9 christos where no REX prefix is present. */ 1373 1.10 christos 1374 1.10 christos if (offset < 4 1375 1.10 christos || (offset + 4) > sec->size) 1376 1.10 christos return elf_x86_tls_error_yes; 1377 1.10 christos 1378 1.10 christos if (!ABI_64_P (abfd) 1379 1.10 christos && contents[offset - 4] == 0x0f 1380 1.10 christos && contents[offset - 3] == 0x38 1381 1.10 christos && contents[offset - 2] == 0x8b) 1382 1.10 christos goto check_gottpoff_modrm; 1383 1.10 christos 1384 1.10 christos if (contents[offset - 4] != 0xd5) 1385 1.10 christos return elf_x86_tls_error_yes; 1386 1.10 christos 1387 1.10 christos goto check_gottpoff; 1388 1.10 christos 1389 1.10 christos case R_X86_64_CODE_5_GOTTPOFF: 1390 1.10 christos /* Check transition from IE access model: 1391 1.10 christos movrs foo@gottpoff(%rip), %reg 1392 1.10 christos where reg isn't one of r16 to r31. */ 1393 1.10 christos if (offset < 5 1394 1.10 christos || (offset + 4) > sec->size 1395 1.10 christos || (contents[offset - 5] | (ABI_64_P (abfd) ? 7 : 0xf)) != 0x4f 1396 1.10 christos || contents[offset - 4] != 0x0f 1397 1.10 christos || contents[offset - 3] != 0x38 1398 1.10 christos || contents[offset - 2] != 0x8b) 1399 1.10 christos return elf_x86_tls_error_yes; 1400 1.10 christos 1401 1.10 christos goto check_gottpoff_modrm; 1402 1.10 christos 1403 1.10 christos case R_X86_64_CODE_6_GOTTPOFF: 1404 1.10 christos /* Check transition from IE access model: 1405 1.10 christos add %reg1, foo@gottpoff(%rip), %reg2 1406 1.10 christos movrs foo@gottpoff(%rip), %reg 1407 1.10 christos where reg1/reg2/reg are one of r16 to r31. */ 1408 1.9 christos 1409 1.10 christos if (offset < 6 1410 1.10 christos || (offset + 4) > sec->size 1411 1.10 christos || contents[offset - 6] != 0x62) 1412 1.10 christos return elf_x86_tls_error_yes; 1413 1.10 christos 1414 1.10 christos val = bfd_get_8 (abfd, contents + offset - 2); 1415 1.9 christos if (val != 0x01 && val != 0x03 && val != 0x8b) 1416 1.10 christos return elf_x86_tls_error_add_movrs; 1417 1.9 christos 1418 1.1 christos goto check_gottpoff_modrm; 1419 1.1 christos 1420 1.1 christos case R_X86_64_GOTTPOFF: 1421 1.1 christos /* Check transition from IE access model: 1422 1.1 christos mov foo@gottpoff(%rip), %reg 1423 1.1 christos add foo@gottpoff(%rip), %reg 1424 1.1 christos */ 1425 1.1 christos 1426 1.1 christos /* Check REX prefix first. */ 1427 1.1 christos if (offset >= 3 && (offset + 4) <= sec->size) 1428 1.1 christos { 1429 1.1 christos val = bfd_get_8 (abfd, contents + offset - 3); 1430 1.1 christos if (val != 0x48 && val != 0x4c) 1431 1.1 christos { 1432 1.10 christos /* X32 may have 0x44 REX prefix or no REX prefix. */ 1433 1.1 christos if (ABI_64_P (abfd)) 1434 1.1 christos return elf_x86_tls_error_yes; 1435 1.1 christos } 1436 1.1 christos } 1437 1.1 christos else 1438 1.1 christos { 1439 1.10 christos /* X32 may not have any REX prefix. */ 1440 1.1 christos if (ABI_64_P (abfd)) 1441 1.10 christos return elf_x86_tls_error_yes; 1442 1.1 christos if (offset < 2 || (offset + 3) > sec->size) 1443 1.1 christos return elf_x86_tls_error_yes; 1444 1.9 christos } 1445 1.1 christos 1446 1.1 christos check_gottpoff: 1447 1.10 christos val = bfd_get_8 (abfd, contents + offset - 2); 1448 1.1 christos if (val != 0x8b && val != 0x03) 1449 1.10 christos return elf_x86_tls_error_add_mov; 1450 1.1 christos 1451 1.10 christos check_gottpoff_modrm: 1452 1.10 christos val = bfd_get_8 (abfd, contents + offset - 1); 1453 1.10 christos return ((val & 0xc7) == 5 1454 1.1 christos ? elf_x86_tls_error_none 1455 1.9 christos : elf_x86_tls_error_yes); 1456 1.9 christos 1457 1.9 christos case R_X86_64_CODE_4_GOTPC32_TLSDESC: 1458 1.9 christos /* Check transition from GDesc access model: 1459 1.9 christos lea x@tlsdesc(%rip), %reg 1460 1.9 christos where reg is one of r16 to r31. */ 1461 1.9 christos 1462 1.9 christos if (offset < 4 1463 1.10 christos || (offset + 4) > sec->size 1464 1.9 christos || contents[offset - 4] != 0xd5) 1465 1.9 christos return elf_x86_tls_error_yes; 1466 1.9 christos 1467 1.1 christos goto check_tlsdesc; 1468 1.1 christos 1469 1.8 christos case R_X86_64_GOTPC32_TLSDESC: 1470 1.8 christos /* Check transition from GDesc access model: 1471 1.1 christos leaq x@tlsdesc(%rip), %rax <--- LP64 mode. 1472 1.1 christos rex leal x@tlsdesc(%rip), %eax <--- X32 mode. 1473 1.1 christos 1474 1.1 christos Make sure it's a leaq adding rip to a 32-bit offset 1475 1.1 christos into any register, although it's probably almost always 1476 1.1 christos going to be rax. */ 1477 1.10 christos 1478 1.1 christos if (offset < 3 || (offset + 4) > sec->size) 1479 1.1 christos return elf_x86_tls_error_yes; 1480 1.8 christos 1481 1.8 christos val = bfd_get_8 (abfd, contents + offset - 3); 1482 1.10 christos val &= 0xfb; 1483 1.1 christos if (val != 0x48 && (ABI_64_P (abfd) || val != 0x40)) 1484 1.9 christos return elf_x86_tls_error_yes; 1485 1.1 christos 1486 1.10 christos check_tlsdesc: 1487 1.1 christos if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d) 1488 1.1 christos return elf_x86_tls_error_lea; 1489 1.10 christos 1490 1.10 christos val = bfd_get_8 (abfd, contents + offset - 1); 1491 1.10 christos return ((val & 0xc7) == 0x05 1492 1.1 christos ? elf_x86_tls_error_none 1493 1.1 christos : elf_x86_tls_error_yes); 1494 1.10 christos 1495 1.10 christos case R_X86_64_TLSDESC_CALL: 1496 1.1 christos /* It has been checked in elf_x86_64_tls_transition. */ 1497 1.1 christos return elf_x86_tls_error_none; 1498 1.1 christos 1499 1.1 christos default: 1500 1.1 christos abort (); 1501 1.1 christos } 1502 1.1 christos } 1503 1.1 christos 1504 1.1 christos /* Return TRUE if the TLS access transition is OK or no transition 1505 1.8 christos will be performed. Update R_TYPE if there is a transition. */ 1506 1.1 christos 1507 1.1 christos static bool 1508 1.1 christos elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd, 1509 1.1 christos asection *sec, bfd_byte *contents, 1510 1.1 christos Elf_Internal_Shdr *symtab_hdr, 1511 1.1 christos struct elf_link_hash_entry **sym_hashes, 1512 1.1 christos unsigned int *r_type, int tls_type, 1513 1.1 christos const Elf_Internal_Rela *rel, 1514 1.10 christos const Elf_Internal_Rela *relend, 1515 1.8 christos struct elf_link_hash_entry *h, 1516 1.1 christos Elf_Internal_Sym *sym, 1517 1.1 christos bool from_relocate_section) 1518 1.1 christos { 1519 1.8 christos unsigned int from_type = *r_type; 1520 1.10 christos unsigned int to_type = from_type; 1521 1.10 christos bool check = true; 1522 1.1 christos bfd_vma offset; 1523 1.1 christos bfd_byte *call; 1524 1.1 christos 1525 1.1 christos /* Skip TLS transition for functions. */ 1526 1.1 christos if (h != NULL 1527 1.8 christos && (h->type == STT_FUNC 1528 1.1 christos || h->type == STT_GNU_IFUNC)) 1529 1.1 christos return true; 1530 1.1 christos 1531 1.10 christos switch (from_type) 1532 1.10 christos { 1533 1.10 christos case R_X86_64_TLSDESC_CALL: 1534 1.10 christos /* Check valid GDesc call: 1535 1.10 christos call *x@tlscall(%rax) <--- LP64 mode. 1536 1.10 christos call *x@tlscall(%eax) <--- X32 mode. 1537 1.10 christos */ 1538 1.10 christos offset = rel->r_offset; 1539 1.10 christos call = NULL; 1540 1.10 christos if (offset + 2 <= sec->size) 1541 1.10 christos { 1542 1.10 christos unsigned int prefix; 1543 1.10 christos call = contents + offset; 1544 1.10 christos prefix = 0; 1545 1.10 christos if (!ABI_64_P (abfd)) 1546 1.10 christos { 1547 1.10 christos /* Check for call *x@tlscall(%eax). */ 1548 1.10 christos if (call[0] == 0x67) 1549 1.10 christos { 1550 1.10 christos prefix = 1; 1551 1.10 christos if (offset + 3 > sec->size) 1552 1.10 christos call = NULL; 1553 1.10 christos } 1554 1.10 christos } 1555 1.10 christos 1556 1.10 christos /* Make sure that it's a call *x@tlscall(%rax). */ 1557 1.10 christos if (call != NULL 1558 1.10 christos && (call[prefix] != 0xff || call[1 + prefix] != 0x10)) 1559 1.10 christos call = NULL; 1560 1.10 christos } 1561 1.10 christos 1562 1.10 christos if (call == NULL) 1563 1.10 christos { 1564 1.10 christos _bfd_x86_elf_link_report_tls_transition_error 1565 1.10 christos (info, abfd, sec, symtab_hdr, h, sym, rel, 1566 1.10 christos "R_X86_64_TLSDESC_CALL", NULL, 1567 1.10 christos elf_x86_tls_error_indirect_call); 1568 1.10 christos return false; 1569 1.10 christos } 1570 1.10 christos 1571 1.1 christos /* Fall through. */ 1572 1.1 christos 1573 1.9 christos case R_X86_64_TLSGD: 1574 1.1 christos case R_X86_64_GOTPC32_TLSDESC: 1575 1.9 christos case R_X86_64_CODE_4_GOTPC32_TLSDESC: 1576 1.10 christos case R_X86_64_GOTTPOFF: 1577 1.10 christos case R_X86_64_CODE_4_GOTTPOFF: 1578 1.3 christos case R_X86_64_CODE_5_GOTTPOFF: 1579 1.1 christos case R_X86_64_CODE_6_GOTTPOFF: 1580 1.1 christos if (bfd_link_executable (info)) 1581 1.1 christos { 1582 1.1 christos if (h == NULL) 1583 1.1 christos to_type = R_X86_64_TPOFF32; 1584 1.1 christos else 1585 1.1 christos to_type = R_X86_64_GOTTPOFF; 1586 1.5 christos } 1587 1.5 christos 1588 1.5 christos /* When we are called from elf_x86_64_relocate_section, there may 1589 1.1 christos be additional transitions based on TLS_TYPE. */ 1590 1.1 christos if (from_relocate_section) 1591 1.1 christos { 1592 1.6 christos unsigned int new_to_type = to_type; 1593 1.1 christos 1594 1.1 christos if (TLS_TRANSITION_IE_TO_LE_P (info, h, tls_type)) 1595 1.1 christos new_to_type = R_X86_64_TPOFF32; 1596 1.1 christos 1597 1.9 christos if (to_type == R_X86_64_TLSGD 1598 1.1 christos || to_type == R_X86_64_GOTPC32_TLSDESC 1599 1.1 christos || to_type == R_X86_64_CODE_4_GOTPC32_TLSDESC 1600 1.1 christos || to_type == R_X86_64_TLSDESC_CALL) 1601 1.1 christos { 1602 1.1 christos if (tls_type == GOT_TLS_IE) 1603 1.1 christos new_to_type = R_X86_64_GOTTPOFF; 1604 1.1 christos } 1605 1.8 christos 1606 1.1 christos /* We checked the transition before when we were called from 1607 1.10 christos elf_x86_64_scan_relocs. We only want to check the new 1608 1.10 christos transition which hasn't been checked before. */ 1609 1.10 christos check = (new_to_type != to_type 1610 1.10 christos && (from_type == to_type 1611 1.10 christos || (from_type == R_X86_64_CODE_4_GOTTPOFF 1612 1.10 christos && to_type == R_X86_64_GOTTPOFF) 1613 1.10 christos || (from_type == R_X86_64_CODE_5_GOTTPOFF 1614 1.10 christos && to_type == R_X86_64_GOTTPOFF) 1615 1.1 christos || (from_type == R_X86_64_CODE_6_GOTTPOFF 1616 1.1 christos && to_type == R_X86_64_GOTTPOFF))); 1617 1.1 christos to_type = new_to_type; 1618 1.1 christos } 1619 1.1 christos 1620 1.1 christos break; 1621 1.3 christos 1622 1.1 christos case R_X86_64_TLSLD: 1623 1.1 christos if (bfd_link_executable (info)) 1624 1.1 christos to_type = R_X86_64_TPOFF32; 1625 1.1 christos break; 1626 1.8 christos 1627 1.1 christos default: 1628 1.1 christos return true; 1629 1.1 christos } 1630 1.9 christos 1631 1.9 christos /* Return TRUE if there is no transition. */ 1632 1.10 christos if (from_type == to_type 1633 1.10 christos || (from_type == R_X86_64_CODE_4_GOTTPOFF 1634 1.10 christos && to_type == R_X86_64_GOTTPOFF) 1635 1.10 christos || (from_type == R_X86_64_CODE_5_GOTTPOFF 1636 1.9 christos && to_type == R_X86_64_GOTTPOFF) 1637 1.8 christos || (from_type == R_X86_64_CODE_6_GOTTPOFF 1638 1.1 christos && to_type == R_X86_64_GOTTPOFF)) 1639 1.1 christos return true; 1640 1.10 christos 1641 1.1 christos /* Check if the transition can be performed. */ 1642 1.10 christos enum elf_x86_tls_error_type tls_error; 1643 1.10 christos if (check 1644 1.10 christos && ((tls_error = elf_x86_64_check_tls_transition (abfd, info, sec, 1645 1.10 christos contents, 1646 1.10 christos symtab_hdr, 1647 1.10 christos sym_hashes, 1648 1.10 christos from_type, rel, 1649 1.10 christos relend)) 1650 1.1 christos != elf_x86_tls_error_none)) 1651 1.1 christos 1652 1.1 christos { 1653 1.10 christos reloc_howto_type *from, *to; 1654 1.10 christos 1655 1.1 christos from = &x86_64_elf_howto_table[from_type]; 1656 1.6 christos to = &x86_64_elf_howto_table[to_type]; 1657 1.8 christos 1658 1.6 christos if (from == NULL || to == NULL) 1659 1.10 christos return false; 1660 1.10 christos 1661 1.10 christos _bfd_x86_elf_link_report_tls_transition_error 1662 1.1 christos (info, abfd, sec, symtab_hdr, h, sym, rel, from->name, 1663 1.8 christos to->name, tls_error); 1664 1.1 christos 1665 1.1 christos return false; 1666 1.1 christos } 1667 1.8 christos 1668 1.1 christos *r_type = to_type; 1669 1.1 christos return true; 1670 1.8 christos } 1671 1.6 christos 1672 1.6 christos static bool 1673 1.5 christos elf_x86_64_need_pic (struct bfd_link_info *info, 1674 1.5 christos bfd *input_bfd, asection *sec, 1675 1.5 christos struct elf_link_hash_entry *h, 1676 1.5 christos Elf_Internal_Shdr *symtab_hdr, 1677 1.5 christos Elf_Internal_Sym *isym, 1678 1.5 christos reloc_howto_type *howto) 1679 1.5 christos { 1680 1.5 christos const char *v = ""; 1681 1.6 christos const char *und = ""; 1682 1.5 christos const char *pic = ""; 1683 1.5 christos const char *object; 1684 1.5 christos 1685 1.5 christos const char *name; 1686 1.5 christos if (h) 1687 1.5 christos { 1688 1.5 christos name = h->root.root.string; 1689 1.5 christos switch (ELF_ST_VISIBILITY (h->other)) 1690 1.5 christos { 1691 1.5 christos case STV_HIDDEN: 1692 1.5 christos v = _("hidden symbol "); 1693 1.5 christos break; 1694 1.5 christos case STV_INTERNAL: 1695 1.5 christos v = _("internal symbol "); 1696 1.5 christos break; 1697 1.5 christos case STV_PROTECTED: 1698 1.5 christos v = _("protected symbol "); 1699 1.6 christos break; 1700 1.6 christos default: 1701 1.6 christos if (((struct elf_x86_link_hash_entry *) h)->def_protected) 1702 1.6 christos v = _("protected symbol "); 1703 1.7 christos else 1704 1.5 christos v = _("symbol "); 1705 1.5 christos pic = NULL; 1706 1.5 christos break; 1707 1.7 christos } 1708 1.5 christos 1709 1.5 christos if (!SYMBOL_DEFINED_NON_SHARED_P (h) && !h->def_dynamic) 1710 1.5 christos und = _("undefined "); 1711 1.5 christos } 1712 1.5 christos else 1713 1.7 christos { 1714 1.5 christos name = bfd_elf_sym_name (input_bfd, symtab_hdr, isym, NULL); 1715 1.5 christos pic = NULL; 1716 1.6 christos } 1717 1.7 christos 1718 1.7 christos if (bfd_link_dll (info)) 1719 1.7 christos { 1720 1.7 christos object = _("a shared object"); 1721 1.7 christos if (!pic) 1722 1.6 christos pic = _("; recompile with -fPIC"); 1723 1.7 christos } 1724 1.7 christos else 1725 1.7 christos { 1726 1.7 christos if (bfd_link_pie (info)) 1727 1.7 christos object = _("a PIE object"); 1728 1.7 christos else 1729 1.7 christos object = _("a PDE object"); 1730 1.7 christos if (!pic) 1731 1.6 christos pic = _("; recompile with -fPIE"); 1732 1.6 christos } 1733 1.6 christos 1734 1.6 christos /* xgettext:c-format */ 1735 1.6 christos _bfd_error_handler (_("%pB: relocation %s against %s%s`%s' can " 1736 1.6 christos "not be used when making %s%s"), 1737 1.5 christos input_bfd, howto->name, und, v, name, 1738 1.5 christos object, pic); 1739 1.8 christos bfd_set_error (bfd_error_bad_value); 1740 1.5 christos sec->check_relocs_failed = 1; 1741 1.5 christos return false; 1742 1.10 christos } 1743 1.10 christos 1744 1.10 christos /* Move the R bits to the B bits in EVEX payload byte 1. */ 1745 1.10 christos static unsigned int evex_move_r_to_b (unsigned int byte1, bool copy) 1746 1.10 christos { 1747 1.10 christos byte1 = (byte1 & ~(1 << 5)) | ((byte1 & (1 << 7)) >> 2); /* R3 -> B3 */ 1748 1.10 christos byte1 = (byte1 & ~(1 << 3)) | ((~byte1 & (1 << 4)) >> 1); /* R4 -> B4 */ 1749 1.10 christos 1750 1.10 christos /* Set both R bits, as they're inverted. */ 1751 1.10 christos if (!copy) 1752 1.10 christos byte1 |= (1 << 4) | (1 << 7); 1753 1.10 christos 1754 1.10 christos return byte1; 1755 1.5 christos } 1756 1.5 christos 1757 1.10 christos /* With the local symbol, foo, we convert 1758 1.5 christos mov foo@GOTPCREL(%rip), %reg 1759 1.5 christos movrs foo@GOTPCREL(%rip), %reg 1760 1.5 christos to 1761 1.5 christos lea foo(%rip), %reg 1762 1.5 christos and convert 1763 1.5 christos call/jmp *foo@GOTPCREL(%rip) 1764 1.5 christos to 1765 1.5 christos nop call foo/jmp foo nop 1766 1.5 christos When PIC is false, convert 1767 1.5 christos test %reg, foo@GOTPCREL(%rip) 1768 1.5 christos to 1769 1.10 christos test $foo, %reg 1770 1.10 christos and convert 1771 1.10 christos push foo@GOTPCREL(%rip) 1772 1.10 christos to 1773 1.5 christos push $foo 1774 1.5 christos and convert 1775 1.5 christos binop foo@GOTPCREL(%rip), %reg 1776 1.10 christos to 1777 1.5 christos binop $foo, %reg 1778 1.5 christos where binop is one of adc, add, and, cmp, imul, or, sbb, sub, xor 1779 1.8 christos instructions. */ 1780 1.6 christos 1781 1.10 christos static bool 1782 1.5 christos elf_x86_64_convert_load_reloc (bfd *abfd, 1783 1.6 christos asection *input_section, 1784 1.5 christos bfd_byte *contents, 1785 1.5 christos unsigned int *r_type_p, 1786 1.8 christos Elf_Internal_Rela *irel, 1787 1.5 christos struct elf_link_hash_entry *h, 1788 1.5 christos bool *converted, 1789 1.6 christos struct bfd_link_info *link_info) 1790 1.8 christos { 1791 1.8 christos struct elf_x86_link_hash_table *htab; 1792 1.8 christos bool is_pic; 1793 1.10 christos bool no_overflow; 1794 1.8 christos bool relocx; 1795 1.8 christos bool is_branch = false; 1796 1.8 christos bool to_reloc_pc32; 1797 1.10 christos bool abs_symbol; 1798 1.5 christos bool local_ref; 1799 1.5 christos asection *tsec = NULL; 1800 1.5 christos bfd_signed_vma raddend; 1801 1.10 christos unsigned int opcode; 1802 1.6 christos unsigned int modrm; 1803 1.5 christos unsigned char evex[3] = { 0, 0, 0 }; 1804 1.5 christos unsigned int r_type = *r_type_p; 1805 1.8 christos unsigned int r_symndx; 1806 1.10 christos bfd_vma roff = irel->r_offset; 1807 1.10 christos bfd_vma abs_relocation; 1808 1.10 christos reloc_howto_type *howto; 1809 1.10 christos bfd_reloc_status_type r; 1810 1.5 christos Elf_Internal_Sym *isym; 1811 1.10 christos bfd_vma relocation; 1812 1.10 christos 1813 1.10 christos switch (r_type) 1814 1.10 christos { 1815 1.10 christos default: 1816 1.10 christos if (roff < 2) 1817 1.10 christos return true; 1818 1.10 christos relocx = (r_type == R_X86_64_GOTPCRELX); 1819 1.10 christos break; 1820 1.10 christos 1821 1.10 christos case R_X86_64_REX_GOTPCRELX: 1822 1.10 christos if (roff < 3) 1823 1.10 christos return true; 1824 1.10 christos relocx = true; 1825 1.10 christos break; 1826 1.10 christos 1827 1.10 christos case R_X86_64_CODE_4_GOTPCRELX: 1828 1.10 christos if (roff < 4) 1829 1.10 christos return true; 1830 1.10 christos 1831 1.10 christos /* Skip if this isn't a REX2 instruction, nor un-prefixed MOVRS. */ 1832 1.10 christos opcode = bfd_get_8 (abfd, contents + roff - 4); 1833 1.10 christos if (opcode != 0xd5 1834 1.10 christos && (opcode != 0x0f 1835 1.10 christos || bfd_get_8 (abfd, contents + roff - 3) != 0x38 1836 1.10 christos || bfd_get_8 (abfd, contents + roff - 2) != 0x8b)) 1837 1.10 christos return true; 1838 1.10 christos 1839 1.10 christos relocx = true; 1840 1.10 christos break; 1841 1.10 christos 1842 1.10 christos case R_X86_64_CODE_5_GOTPCRELX: 1843 1.10 christos if (roff < 5) 1844 1.10 christos return true; 1845 1.10 christos 1846 1.10 christos /* Skip if this isn't REX-prefixed MOVRS. */ 1847 1.10 christos if ((bfd_get_8 (abfd, contents + roff - 5) | 0xf) != 0x4f 1848 1.10 christos || bfd_get_8 (abfd, contents + roff - 4) != 0x0f 1849 1.10 christos || bfd_get_8 (abfd, contents + roff - 3) != 0x38 1850 1.10 christos || bfd_get_8 (abfd, contents + roff - 2) != 0x8b) 1851 1.10 christos return true; 1852 1.10 christos 1853 1.10 christos relocx = true; 1854 1.10 christos break; 1855 1.10 christos 1856 1.10 christos case R_X86_64_CODE_6_GOTPCRELX: 1857 1.10 christos if (roff < 6) 1858 1.10 christos return true; 1859 1.10 christos 1860 1.10 christos /* Skip if this isn't an EVEX instruction. */ 1861 1.10 christos if (bfd_get_8 (abfd, contents + roff - 6) != 0x62) 1862 1.10 christos return true; 1863 1.10 christos 1864 1.10 christos evex[0] = bfd_get_8 (abfd, contents + roff - 5); 1865 1.10 christos evex[1] = bfd_get_8 (abfd, contents + roff - 4); 1866 1.10 christos evex[2] = bfd_get_8 (abfd, contents + roff - 3); 1867 1.10 christos 1868 1.10 christos /* Skip if this isn't a Map 4 NP instruction. */ 1869 1.10 christos if ((evex[0] & 7) != 4 1870 1.10 christos || (evex[1] & 3) != 0 1871 1.10 christos || (evex[2] & 0xe0) != 0) 1872 1.10 christos return true; 1873 1.10 christos 1874 1.10 christos relocx = true; 1875 1.5 christos break; 1876 1.5 christos } 1877 1.5 christos 1878 1.5 christos raddend = irel->r_addend; 1879 1.8 christos /* Addend for 32-bit PC-relative relocation must be -4. */ 1880 1.5 christos if (raddend != -4) 1881 1.6 christos return true; 1882 1.5 christos 1883 1.5 christos htab = elf_x86_hash_table (link_info, X86_64_ELF_DATA); 1884 1.6 christos is_pic = bfd_link_pic (link_info); 1885 1.6 christos 1886 1.5 christos /* TRUE if --no-relax is used. */ 1887 1.5 christos no_overflow = link_info->disable_target_specific_optimizations > 1; 1888 1.5 christos 1889 1.5 christos r_symndx = htab->r_sym (irel->r_info); 1890 1.10 christos 1891 1.10 christos opcode = bfd_get_8 (abfd, contents + roff - 2); 1892 1.10 christos modrm = bfd_get_8 (abfd, contents + roff - 1); 1893 1.10 christos if (opcode == 0xff) 1894 1.10 christos { 1895 1.10 christos switch (modrm & 0x38) 1896 1.10 christos { 1897 1.10 christos case 0x10: /* CALL */ 1898 1.10 christos case 0x20: /* JMP */ 1899 1.10 christos is_branch = true; 1900 1.10 christos break; 1901 1.10 christos 1902 1.10 christos case 0x30: /* PUSH */ 1903 1.10 christos break; 1904 1.10 christos 1905 1.10 christos default: 1906 1.10 christos return true; 1907 1.5 christos } 1908 1.5 christos } 1909 1.5 christos 1910 1.5 christos /* Convert mov to lea since it has been done for a while. */ 1911 1.9 christos if (opcode != 0x8b) 1912 1.10 christos { 1913 1.9 christos /* Only convert R_X86_64_GOTPCRELX, R_X86_64_REX_GOTPCRELX 1914 1.5 christos and R_X86_64_CODE_<n>_GOTPCRELX for call, jmp or one of adc, 1915 1.8 christos add, and, cmp, or, sbb, sub, test, xor instructions. */ 1916 1.5 christos if (!relocx) 1917 1.5 christos return true; 1918 1.5 christos } 1919 1.5 christos 1920 1.5 christos /* We convert only to R_X86_64_PC32: 1921 1.6 christos 1. Branch. 1922 1.5 christos 2. R_X86_64_GOTPCREL since we can't modify REX byte. 1923 1.5 christos 3. no_overflow is true. 1924 1.10 christos 4. PIC. 1925 1.5 christos */ 1926 1.6 christos to_reloc_pc32 = (is_branch 1927 1.5 christos || !relocx 1928 1.5 christos || no_overflow 1929 1.8 christos || is_pic); 1930 1.8 christos 1931 1.8 christos abs_symbol = false; 1932 1.5 christos abs_relocation = 0; 1933 1.5 christos 1934 1.5 christos /* Get the symbol referred to by the reloc. */ 1935 1.10 christos if (h == NULL) 1936 1.10 christos { 1937 1.5 christos isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, 1938 1.5 christos r_symndx); 1939 1.5 christos 1940 1.8 christos /* Skip relocation against undefined symbols. */ 1941 1.5 christos if (isym->st_shndx == SHN_UNDEF) 1942 1.8 christos return true; 1943 1.5 christos 1944 1.8 christos local_ref = true; 1945 1.8 christos if (isym->st_shndx == SHN_ABS) 1946 1.8 christos { 1947 1.8 christos tsec = bfd_abs_section_ptr; 1948 1.8 christos abs_symbol = true; 1949 1.5 christos abs_relocation = isym->st_value; 1950 1.5 christos } 1951 1.5 christos else if (isym->st_shndx == SHN_COMMON) 1952 1.5 christos tsec = bfd_com_section_ptr; 1953 1.5 christos else if (isym->st_shndx == SHN_X86_64_LCOMMON) 1954 1.5 christos tsec = &_bfd_elf_large_com_section; 1955 1.5 christos else 1956 1.5 christos tsec = bfd_section_from_elf_index (abfd, isym->st_shndx); 1957 1.5 christos } 1958 1.5 christos else 1959 1.5 christos { 1960 1.5 christos /* Undefined weak symbol is only bound locally in executable 1961 1.5 christos and its reference is resolved as 0 without relocation 1962 1.5 christos overflow. We can only perform this optimization for 1963 1.5 christos GOTPCRELX relocations since we need to modify REX byte. 1964 1.6 christos It is OK convert mov with R_X86_64_GOTPCREL to 1965 1.6 christos R_X86_64_PC32. */ 1966 1.10 christos struct elf_x86_link_hash_entry *eh = elf_x86_hash_entry (h); 1967 1.10 christos 1968 1.10 christos isym = NULL; 1969 1.8 christos tsec = NULL; 1970 1.8 christos 1971 1.8 christos abs_symbol = ABS_SYMBOL_P (h); 1972 1.6 christos abs_relocation = h->root.u.def.value; 1973 1.6 christos 1974 1.5 christos /* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P. */ 1975 1.6 christos local_ref = SYMBOL_REFERENCES_LOCAL_P (link_info, h); 1976 1.6 christos if ((relocx || opcode == 0x8b) 1977 1.6 christos && (h->root.type == bfd_link_hash_undefweak 1978 1.5 christos && !eh->linker_def 1979 1.10 christos && local_ref)) 1980 1.5 christos { 1981 1.5 christos if (is_branch) 1982 1.5 christos { 1983 1.6 christos /* Skip for branch instructions since R_X86_64_PC32 1984 1.8 christos may overflow. */ 1985 1.5 christos if (no_overflow) 1986 1.5 christos return true; 1987 1.5 christos } 1988 1.5 christos else if (relocx) 1989 1.5 christos { 1990 1.5 christos /* For non-branch instructions, we can convert to 1991 1.8 christos R_X86_64_32/R_X86_64_32S since we know if there 1992 1.5 christos is a REX byte. */ 1993 1.5 christos to_reloc_pc32 = false; 1994 1.5 christos } 1995 1.5 christos 1996 1.5 christos /* Since we don't know the current PC when PIC is true, 1997 1.8 christos we can't convert to R_X86_64_PC32. */ 1998 1.5 christos if (to_reloc_pc32 && is_pic) 1999 1.5 christos return true; 2000 1.5 christos 2001 1.5 christos goto convert; 2002 1.5 christos } 2003 1.6 christos /* Avoid optimizing GOTPCREL relocations againt _DYNAMIC since 2004 1.6 christos ld.so may use its link-time address. */ 2005 1.6 christos else if (h->start_stop 2006 1.6 christos || eh->linker_def 2007 1.6 christos || ((h->def_regular 2008 1.6 christos || h->root.type == bfd_link_hash_defined 2009 1.6 christos || h->root.type == bfd_link_hash_defweak) 2010 1.5 christos && h != htab->elf.hdynamic 2011 1.5 christos && local_ref)) 2012 1.5 christos { 2013 1.6 christos /* bfd_link_hash_new or bfd_link_hash_undefined is 2014 1.6 christos set by an assignment in a linker script in 2015 1.6 christos bfd_elf_record_link_assignment. start_stop is set 2016 1.6 christos on __start_SECNAME/__stop_SECNAME which mark section 2017 1.6 christos SECNAME. */ 2018 1.6 christos if (h->start_stop 2019 1.6 christos || eh->linker_def 2020 1.6 christos || (h->def_regular 2021 1.6 christos && (h->root.type == bfd_link_hash_new 2022 1.6 christos || h->root.type == bfd_link_hash_undefined 2023 1.6 christos || ((h->root.type == bfd_link_hash_defined 2024 1.5 christos || h->root.type == bfd_link_hash_defweak) 2025 1.5 christos && h->root.u.def.section == bfd_und_section_ptr)))) 2026 1.6 christos { 2027 1.8 christos /* Skip since R_X86_64_32/R_X86_64_32S may overflow. */ 2028 1.10 christos if (no_overflow) 2029 1.10 christos return true; 2030 1.10 christos if (h->start_stop) 2031 1.10 christos tsec = h->root.u.def.section; 2032 1.10 christos else if (h == htab->elf.hehdr_start) 2033 1.10 christos { 2034 1.10 christos /* Use the lowest-addressed section to estimate the 2035 1.10 christos __ehdr_start symbol value. */ 2036 1.10 christos asection *sec; 2037 1.10 christos tsec = NULL; 2038 1.10 christos for (sec = link_info->output_bfd->sections; 2039 1.10 christos sec != NULL; 2040 1.10 christos sec = sec->next) 2041 1.10 christos if ((sec->flags & SEC_LOAD) != 0 2042 1.10 christos && (tsec == NULL || tsec->vma > sec->vma)) 2043 1.10 christos tsec = sec; 2044 1.5 christos 2045 1.5 christos } 2046 1.5 christos goto convert; 2047 1.5 christos } 2048 1.5 christos tsec = h->root.u.def.section; 2049 1.8 christos } 2050 1.5 christos else 2051 1.5 christos return true; 2052 1.10 christos } 2053 1.10 christos 2054 1.10 christos if (tsec == NULL) 2055 1.5 christos return false; 2056 1.5 christos 2057 1.5 christos /* Don't convert GOTPCREL relocation against large section. */ 2058 1.8 christos if (elf_section_data (tsec) != NULL 2059 1.5 christos && (elf_section_flags (tsec) & SHF_X86_64_LARGE) != 0) 2060 1.6 christos return true; 2061 1.6 christos 2062 1.8 christos /* Skip since R_X86_64_PC32/R_X86_64_32/R_X86_64_32S may overflow. */ 2063 1.5 christos if (no_overflow) 2064 1.8 christos return true; 2065 1.10 christos 2066 1.10 christos convert: 2067 1.10 christos /* Compute relocation value so that it can be used later to check for 2068 1.10 christos overflow against the converted relocation. */ 2069 1.10 christos if (h == NULL) 2070 1.10 christos { 2071 1.10 christos /* Make a copy of IREL so that _bfd_elf_rela_local_sym won't 2072 1.10 christos change IREL. */ 2073 1.10 christos Elf_Internal_Rela rel = *irel; 2074 1.10 christos relocation = _bfd_elf_rela_local_sym (link_info->output_bfd, isym, 2075 1.10 christos &tsec, &rel); 2076 1.10 christos /* Use the updated r_addend. */ 2077 1.10 christos raddend = rel.r_addend; 2078 1.10 christos } 2079 1.10 christos else if (tsec != NULL) 2080 1.10 christos relocation = (h->root.u.def.value 2081 1.10 christos + tsec->output_section->vma 2082 1.10 christos + tsec->output_offset); 2083 1.10 christos else 2084 1.10 christos relocation = 0; 2085 1.5 christos 2086 1.5 christos if (is_branch) 2087 1.5 christos { 2088 1.5 christos /* We have "call/jmp *foo@GOTPCREL(%rip)". */ 2089 1.5 christos unsigned int nop; 2090 1.5 christos unsigned int disp; 2091 1.10 christos bfd_vma nop_offset; 2092 1.10 christos 2093 1.10 christos r_type = R_X86_64_PC32; 2094 1.10 christos 2095 1.10 christos /* Skip if the converted relocation will overflow. */ 2096 1.10 christos howto = &x86_64_elf_howto_table[r_type]; 2097 1.10 christos r = _bfd_final_link_relocate (howto, abfd, input_section, 2098 1.10 christos contents, irel->r_offset, 2099 1.10 christos relocation, raddend); 2100 1.10 christos if (r == bfd_reloc_overflow) 2101 1.5 christos return true; 2102 1.5 christos 2103 1.5 christos /* Convert R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX to 2104 1.5 christos R_X86_64_PC32. */ 2105 1.5 christos if (modrm == 0x25) 2106 1.5 christos { 2107 1.5 christos /* Convert to "jmp foo nop". */ 2108 1.5 christos modrm = 0xe9; 2109 1.5 christos nop = NOP_OPCODE; 2110 1.5 christos nop_offset = irel->r_offset + 3; 2111 1.5 christos disp = bfd_get_32 (abfd, contents + irel->r_offset); 2112 1.5 christos irel->r_offset -= 1; 2113 1.5 christos bfd_put_32 (abfd, disp, contents + irel->r_offset); 2114 1.5 christos } 2115 1.6 christos else 2116 1.6 christos { 2117 1.5 christos struct elf_x86_link_hash_entry *eh 2118 1.5 christos = (struct elf_x86_link_hash_entry *) h; 2119 1.5 christos 2120 1.5 christos /* Convert to "nop call foo". ADDR_PREFIX_OPCODE 2121 1.5 christos is a nop prefix. */ 2122 1.5 christos modrm = 0xe8; 2123 1.6 christos /* To support TLS optimization, always use addr32 prefix for 2124 1.5 christos "call *__tls_get_addr@GOTPCREL(%rip)". */ 2125 1.5 christos if (eh && eh->tls_get_addr) 2126 1.5 christos { 2127 1.5 christos nop = 0x67; 2128 1.5 christos nop_offset = irel->r_offset - 2; 2129 1.5 christos } 2130 1.7 christos else 2131 1.7 christos { 2132 1.5 christos nop = htab->params->call_nop_byte; 2133 1.5 christos if (htab->params->call_nop_as_suffix) 2134 1.5 christos { 2135 1.5 christos nop_offset = irel->r_offset + 3; 2136 1.5 christos disp = bfd_get_32 (abfd, contents + irel->r_offset); 2137 1.5 christos irel->r_offset -= 1; 2138 1.5 christos bfd_put_32 (abfd, disp, contents + irel->r_offset); 2139 1.5 christos } 2140 1.5 christos else 2141 1.5 christos nop_offset = irel->r_offset - 2; 2142 1.5 christos } 2143 1.5 christos } 2144 1.10 christos bfd_put_8 (abfd, nop, contents + nop_offset); 2145 1.10 christos bfd_put_8 (abfd, modrm, contents + irel->r_offset - 1); 2146 1.10 christos } 2147 1.10 christos else if (r_type == R_X86_64_CODE_6_GOTPCRELX && opcode != 0x8b) 2148 1.10 christos { 2149 1.10 christos bool move_v_r = false; 2150 1.10 christos 2151 1.10 christos /* R_X86_64_PC32 isn't supported. */ 2152 1.10 christos if (to_reloc_pc32) 2153 1.10 christos return true; 2154 1.10 christos 2155 1.10 christos if (opcode == 0x85) 2156 1.10 christos { 2157 1.10 christos /* Convert "ctest<cc> %reg, foo@GOTPCREL(%rip)" to 2158 1.10 christos "ctest<cc> $foo, %reg". */ 2159 1.10 christos modrm = 0xc0 | (modrm & 0x38) >> 3; 2160 1.10 christos opcode = 0xf7; 2161 1.10 christos } 2162 1.10 christos else if ((opcode | 0x3a) == 0x3b) 2163 1.10 christos { 2164 1.10 christos /* Don't convert (non-NDD) forms with memory destination. */ 2165 1.10 christos if (!(evex[2] & 0x10) && (opcode | 0x38) != 0x3b) 2166 1.10 christos return true; 2167 1.10 christos 2168 1.10 christos /* Don't convert non-commutative insns with the memory operand 2169 1.10 christos 2nd. */ 2170 1.10 christos if ((evex[2] & 0x10) && (opcode | 0x38) != 0x3b 2171 1.10 christos && (opcode == 0x19 /* SBB */ 2172 1.10 christos || opcode == 0x29 /* SUB */)) 2173 1.10 christos return true; 2174 1.10 christos 2175 1.10 christos /* Convert "binop foo@GOTPCREL(%rip), %reg" to 2176 1.10 christos "binop $foo, %reg", or alike for 3-operand forms. */ 2177 1.10 christos modrm = 0xc0 | ((modrm & 0x38) >> 3) | (opcode & 0x38); 2178 1.10 christos opcode = 0x81; 2179 1.10 christos } 2180 1.10 christos else if (opcode == 0xaf) 2181 1.10 christos { 2182 1.10 christos if (!(evex[2] & 0x10)) 2183 1.10 christos { 2184 1.10 christos /* Convert "imul foo@GOTPCREL(%rip), %reg" to 2185 1.10 christos "imul $foo, %reg, %reg". */ 2186 1.10 christos modrm = 0xc0 | ((modrm & 0x38) >> 3) | (modrm & 0x38); 2187 1.10 christos } 2188 1.10 christos else 2189 1.10 christos { 2190 1.10 christos /* Convert "imul foo@GOTPCREL(%rip), %reg1, %reg2" to 2191 1.10 christos "imul $foo, %reg1, %reg2". */ 2192 1.10 christos modrm = 0xc0 | ((modrm & 0x38) >> 3) | (~evex[1] & 0x38); 2193 1.10 christos move_v_r = true; 2194 1.10 christos } 2195 1.10 christos opcode = 0x69; 2196 1.10 christos } 2197 1.10 christos else 2198 1.10 christos return true; 2199 1.10 christos 2200 1.10 christos /* Use R_X86_64_32 with 32-bit operand to avoid relocation 2201 1.10 christos overflow when sign-extending imm32 to 64 bits. */ 2202 1.10 christos r_type = evex[1] & 0x80 ? R_X86_64_32S : R_X86_64_32; 2203 1.10 christos 2204 1.10 christos /* Skip if the converted relocation will overflow. */ 2205 1.10 christos howto = elf_x86_64_rtype_to_howto (abfd, r_type); 2206 1.10 christos r = _bfd_final_link_relocate (howto, abfd, input_section, 2207 1.10 christos contents, irel->r_offset, 2208 1.10 christos relocation, 0); 2209 1.10 christos if (r == bfd_reloc_overflow) 2210 1.10 christos return true; 2211 1.10 christos 2212 1.10 christos if (abs_relocation) /* Bogus; should be abs_symbol. */ 2213 1.10 christos { 2214 1.10 christos /* Check if R_X86_64_32S/R_X86_64_32 fits. */ 2215 1.10 christos if (r_type == R_X86_64_32S) 2216 1.10 christos { 2217 1.10 christos if ((abs_relocation + 0x80000000) > 0xffffffff) 2218 1.10 christos return true; 2219 1.10 christos } 2220 1.10 christos else 2221 1.10 christos { 2222 1.10 christos if (abs_relocation > 0xffffffff) 2223 1.10 christos return true; 2224 1.10 christos } 2225 1.10 christos } 2226 1.10 christos 2227 1.10 christos bfd_put_8 (abfd, opcode, contents + roff - 2); 2228 1.10 christos bfd_put_8 (abfd, modrm, contents + roff - 1); 2229 1.10 christos 2230 1.10 christos evex[0] = evex_move_r_to_b (evex[0], opcode == 0x69 && !move_v_r); 2231 1.10 christos if (move_v_r) 2232 1.10 christos { 2233 1.10 christos /* Move the top two V bits to the R bits in EVEX payload byte 1. 2234 1.10 christos Note that evex_move_r_to_b() set both R bits. */ 2235 1.10 christos if (!(evex[1] & (1 << 6))) 2236 1.10 christos evex[0] &= ~(1 << 7); /* V3 -> R3 */ 2237 1.10 christos if (!(evex[2] & (1 << 3))) 2238 1.10 christos evex[0] &= ~(1 << 4); /* V4 -> R4 */ 2239 1.10 christos /* Set all V bits, as they're inverted. */ 2240 1.10 christos evex[1] |= 0xf << 3; 2241 1.10 christos evex[2] |= 1 << 3; 2242 1.10 christos /* Clear the ND (ZU) bit (it ought to be ignored anyway). */ 2243 1.10 christos evex[2] &= ~(1 << 4); 2244 1.10 christos bfd_put_8 (abfd, evex[2], contents + roff - 3); 2245 1.10 christos bfd_put_8 (abfd, evex[1], contents + roff - 4); 2246 1.10 christos } 2247 1.10 christos bfd_put_8 (abfd, evex[0], contents + roff - 5); 2248 1.10 christos 2249 1.5 christos /* No addend for R_X86_64_32/R_X86_64_32S relocations. */ 2250 1.5 christos irel->r_addend = 0; 2251 1.5 christos } 2252 1.9 christos else 2253 1.5 christos { 2254 1.9 christos unsigned int rex = 0; 2255 1.9 christos unsigned int rex_mask = REX_R; 2256 1.10 christos unsigned int rex2 = 0; 2257 1.9 christos unsigned int rex2_mask = REX_R | REX_R << 4; 2258 1.5 christos unsigned int movrs = 0; 2259 1.10 christos bool rex_w = false; 2260 1.10 christos 2261 1.10 christos if (r_type == R_X86_64_CODE_6_GOTPCRELX) 2262 1.10 christos { 2263 1.10 christos /* Synthesize a REX2 prefix from EVEX, just enough for the LEA 2264 1.10 christos and MOV case below. */ 2265 1.10 christos unsigned int p; 2266 1.10 christos 2267 1.10 christos p = bfd_get_8 (abfd, contents + roff - 5); 2268 1.10 christos if (!(p & 0x80)) 2269 1.10 christos rex2 |= REX_R; 2270 1.10 christos if (!(p & 0x10)) 2271 1.10 christos rex2 |= REX_R << 4; 2272 1.10 christos if (bfd_get_8 (abfd, contents + roff - 4) & 0x80) 2273 1.10 christos { 2274 1.10 christos rex2 |= REX_W; 2275 1.10 christos rex_w = true; 2276 1.10 christos } 2277 1.10 christos movrs = 6; 2278 1.9 christos } 2279 1.10 christos else if (r_type == R_X86_64_CODE_5_GOTPCRELX) 2280 1.10 christos { 2281 1.10 christos rex = bfd_get_8 (abfd, contents + roff - 5); 2282 1.10 christos rex_w = (rex & REX_W) != 0; 2283 1.10 christos movrs = 5; 2284 1.10 christos } 2285 1.10 christos else if (r_type == R_X86_64_CODE_4_GOTPCRELX) 2286 1.10 christos { 2287 1.10 christos if (bfd_get_8 (abfd, contents + roff - 4) == 0xd5) 2288 1.10 christos { 2289 1.10 christos /* Make sure even an all-zero payload leaves a non-zero value 2290 1.10 christos in the variable. */ 2291 1.10 christos rex2 = bfd_get_8 (abfd, contents + roff - 3) | 0x100; 2292 1.10 christos rex2_mask |= 0x100; 2293 1.10 christos rex_w = (rex2 & REX_W) != 0; 2294 1.10 christos } 2295 1.9 christos else if (bfd_get_8 (abfd, contents + roff - 4) == 0x0f) 2296 1.9 christos movrs = 4; 2297 1.9 christos } 2298 1.9 christos else if (r_type == R_X86_64_REX_GOTPCRELX) 2299 1.9 christos { 2300 1.9 christos rex = bfd_get_8 (abfd, contents + roff - 3); 2301 1.5 christos rex_w = (rex & REX_W) != 0; 2302 1.5 christos } 2303 1.5 christos 2304 1.8 christos if (opcode == 0x8b) 2305 1.8 christos { 2306 1.8 christos if (abs_symbol && local_ref && relocx) 2307 1.5 christos to_reloc_pc32 = false; 2308 1.5 christos 2309 1.5 christos if (to_reloc_pc32) 2310 1.5 christos { 2311 1.5 christos /* Convert "mov foo@GOTPCREL(%rip), %reg" to 2312 1.5 christos "lea foo(%rip), %reg". */ 2313 1.10 christos opcode = 0x8d; 2314 1.10 christos r_type = R_X86_64_PC32; 2315 1.10 christos 2316 1.10 christos /* Skip if the converted relocation will overflow. */ 2317 1.10 christos howto = &x86_64_elf_howto_table[r_type]; 2318 1.10 christos r = _bfd_final_link_relocate (howto, abfd, input_section, 2319 1.10 christos contents, irel->r_offset, 2320 1.10 christos relocation, 2321 1.10 christos raddend); 2322 1.10 christos if (r == bfd_reloc_overflow) 2323 1.10 christos return true; 2324 1.10 christos 2325 1.10 christos /* For MOVRS move a possible REX prefix as necessary. */ 2326 1.5 christos if (movrs == 5) 2327 1.5 christos bfd_put_8 (abfd, rex, contents + roff - 3); 2328 1.5 christos } 2329 1.5 christos else 2330 1.5 christos { 2331 1.5 christos /* Convert "mov foo@GOTPCREL(%rip), %reg" to 2332 1.5 christos "mov $foo, %reg". */ 2333 1.9 christos opcode = 0xc7; 2334 1.5 christos modrm = 0xc0 | (modrm & 0x38) >> 3; 2335 1.5 christos if (rex_w && ABI_64_P (link_info->output_bfd)) 2336 1.5 christos { 2337 1.5 christos /* Keep the REX_W bit in REX byte for LP64. */ 2338 1.5 christos r_type = R_X86_64_32S; 2339 1.5 christos goto rewrite_modrm_rex; 2340 1.5 christos } 2341 1.5 christos else 2342 1.5 christos { 2343 1.5 christos /* If the REX_W bit in REX byte isn't needed, 2344 1.5 christos use R_X86_64_32 and clear the W bit to avoid 2345 1.9 christos sign-extend imm32 to imm64. */ 2346 1.5 christos r_type = R_X86_64_32; 2347 1.9 christos /* Clear the W bit in REX byte and REX2 payload. */ 2348 1.5 christos rex_mask |= REX_W; 2349 1.5 christos rex2_mask |= REX_W; 2350 1.5 christos goto rewrite_modrm_rex; 2351 1.5 christos } 2352 1.5 christos } 2353 1.5 christos } 2354 1.5 christos else 2355 1.5 christos { 2356 1.8 christos /* R_X86_64_PC32 isn't supported. */ 2357 1.5 christos if (to_reloc_pc32) 2358 1.10 christos return true; 2359 1.5 christos 2360 1.5 christos if (opcode == 0x85 && !(rex2 & (REX2_M << 4))) 2361 1.5 christos { 2362 1.5 christos /* Convert "test %reg, foo@GOTPCREL(%rip)" to 2363 1.5 christos "test $foo, %reg". */ 2364 1.5 christos modrm = 0xc0 | (modrm & 0x38) >> 3; 2365 1.10 christos opcode = 0xf7; 2366 1.5 christos } 2367 1.5 christos else if ((opcode | 0x38) == 0x3b && !(rex2 & (REX2_M << 4))) 2368 1.5 christos { 2369 1.10 christos /* Convert "binop foo@GOTPCREL(%rip), %reg" to 2370 1.5 christos "binop $foo, %reg". */ 2371 1.5 christos modrm = 0xc0 | ((modrm & 0x38) >> 3) | (opcode & 0x38); 2372 1.10 christos opcode = 0x81; 2373 1.10 christos } 2374 1.10 christos else if (opcode == 0xaf && (rex2 & (REX2_M << 4))) 2375 1.10 christos { 2376 1.10 christos /* Convert "imul foo@GOTPCREL(%rip), %reg" to 2377 1.10 christos "imul $foo, %reg, %reg". */ 2378 1.10 christos modrm = 0xc0 | ((modrm & 0x38) >> 3) | (modrm & 0x38); 2379 1.10 christos rex_mask = 0; 2380 1.10 christos rex2_mask = REX2_M << 4; 2381 1.10 christos opcode = 0x69; 2382 1.10 christos } 2383 1.10 christos else if (opcode == 0xff && !(rex2 & (REX2_M << 4))) 2384 1.10 christos { 2385 1.10 christos /* Convert "push foo@GOTPCREL(%rip)" to 2386 1.10 christos "push $foo". */ 2387 1.10 christos bfd_put_8 (abfd, 0x68, contents + roff - 1); 2388 1.10 christos if (rex) 2389 1.10 christos { 2390 1.10 christos bfd_put_8 (abfd, 0x2e, contents + roff - 3); 2391 1.10 christos bfd_put_8 (abfd, rex, contents + roff - 2); 2392 1.10 christos } 2393 1.10 christos else if (rex2) 2394 1.10 christos { 2395 1.10 christos bfd_put_8 (abfd, 0x2e, contents + roff - 4); 2396 1.10 christos bfd_put_8 (abfd, 0xd5, contents + roff - 3); 2397 1.10 christos bfd_put_8 (abfd, rex2, contents + roff - 2); 2398 1.10 christos } 2399 1.10 christos else 2400 1.10 christos bfd_put_8 (abfd, 0x2e, contents + roff - 2); 2401 1.10 christos 2402 1.10 christos r_type = R_X86_64_32S; 2403 1.10 christos /* No addend for R_X86_64_32S relocations. */ 2404 1.10 christos irel->r_addend = 0; 2405 1.10 christos goto finish; 2406 1.10 christos } 2407 1.5 christos else 2408 1.5 christos return true; 2409 1.5 christos 2410 1.9 christos /* Use R_X86_64_32 with 32-bit operand to avoid relocation 2411 1.5 christos overflow when sign-extending imm32 to imm64. */ 2412 1.8 christos r_type = rex_w ? R_X86_64_32S : R_X86_64_32; 2413 1.10 christos 2414 1.10 christos rewrite_modrm_rex: 2415 1.10 christos /* Skip if the converted relocation will overflow. */ 2416 1.10 christos howto = elf_x86_64_rtype_to_howto (abfd, r_type); 2417 1.10 christos r = _bfd_final_link_relocate (howto, abfd, input_section, 2418 1.10 christos contents, irel->r_offset, 2419 1.10 christos relocation, 0); 2420 1.10 christos if (r == bfd_reloc_overflow) 2421 1.8 christos return true; 2422 1.8 christos 2423 1.8 christos if (abs_relocation) 2424 1.8 christos { 2425 1.8 christos /* Check if R_X86_64_32S/R_X86_64_32 fits. */ 2426 1.8 christos if (r_type == R_X86_64_32S) 2427 1.8 christos { 2428 1.8 christos if ((abs_relocation + 0x80000000) > 0xffffffff) 2429 1.8 christos return true; 2430 1.8 christos } 2431 1.8 christos else 2432 1.8 christos { 2433 1.8 christos if (abs_relocation > 0xffffffff) 2434 1.8 christos return true; 2435 1.8 christos } 2436 1.5 christos } 2437 1.5 christos 2438 1.5 christos bfd_put_8 (abfd, modrm, contents + roff - 1); 2439 1.5 christos 2440 1.5 christos if (rex) 2441 1.5 christos { 2442 1.5 christos /* Move the R bit to the B bit in REX byte. */ 2443 1.5 christos rex = (rex & ~rex_mask) | (rex & REX_R) >> 2; 2444 1.9 christos bfd_put_8 (abfd, rex, contents + roff - 3); 2445 1.9 christos } 2446 1.9 christos else if (rex2) 2447 1.9 christos { 2448 1.9 christos /* Move the R bits to the B bits in REX2 payload byte. */ 2449 1.9 christos rex2 = ((rex2 & ~rex2_mask) 2450 1.9 christos | (rex2 & (REX_R | REX_R << 4)) >> 2); 2451 1.5 christos bfd_put_8 (abfd, rex2, contents + roff - 3); 2452 1.5 christos } 2453 1.5 christos 2454 1.5 christos /* No addend for R_X86_64_32/R_X86_64_32S relocations. */ 2455 1.5 christos irel->r_addend = 0; 2456 1.5 christos } 2457 1.10 christos 2458 1.10 christos bfd_put_8 (abfd, opcode, contents + roff - 2); 2459 1.10 christos 2460 1.10 christos /* For MOVRS zap the 0f38 or EVEX prefix, applying meaningless CS 2461 1.10 christos segment overrides instead. When necessary also install the REX2 2462 1.10 christos prefix and payload (which may not have been written yet). */ 2463 1.10 christos if (movrs) 2464 1.10 christos { 2465 1.10 christos bfd_put_8 (abfd, 0x2e, contents + roff - movrs); 2466 1.10 christos bfd_put_8 (abfd, 0x2e, contents + roff - movrs + 1); 2467 1.10 christos if (movrs == 6) 2468 1.10 christos { 2469 1.10 christos bfd_put_8 (abfd, 0xd5, contents + roff - 4); 2470 1.10 christos bfd_put_8 (abfd, rex2, contents + roff - 3); 2471 1.5 christos } 2472 1.5 christos } 2473 1.10 christos } 2474 1.6 christos 2475 1.6 christos finish: 2476 1.6 christos *r_type_p = r_type; 2477 1.5 christos irel->r_info = htab->r_info (r_symndx, 2478 1.8 christos r_type | R_X86_64_converted_reloc_bit); 2479 1.5 christos 2480 1.8 christos *converted = true; 2481 1.5 christos 2482 1.3 christos return true; 2483 1.1 christos } 2484 1.8 christos 2485 1.8 christos /* Look through the relocs for a section during the first phase, and 2486 1.1 christos calculate needed space in the global offset table, and procedure 2487 1.8 christos linkage table. */ 2488 1.8 christos 2489 1.8 christos static bool 2490 1.8 christos elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info, 2491 1.1 christos asection *sec, 2492 1.6 christos const Elf_Internal_Rela *relocs) 2493 1.1 christos { 2494 1.1 christos struct elf_x86_link_hash_table *htab; 2495 1.1 christos Elf_Internal_Shdr *symtab_hdr; 2496 1.1 christos struct elf_link_hash_entry **sym_hashes; 2497 1.5 christos const Elf_Internal_Rela *rel; 2498 1.8 christos const Elf_Internal_Rela *rel_end; 2499 1.1 christos bfd_byte *contents; 2500 1.3 christos bool converted; 2501 1.8 christos 2502 1.5 christos if (bfd_link_relocatable (info)) 2503 1.6 christos return true; 2504 1.1 christos 2505 1.5 christos htab = elf_x86_hash_table (info, X86_64_ELF_DATA); 2506 1.5 christos if (htab == NULL) 2507 1.8 christos { 2508 1.5 christos sec->check_relocs_failed = 1; 2509 1.5 christos return false; 2510 1.6 christos } 2511 1.6 christos 2512 1.5 christos BFD_ASSERT (is_x86_elf (abfd, htab)); 2513 1.5 christos 2514 1.5 christos /* Get the section contents. */ 2515 1.10 christos if (elf_section_data (sec)->this_hdr.contents != NULL) 2516 1.5 christos contents = elf_section_data (sec)->this_hdr.contents; 2517 1.5 christos else if (!_bfd_elf_mmap_section_contents (abfd, sec, &contents)) 2518 1.8 christos { 2519 1.5 christos sec->check_relocs_failed = 1; 2520 1.1 christos return false; 2521 1.1 christos } 2522 1.1 christos 2523 1.1 christos symtab_hdr = &elf_symtab_hdr (abfd); 2524 1.8 christos sym_hashes = elf_sym_hashes (abfd); 2525 1.1 christos 2526 1.1 christos converted = false; 2527 1.1 christos 2528 1.1 christos rel_end = relocs + sec->reloc_count; 2529 1.1 christos for (rel = relocs; rel < rel_end; rel++) 2530 1.6 christos { 2531 1.1 christos unsigned int r_type; 2532 1.6 christos unsigned int r_symndx; 2533 1.1 christos struct elf_link_hash_entry *h; 2534 1.1 christos struct elf_x86_link_hash_entry *eh; 2535 1.8 christos Elf_Internal_Sym *isym; 2536 1.8 christos const char *name; 2537 1.8 christos bool size_reloc; 2538 1.10 christos bool converted_reloc; 2539 1.1 christos bool no_dynreloc; 2540 1.1 christos reloc_howto_type *howto; 2541 1.1 christos 2542 1.1 christos r_symndx = htab->r_sym (rel->r_info); 2543 1.9 christos r_type = ELF32_R_TYPE (rel->r_info); 2544 1.9 christos 2545 1.9 christos /* Don't check R_X86_64_NONE. */ 2546 1.9 christos if (r_type == R_X86_64_NONE) 2547 1.1 christos continue; 2548 1.1 christos 2549 1.6 christos if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr)) 2550 1.6 christos { 2551 1.6 christos /* xgettext:c-format */ 2552 1.5 christos _bfd_error_handler (_("%pB: bad symbol index: %d"), 2553 1.1 christos abfd, r_symndx); 2554 1.1 christos goto error_return; 2555 1.10 christos } 2556 1.10 christos 2557 1.10 christos howto = elf_x86_64_rtype_to_howto (abfd, r_type); 2558 1.10 christos if (howto == NULL) 2559 1.10 christos { 2560 1.10 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 2561 1.10 christos abfd, r_type); 2562 1.10 christos goto error_return; 2563 1.10 christos } 2564 1.10 christos if (!bfd_reloc_offset_in_range (howto, abfd, sec, rel->r_offset)) 2565 1.10 christos { 2566 1.10 christos /* xgettext:c-format */ 2567 1.10 christos _bfd_error_handler 2568 1.10 christos (_("%pB: bad reloc offset (%#" PRIx64 " > %#" PRIx64 ") for" 2569 1.10 christos " section `%pA'"), abfd, (uint64_t) rel->r_offset, 2570 1.10 christos (uint64_t) sec->size, sec); 2571 1.10 christos goto error_return; 2572 1.1 christos } 2573 1.1 christos 2574 1.1 christos if (r_symndx < symtab_hdr->sh_info) 2575 1.8 christos { 2576 1.1 christos /* A local symbol. */ 2577 1.1 christos isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, 2578 1.5 christos abfd, r_symndx); 2579 1.1 christos if (isym == NULL) 2580 1.1 christos goto error_return; 2581 1.1 christos 2582 1.1 christos /* Check relocation against local STT_GNU_IFUNC symbol. */ 2583 1.6 christos if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC) 2584 1.8 christos { 2585 1.1 christos h = _bfd_elf_x86_get_local_sym_hash (htab, abfd, rel, 2586 1.5 christos true); 2587 1.1 christos if (h == NULL) 2588 1.1 christos goto error_return; 2589 1.6 christos 2590 1.6 christos /* Fake a STT_GNU_IFUNC symbol. */ 2591 1.1 christos h->root.root.string = bfd_elf_sym_name (abfd, symtab_hdr, 2592 1.1 christos isym, NULL); 2593 1.1 christos h->type = STT_GNU_IFUNC; 2594 1.1 christos h->def_regular = 1; 2595 1.1 christos h->ref_regular = 1; 2596 1.1 christos h->forced_local = 1; 2597 1.1 christos h->root.type = bfd_link_hash_defined; 2598 1.1 christos } 2599 1.1 christos else 2600 1.1 christos h = NULL; 2601 1.1 christos } 2602 1.1 christos else 2603 1.10 christos { 2604 1.1 christos isym = NULL; 2605 1.1 christos h = _bfd_elf_get_link_hash_entry (sym_hashes, r_symndx, symtab_hdr); 2606 1.1 christos } 2607 1.1 christos 2608 1.1 christos /* Check invalid x32 relocations. */ 2609 1.1 christos if (!ABI_64_P (abfd)) 2610 1.1 christos switch (r_type) 2611 1.1 christos { 2612 1.1 christos default: 2613 1.1 christos break; 2614 1.1 christos 2615 1.1 christos case R_X86_64_DTPOFF64: 2616 1.1 christos case R_X86_64_TPOFF64: 2617 1.1 christos case R_X86_64_PC64: 2618 1.1 christos case R_X86_64_GOTOFF64: 2619 1.1 christos case R_X86_64_GOT64: 2620 1.1 christos case R_X86_64_GOTPCREL64: 2621 1.1 christos case R_X86_64_GOTPC64: 2622 1.1 christos case R_X86_64_GOTPLT64: 2623 1.1 christos case R_X86_64_PLTOFF64: 2624 1.1 christos { 2625 1.1 christos if (h) 2626 1.1 christos name = h->root.root.string; 2627 1.1 christos else 2628 1.6 christos name = bfd_elf_sym_name (abfd, symtab_hdr, isym, 2629 1.6 christos NULL); 2630 1.6 christos _bfd_error_handler 2631 1.1 christos /* xgettext:c-format */ 2632 1.1 christos (_("%pB: relocation %s against symbol `%s' isn't " 2633 1.1 christos "supported in x32 mode"), abfd, 2634 1.5 christos x86_64_elf_howto_table[r_type].name, name); 2635 1.1 christos bfd_set_error (bfd_error_bad_value); 2636 1.1 christos goto error_return; 2637 1.1 christos } 2638 1.1 christos break; 2639 1.8 christos } 2640 1.8 christos 2641 1.1 christos eh = (struct elf_x86_link_hash_entry *) h; 2642 1.1 christos 2643 1.3 christos if (h != NULL) 2644 1.3 christos { 2645 1.1 christos /* It is referenced by a non-shared object. */ 2646 1.1 christos h->ref_regular = 1; 2647 1.8 christos } 2648 1.6 christos 2649 1.6 christos converted_reloc = false; 2650 1.9 christos if ((r_type == R_X86_64_GOTPCREL 2651 1.10 christos || r_type == R_X86_64_GOTPCRELX 2652 1.10 christos || r_type == R_X86_64_REX_GOTPCRELX 2653 1.10 christos || r_type == R_X86_64_CODE_4_GOTPCRELX 2654 1.6 christos || r_type == R_X86_64_CODE_5_GOTPCRELX 2655 1.6 christos || r_type == R_X86_64_CODE_6_GOTPCRELX) 2656 1.6 christos && (h == NULL || h->type != STT_GNU_IFUNC)) 2657 1.10 christos { 2658 1.10 christos Elf_Internal_Rela *irel = (Elf_Internal_Rela *) rel; 2659 1.10 christos if (!elf_x86_64_convert_load_reloc (abfd, sec, contents, 2660 1.6 christos &r_type, irel, h, 2661 1.6 christos &converted_reloc, info)) 2662 1.6 christos goto error_return; 2663 1.8 christos 2664 1.6 christos if (converted_reloc) 2665 1.6 christos converted = true; 2666 1.8 christos } 2667 1.8 christos 2668 1.10 christos if (!_bfd_elf_x86_valid_reloc_p (sec, info, htab, rel, h, isym, 2669 1.8 christos symtab_hdr, &no_dynreloc)) 2670 1.5 christos goto error_return; 2671 1.1 christos 2672 1.1 christos if (! elf_x86_64_tls_transition (info, abfd, sec, contents, 2673 1.10 christos symtab_hdr, sym_hashes, 2674 1.5 christos &r_type, GOT_UNKNOWN, 2675 1.1 christos rel, rel_end, h, isym, false)) 2676 1.6 christos goto error_return; 2677 1.6 christos 2678 1.8 christos /* Check if _GLOBAL_OFFSET_TABLE_ is referenced. */ 2679 1.6 christos if (h == htab->elf.hgot) 2680 1.1 christos htab->got_referenced = true; 2681 1.1 christos 2682 1.1 christos switch (r_type) 2683 1.6 christos { 2684 1.1 christos case R_X86_64_TLSLD: 2685 1.1 christos htab->tls_ld_or_ldm_got.refcount = 1; 2686 1.1 christos goto create_got; 2687 1.3 christos 2688 1.10 christos case R_X86_64_TPOFF32: 2689 1.10 christos if (!bfd_link_executable (info) && ABI_64_P (abfd)) 2690 1.10 christos { 2691 1.10 christos elf_x86_64_need_pic (info, abfd, sec, h, symtab_hdr, isym, 2692 1.10 christos &x86_64_elf_howto_table[r_type]); 2693 1.5 christos goto error_return; 2694 1.6 christos } 2695 1.1 christos if (eh != NULL) 2696 1.1 christos eh->zero_undefweak &= 0x2; 2697 1.1 christos break; 2698 1.9 christos 2699 1.10 christos case R_X86_64_GOTTPOFF: 2700 1.10 christos case R_X86_64_CODE_4_GOTTPOFF: 2701 1.3 christos case R_X86_64_CODE_5_GOTTPOFF: 2702 1.1 christos case R_X86_64_CODE_6_GOTTPOFF: 2703 1.1 christos if (!bfd_link_executable (info)) 2704 1.1 christos info->flags |= DF_STATIC_TLS; 2705 1.1 christos /* Fall through */ 2706 1.1 christos 2707 1.3 christos case R_X86_64_GOT32: 2708 1.3 christos case R_X86_64_GOTPCREL: 2709 1.9 christos case R_X86_64_GOTPCRELX: 2710 1.10 christos case R_X86_64_REX_GOTPCRELX: 2711 1.10 christos case R_X86_64_CODE_4_GOTPCRELX: 2712 1.1 christos case R_X86_64_CODE_5_GOTPCRELX: 2713 1.1 christos case R_X86_64_CODE_6_GOTPCRELX: 2714 1.1 christos case R_X86_64_TLSGD: 2715 1.1 christos case R_X86_64_GOT64: 2716 1.1 christos case R_X86_64_GOTPCREL64: 2717 1.9 christos case R_X86_64_GOTPLT64: 2718 1.1 christos case R_X86_64_GOTPC32_TLSDESC: 2719 1.1 christos case R_X86_64_CODE_4_GOTPC32_TLSDESC: 2720 1.1 christos case R_X86_64_TLSDESC_CALL: 2721 1.1 christos /* This symbol requires a global offset table entry. */ 2722 1.1 christos { 2723 1.1 christos int tls_type, old_tls_type; 2724 1.1 christos 2725 1.8 christos switch (r_type) 2726 1.8 christos { 2727 1.8 christos default: 2728 1.8 christos tls_type = GOT_NORMAL; 2729 1.8 christos if (h) 2730 1.8 christos { 2731 1.8 christos if (ABS_SYMBOL_P (h)) 2732 1.8 christos tls_type = GOT_ABS; 2733 1.8 christos } 2734 1.8 christos else if (isym->st_shndx == SHN_ABS) 2735 1.8 christos tls_type = GOT_ABS; 2736 1.8 christos break; 2737 1.8 christos case R_X86_64_TLSGD: 2738 1.8 christos tls_type = GOT_TLS_GD; 2739 1.9 christos break; 2740 1.10 christos case R_X86_64_GOTTPOFF: 2741 1.10 christos case R_X86_64_CODE_4_GOTTPOFF: 2742 1.8 christos case R_X86_64_CODE_5_GOTTPOFF: 2743 1.8 christos case R_X86_64_CODE_6_GOTTPOFF: 2744 1.1 christos tls_type = GOT_TLS_IE; 2745 1.9 christos break; 2746 1.1 christos case R_X86_64_GOTPC32_TLSDESC: 2747 1.8 christos case R_X86_64_CODE_4_GOTPC32_TLSDESC: 2748 1.8 christos case R_X86_64_TLSDESC_CALL: 2749 1.1 christos tls_type = GOT_TLS_GDESC; 2750 1.1 christos break; 2751 1.1 christos } 2752 1.1 christos 2753 1.6 christos if (h != NULL) 2754 1.5 christos { 2755 1.1 christos h->got.refcount = 1; 2756 1.1 christos old_tls_type = eh->tls_type; 2757 1.1 christos } 2758 1.1 christos else 2759 1.1 christos { 2760 1.8 christos bfd_signed_vma *local_got_refcounts; 2761 1.8 christos 2762 1.10 christos if (!elf_x86_allocate_local_got_info (abfd, 2763 1.8 christos symtab_hdr->sh_info)) 2764 1.1 christos goto error_return; 2765 1.1 christos 2766 1.6 christos /* This is a global offset table entry for a local symbol. */ 2767 1.1 christos local_got_refcounts = elf_local_got_refcounts (abfd); 2768 1.6 christos local_got_refcounts[r_symndx] = 1; 2769 1.1 christos old_tls_type 2770 1.1 christos = elf_x86_local_got_tls_type (abfd) [r_symndx]; 2771 1.1 christos } 2772 1.1 christos 2773 1.1 christos /* If a TLS symbol is accessed using IE at least once, 2774 1.1 christos there is no point to use dynamic model for it. */ 2775 1.1 christos if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN 2776 1.1 christos && (! GOT_TLS_GD_ANY_P (old_tls_type) 2777 1.1 christos || tls_type != GOT_TLS_IE)) 2778 1.1 christos { 2779 1.1 christos if (old_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (tls_type)) 2780 1.1 christos tls_type = old_tls_type; 2781 1.1 christos else if (GOT_TLS_GD_ANY_P (old_tls_type) 2782 1.1 christos && GOT_TLS_GD_ANY_P (tls_type)) 2783 1.1 christos tls_type |= old_tls_type; 2784 1.1 christos else 2785 1.1 christos { 2786 1.1 christos if (h) 2787 1.1 christos name = h->root.root.string; 2788 1.1 christos else 2789 1.6 christos name = bfd_elf_sym_name (abfd, symtab_hdr, 2790 1.6 christos isym, NULL); 2791 1.6 christos _bfd_error_handler 2792 1.6 christos /* xgettext:c-format */ 2793 1.1 christos (_("%pB: '%s' accessed both as normal and" 2794 1.3 christos " thread local symbol"), 2795 1.5 christos abfd, name); 2796 1.1 christos bfd_set_error (bfd_error_bad_value); 2797 1.1 christos goto error_return; 2798 1.1 christos } 2799 1.1 christos } 2800 1.1 christos 2801 1.5 christos if (old_tls_type != tls_type) 2802 1.5 christos { 2803 1.1 christos if (eh != NULL) 2804 1.6 christos eh->tls_type = tls_type; 2805 1.1 christos else 2806 1.1 christos elf_x86_local_got_tls_type (abfd) [r_symndx] = tls_type; 2807 1.1 christos } 2808 1.1 christos } 2809 1.1 christos /* Fall through */ 2810 1.1 christos 2811 1.1 christos case R_X86_64_GOTOFF64: 2812 1.1 christos case R_X86_64_GOTPC32: 2813 1.5 christos case R_X86_64_GOTPC64: 2814 1.6 christos create_got: 2815 1.1 christos if (eh != NULL) 2816 1.1 christos eh->zero_undefweak &= 0x2; 2817 1.1 christos break; 2818 1.1 christos 2819 1.1 christos case R_X86_64_PLT32: 2820 1.1 christos /* This symbol requires a procedure linkage table entry. We 2821 1.1 christos actually build the entry in adjust_dynamic_symbol, 2822 1.1 christos because this might be a case of linking PIC code which is 2823 1.1 christos never referenced by a dynamic object, in which case we 2824 1.1 christos don't need to generate a procedure linkage table entry 2825 1.1 christos after all. */ 2826 1.1 christos 2827 1.1 christos /* If this is a local symbol, we resolve it directly without 2828 1.1 christos creating a procedure linkage table entry. */ 2829 1.1 christos if (h == NULL) 2830 1.6 christos continue; 2831 1.1 christos 2832 1.6 christos eh->zero_undefweak &= 0x2; 2833 1.1 christos h->needs_plt = 1; 2834 1.1 christos h->plt.refcount = 1; 2835 1.1 christos break; 2836 1.1 christos 2837 1.1 christos case R_X86_64_PLTOFF64: 2838 1.1 christos /* This tries to form the 'address' of a function relative 2839 1.1 christos to GOT. For global symbols we need a PLT entry. */ 2840 1.1 christos if (h != NULL) 2841 1.6 christos { 2842 1.1 christos h->needs_plt = 1; 2843 1.1 christos h->plt.refcount = 1; 2844 1.1 christos } 2845 1.3 christos goto create_got; 2846 1.3 christos 2847 1.8 christos case R_X86_64_SIZE32: 2848 1.3 christos case R_X86_64_SIZE64: 2849 1.3 christos size_reloc = true; 2850 1.1 christos goto do_size; 2851 1.1 christos 2852 1.1 christos case R_X86_64_32: 2853 1.6 christos if (!ABI_64_P (abfd)) 2854 1.1 christos goto pointer; 2855 1.1 christos /* Fall through. */ 2856 1.1 christos case R_X86_64_8: 2857 1.5 christos case R_X86_64_16: 2858 1.5 christos case R_X86_64_32S: 2859 1.1 christos /* Check relocation overflow as these relocs may lead to 2860 1.5 christos run-time relocation overflow. Don't error out for 2861 1.7 christos sections we don't care about, such as debug sections or 2862 1.6 christos when relocation overflow check is disabled. */ 2863 1.5 christos if (!htab->params->no_reloc_overflow_check 2864 1.5 christos && !converted_reloc 2865 1.5 christos && (bfd_link_pic (info) 2866 1.5 christos || (bfd_link_executable (info) 2867 1.5 christos && h != NULL 2868 1.5 christos && !h->def_regular 2869 1.10 christos && h->def_dynamic 2870 1.10 christos && (sec->flags & SEC_READONLY) == 0))) 2871 1.10 christos { 2872 1.10 christos elf_x86_64_need_pic (info, abfd, sec, h, symtab_hdr, isym, 2873 1.10 christos &x86_64_elf_howto_table[r_type]); 2874 1.1 christos goto error_return; 2875 1.1 christos } 2876 1.1 christos /* Fall through. */ 2877 1.1 christos 2878 1.1 christos case R_X86_64_PC8: 2879 1.1 christos case R_X86_64_PC16: 2880 1.1 christos case R_X86_64_PC32: 2881 1.8 christos case R_X86_64_PC64: 2882 1.5 christos case R_X86_64_64: 2883 1.6 christos pointer: 2884 1.5 christos if (eh != NULL && (sec->flags & SEC_CODE) != 0) 2885 1.5 christos eh->zero_undefweak |= 0x2; 2886 1.5 christos /* We are called after all symbols have been resolved. Only 2887 1.5 christos relocation against STT_GNU_IFUNC symbol must go through 2888 1.5 christos PLT. */ 2889 1.5 christos if (h != NULL 2890 1.1 christos && (bfd_link_executable (info) 2891 1.8 christos || h->type == STT_GNU_IFUNC)) 2892 1.5 christos { 2893 1.3 christos bool func_pointer_ref = false; 2894 1.3 christos 2895 1.3 christos if (r_type == R_X86_64_PC32) 2896 1.3 christos { 2897 1.3 christos /* Since something like ".long foo - ." may be used 2898 1.3 christos as pointer, make sure that PLT is used if foo is 2899 1.6 christos a function defined in a shared library. */ 2900 1.6 christos if ((sec->flags & SEC_CODE) == 0) 2901 1.6 christos { 2902 1.6 christos h->pointer_equality_needed = 1; 2903 1.6 christos if (bfd_link_pie (info) 2904 1.6 christos && h->type == STT_FUNC 2905 1.6 christos && !h->def_regular 2906 1.6 christos && h->def_dynamic) 2907 1.6 christos { 2908 1.6 christos h->needs_plt = 1; 2909 1.6 christos h->plt.refcount = 1; 2910 1.3 christos } 2911 1.9 christos } 2912 1.3 christos } 2913 1.3 christos else if (r_type != R_X86_64_PC64) 2914 1.3 christos { 2915 1.8 christos /* At run-time, R_X86_64_64 can be resolved for both 2916 1.8 christos x86-64 and x32. But R_X86_64_32 and R_X86_64_32S 2917 1.3 christos can only be resolved for x32. Function pointer 2918 1.3 christos reference doesn't need PLT for pointer equality. */ 2919 1.3 christos if ((sec->flags & SEC_READONLY) == 0 2920 1.3 christos && (r_type == R_X86_64_64 2921 1.3 christos || (!ABI_64_P (abfd) 2922 1.8 christos && (r_type == R_X86_64_32 2923 1.8 christos || r_type == R_X86_64_32S)))) 2924 1.8 christos func_pointer_ref = true; 2925 1.8 christos 2926 1.8 christos /* IFUNC symbol needs pointer equality in PDE so that 2927 1.8 christos function pointer reference will be resolved to its 2928 1.8 christos PLT entry directly. */ 2929 1.8 christos if (!func_pointer_ref 2930 1.8 christos || (bfd_link_pde (info) 2931 1.6 christos && h->type == STT_GNU_IFUNC)) 2932 1.6 christos h->pointer_equality_needed = 1; 2933 1.6 christos } 2934 1.6 christos 2935 1.6 christos if (!func_pointer_ref) 2936 1.6 christos { 2937 1.6 christos /* If this reloc is in a read-only section, we might 2938 1.6 christos need a copy reloc. We can't check reliably at this 2939 1.6 christos stage whether the section is read-only, as input 2940 1.6 christos sections have not yet been mapped to output sections. 2941 1.6 christos Tentatively set the flag for now, and correct in 2942 1.6 christos adjust_dynamic_symbol. */ 2943 1.8 christos h->non_got_ref = 1; 2944 1.8 christos 2945 1.8 christos if (!elf_has_indirect_extern_access (sec->owner)) 2946 1.6 christos eh->non_got_ref_without_indirect_extern_access = 1; 2947 1.6 christos 2948 1.6 christos /* We may need a .plt entry if the symbol is a function 2949 1.6 christos defined in a shared lib or is a function referenced 2950 1.6 christos from the code or read-only section. */ 2951 1.6 christos if (!h->def_regular 2952 1.8 christos || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0) 2953 1.9 christos h->plt.refcount = 1; 2954 1.9 christos 2955 1.8 christos if (htab->elf.target_os != is_solaris 2956 1.8 christos && h->pointer_equality_needed 2957 1.8 christos && h->type == STT_FUNC 2958 1.8 christos && eh->def_protected 2959 1.8 christos && !SYMBOL_DEFINED_NON_SHARED_P (h) 2960 1.8 christos && h->def_dynamic) 2961 1.8 christos { 2962 1.8 christos /* Disallow non-canonical reference to canonical 2963 1.8 christos protected function. */ 2964 1.8 christos _bfd_error_handler 2965 1.8 christos /* xgettext:c-format */ 2966 1.8 christos (_("%pB: non-canonical reference to canonical " 2967 1.8 christos "protected function `%s' in %pB"), 2968 1.8 christos abfd, h->root.root.string, 2969 1.8 christos h->root.u.def.section->owner); 2970 1.8 christos bfd_set_error (bfd_error_bad_value); 2971 1.3 christos goto error_return; 2972 1.1 christos } 2973 1.1 christos } 2974 1.8 christos } 2975 1.8 christos 2976 1.8 christos size_reloc = false; 2977 1.8 christos do_size: 2978 1.8 christos if (!no_dynreloc 2979 1.8 christos && NEED_DYNAMIC_RELOCATION_P (true, info, true, h, sec, 2980 1.1 christos r_type, 2981 1.1 christos htab->pointer_r_type)) 2982 1.1 christos { 2983 1.1 christos struct elf_dyn_relocs *p; 2984 1.1 christos struct elf_dyn_relocs **head; 2985 1.1 christos 2986 1.1 christos /* If this is a global symbol, we count the number of 2987 1.8 christos relocations we need for this symbol. */ 2988 1.1 christos if (h != NULL) 2989 1.1 christos head = &h->dyn_relocs; 2990 1.1 christos else 2991 1.1 christos { 2992 1.1 christos /* Track dynamic relocs needed for local syms too. 2993 1.1 christos We really need local syms available to do this 2994 1.1 christos easily. Oh well. */ 2995 1.1 christos asection *s; 2996 1.8 christos void **vpp; 2997 1.1 christos 2998 1.1 christos isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, 2999 1.5 christos abfd, r_symndx); 3000 1.1 christos if (isym == NULL) 3001 1.1 christos goto error_return; 3002 1.1 christos 3003 1.1 christos s = bfd_section_from_elf_index (abfd, isym->st_shndx); 3004 1.1 christos if (s == NULL) 3005 1.1 christos s = sec; 3006 1.1 christos 3007 1.1 christos /* Beware of type punned pointers vs strict aliasing 3008 1.1 christos rules. */ 3009 1.1 christos vpp = &(elf_section_data (s)->local_dynrel); 3010 1.1 christos head = (struct elf_dyn_relocs **)vpp; 3011 1.1 christos } 3012 1.1 christos 3013 1.1 christos p = *head; 3014 1.8 christos if (p == NULL || p->sec != sec) 3015 1.1 christos { 3016 1.1 christos size_t amt = sizeof *p; 3017 1.1 christos 3018 1.1 christos p = ((struct elf_dyn_relocs *) 3019 1.5 christos bfd_alloc (htab->elf.dynobj, amt)); 3020 1.1 christos if (p == NULL) 3021 1.1 christos goto error_return; 3022 1.1 christos p->next = *head; 3023 1.1 christos *head = p; 3024 1.1 christos p->sec = sec; 3025 1.1 christos p->count = 0; 3026 1.1 christos p->pc_count = 0; 3027 1.1 christos } 3028 1.3 christos 3029 1.8 christos p->count += 1; 3030 1.1 christos /* Count size relocation as PC-relative relocation. */ 3031 1.1 christos if (X86_PCREL_TYPE_P (true, r_type) || size_reloc) 3032 1.1 christos p->pc_count += 1; 3033 1.1 christos } 3034 1.10 christos break; 3035 1.10 christos 3036 1.10 christos case R_X86_64_CODE_5_GOTPC32_TLSDESC: 3037 1.10 christos case R_X86_64_CODE_6_GOTPC32_TLSDESC: 3038 1.10 christos { 3039 1.10 christos /* These relocations are added only for completeness and 3040 1.10 christos aren't be used. */ 3041 1.10 christos if (h) 3042 1.10 christos name = h->root.root.string; 3043 1.10 christos else 3044 1.10 christos name = bfd_elf_sym_name (abfd, symtab_hdr, isym, 3045 1.10 christos NULL); 3046 1.10 christos _bfd_error_handler 3047 1.10 christos /* xgettext:c-format */ 3048 1.10 christos (_("%pB: unsupported relocation %s against symbol `%s'"), 3049 1.10 christos abfd, x86_64_elf_howto_table[r_type].name, name); 3050 1.10 christos } 3051 1.1 christos break; 3052 1.1 christos 3053 1.1 christos /* This relocation describes the C++ object vtable hierarchy. 3054 1.1 christos Reconstruct it for later use during GC. */ 3055 1.5 christos case R_X86_64_GNU_VTINHERIT: 3056 1.1 christos if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) 3057 1.1 christos goto error_return; 3058 1.1 christos break; 3059 1.1 christos 3060 1.1 christos /* This relocation describes which C++ vtable entries are actually 3061 1.7 christos used. Record for later use during GC. */ 3062 1.5 christos case R_X86_64_GNU_VTENTRY: 3063 1.1 christos if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) 3064 1.1 christos goto error_return; 3065 1.1 christos break; 3066 1.1 christos 3067 1.1 christos default: 3068 1.1 christos break; 3069 1.1 christos } 3070 1.5 christos } 3071 1.5 christos 3072 1.10 christos if (elf_section_data (sec)->this_hdr.contents != contents) 3073 1.10 christos { 3074 1.5 christos if (!converted) 3075 1.5 christos _bfd_elf_munmap_section_contents (sec, contents); 3076 1.6 christos else 3077 1.6 christos { 3078 1.5 christos /* Cache the section contents for elf_link_input_bfd if any 3079 1.8 christos load is converted or --no-keep-memory isn't used. */ 3080 1.5 christos elf_section_data (sec)->this_hdr.contents = contents; 3081 1.5 christos info->cache_size += sec->size; 3082 1.5 christos } 3083 1.6 christos } 3084 1.6 christos 3085 1.6 christos /* Cache relocations if any load is converted. */ 3086 1.6 christos if (elf_section_data (sec)->relocs != relocs && converted) 3087 1.8 christos elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs; 3088 1.5 christos 3089 1.8 christos return true; 3090 1.5 christos 3091 1.10 christos error_return: 3092 1.5 christos if (elf_section_data (sec)->this_hdr.contents != contents) 3093 1.8 christos _bfd_elf_munmap_section_contents (sec, contents); 3094 1.8 christos sec->check_relocs_failed = 1; 3095 1.8 christos return false; 3096 1.8 christos } 3097 1.10 christos 3098 1.8 christos static bool 3099 1.8 christos elf_x86_64_early_size_sections (bfd *output_bfd, struct bfd_link_info *info) 3100 1.8 christos { 3101 1.8 christos bfd *abfd; 3102 1.8 christos 3103 1.8 christos /* Scan relocations after rel_from_abs has been set on __ehdr_start. */ 3104 1.8 christos for (abfd = info->input_bfds; 3105 1.8 christos abfd != (bfd *) NULL; 3106 1.8 christos abfd = abfd->link.next) 3107 1.8 christos if (bfd_get_flavour (abfd) == bfd_target_elf_flavour 3108 1.8 christos && !_bfd_elf_link_iterate_on_relocs (abfd, info, 3109 1.8 christos elf_x86_64_scan_relocs)) 3110 1.10 christos return false; 3111 1.1 christos 3112 1.1 christos return _bfd_x86_elf_early_size_sections (output_bfd, info); 3113 1.6 christos } 3114 1.6 christos 3115 1.1 christos /* Return the relocation value for @tpoff relocation 3116 1.6 christos if STT_TLS virtual address is ADDRESS. */ 3117 1.6 christos 3118 1.6 christos static bfd_vma 3119 1.6 christos elf_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address) 3120 1.1 christos { 3121 1.1 christos struct elf_link_hash_table *htab = elf_hash_table (info); 3122 1.1 christos const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd); 3123 1.1 christos bfd_vma static_tls_size; 3124 1.1 christos 3125 1.1 christos /* If tls_segment is NULL, we should have signalled an error already. */ 3126 1.1 christos if (htab->tls_sec == NULL) 3127 1.1 christos return 0; 3128 1.1 christos 3129 1.1 christos /* Consider special static TLS alignment requirements. */ 3130 1.1 christos static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment); 3131 1.1 christos return address - static_tls_size - htab->tls_sec->vma; 3132 1.1 christos } 3133 1.1 christos 3134 1.8 christos /* Relocate an x86_64 ELF section. */ 3135 1.1 christos 3136 1.1 christos static int 3137 1.1 christos elf_x86_64_relocate_section (bfd *output_bfd, 3138 1.1 christos struct bfd_link_info *info, 3139 1.1 christos bfd *input_bfd, 3140 1.1 christos asection *input_section, 3141 1.1 christos bfd_byte *contents, 3142 1.1 christos Elf_Internal_Rela *relocs, 3143 1.1 christos Elf_Internal_Sym *local_syms, 3144 1.6 christos asection **local_sections) 3145 1.1 christos { 3146 1.1 christos struct elf_x86_link_hash_table *htab; 3147 1.1 christos Elf_Internal_Shdr *symtab_hdr; 3148 1.1 christos struct elf_link_hash_entry **sym_hashes; 3149 1.1 christos bfd_vma *local_got_offsets; 3150 1.3 christos bfd_vma *local_tlsdesc_gotents; 3151 1.1 christos Elf_Internal_Rela *rel; 3152 1.6 christos Elf_Internal_Rela *wrel; 3153 1.8 christos Elf_Internal_Rela *relend; 3154 1.1 christos unsigned int plt_entry_size; 3155 1.8 christos bool status; 3156 1.5 christos 3157 1.8 christos /* Skip if check_relocs or scan_relocs failed. */ 3158 1.5 christos if (input_section->check_relocs_failed) 3159 1.6 christos return false; 3160 1.1 christos 3161 1.8 christos htab = elf_x86_hash_table (info, X86_64_ELF_DATA); 3162 1.6 christos if (htab == NULL) 3163 1.7 christos return false; 3164 1.7 christos 3165 1.7 christos if (!is_x86_elf (input_bfd, htab)) 3166 1.8 christos { 3167 1.7 christos bfd_set_error (bfd_error_wrong_format); 3168 1.6 christos return false; 3169 1.6 christos } 3170 1.1 christos 3171 1.1 christos plt_entry_size = htab->plt.plt_entry_size; 3172 1.1 christos symtab_hdr = &elf_symtab_hdr (input_bfd); 3173 1.6 christos sym_hashes = elf_sym_hashes (input_bfd); 3174 1.1 christos local_got_offsets = elf_local_got_offsets (input_bfd); 3175 1.6 christos local_tlsdesc_gotents = elf_x86_local_tlsdesc_gotent (input_bfd); 3176 1.1 christos 3177 1.8 christos _bfd_x86_elf_set_tls_module_base (info); 3178 1.3 christos 3179 1.1 christos status = true; 3180 1.3 christos rel = wrel = relocs; 3181 1.1 christos relend = relocs + input_section->reloc_count; 3182 1.6 christos for (; rel < relend; wrel++, rel++) 3183 1.1 christos { 3184 1.1 christos unsigned int r_type, r_type_tls; 3185 1.1 christos reloc_howto_type *howto; 3186 1.6 christos unsigned long r_symndx; 3187 1.1 christos struct elf_link_hash_entry *h; 3188 1.1 christos struct elf_x86_link_hash_entry *eh; 3189 1.3 christos Elf_Internal_Sym *sym; 3190 1.1 christos asection *sec; 3191 1.8 christos bfd_vma off, offplt, plt_offset; 3192 1.1 christos bfd_vma relocation; 3193 1.1 christos bool unresolved_reloc; 3194 1.3 christos bfd_reloc_status_type r; 3195 1.3 christos int tls_type; 3196 1.8 christos asection *base_got, *resolved_plt; 3197 1.8 christos bfd_vma st_size; 3198 1.8 christos bool resolved_to_zero; 3199 1.8 christos bool relative_reloc; 3200 1.8 christos bool converted_reloc; 3201 1.1 christos bool need_copy_reloc_in_pie; 3202 1.1 christos bool no_copyreloc_p; 3203 1.1 christos 3204 1.1 christos r_type = ELF32_R_TYPE (rel->r_info); 3205 1.3 christos if (r_type == (int) R_X86_64_GNU_VTINHERIT 3206 1.3 christos || r_type == (int) R_X86_64_GNU_VTENTRY) 3207 1.3 christos { 3208 1.3 christos if (wrel != rel) 3209 1.3 christos *wrel = *rel; 3210 1.1 christos continue; 3211 1.6 christos } 3212 1.6 christos 3213 1.6 christos r_symndx = htab->r_sym (rel->r_info); 3214 1.1 christos converted_reloc = (r_type & R_X86_64_converted_reloc_bit) != 0; 3215 1.6 christos if (converted_reloc) 3216 1.6 christos { 3217 1.1 christos r_type &= ~R_X86_64_converted_reloc_bit; 3218 1.1 christos rel->r_info = htab->r_info (r_symndx, r_type); 3219 1.7 christos } 3220 1.7 christos 3221 1.6 christos howto = elf_x86_64_rtype_to_howto (input_bfd, r_type); 3222 1.6 christos if (howto == NULL) 3223 1.1 christos return _bfd_unrecognized_reloc (input_bfd, input_section, r_type); 3224 1.1 christos 3225 1.1 christos h = NULL; 3226 1.8 christos sym = NULL; 3227 1.1 christos sec = NULL; 3228 1.1 christos unresolved_reloc = false; 3229 1.1 christos if (r_symndx < symtab_hdr->sh_info) 3230 1.1 christos { 3231 1.1 christos sym = local_syms + r_symndx; 3232 1.1 christos sec = local_sections[r_symndx]; 3233 1.1 christos 3234 1.3 christos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, 3235 1.1 christos &sec, rel); 3236 1.1 christos st_size = sym->st_size; 3237 1.3 christos 3238 1.1 christos /* Relocate against local STT_GNU_IFUNC symbol. */ 3239 1.1 christos if (!bfd_link_relocatable (info) 3240 1.6 christos && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC) 3241 1.8 christos { 3242 1.1 christos h = _bfd_elf_x86_get_local_sym_hash (htab, input_bfd, 3243 1.1 christos rel, false); 3244 1.1 christos if (h == NULL) 3245 1.1 christos abort (); 3246 1.1 christos 3247 1.1 christos /* Set STT_GNU_IFUNC symbol value. */ 3248 1.1 christos h->root.u.def.value = sym->st_value; 3249 1.1 christos h->root.u.def.section = sec; 3250 1.1 christos } 3251 1.1 christos } 3252 1.8 christos else 3253 1.8 christos { 3254 1.1 christos bool warned ATTRIBUTE_UNUSED; 3255 1.1 christos bool ignored ATTRIBUTE_UNUSED; 3256 1.1 christos 3257 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 3258 1.3 christos r_symndx, symtab_hdr, sym_hashes, 3259 1.3 christos h, sec, relocation, 3260 1.1 christos unresolved_reloc, warned, ignored); 3261 1.1 christos st_size = h->size; 3262 1.1 christos } 3263 1.3 christos 3264 1.3 christos if (sec != NULL && discarded_section (sec)) 3265 1.7 christos { 3266 1.3 christos _bfd_clear_contents (howto, input_bfd, input_section, 3267 1.3 christos contents, rel->r_offset); 3268 1.3 christos wrel->r_offset = rel->r_offset; 3269 1.3 christos wrel->r_info = 0; 3270 1.3 christos wrel->r_addend = 0; 3271 1.10 christos 3272 1.10 christos /* For ld -r, remove relocations in debug sections against 3273 1.10 christos sections defined in discarded sections, including sframe 3274 1.10 christos sections. Not done for eh_frame editing code expects to 3275 1.10 christos be present. NB: Since sframe code keeps R_X86_64_NONE 3276 1.3 christos reloc as is, its r_offset is wrong, we must not generate 3277 1.10 christos R_X86_64_NONE reloc in sframe section. */ 3278 1.10 christos if (bfd_link_relocatable (info) 3279 1.3 christos && ((input_section->flags & SEC_DEBUGGING) != 0 3280 1.1 christos || elf_section_type (input_section) == SHT_GNU_SFRAME)) 3281 1.3 christos wrel--; 3282 1.3 christos 3283 1.3 christos continue; 3284 1.3 christos } 3285 1.3 christos 3286 1.3 christos if (bfd_link_relocatable (info)) 3287 1.3 christos { 3288 1.3 christos if (wrel != rel) 3289 1.3 christos *wrel = *rel; 3290 1.1 christos continue; 3291 1.3 christos } 3292 1.3 christos 3293 1.3 christos if (rel->r_addend == 0 && !ABI_64_P (output_bfd)) 3294 1.3 christos { 3295 1.3 christos if (r_type == R_X86_64_64) 3296 1.3 christos { 3297 1.3 christos /* For x32, treat R_X86_64_64 like R_X86_64_32 and 3298 1.3 christos zero-extend it to 64bit if addend is zero. */ 3299 1.3 christos r_type = R_X86_64_32; 3300 1.3 christos memset (contents + rel->r_offset + 4, 0, 4); 3301 1.3 christos } 3302 1.3 christos else if (r_type == R_X86_64_SIZE64) 3303 1.3 christos { 3304 1.3 christos /* For x32, treat R_X86_64_SIZE64 like R_X86_64_SIZE32 and 3305 1.3 christos zero-extend it to 64bit if addend is zero. */ 3306 1.3 christos r_type = R_X86_64_SIZE32; 3307 1.1 christos memset (contents + rel->r_offset + 4, 0, 4); 3308 1.1 christos } 3309 1.6 christos } 3310 1.3 christos 3311 1.1 christos eh = (struct elf_x86_link_hash_entry *) h; 3312 1.1 christos 3313 1.1 christos /* Since STT_GNU_IFUNC symbol must go through PLT, we handle 3314 1.1 christos it here if it is defined in a non-shared object. */ 3315 1.1 christos if (h != NULL 3316 1.1 christos && h->type == STT_GNU_IFUNC 3317 1.1 christos && h->def_regular) 3318 1.1 christos { 3319 1.1 christos bfd_vma plt_index; 3320 1.3 christos const char *name; 3321 1.3 christos 3322 1.6 christos if ((input_section->flags & SEC_ALLOC) == 0) 3323 1.6 christos { 3324 1.6 christos /* If this is a SHT_NOTE section without SHF_ALLOC, treat 3325 1.6 christos STT_GNU_IFUNC symbol as STT_FUNC. */ 3326 1.3 christos if (elf_section_type (input_section) == SHT_NOTE) 3327 1.3 christos goto skip_ifunc; 3328 1.3 christos /* Dynamic relocs are not propagated for SEC_DEBUGGING 3329 1.3 christos sections because such sections are not SEC_ALLOC and 3330 1.3 christos thus ld.so will not process them. */ 3331 1.3 christos if ((input_section->flags & SEC_DEBUGGING) != 0) 3332 1.3 christos continue; 3333 1.5 christos abort (); 3334 1.5 christos } 3335 1.5 christos 3336 1.5 christos switch (r_type) 3337 1.5 christos { 3338 1.5 christos default: 3339 1.5 christos break; 3340 1.5 christos 3341 1.5 christos case R_X86_64_GOTPCREL: 3342 1.9 christos case R_X86_64_GOTPCRELX: 3343 1.10 christos case R_X86_64_REX_GOTPCRELX: 3344 1.10 christos case R_X86_64_CODE_4_GOTPCRELX: 3345 1.5 christos case R_X86_64_CODE_5_GOTPCRELX: 3346 1.5 christos case R_X86_64_CODE_6_GOTPCRELX: 3347 1.5 christos case R_X86_64_GOTPCREL64: 3348 1.5 christos base_got = htab->elf.sgot; 3349 1.5 christos off = h->got.offset; 3350 1.5 christos 3351 1.5 christos if (base_got == NULL) 3352 1.5 christos abort (); 3353 1.5 christos 3354 1.5 christos if (off == (bfd_vma) -1) 3355 1.5 christos { 3356 1.5 christos /* We can't use h->got.offset here to save state, or 3357 1.5 christos even just remember the offset, as finish_dynamic_symbol 3358 1.5 christos would use that as offset into .got. */ 3359 1.5 christos 3360 1.5 christos if (h->plt.offset == (bfd_vma) -1) 3361 1.5 christos abort (); 3362 1.5 christos 3363 1.6 christos if (htab->elf.splt != NULL) 3364 1.6 christos { 3365 1.5 christos plt_index = (h->plt.offset / plt_entry_size 3366 1.5 christos - htab->plt.has_plt0); 3367 1.5 christos off = (plt_index + 3) * GOT_ENTRY_SIZE; 3368 1.5 christos base_got = htab->elf.sgotplt; 3369 1.5 christos } 3370 1.5 christos else 3371 1.5 christos { 3372 1.5 christos plt_index = h->plt.offset / plt_entry_size; 3373 1.5 christos off = plt_index * GOT_ENTRY_SIZE; 3374 1.5 christos base_got = htab->elf.igotplt; 3375 1.5 christos } 3376 1.5 christos 3377 1.5 christos if (h->dynindx == -1 3378 1.5 christos || h->forced_local 3379 1.5 christos || info->symbolic) 3380 1.5 christos { 3381 1.5 christos /* This references the local defitionion. We must 3382 1.5 christos initialize this entry in the global offset table. 3383 1.5 christos Since the offset must always be a multiple of 8, 3384 1.5 christos we use the least significant bit to record 3385 1.5 christos whether we have initialized it already. 3386 1.5 christos 3387 1.5 christos When doing a dynamic link, we create a .rela.got 3388 1.5 christos relocation entry to initialize the value. This 3389 1.5 christos is done in the finish_dynamic_symbol routine. */ 3390 1.5 christos if ((off & 1) != 0) 3391 1.5 christos off &= ~1; 3392 1.5 christos else 3393 1.5 christos { 3394 1.5 christos bfd_put_64 (output_bfd, relocation, 3395 1.5 christos base_got->contents + off); 3396 1.5 christos /* Note that this is harmless for the GOTPLT64 3397 1.5 christos case, as -1 | 1 still is -1. */ 3398 1.5 christos h->got.offset |= 1; 3399 1.5 christos } 3400 1.5 christos } 3401 1.5 christos } 3402 1.5 christos 3403 1.5 christos relocation = (base_got->output_section->vma 3404 1.5 christos + base_got->output_offset + off); 3405 1.5 christos 3406 1.5 christos goto do_relocation; 3407 1.5 christos } 3408 1.5 christos 3409 1.5 christos if (h->plt.offset == (bfd_vma) -1) 3410 1.5 christos { 3411 1.5 christos /* Handle static pointers of STT_GNU_IFUNC symbols. */ 3412 1.5 christos if (r_type == htab->pointer_r_type 3413 1.5 christos && (input_section->flags & SEC_CODE) == 0) 3414 1.5 christos goto do_ifunc_pointer; 3415 1.1 christos goto bad_ifunc_reloc; 3416 1.1 christos } 3417 1.3 christos 3418 1.3 christos /* STT_GNU_IFUNC symbol must go through PLT. */ 3419 1.6 christos if (htab->elf.splt != NULL) 3420 1.3 christos { 3421 1.6 christos if (htab->plt_second != NULL) 3422 1.6 christos { 3423 1.3 christos resolved_plt = htab->plt_second; 3424 1.3 christos plt_offset = eh->plt_second.offset; 3425 1.3 christos } 3426 1.3 christos else 3427 1.3 christos { 3428 1.3 christos resolved_plt = htab->elf.splt; 3429 1.3 christos plt_offset = h->plt.offset; 3430 1.3 christos } 3431 1.3 christos } 3432 1.3 christos else 3433 1.3 christos { 3434 1.3 christos resolved_plt = htab->elf.iplt; 3435 1.3 christos plt_offset = h->plt.offset; 3436 1.3 christos } 3437 1.3 christos 3438 1.1 christos relocation = (resolved_plt->output_section->vma 3439 1.1 christos + resolved_plt->output_offset + plt_offset); 3440 1.1 christos 3441 1.1 christos switch (r_type) 3442 1.8 christos { 3443 1.1 christos default: 3444 1.1 christos bad_ifunc_reloc: 3445 1.1 christos if (h->root.root.string) 3446 1.1 christos name = h->root.root.string; 3447 1.1 christos else 3448 1.6 christos name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym, 3449 1.6 christos NULL); 3450 1.6 christos _bfd_error_handler 3451 1.5 christos /* xgettext:c-format */ 3452 1.5 christos (_("%pB: relocation %s against STT_GNU_IFUNC " 3453 1.1 christos "symbol `%s' isn't supported"), input_bfd, 3454 1.8 christos howto->name, name); 3455 1.1 christos bfd_set_error (bfd_error_bad_value); 3456 1.1 christos return false; 3457 1.3 christos 3458 1.1 christos case R_X86_64_32S: 3459 1.1 christos if (bfd_link_pic (info)) 3460 1.1 christos abort (); 3461 1.1 christos goto do_relocation; 3462 1.1 christos 3463 1.1 christos case R_X86_64_32: 3464 1.1 christos if (ABI_64_P (output_bfd)) 3465 1.1 christos goto do_relocation; 3466 1.8 christos /* FALLTHROUGH */ 3467 1.1 christos case R_X86_64_64: 3468 1.1 christos do_ifunc_pointer: 3469 1.1 christos if (rel->r_addend != 0) 3470 1.1 christos { 3471 1.1 christos if (h->root.root.string) 3472 1.1 christos name = h->root.root.string; 3473 1.1 christos else 3474 1.6 christos name = bfd_elf_sym_name (input_bfd, symtab_hdr, 3475 1.6 christos sym, NULL); 3476 1.6 christos _bfd_error_handler 3477 1.6 christos /* xgettext:c-format */ 3478 1.6 christos (_("%pB: relocation %s against STT_GNU_IFUNC " 3479 1.1 christos "symbol `%s' has non-zero addend: %" PRId64), 3480 1.8 christos input_bfd, howto->name, name, (int64_t) rel->r_addend); 3481 1.1 christos bfd_set_error (bfd_error_bad_value); 3482 1.1 christos return false; 3483 1.1 christos } 3484 1.5 christos 3485 1.5 christos /* Generate dynamic relcoation only when there is a 3486 1.5 christos non-GOT reference in a shared object or there is no 3487 1.5 christos PLT. */ 3488 1.1 christos if ((bfd_link_pic (info) && h->non_got_ref) 3489 1.1 christos || h->plt.offset == (bfd_vma) -1) 3490 1.1 christos { 3491 1.1 christos Elf_Internal_Rela outrel; 3492 1.1 christos asection *sreloc; 3493 1.1 christos 3494 1.1 christos /* Need a dynamic relocation to get the real function 3495 1.1 christos address. */ 3496 1.1 christos outrel.r_offset = _bfd_elf_section_offset (output_bfd, 3497 1.1 christos info, 3498 1.1 christos input_section, 3499 1.1 christos rel->r_offset); 3500 1.1 christos if (outrel.r_offset == (bfd_vma) -1 3501 1.1 christos || outrel.r_offset == (bfd_vma) -2) 3502 1.1 christos abort (); 3503 1.1 christos 3504 1.1 christos outrel.r_offset += (input_section->output_section->vma 3505 1.6 christos + input_section->output_offset); 3506 1.1 christos 3507 1.6 christos if (POINTER_LOCAL_IFUNC_P (info, h)) 3508 1.6 christos { 3509 1.6 christos info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"), 3510 1.6 christos h->root.root.string, 3511 1.1 christos h->root.u.def.section->owner); 3512 1.1 christos 3513 1.1 christos /* This symbol is resolved locally. */ 3514 1.1 christos outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE); 3515 1.1 christos outrel.r_addend = (h->root.u.def.value 3516 1.8 christos + h->root.u.def.section->output_section->vma 3517 1.8 christos + h->root.u.def.section->output_offset); 3518 1.8 christos 3519 1.8 christos if (htab->params->report_relative_reloc) 3520 1.8 christos _bfd_x86_elf_link_report_relative_reloc 3521 1.1 christos (info, input_section, h, sym, 3522 1.1 christos "R_X86_64_IRELATIVE", &outrel); 3523 1.1 christos } 3524 1.1 christos else 3525 1.1 christos { 3526 1.1 christos outrel.r_info = htab->r_info (h->dynindx, r_type); 3527 1.1 christos outrel.r_addend = 0; 3528 1.5 christos } 3529 1.5 christos 3530 1.5 christos /* Dynamic relocations are stored in 3531 1.5 christos 1. .rela.ifunc section in PIC object. 3532 1.5 christos 2. .rela.got section in dynamic executable. 3533 1.5 christos 3. .rela.iplt section in static executable. */ 3534 1.5 christos if (bfd_link_pic (info)) 3535 1.5 christos sreloc = htab->elf.irelifunc; 3536 1.5 christos else if (htab->elf.splt != NULL) 3537 1.5 christos sreloc = htab->elf.srelgot; 3538 1.1 christos else 3539 1.1 christos sreloc = htab->elf.irelplt; 3540 1.1 christos elf_append_rela (output_bfd, sreloc, &outrel); 3541 1.1 christos 3542 1.1 christos /* If this reloc is against an external symbol, we 3543 1.1 christos do not want to fiddle with the addend. Otherwise, 3544 1.1 christos we need to include the symbol value so that it 3545 1.1 christos becomes an addend for the dynamic reloc. For an 3546 1.1 christos internal symbol, we have updated addend. */ 3547 1.1 christos continue; 3548 1.1 christos } 3549 1.1 christos /* FALLTHROUGH */ 3550 1.1 christos case R_X86_64_PC32: 3551 1.1 christos case R_X86_64_PC64: 3552 1.1 christos case R_X86_64_PLT32: 3553 1.1 christos goto do_relocation; 3554 1.1 christos } 3555 1.8 christos } 3556 1.5 christos 3557 1.6 christos skip_ifunc: 3558 1.5 christos resolved_to_zero = (eh != NULL 3559 1.1 christos && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh)); 3560 1.1 christos 3561 1.1 christos /* When generating a shared object, the relocations handled here are 3562 1.1 christos copied into the output file to be resolved at run time. */ 3563 1.1 christos switch (r_type) 3564 1.1 christos { 3565 1.1 christos case R_X86_64_GOT32: 3566 1.1 christos case R_X86_64_GOT64: 3567 1.1 christos /* Relocation is to the entry for this symbol in the global 3568 1.3 christos offset table. */ 3569 1.3 christos case R_X86_64_GOTPCREL: 3570 1.9 christos case R_X86_64_GOTPCRELX: 3571 1.10 christos case R_X86_64_REX_GOTPCRELX: 3572 1.10 christos case R_X86_64_CODE_4_GOTPCRELX: 3573 1.1 christos case R_X86_64_CODE_5_GOTPCRELX: 3574 1.1 christos case R_X86_64_CODE_6_GOTPCRELX: 3575 1.1 christos case R_X86_64_GOTPCREL64: 3576 1.6 christos /* Use global offset table entry as symbol value. */ 3577 1.1 christos case R_X86_64_GOTPLT64: 3578 1.1 christos /* This is obsolete and treated the same as GOT64. */ 3579 1.1 christos base_got = htab->elf.sgot; 3580 1.1 christos 3581 1.1 christos if (htab->elf.sgot == NULL) 3582 1.8 christos abort (); 3583 1.1 christos 3584 1.1 christos relative_reloc = false; 3585 1.1 christos if (h != NULL) 3586 1.1 christos { 3587 1.1 christos off = h->got.offset; 3588 1.1 christos if (h->needs_plt 3589 1.1 christos && h->plt.offset != (bfd_vma)-1 3590 1.1 christos && off == (bfd_vma)-1) 3591 1.1 christos { 3592 1.1 christos /* We can't use h->got.offset here to save 3593 1.1 christos state, or even just remember the offset, as 3594 1.6 christos finish_dynamic_symbol would use that as offset into 3595 1.6 christos .got. */ 3596 1.1 christos bfd_vma plt_index = (h->plt.offset / plt_entry_size 3597 1.1 christos - htab->plt.has_plt0); 3598 1.1 christos off = (plt_index + 3) * GOT_ENTRY_SIZE; 3599 1.1 christos base_got = htab->elf.sgotplt; 3600 1.6 christos } 3601 1.6 christos 3602 1.6 christos if (RESOLVED_LOCALLY_P (info, h, htab)) 3603 1.6 christos { 3604 1.6 christos /* We must initialize this entry in the global offset 3605 1.6 christos table. Since the offset must always be a multiple 3606 1.1 christos of 8, we use the least significant bit to record 3607 1.1 christos whether we have initialized it already. 3608 1.1 christos 3609 1.1 christos When doing a dynamic link, we create a .rela.got 3610 1.1 christos relocation entry to initialize the value. This is 3611 1.1 christos done in the finish_dynamic_symbol routine. */ 3612 1.1 christos if ((off & 1) != 0) 3613 1.1 christos off &= ~1; 3614 1.1 christos else 3615 1.1 christos { 3616 1.1 christos bfd_put_64 (output_bfd, relocation, 3617 1.6 christos base_got->contents + off); 3618 1.6 christos /* Note that this is harmless for the GOTPLT64 case, 3619 1.6 christos as -1 | 1 still is -1. */ 3620 1.8 christos h->got.offset |= 1; 3621 1.8 christos 3622 1.8 christos /* NB: Don't generate relative relocation here if 3623 1.8 christos it has been generated by DT_RELR. */ 3624 1.6 christos if (!info->enable_dt_relr 3625 1.6 christos && GENERATE_RELATIVE_RELOC_P (info, h)) 3626 1.6 christos { 3627 1.6 christos /* If this symbol isn't dynamic in PIC, 3628 1.8 christos generate R_X86_64_RELATIVE here. */ 3629 1.6 christos eh->no_finish_dynamic_symbol = 1; 3630 1.1 christos relative_reloc = true; 3631 1.1 christos } 3632 1.1 christos } 3633 1.8 christos } 3634 1.1 christos else 3635 1.1 christos unresolved_reloc = false; 3636 1.1 christos } 3637 1.1 christos else 3638 1.1 christos { 3639 1.1 christos if (local_got_offsets == NULL) 3640 1.1 christos abort (); 3641 1.1 christos 3642 1.1 christos off = local_got_offsets[r_symndx]; 3643 1.1 christos 3644 1.1 christos /* The offset must always be a multiple of 8. We use 3645 1.1 christos the least significant bit to record whether we have 3646 1.1 christos already generated the necessary reloc. */ 3647 1.1 christos if ((off & 1) != 0) 3648 1.1 christos off &= ~1; 3649 1.1 christos else 3650 1.1 christos { 3651 1.6 christos bfd_put_64 (output_bfd, relocation, 3652 1.1 christos base_got->contents + off); 3653 1.8 christos local_got_offsets[r_symndx] |= 1; 3654 1.8 christos 3655 1.8 christos /* NB: GOTPCREL relocations against local absolute 3656 1.8 christos symbol store relocation value in the GOT slot 3657 1.8 christos without relative relocation. Don't generate 3658 1.8 christos relative relocation here if it has been generated 3659 1.8 christos by DT_RELR. */ 3660 1.8 christos if (!info->enable_dt_relr 3661 1.8 christos && bfd_link_pic (info) 3662 1.8 christos && !(sym->st_shndx == SHN_ABS 3663 1.9 christos && (r_type == R_X86_64_GOTPCREL 3664 1.10 christos || r_type == R_X86_64_GOTPCRELX 3665 1.10 christos || r_type == R_X86_64_REX_GOTPCRELX 3666 1.10 christos || r_type == R_X86_64_CODE_4_GOTPCRELX 3667 1.8 christos || r_type == R_X86_64_CODE_5_GOTPCRELX 3668 1.6 christos || r_type == R_X86_64_CODE_6_GOTPCRELX))) 3669 1.6 christos relative_reloc = true; 3670 1.6 christos } 3671 1.6 christos } 3672 1.6 christos 3673 1.6 christos if (relative_reloc) 3674 1.6 christos { 3675 1.1 christos asection *s; 3676 1.6 christos Elf_Internal_Rela outrel; 3677 1.6 christos 3678 1.6 christos /* We need to generate a R_X86_64_RELATIVE reloc 3679 1.6 christos for the dynamic linker. */ 3680 1.6 christos s = htab->elf.srelgot; 3681 1.1 christos if (s == NULL) 3682 1.6 christos abort (); 3683 1.6 christos 3684 1.6 christos outrel.r_offset = (base_got->output_section->vma 3685 1.6 christos + base_got->output_offset 3686 1.6 christos + off); 3687 1.8 christos outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE); 3688 1.8 christos outrel.r_addend = relocation; 3689 1.8 christos 3690 1.8 christos if (htab->params->report_relative_reloc) 3691 1.8 christos _bfd_x86_elf_link_report_relative_reloc 3692 1.8 christos (info, input_section, h, sym, "R_X86_64_RELATIVE", 3693 1.6 christos &outrel); 3694 1.1 christos 3695 1.1 christos elf_append_rela (output_bfd, s, &outrel); 3696 1.1 christos } 3697 1.1 christos 3698 1.1 christos if (off >= (bfd_vma) -2) 3699 1.1 christos abort (); 3700 1.1 christos 3701 1.3 christos relocation = base_got->output_section->vma 3702 1.3 christos + base_got->output_offset + off; 3703 1.3 christos if (r_type != R_X86_64_GOTPCREL 3704 1.9 christos && r_type != R_X86_64_GOTPCRELX 3705 1.10 christos && r_type != R_X86_64_REX_GOTPCRELX 3706 1.10 christos && r_type != R_X86_64_CODE_4_GOTPCRELX 3707 1.3 christos && r_type != R_X86_64_CODE_5_GOTPCRELX 3708 1.1 christos && r_type != R_X86_64_CODE_6_GOTPCRELX 3709 1.1 christos && r_type != R_X86_64_GOTPCREL64) 3710 1.1 christos relocation -= htab->elf.sgotplt->output_section->vma 3711 1.1 christos - htab->elf.sgotplt->output_offset; 3712 1.1 christos 3713 1.1 christos break; 3714 1.1 christos 3715 1.1 christos case R_X86_64_GOTOFF64: 3716 1.1 christos /* Relocation is relative to the start of the global offset 3717 1.3 christos table. */ 3718 1.3 christos 3719 1.3 christos /* Check to make sure it isn't a protected function or data 3720 1.3 christos symbol for shared library since it may not be local when 3721 1.3 christos used as function address or with copy relocation. We also 3722 1.1 christos need to make sure that a symbol is referenced locally. */ 3723 1.3 christos if (bfd_link_pic (info) && h) 3724 1.3 christos { 3725 1.3 christos if (!h->def_regular) 3726 1.3 christos { 3727 1.3 christos const char *v; 3728 1.3 christos 3729 1.3 christos switch (ELF_ST_VISIBILITY (h->other)) 3730 1.3 christos { 3731 1.3 christos case STV_HIDDEN: 3732 1.3 christos v = _("hidden symbol"); 3733 1.3 christos break; 3734 1.3 christos case STV_INTERNAL: 3735 1.3 christos v = _("internal symbol"); 3736 1.3 christos break; 3737 1.3 christos case STV_PROTECTED: 3738 1.3 christos v = _("protected symbol"); 3739 1.3 christos break; 3740 1.3 christos default: 3741 1.3 christos v = _("symbol"); 3742 1.3 christos break; 3743 1.6 christos } 3744 1.6 christos 3745 1.6 christos _bfd_error_handler 3746 1.6 christos /* xgettext:c-format */ 3747 1.3 christos (_("%pB: relocation R_X86_64_GOTOFF64 against undefined %s" 3748 1.3 christos " `%s' can not be used when making a shared object"), 3749 1.8 christos input_bfd, v, h->root.root.string); 3750 1.3 christos bfd_set_error (bfd_error_bad_value); 3751 1.3 christos return false; 3752 1.6 christos } 3753 1.3 christos else if (!bfd_link_executable (info) 3754 1.3 christos && !SYMBOL_REFERENCES_LOCAL_P (info, h) 3755 1.3 christos && (h->type == STT_FUNC 3756 1.3 christos || h->type == STT_OBJECT) 3757 1.6 christos && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) 3758 1.7 christos { 3759 1.6 christos _bfd_error_handler 3760 1.6 christos /* xgettext:c-format */ 3761 1.3 christos (_("%pB: relocation R_X86_64_GOTOFF64 against protected %s" 3762 1.3 christos " `%s' can not be used when making a shared object"), 3763 1.3 christos input_bfd, 3764 1.3 christos h->type == STT_FUNC ? "function" : "data", 3765 1.8 christos h->root.root.string); 3766 1.3 christos bfd_set_error (bfd_error_bad_value); 3767 1.1 christos return false; 3768 1.1 christos } 3769 1.1 christos } 3770 1.1 christos 3771 1.1 christos /* Note that sgot is not involved in this 3772 1.1 christos calculation. We always want the start of .got.plt. If we 3773 1.1 christos defined _GLOBAL_OFFSET_TABLE_ in a different way, as is 3774 1.1 christos permitted by the ABI, we might have to change this 3775 1.1 christos calculation. */ 3776 1.1 christos relocation -= htab->elf.sgotplt->output_section->vma 3777 1.1 christos + htab->elf.sgotplt->output_offset; 3778 1.1 christos break; 3779 1.1 christos 3780 1.1 christos case R_X86_64_GOTPC32: 3781 1.1 christos case R_X86_64_GOTPC64: 3782 1.1 christos /* Use global offset table as symbol value. */ 3783 1.8 christos relocation = htab->elf.sgotplt->output_section->vma 3784 1.1 christos + htab->elf.sgotplt->output_offset; 3785 1.1 christos unresolved_reloc = false; 3786 1.1 christos break; 3787 1.1 christos 3788 1.1 christos case R_X86_64_PLTOFF64: 3789 1.1 christos /* Relocation is PLT entry relative to GOT. For local 3790 1.1 christos symbols it's the symbol itself relative to GOT. */ 3791 1.6 christos if (h != NULL 3792 1.6 christos /* See PLT32 handling. */ 3793 1.1 christos && (h->plt.offset != (bfd_vma) -1 3794 1.1 christos || eh->plt_got.offset != (bfd_vma) -1) 3795 1.6 christos && htab->elf.splt != NULL) 3796 1.6 christos { 3797 1.6 christos if (eh->plt_got.offset != (bfd_vma) -1) 3798 1.6 christos { 3799 1.6 christos /* Use the GOT PLT. */ 3800 1.6 christos resolved_plt = htab->plt_got; 3801 1.6 christos plt_offset = eh->plt_got.offset; 3802 1.3 christos } 3803 1.6 christos else if (htab->plt_second != NULL) 3804 1.6 christos { 3805 1.3 christos resolved_plt = htab->plt_second; 3806 1.3 christos plt_offset = eh->plt_second.offset; 3807 1.3 christos } 3808 1.3 christos else 3809 1.3 christos { 3810 1.3 christos resolved_plt = htab->elf.splt; 3811 1.3 christos plt_offset = h->plt.offset; 3812 1.3 christos } 3813 1.3 christos 3814 1.3 christos relocation = (resolved_plt->output_section->vma 3815 1.8 christos + resolved_plt->output_offset 3816 1.1 christos + plt_offset); 3817 1.1 christos unresolved_reloc = false; 3818 1.1 christos } 3819 1.1 christos 3820 1.1 christos relocation -= htab->elf.sgotplt->output_section->vma 3821 1.1 christos + htab->elf.sgotplt->output_offset; 3822 1.1 christos break; 3823 1.1 christos 3824 1.1 christos case R_X86_64_PLT32: 3825 1.1 christos /* Relocation is to the entry for this symbol in the 3826 1.1 christos procedure linkage table. */ 3827 1.1 christos 3828 1.1 christos /* Resolve a PLT32 reloc against a local symbol directly, 3829 1.1 christos without using the procedure linkage table. */ 3830 1.1 christos if (h == NULL) 3831 1.3 christos break; 3832 1.3 christos 3833 1.1 christos if ((h->plt.offset == (bfd_vma) -1 3834 1.1 christos && eh->plt_got.offset == (bfd_vma) -1) 3835 1.1 christos || htab->elf.splt == NULL) 3836 1.1 christos { 3837 1.1 christos /* We didn't make a PLT entry for this symbol. This 3838 1.1 christos happens when statically linking PIC code, or when 3839 1.1 christos using -Bsymbolic. */ 3840 1.1 christos break; 3841 1.8 christos } 3842 1.3 christos 3843 1.3 christos use_plt: 3844 1.6 christos if (h->plt.offset != (bfd_vma) -1) 3845 1.3 christos { 3846 1.6 christos if (htab->plt_second != NULL) 3847 1.6 christos { 3848 1.3 christos resolved_plt = htab->plt_second; 3849 1.3 christos plt_offset = eh->plt_second.offset; 3850 1.3 christos } 3851 1.3 christos else 3852 1.3 christos { 3853 1.3 christos resolved_plt = htab->elf.splt; 3854 1.3 christos plt_offset = h->plt.offset; 3855 1.3 christos } 3856 1.3 christos } 3857 1.3 christos else 3858 1.3 christos { 3859 1.3 christos /* Use the GOT PLT. */ 3860 1.3 christos resolved_plt = htab->plt_got; 3861 1.3 christos plt_offset = eh->plt_got.offset; 3862 1.3 christos } 3863 1.3 christos 3864 1.3 christos relocation = (resolved_plt->output_section->vma 3865 1.8 christos + resolved_plt->output_offset 3866 1.1 christos + plt_offset); 3867 1.1 christos unresolved_reloc = false; 3868 1.3 christos break; 3869 1.3 christos 3870 1.3 christos case R_X86_64_SIZE32: 3871 1.3 christos case R_X86_64_SIZE64: 3872 1.3 christos /* Set to symbol size. */ 3873 1.3 christos relocation = st_size; 3874 1.1 christos goto direct; 3875 1.1 christos 3876 1.1 christos case R_X86_64_PC8: 3877 1.3 christos case R_X86_64_PC16: 3878 1.6 christos case R_X86_64_PC32: 3879 1.6 christos /* Don't complain about -fPIC if the symbol is undefined when 3880 1.6 christos building executable unless it is unresolved weak symbol, 3881 1.7 christos references a dynamic definition in PIE or -z nocopyreloc 3882 1.7 christos is used. */ 3883 1.7 christos no_copyreloc_p 3884 1.7 christos = (info->nocopyreloc 3885 1.7 christos || (h != NULL 3886 1.8 christos && !h->root.linker_def 3887 1.7 christos && !h->root.ldscript_def 3888 1.6 christos && eh->def_protected)); 3889 1.1 christos 3890 1.3 christos if ((input_section->flags & SEC_ALLOC) != 0 3891 1.5 christos && (input_section->flags & SEC_READONLY) != 0 3892 1.6 christos && h != NULL 3893 1.7 christos && ((bfd_link_executable (info) 3894 1.7 christos && ((h->root.type == bfd_link_hash_undefweak 3895 1.7 christos && (eh == NULL 3896 1.6 christos || !UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, 3897 1.7 christos eh))) 3898 1.6 christos || (bfd_link_pie (info) 3899 1.7 christos && !SYMBOL_DEFINED_NON_SHARED_P (h) 3900 1.6 christos && h->def_dynamic) 3901 1.6 christos || (no_copyreloc_p 3902 1.8 christos && h->def_dynamic 3903 1.8 christos && !(h->root.u.def.section->flags & SEC_CODE)))) 3904 1.6 christos || (bfd_link_pie (info) 3905 1.1 christos && h->root.type == bfd_link_hash_undefweak) 3906 1.8 christos || bfd_link_dll (info))) 3907 1.6 christos { 3908 1.1 christos bool fail = false; 3909 1.1 christos if (SYMBOL_REFERENCES_LOCAL_P (info, h)) 3910 1.6 christos { 3911 1.7 christos /* Symbol is referenced locally. Make sure it is 3912 1.1 christos defined locally. */ 3913 1.7 christos fail = !SYMBOL_DEFINED_NON_SHARED_P (h); 3914 1.1 christos } 3915 1.7 christos else if (bfd_link_pie (info)) 3916 1.7 christos { 3917 1.8 christos /* We can only use PC-relative relocations in PIE 3918 1.8 christos from non-code sections. */ 3919 1.8 christos if (h->root.type == bfd_link_hash_undefweak 3920 1.8 christos || (h->type == STT_FUNC 3921 1.7 christos && (sec->flags & SEC_CODE) != 0)) 3922 1.7 christos fail = true; 3923 1.7 christos } 3924 1.7 christos else if (no_copyreloc_p || bfd_link_dll (info)) 3925 1.7 christos { 3926 1.7 christos /* Symbol doesn't need copy reloc and isn't 3927 1.7 christos referenced locally. Don't allow PC-relative 3928 1.7 christos relocations against default and protected 3929 1.7 christos symbols since address of protected function 3930 1.6 christos and location of protected data may not be in 3931 1.7 christos the shared object. */ 3932 1.1 christos fail = (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT 3933 1.1 christos || ELF_ST_VISIBILITY (h->other) == STV_PROTECTED); 3934 1.1 christos } 3935 1.6 christos 3936 1.5 christos if (fail) 3937 1.1 christos return elf_x86_64_need_pic (info, input_bfd, input_section, 3938 1.6 christos h, NULL, NULL, howto); 3939 1.6 christos } 3940 1.6 christos /* Since x86-64 has PC-relative PLT, we can use PLT in PIE 3941 1.6 christos as function address. */ 3942 1.6 christos else if (h != NULL 3943 1.6 christos && (input_section->flags & SEC_CODE) == 0 3944 1.6 christos && bfd_link_pie (info) 3945 1.6 christos && h->type == STT_FUNC 3946 1.6 christos && !h->def_regular 3947 1.1 christos && h->def_dynamic) 3948 1.1 christos goto use_plt; 3949 1.1 christos /* Fall through. */ 3950 1.1 christos 3951 1.1 christos case R_X86_64_8: 3952 1.1 christos case R_X86_64_16: 3953 1.1 christos case R_X86_64_32: 3954 1.1 christos case R_X86_64_PC64: 3955 1.1 christos case R_X86_64_64: 3956 1.1 christos /* FIXME: The ABI says the linker should make sure the value is 3957 1.8 christos the same when it's zeroextended to 64 bit. */ 3958 1.1 christos 3959 1.1 christos direct: 3960 1.1 christos if ((input_section->flags & SEC_ALLOC) == 0) 3961 1.6 christos break; 3962 1.6 christos 3963 1.6 christos need_copy_reloc_in_pie = (bfd_link_pie (info) 3964 1.6 christos && h != NULL 3965 1.6 christos && (h->needs_copy 3966 1.6 christos || eh->needs_copy 3967 1.8 christos || (h->root.type 3968 1.8 christos == bfd_link_hash_undefined)) 3969 1.8 christos && (X86_PCREL_TYPE_P (true, r_type) 3970 1.6 christos || X86_SIZE_TYPE_P (true, 3971 1.8 christos r_type))); 3972 1.6 christos 3973 1.8 christos if (GENERATE_DYNAMIC_RELOCATION_P (true, info, eh, r_type, sec, 3974 1.1 christos need_copy_reloc_in_pie, 3975 1.1 christos resolved_to_zero, false)) 3976 1.8 christos { 3977 1.8 christos Elf_Internal_Rela outrel; 3978 1.1 christos bool skip, relocate; 3979 1.8 christos bool generate_dynamic_reloc = true; 3980 1.1 christos asection *sreloc; 3981 1.1 christos const char *relative_reloc_name = NULL; 3982 1.1 christos 3983 1.1 christos /* When generating a shared object, these relocations 3984 1.8 christos are copied into the output file to be resolved at run 3985 1.8 christos time. */ 3986 1.1 christos skip = false; 3987 1.1 christos relocate = false; 3988 1.1 christos 3989 1.1 christos outrel.r_offset = 3990 1.1 christos _bfd_elf_section_offset (output_bfd, info, input_section, 3991 1.8 christos rel->r_offset); 3992 1.1 christos if (outrel.r_offset == (bfd_vma) -1) 3993 1.8 christos skip = true; 3994 1.1 christos else if (outrel.r_offset == (bfd_vma) -2) 3995 1.1 christos skip = true, relocate = true; 3996 1.1 christos 3997 1.1 christos outrel.r_offset += (input_section->output_section->vma 3998 1.1 christos + input_section->output_offset); 3999 1.1 christos 4000 1.1 christos if (skip) 4001 1.8 christos memset (&outrel, 0, sizeof outrel); 4002 1.1 christos 4003 1.1 christos else if (COPY_INPUT_RELOC_P (true, info, h, r_type)) 4004 1.1 christos { 4005 1.1 christos outrel.r_info = htab->r_info (h->dynindx, r_type); 4006 1.1 christos outrel.r_addend = rel->r_addend; 4007 1.1 christos } 4008 1.5 christos else 4009 1.5 christos { 4010 1.5 christos /* This symbol is local, or marked to become local. 4011 1.5 christos When relocation overflow check is disabled, we 4012 1.5 christos convert R_X86_64_32 to dynamic R_X86_64_RELATIVE. */ 4013 1.7 christos if (r_type == htab->pointer_r_type 4014 1.1 christos || (r_type == R_X86_64_32 4015 1.8 christos && htab->params->no_reloc_overflow_check)) 4016 1.8 christos { 4017 1.8 christos relocate = true; 4018 1.8 christos /* NB: Don't generate relative relocation here if 4019 1.8 christos it has been generated by DT_RELR. */ 4020 1.8 christos if (info->enable_dt_relr) 4021 1.8 christos generate_dynamic_reloc = false; 4022 1.8 christos else 4023 1.8 christos { 4024 1.8 christos outrel.r_info = 4025 1.8 christos htab->r_info (0, R_X86_64_RELATIVE); 4026 1.8 christos outrel.r_addend = relocation + rel->r_addend; 4027 1.1 christos relative_reloc_name = "R_X86_64_RELATIVE"; 4028 1.1 christos } 4029 1.1 christos } 4030 1.1 christos else if (r_type == R_X86_64_64 4031 1.8 christos && !ABI_64_P (output_bfd)) 4032 1.1 christos { 4033 1.1 christos relocate = true; 4034 1.1 christos outrel.r_info = htab->r_info (0, 4035 1.8 christos R_X86_64_RELATIVE64); 4036 1.1 christos outrel.r_addend = relocation + rel->r_addend; 4037 1.1 christos relative_reloc_name = "R_X86_64_RELATIVE64"; 4038 1.1 christos /* Check addend overflow. */ 4039 1.1 christos if ((outrel.r_addend & 0x80000000) 4040 1.1 christos != (rel->r_addend & 0x80000000)) 4041 1.1 christos { 4042 1.1 christos const char *name; 4043 1.1 christos int addend = rel->r_addend; 4044 1.1 christos if (h && h->root.root.string) 4045 1.1 christos name = h->root.root.string; 4046 1.1 christos else 4047 1.6 christos name = bfd_elf_sym_name (input_bfd, symtab_hdr, 4048 1.6 christos sym, NULL); 4049 1.6 christos _bfd_error_handler 4050 1.6 christos /* xgettext:c-format */ 4051 1.6 christos (_("%pB: addend %s%#x in relocation %s against " 4052 1.6 christos "symbol `%s' at %#" PRIx64 4053 1.6 christos " in section `%pA' is out of range"), 4054 1.6 christos input_bfd, addend < 0 ? "-" : "", addend, 4055 1.1 christos howto->name, name, (uint64_t) rel->r_offset, 4056 1.8 christos input_section); 4057 1.1 christos bfd_set_error (bfd_error_bad_value); 4058 1.1 christos return false; 4059 1.1 christos } 4060 1.1 christos } 4061 1.1 christos else 4062 1.1 christos { 4063 1.1 christos long sindx; 4064 1.1 christos 4065 1.1 christos if (bfd_is_abs_section (sec)) 4066 1.1 christos sindx = 0; 4067 1.1 christos else if (sec == NULL || sec->owner == NULL) 4068 1.8 christos { 4069 1.1 christos bfd_set_error (bfd_error_bad_value); 4070 1.1 christos return false; 4071 1.1 christos } 4072 1.1 christos else 4073 1.1 christos { 4074 1.1 christos asection *osec; 4075 1.1 christos 4076 1.1 christos /* We are turning this relocation into one 4077 1.1 christos against a section symbol. It would be 4078 1.1 christos proper to subtract the symbol's value, 4079 1.1 christos osec->vma, from the emitted reloc addend, 4080 1.1 christos but ld.so expects buggy relocs. */ 4081 1.1 christos osec = sec->output_section; 4082 1.1 christos sindx = elf_section_data (osec)->dynindx; 4083 1.1 christos if (sindx == 0) 4084 1.1 christos { 4085 1.1 christos asection *oi = htab->elf.text_index_section; 4086 1.1 christos sindx = elf_section_data (oi)->dynindx; 4087 1.1 christos } 4088 1.1 christos BFD_ASSERT (sindx != 0); 4089 1.1 christos } 4090 1.1 christos 4091 1.1 christos outrel.r_info = htab->r_info (sindx, r_type); 4092 1.1 christos outrel.r_addend = relocation + rel->r_addend; 4093 1.1 christos } 4094 1.8 christos } 4095 1.8 christos 4096 1.8 christos if (generate_dynamic_reloc) 4097 1.8 christos { 4098 1.8 christos sreloc = elf_section_data (input_section)->sreloc; 4099 1.8 christos 4100 1.8 christos if (sreloc == NULL || sreloc->contents == NULL) 4101 1.8 christos { 4102 1.8 christos r = bfd_reloc_notsupported; 4103 1.8 christos goto check_relocation_error; 4104 1.8 christos } 4105 1.8 christos 4106 1.8 christos if (relative_reloc_name 4107 1.8 christos && htab->params->report_relative_reloc) 4108 1.8 christos _bfd_x86_elf_link_report_relative_reloc 4109 1.1 christos (info, input_section, h, sym, 4110 1.8 christos relative_reloc_name, &outrel); 4111 1.1 christos 4112 1.1 christos elf_append_rela (output_bfd, sreloc, &outrel); 4113 1.1 christos } 4114 1.1 christos 4115 1.1 christos /* If this reloc is against an external symbol, we do 4116 1.1 christos not want to fiddle with the addend. Otherwise, we 4117 1.1 christos need to include the symbol value so that it becomes 4118 1.1 christos an addend for the dynamic reloc. */ 4119 1.1 christos if (! relocate) 4120 1.1 christos continue; 4121 1.1 christos } 4122 1.1 christos 4123 1.1 christos break; 4124 1.1 christos 4125 1.9 christos case R_X86_64_TLSGD: 4126 1.1 christos case R_X86_64_GOTPC32_TLSDESC: 4127 1.1 christos case R_X86_64_CODE_4_GOTPC32_TLSDESC: 4128 1.9 christos case R_X86_64_TLSDESC_CALL: 4129 1.10 christos case R_X86_64_GOTTPOFF: 4130 1.10 christos case R_X86_64_CODE_4_GOTTPOFF: 4131 1.1 christos case R_X86_64_CODE_5_GOTTPOFF: 4132 1.1 christos case R_X86_64_CODE_6_GOTTPOFF: 4133 1.6 christos tls_type = GOT_UNKNOWN; 4134 1.1 christos if (h == NULL && local_got_offsets) 4135 1.6 christos tls_type = elf_x86_local_got_tls_type (input_bfd) [r_symndx]; 4136 1.1 christos else if (h != NULL) 4137 1.6 christos tls_type = elf_x86_hash_entry (h)->tls_type; 4138 1.1 christos 4139 1.1 christos r_type_tls = r_type; 4140 1.1 christos if (! elf_x86_64_tls_transition (info, input_bfd, 4141 1.6 christos input_section, contents, 4142 1.10 christos symtab_hdr, sym_hashes, 4143 1.8 christos &r_type_tls, tls_type, rel, 4144 1.1 christos relend, h, sym, true)) 4145 1.6 christos return false; 4146 1.1 christos 4147 1.1 christos if (r_type_tls == R_X86_64_TPOFF32) 4148 1.1 christos { 4149 1.9 christos bfd_vma roff = rel->r_offset; 4150 1.9 christos 4151 1.9 christos if (roff >= input_section->size) 4152 1.1 christos goto corrupt_input; 4153 1.1 christos 4154 1.6 christos BFD_ASSERT (! unresolved_reloc); 4155 1.1 christos 4156 1.1 christos if (r_type == R_X86_64_TLSGD) 4157 1.5 christos { 4158 1.5 christos /* GD->LE transition. For 64bit, change 4159 1.5 christos .byte 0x66; leaq foo@tlsgd(%rip), %rdi 4160 1.5 christos .word 0x6666; rex64; call __tls_get_addr@PLT 4161 1.5 christos or 4162 1.5 christos .byte 0x66; leaq foo@tlsgd(%rip), %rdi 4163 1.5 christos .byte 0x66; rex64 4164 1.5 christos call *__tls_get_addr@GOTPCREL(%rip) 4165 1.1 christos which may be converted to 4166 1.5 christos addr32 call __tls_get_addr 4167 1.5 christos into: 4168 1.1 christos movq %fs:0, %rax 4169 1.5 christos leaq foo@tpoff(%rax), %rax 4170 1.5 christos For 32bit, change 4171 1.5 christos leaq foo@tlsgd(%rip), %rdi 4172 1.5 christos .word 0x6666; rex64; call __tls_get_addr@PLT 4173 1.5 christos or 4174 1.5 christos leaq foo@tlsgd(%rip), %rdi 4175 1.5 christos .byte 0x66; rex64 4176 1.5 christos call *__tls_get_addr@GOTPCREL(%rip) 4177 1.1 christos which may be converted to 4178 1.5 christos addr32 call __tls_get_addr 4179 1.5 christos into: 4180 1.3 christos movl %fs:0, %eax 4181 1.5 christos leaq foo@tpoff(%rax), %rax 4182 1.5 christos For largepic, change: 4183 1.5 christos leaq foo@tlsgd(%rip), %rdi 4184 1.5 christos movabsq $__tls_get_addr@pltoff, %rax 4185 1.3 christos addq %r15, %rax 4186 1.5 christos call *%rax 4187 1.5 christos into: 4188 1.5 christos movq %fs:0, %rax 4189 1.3 christos leaq foo@tpoff(%rax), %rax 4190 1.5 christos nopw 0x0(%rax,%rax,1) */ 4191 1.3 christos int largepic = 0; 4192 1.9 christos if (ABI_64_P (output_bfd)) 4193 1.9 christos { 4194 1.5 christos if (roff + 5 >= input_section->size) 4195 1.5 christos goto corrupt_input; 4196 1.7 christos if (contents[roff + 5] == 0xb8) 4197 1.7 christos { 4198 1.7 christos if (roff < 3 4199 1.8 christos || (roff - 3 + 22) > input_section->size) 4200 1.10 christos { 4201 1.10 christos corrupt_input: 4202 1.7 christos info->callbacks->fatal 4203 1.8 christos (_("%P: corrupt input: %pB\n"), 4204 1.7 christos input_bfd); 4205 1.5 christos return false; 4206 1.5 christos } 4207 1.5 christos memcpy (contents + roff - 3, 4208 1.5 christos "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80" 4209 1.5 christos "\0\0\0\0\x66\x0f\x1f\x44\0", 22); 4210 1.5 christos largepic = 1; 4211 1.7 christos } 4212 1.7 christos else 4213 1.7 christos { 4214 1.7 christos if (roff < 4 4215 1.7 christos || (roff - 4 + 16) > input_section->size) 4216 1.7 christos goto corrupt_input; 4217 1.7 christos memcpy (contents + roff - 4, 4218 1.7 christos "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0", 4219 1.3 christos 16); 4220 1.1 christos } 4221 1.7 christos } 4222 1.7 christos else 4223 1.7 christos { 4224 1.7 christos if (roff < 3 4225 1.7 christos || (roff - 3 + 15) > input_section->size) 4226 1.7 christos goto corrupt_input; 4227 1.7 christos memcpy (contents + roff - 3, 4228 1.7 christos "\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0", 4229 1.9 christos 15); 4230 1.9 christos } 4231 1.9 christos 4232 1.9 christos if (roff + 8 + largepic >= input_section->size) 4233 1.1 christos goto corrupt_input; 4234 1.1 christos 4235 1.3 christos bfd_put_32 (output_bfd, 4236 1.5 christos elf_x86_64_tpoff (info, relocation), 4237 1.5 christos contents + roff + 8 + largepic); 4238 1.1 christos /* Skip R_X86_64_PC32, R_X86_64_PLT32, 4239 1.3 christos R_X86_64_GOTPCRELX and R_X86_64_PLTOFF64. */ 4240 1.1 christos rel++; 4241 1.1 christos wrel++; 4242 1.6 christos continue; 4243 1.1 christos } 4244 1.1 christos else if (r_type == R_X86_64_GOTPC32_TLSDESC) 4245 1.1 christos { 4246 1.8 christos /* GDesc -> LE transition. 4247 1.8 christos It's originally something like: 4248 1.1 christos leaq x@tlsdesc(%rip), %rax <--- LP64 mode. 4249 1.1 christos rex leal x@tlsdesc(%rip), %eax <--- X32 mode. 4250 1.8 christos 4251 1.8 christos Change it to: 4252 1.8 christos movq $x@tpoff, %rax <--- LP64 mode. 4253 1.1 christos rex movl $x@tpoff, %eax <--- X32 mode. 4254 1.1 christos */ 4255 1.1 christos 4256 1.7 christos unsigned int val, type; 4257 1.7 christos 4258 1.1 christos if (roff < 3) 4259 1.1 christos goto corrupt_input; 4260 1.8 christos type = bfd_get_8 (input_bfd, contents + roff - 3); 4261 1.8 christos val = bfd_get_8 (input_bfd, contents + roff - 1); 4262 1.1 christos bfd_put_8 (output_bfd, 4263 1.1 christos (type & 0x48) | ((type >> 2) & 1), 4264 1.1 christos contents + roff - 3); 4265 1.1 christos bfd_put_8 (output_bfd, 0xc7, contents + roff - 2); 4266 1.1 christos bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7), 4267 1.1 christos contents + roff - 1); 4268 1.1 christos bfd_put_32 (output_bfd, 4269 1.1 christos elf_x86_64_tpoff (info, relocation), 4270 1.1 christos contents + roff); 4271 1.9 christos continue; 4272 1.9 christos } 4273 1.9 christos else if (r_type == R_X86_64_CODE_4_GOTPC32_TLSDESC) 4274 1.9 christos { 4275 1.9 christos /* GDesc -> LE transition. 4276 1.9 christos It's originally something like: 4277 1.9 christos lea x@tlsdesc(%rip), %reg 4278 1.9 christos 4279 1.9 christos Change it to: 4280 1.9 christos mov $x@tpoff, %reg 4281 1.9 christos where reg is one of r16 to r31. */ 4282 1.9 christos 4283 1.9 christos unsigned int val, rex2; 4284 1.9 christos unsigned int rex2_mask = REX_R | REX_R << 4; 4285 1.9 christos 4286 1.9 christos if (roff < 4) 4287 1.9 christos goto corrupt_input; 4288 1.9 christos rex2 = bfd_get_8 (input_bfd, contents + roff - 3); 4289 1.9 christos val = bfd_get_8 (input_bfd, contents + roff - 1); 4290 1.9 christos /* Move the R bits to the B bits in REX2 payload 4291 1.9 christos byte. */ 4292 1.9 christos bfd_put_8 (output_bfd, 4293 1.9 christos ((rex2 & ~rex2_mask) 4294 1.9 christos | (rex2 & rex2_mask) >> 2), 4295 1.9 christos contents + roff - 3); 4296 1.9 christos bfd_put_8 (output_bfd, 0xc7, contents + roff - 2); 4297 1.9 christos bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7), 4298 1.9 christos contents + roff - 1); 4299 1.9 christos bfd_put_32 (output_bfd, 4300 1.9 christos elf_x86_64_tpoff (info, relocation), 4301 1.9 christos contents + roff); 4302 1.6 christos continue; 4303 1.1 christos } 4304 1.1 christos else if (r_type == R_X86_64_TLSDESC_CALL) 4305 1.1 christos { 4306 1.8 christos /* GDesc -> LE transition. 4307 1.8 christos It's originally: 4308 1.1 christos call *(%rax) <--- LP64 mode. 4309 1.8 christos call *(%eax) <--- X32 mode. 4310 1.8 christos Turn it into: 4311 1.8 christos xchg %ax,%ax <-- LP64 mode. 4312 1.8 christos nopl (%rax) <-- X32 mode. 4313 1.8 christos */ 4314 1.8 christos unsigned int prefix = 0; 4315 1.10 christos if (!ABI_64_P (input_bfd)) 4316 1.8 christos { 4317 1.8 christos /* Check for call *x@tlscall(%eax). */ 4318 1.8 christos if (contents[roff] == 0x67) 4319 1.8 christos prefix = 1; 4320 1.8 christos } 4321 1.9 christos if (prefix) 4322 1.9 christos { 4323 1.9 christos if (roff + 2 >= input_section->size) 4324 1.8 christos goto corrupt_input; 4325 1.8 christos 4326 1.8 christos bfd_put_8 (output_bfd, 0x0f, contents + roff); 4327 1.8 christos bfd_put_8 (output_bfd, 0x1f, contents + roff + 1); 4328 1.8 christos bfd_put_8 (output_bfd, 0x00, contents + roff + 2); 4329 1.8 christos } 4330 1.9 christos else 4331 1.9 christos { 4332 1.9 christos if (roff + 1 >= input_section->size) 4333 1.8 christos goto corrupt_input; 4334 1.8 christos 4335 1.8 christos bfd_put_8 (output_bfd, 0x66, contents + roff); 4336 1.1 christos bfd_put_8 (output_bfd, 0x90, contents + roff + 1); 4337 1.1 christos } 4338 1.6 christos continue; 4339 1.1 christos } 4340 1.1 christos else if (r_type == R_X86_64_GOTTPOFF) 4341 1.3 christos { 4342 1.1 christos /* IE->LE transition: 4343 1.1 christos For 64bit, originally it can be one of: 4344 1.1 christos movq foo@gottpoff(%rip), %reg 4345 1.1 christos addq foo@gottpoff(%rip), %reg 4346 1.1 christos We change it into: 4347 1.3 christos movq $foo, %reg 4348 1.3 christos leaq foo(%reg), %reg 4349 1.3 christos addq $foo, %reg. 4350 1.3 christos For 32bit, originally it can be one of: 4351 1.3 christos movq foo@gottpoff(%rip), %reg 4352 1.3 christos addl foo@gottpoff(%rip), %reg 4353 1.3 christos We change it into: 4354 1.3 christos movq $foo, %reg 4355 1.1 christos leal foo(%reg), %reg 4356 1.1 christos addl $foo, %reg. */ 4357 1.1 christos 4358 1.3 christos unsigned int val, type, reg; 4359 1.3 christos 4360 1.3 christos if (roff >= 3) 4361 1.7 christos val = bfd_get_8 (input_bfd, contents + roff - 3); 4362 1.7 christos else 4363 1.7 christos { 4364 1.7 christos if (roff < 2) 4365 1.7 christos goto corrupt_input; 4366 1.1 christos val = 0; 4367 1.1 christos } 4368 1.1 christos type = bfd_get_8 (input_bfd, contents + roff - 2); 4369 1.1 christos reg = bfd_get_8 (input_bfd, contents + roff - 1); 4370 1.1 christos reg >>= 3; 4371 1.1 christos if (type == 0x8b) 4372 1.1 christos { 4373 1.7 christos /* movq */ 4374 1.7 christos if (val == 0x4c) 4375 1.7 christos { 4376 1.7 christos if (roff < 3) 4377 1.7 christos goto corrupt_input; 4378 1.7 christos bfd_put_8 (output_bfd, 0x49, 4379 1.1 christos contents + roff - 3); 4380 1.7 christos } 4381 1.7 christos else if (!ABI_64_P (output_bfd) && val == 0x44) 4382 1.7 christos { 4383 1.7 christos if (roff < 3) 4384 1.7 christos goto corrupt_input; 4385 1.7 christos bfd_put_8 (output_bfd, 0x41, 4386 1.1 christos contents + roff - 3); 4387 1.1 christos } 4388 1.1 christos bfd_put_8 (output_bfd, 0xc7, 4389 1.1 christos contents + roff - 2); 4390 1.1 christos bfd_put_8 (output_bfd, 0xc0 | reg, 4391 1.1 christos contents + roff - 1); 4392 1.1 christos } 4393 1.3 christos else if (reg == 4) 4394 1.3 christos { 4395 1.1 christos /* addq/addl -> addq/addl - addressing with %rsp/%r12 4396 1.7 christos is special */ 4397 1.7 christos if (val == 0x4c) 4398 1.7 christos { 4399 1.7 christos if (roff < 3) 4400 1.7 christos goto corrupt_input; 4401 1.7 christos bfd_put_8 (output_bfd, 0x49, 4402 1.1 christos contents + roff - 3); 4403 1.7 christos } 4404 1.7 christos else if (!ABI_64_P (output_bfd) && val == 0x44) 4405 1.7 christos { 4406 1.7 christos if (roff < 3) 4407 1.7 christos goto corrupt_input; 4408 1.7 christos bfd_put_8 (output_bfd, 0x41, 4409 1.1 christos contents + roff - 3); 4410 1.1 christos } 4411 1.1 christos bfd_put_8 (output_bfd, 0x81, 4412 1.1 christos contents + roff - 2); 4413 1.1 christos bfd_put_8 (output_bfd, 0xc0 | reg, 4414 1.1 christos contents + roff - 1); 4415 1.1 christos } 4416 1.3 christos else 4417 1.1 christos { 4418 1.7 christos /* addq/addl -> leaq/leal */ 4419 1.7 christos if (val == 0x4c) 4420 1.7 christos { 4421 1.7 christos if (roff < 3) 4422 1.7 christos goto corrupt_input; 4423 1.7 christos bfd_put_8 (output_bfd, 0x4d, 4424 1.1 christos contents + roff - 3); 4425 1.7 christos } 4426 1.7 christos else if (!ABI_64_P (output_bfd) && val == 0x44) 4427 1.7 christos { 4428 1.7 christos if (roff < 3) 4429 1.7 christos goto corrupt_input; 4430 1.7 christos bfd_put_8 (output_bfd, 0x45, 4431 1.1 christos contents + roff - 3); 4432 1.1 christos } 4433 1.1 christos bfd_put_8 (output_bfd, 0x8d, 4434 1.1 christos contents + roff - 2); 4435 1.1 christos bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3), 4436 1.1 christos contents + roff - 1); 4437 1.1 christos } 4438 1.1 christos bfd_put_32 (output_bfd, 4439 1.1 christos elf_x86_64_tpoff (info, relocation), 4440 1.1 christos contents + roff); 4441 1.9 christos continue; 4442 1.9 christos } 4443 1.9 christos else if (r_type == R_X86_64_CODE_4_GOTTPOFF) 4444 1.9 christos { 4445 1.9 christos /* IE->LE transition: 4446 1.9 christos Originally it can be one of: 4447 1.10 christos mov foo@gottpoff(%rip), %reg 4448 1.9 christos add foo@gottpoff(%rip), %reg 4449 1.9 christos movrs foo@gottpoff(%rip), %reg 4450 1.9 christos We change it into: 4451 1.10 christos mov $foo@tpoff, %reg 4452 1.10 christos add $foo@tpoff, %reg 4453 1.9 christos where reg is one of r16 to r31, except for MOVRS, where 4454 1.9 christos it's not one of r8 to r31 and no REX byte is present. */ 4455 1.9 christos 4456 1.9 christos unsigned int rex2, type, reg; 4457 1.9 christos unsigned int rex2_mask = REX_R | REX_R << 4; 4458 1.9 christos 4459 1.9 christos if (roff < 4) 4460 1.9 christos goto corrupt_input; 4461 1.9 christos 4462 1.9 christos rex2 = bfd_get_8 (input_bfd, contents + roff - 3); 4463 1.9 christos type = bfd_get_8 (input_bfd, contents + roff - 2); 4464 1.9 christos reg = bfd_get_8 (input_bfd, contents + roff - 1); 4465 1.9 christos reg >>= 3; 4466 1.9 christos /* Move the R bits to the B bits in REX2 payload 4467 1.10 christos byte. */ 4468 1.10 christos if (type == 0x8b) 4469 1.10 christos { 4470 1.10 christos /* For MOVRS emit meaningless CS prefixes. */ 4471 1.10 christos if (bfd_get_8 (input_bfd, contents + roff - 4) == 0x0f) 4472 1.10 christos { 4473 1.10 christos bfd_put_8 (output_bfd, 0x2e, contents + roff - 4); 4474 1.10 christos rex2 = 0x2e; 4475 1.10 christos rex2_mask = 0; 4476 1.10 christos } 4477 1.9 christos type = 0xc7; 4478 1.9 christos } 4479 1.9 christos else 4480 1.9 christos type = 0x81; 4481 1.9 christos bfd_put_8 (output_bfd, 4482 1.9 christos ((rex2 & ~rex2_mask) 4483 1.9 christos | (rex2 & rex2_mask) >> 2), 4484 1.9 christos contents + roff - 3); 4485 1.9 christos bfd_put_8 (output_bfd, type, 4486 1.9 christos contents + roff - 2); 4487 1.9 christos bfd_put_8 (output_bfd, 0xc0 | reg, 4488 1.9 christos contents + roff - 1); 4489 1.9 christos bfd_put_32 (output_bfd, 4490 1.9 christos elf_x86_64_tpoff (info, relocation), 4491 1.9 christos contents + roff); 4492 1.10 christos continue; 4493 1.10 christos } 4494 1.10 christos else if (r_type == R_X86_64_CODE_5_GOTTPOFF) 4495 1.10 christos { 4496 1.10 christos /* IE->LE transition: 4497 1.10 christos Originally it is 4498 1.10 christos movrs foo@gottpoff(%rip), %reg 4499 1.10 christos We change it into: 4500 1.10 christos mov $foo@tpoff, %reg 4501 1.10 christos where reg isn't one of r16 to r31, but a REX 4502 1.10 christos byte is present. */ 4503 1.10 christos unsigned int rex = bfd_get_8 (input_bfd, contents + roff - 5); 4504 1.10 christos 4505 1.10 christos /* Move REX.R to REX.B. */ 4506 1.10 christos rex = (rex & ~(REX_R | REX_B)) 4507 1.10 christos | ((rex & REX_R) / (REX_R / REX_B)); 4508 1.10 christos 4509 1.10 christos unsigned int reg = bfd_get_8 (input_bfd, contents + roff - 1); 4510 1.10 christos reg >>= 3; 4511 1.10 christos 4512 1.10 christos /* Replace 0f38 by meaningless CS prefixes, shifting the REX 4513 1.10 christos prefix forward. */ 4514 1.10 christos bfd_put_8 (output_bfd, 0x2e, contents + roff - 5); 4515 1.10 christos bfd_put_8 (output_bfd, 0x2e, contents + roff - 4); 4516 1.10 christos bfd_put_8 (output_bfd, rex, contents + roff - 3); 4517 1.10 christos bfd_put_8 (output_bfd, 0xc7, contents + roff - 2); 4518 1.10 christos bfd_put_8 (output_bfd, 0xc0 | reg, contents + roff - 1); 4519 1.10 christos 4520 1.10 christos bfd_put_32 (output_bfd, 4521 1.10 christos elf_x86_64_tpoff (info, relocation), 4522 1.10 christos contents + roff); 4523 1.10 christos continue; 4524 1.10 christos } 4525 1.10 christos else if (r_type == R_X86_64_CODE_6_GOTTPOFF) 4526 1.10 christos { 4527 1.10 christos /* IE->LE transition: 4528 1.10 christos Originally it is 4529 1.10 christos add %reg1, foo@gottpoff(%rip), %reg2 4530 1.10 christos or 4531 1.10 christos add foo@gottpoff(%rip), %reg1, %reg2 4532 1.10 christos or 4533 1.10 christos movrs foo@gottpoff(%rip), %reg 4534 1.10 christos We change it into: 4535 1.10 christos add $foo@tpoff, %reg1, %reg2 4536 1.10 christos mov $foo@tpoff, %reg 4537 1.10 christos where reg is one of r16 to r31. */ 4538 1.10 christos unsigned int type, reg, byte1; 4539 1.10 christos 4540 1.10 christos if (roff < 6) 4541 1.10 christos goto corrupt_input; 4542 1.10 christos 4543 1.10 christos byte1 = bfd_get_8 (input_bfd, contents + roff - 5); 4544 1.10 christos type = bfd_get_8 (input_bfd, contents + roff - 2); 4545 1.10 christos reg = bfd_get_8 (input_bfd, contents + roff - 1); 4546 1.10 christos reg >>= 3; 4547 1.10 christos 4548 1.10 christos if (type == 0x8b) 4549 1.10 christos { 4550 1.10 christos /* Convert MOVRS to REX2-encoded MOV. */ 4551 1.10 christos unsigned int rex2 = 0; 4552 1.10 christos 4553 1.10 christos /* Move the EVEX R bits to the REX2 B ones. */ 4554 1.10 christos if (!(byte1 & (1 << 7))) 4555 1.10 christos rex2 |= REX_B; 4556 1.10 christos if (!(byte1 & (1 << 4))) 4557 1.10 christos rex2 |= REX_B << 4; 4558 1.10 christos /* Propagate the EVEX W bit to the REX2 one. */ 4559 1.10 christos type = bfd_get_8 (input_bfd, contents + roff - 4); 4560 1.10 christos if (type & (1 << 7)) 4561 1.10 christos rex2 |= REX_W; 4562 1.10 christos 4563 1.10 christos 4564 1.10 christos bfd_put_8 (output_bfd, 0x2e, contents + roff - 6); 4565 1.10 christos bfd_put_8 (output_bfd, 0x2e, contents + roff - 5); 4566 1.10 christos bfd_put_8 (output_bfd, 0xd5, contents + roff - 4); 4567 1.10 christos bfd_put_8 (output_bfd, rex2, contents + roff - 3); 4568 1.10 christos bfd_put_8 (output_bfd, 0xc7, contents + roff - 2); 4569 1.10 christos bfd_put_8 (output_bfd, 0xc0 | reg, contents + roff - 1); 4570 1.10 christos bfd_put_32 (output_bfd, 4571 1.10 christos elf_x86_64_tpoff (info, relocation), 4572 1.10 christos contents + roff); 4573 1.10 christos continue; 4574 1.10 christos } 4575 1.10 christos 4576 1.10 christos byte1 = evex_move_r_to_b (byte1, false); 4577 1.10 christos bfd_put_8 (output_bfd, byte1, contents + roff - 5); 4578 1.10 christos bfd_put_8 (output_bfd, 0x81, contents + roff - 2); 4579 1.10 christos bfd_put_8 (output_bfd, 0xc0 | reg, contents + roff - 1); 4580 1.10 christos bfd_put_32 (output_bfd, 4581 1.10 christos elf_x86_64_tpoff (info, relocation), 4582 1.10 christos contents + roff); 4583 1.1 christos continue; 4584 1.8 christos } 4585 1.1 christos else 4586 1.1 christos BFD_ASSERT (false); 4587 1.1 christos } 4588 1.1 christos 4589 1.1 christos if (htab->elf.sgot == NULL) 4590 1.1 christos abort (); 4591 1.1 christos 4592 1.1 christos if (h != NULL) 4593 1.6 christos { 4594 1.1 christos off = h->got.offset; 4595 1.1 christos offplt = elf_x86_hash_entry (h)->tlsdesc_got; 4596 1.1 christos } 4597 1.1 christos else 4598 1.1 christos { 4599 1.1 christos if (local_got_offsets == NULL) 4600 1.1 christos abort (); 4601 1.1 christos 4602 1.1 christos off = local_got_offsets[r_symndx]; 4603 1.1 christos offplt = local_tlsdesc_gotents[r_symndx]; 4604 1.1 christos } 4605 1.1 christos 4606 1.1 christos if ((off & 1) != 0) 4607 1.1 christos off &= ~1; 4608 1.1 christos else 4609 1.1 christos { 4610 1.1 christos Elf_Internal_Rela outrel; 4611 1.1 christos int dr_type, indx; 4612 1.1 christos asection *sreloc; 4613 1.1 christos 4614 1.1 christos if (htab->elf.srelgot == NULL) 4615 1.1 christos abort (); 4616 1.1 christos 4617 1.1 christos indx = h && h->dynindx != -1 ? h->dynindx : 0; 4618 1.1 christos 4619 1.1 christos if (GOT_TLS_GDESC_P (tls_type)) 4620 1.1 christos { 4621 1.1 christos outrel.r_info = htab->r_info (indx, R_X86_64_TLSDESC); 4622 1.1 christos BFD_ASSERT (htab->sgotplt_jump_table_size + offplt 4623 1.1 christos + 2 * GOT_ENTRY_SIZE <= htab->elf.sgotplt->size); 4624 1.1 christos outrel.r_offset = (htab->elf.sgotplt->output_section->vma 4625 1.1 christos + htab->elf.sgotplt->output_offset 4626 1.1 christos + offplt 4627 1.1 christos + htab->sgotplt_jump_table_size); 4628 1.6 christos sreloc = htab->elf.srelplt; 4629 1.1 christos if (indx == 0) 4630 1.1 christos outrel.r_addend = relocation - _bfd_x86_elf_dtpoff_base (info); 4631 1.1 christos else 4632 1.1 christos outrel.r_addend = 0; 4633 1.1 christos elf_append_rela (output_bfd, sreloc, &outrel); 4634 1.1 christos } 4635 1.1 christos 4636 1.1 christos sreloc = htab->elf.srelgot; 4637 1.1 christos 4638 1.1 christos outrel.r_offset = (htab->elf.sgot->output_section->vma 4639 1.1 christos + htab->elf.sgot->output_offset + off); 4640 1.1 christos 4641 1.1 christos if (GOT_TLS_GD_P (tls_type)) 4642 1.1 christos dr_type = R_X86_64_DTPMOD64; 4643 1.1 christos else if (GOT_TLS_GDESC_P (tls_type)) 4644 1.1 christos goto dr_done; 4645 1.1 christos else 4646 1.1 christos dr_type = R_X86_64_TPOFF64; 4647 1.1 christos 4648 1.1 christos bfd_put_64 (output_bfd, 0, htab->elf.sgot->contents + off); 4649 1.1 christos outrel.r_addend = 0; 4650 1.6 christos if ((dr_type == R_X86_64_TPOFF64 4651 1.1 christos || dr_type == R_X86_64_TLSDESC) && indx == 0) 4652 1.1 christos outrel.r_addend = relocation - _bfd_x86_elf_dtpoff_base (info); 4653 1.1 christos outrel.r_info = htab->r_info (indx, dr_type); 4654 1.1 christos 4655 1.1 christos elf_append_rela (output_bfd, sreloc, &outrel); 4656 1.1 christos 4657 1.1 christos if (GOT_TLS_GD_P (tls_type)) 4658 1.1 christos { 4659 1.1 christos if (indx == 0) 4660 1.1 christos { 4661 1.6 christos BFD_ASSERT (! unresolved_reloc); 4662 1.1 christos bfd_put_64 (output_bfd, 4663 1.1 christos relocation - _bfd_x86_elf_dtpoff_base (info), 4664 1.1 christos htab->elf.sgot->contents + off + GOT_ENTRY_SIZE); 4665 1.1 christos } 4666 1.1 christos else 4667 1.1 christos { 4668 1.1 christos bfd_put_64 (output_bfd, 0, 4669 1.1 christos htab->elf.sgot->contents + off + GOT_ENTRY_SIZE); 4670 1.1 christos outrel.r_info = htab->r_info (indx, 4671 1.1 christos R_X86_64_DTPOFF64); 4672 1.1 christos outrel.r_offset += GOT_ENTRY_SIZE; 4673 1.1 christos elf_append_rela (output_bfd, sreloc, 4674 1.1 christos &outrel); 4675 1.1 christos } 4676 1.1 christos } 4677 1.1 christos 4678 1.1 christos dr_done: 4679 1.1 christos if (h != NULL) 4680 1.1 christos h->got.offset |= 1; 4681 1.1 christos else 4682 1.1 christos local_got_offsets[r_symndx] |= 1; 4683 1.1 christos } 4684 1.1 christos 4685 1.1 christos if (off >= (bfd_vma) -2 4686 1.6 christos && ! GOT_TLS_GDESC_P (tls_type)) 4687 1.1 christos abort (); 4688 1.1 christos if (r_type_tls == r_type) 4689 1.9 christos { 4690 1.1 christos if (r_type == R_X86_64_GOTPC32_TLSDESC 4691 1.1 christos || r_type == R_X86_64_CODE_4_GOTPC32_TLSDESC 4692 1.1 christos || r_type == R_X86_64_TLSDESC_CALL) 4693 1.1 christos relocation = htab->elf.sgotplt->output_section->vma 4694 1.1 christos + htab->elf.sgotplt->output_offset 4695 1.1 christos + offplt + htab->sgotplt_jump_table_size; 4696 1.1 christos else 4697 1.8 christos relocation = htab->elf.sgot->output_section->vma 4698 1.1 christos + htab->elf.sgot->output_offset + off; 4699 1.1 christos unresolved_reloc = false; 4700 1.1 christos } 4701 1.1 christos else 4702 1.1 christos { 4703 1.6 christos bfd_vma roff = rel->r_offset; 4704 1.1 christos 4705 1.1 christos if (r_type == R_X86_64_TLSGD) 4706 1.5 christos { 4707 1.5 christos /* GD->IE transition. For 64bit, change 4708 1.5 christos .byte 0x66; leaq foo@tlsgd(%rip), %rdi 4709 1.5 christos .word 0x6666; rex64; call __tls_get_addr@PLT 4710 1.5 christos or 4711 1.5 christos .byte 0x66; leaq foo@tlsgd(%rip), %rdi 4712 1.5 christos .byte 0x66; rex64 4713 1.5 christos call *__tls_get_addr@GOTPCREL(%rip 4714 1.1 christos which may be converted to 4715 1.5 christos addr32 call __tls_get_addr 4716 1.5 christos into: 4717 1.1 christos movq %fs:0, %rax 4718 1.5 christos addq foo@gottpoff(%rip), %rax 4719 1.5 christos For 32bit, change 4720 1.5 christos leaq foo@tlsgd(%rip), %rdi 4721 1.5 christos .word 0x6666; rex64; call __tls_get_addr@PLT 4722 1.5 christos or 4723 1.5 christos leaq foo@tlsgd(%rip), %rdi 4724 1.5 christos .byte 0x66; rex64; 4725 1.5 christos call *__tls_get_addr@GOTPCREL(%rip) 4726 1.1 christos which may be converted to 4727 1.5 christos addr32 call __tls_get_addr 4728 1.5 christos into: 4729 1.3 christos movl %fs:0, %eax 4730 1.5 christos addq foo@gottpoff(%rip), %rax 4731 1.5 christos For largepic, change: 4732 1.5 christos leaq foo@tlsgd(%rip), %rdi 4733 1.5 christos movabsq $__tls_get_addr@pltoff, %rax 4734 1.3 christos addq %r15, %rax 4735 1.5 christos call *%rax 4736 1.5 christos into: 4737 1.5 christos movq %fs:0, %rax 4738 1.3 christos addq foo@gottpoff(%rax), %rax 4739 1.5 christos nopw 0x0(%rax,%rax,1) */ 4740 1.3 christos int largepic = 0; 4741 1.5 christos if (ABI_64_P (output_bfd)) 4742 1.5 christos { 4743 1.7 christos if (contents[roff + 5] == 0xb8) 4744 1.7 christos { 4745 1.7 christos if (roff < 3 4746 1.5 christos || (roff - 3 + 22) > input_section->size) 4747 1.5 christos goto corrupt_input; 4748 1.5 christos memcpy (contents + roff - 3, 4749 1.5 christos "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05" 4750 1.5 christos "\0\0\0\0\x66\x0f\x1f\x44\0", 22); 4751 1.5 christos largepic = 1; 4752 1.7 christos } 4753 1.7 christos else 4754 1.7 christos { 4755 1.7 christos if (roff < 4 4756 1.7 christos || (roff - 4 + 16) > input_section->size) 4757 1.7 christos goto corrupt_input; 4758 1.7 christos memcpy (contents + roff - 4, 4759 1.7 christos "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0", 4760 1.3 christos 16); 4761 1.1 christos } 4762 1.7 christos } 4763 1.7 christos else 4764 1.7 christos { 4765 1.7 christos if (roff < 3 4766 1.7 christos || (roff - 3 + 15) > input_section->size) 4767 1.7 christos goto corrupt_input; 4768 1.7 christos memcpy (contents + roff - 3, 4769 1.7 christos "\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0", 4770 1.1 christos 15); 4771 1.1 christos } 4772 1.1 christos 4773 1.1 christos relocation = (htab->elf.sgot->output_section->vma 4774 1.3 christos + htab->elf.sgot->output_offset + off 4775 1.1 christos - roff 4776 1.1 christos - largepic 4777 1.1 christos - input_section->output_section->vma 4778 1.1 christos - input_section->output_offset 4779 1.3 christos - 12); 4780 1.3 christos bfd_put_32 (output_bfd, relocation, 4781 1.1 christos contents + roff + 8 + largepic); 4782 1.3 christos /* Skip R_X86_64_PLT32/R_X86_64_PLTOFF64. */ 4783 1.1 christos rel++; 4784 1.1 christos wrel++; 4785 1.9 christos continue; 4786 1.9 christos } 4787 1.1 christos else if (r_type == R_X86_64_GOTPC32_TLSDESC 4788 1.1 christos || r_type == R_X86_64_CODE_4_GOTPC32_TLSDESC) 4789 1.1 christos { 4790 1.8 christos /* GDesc -> IE transition. 4791 1.8 christos It's originally something like: 4792 1.1 christos leaq x@tlsdesc(%rip), %rax <--- LP64 mode. 4793 1.1 christos rex leal x@tlsdesc(%rip), %eax <--- X32 mode. 4794 1.8 christos 4795 1.8 christos Change it to: 4796 1.8 christos # before xchg %ax,%ax in LP64 mode. 4797 1.8 christos movq x@gottpoff(%rip), %rax 4798 1.8 christos # before nopl (%rax) in X32 mode. 4799 1.1 christos rex movl x@gottpoff(%rip), %eax 4800 1.1 christos */ 4801 1.8 christos 4802 1.1 christos /* Now modify the instruction as appropriate. To 4803 1.1 christos turn a lea into a mov in the form we use it, it 4804 1.7 christos suffices to change the second byte from 0x8d to 4805 1.7 christos 0x8b. */ 4806 1.1 christos if (roff < 2) 4807 1.1 christos goto corrupt_input; 4808 1.1 christos bfd_put_8 (output_bfd, 0x8b, contents + roff - 2); 4809 1.1 christos 4810 1.1 christos bfd_put_32 (output_bfd, 4811 1.1 christos htab->elf.sgot->output_section->vma 4812 1.1 christos + htab->elf.sgot->output_offset + off 4813 1.1 christos - rel->r_offset 4814 1.1 christos - input_section->output_section->vma 4815 1.1 christos - input_section->output_offset 4816 1.1 christos - 4, 4817 1.1 christos contents + roff); 4818 1.6 christos continue; 4819 1.1 christos } 4820 1.1 christos else if (r_type == R_X86_64_TLSDESC_CALL) 4821 1.1 christos { 4822 1.8 christos /* GDesc -> IE transition. 4823 1.8 christos It's originally: 4824 1.1 christos call *(%rax) <--- LP64 mode. 4825 1.1 christos call *(%eax) <--- X32 mode. 4826 1.8 christos 4827 1.8 christos Change it to: 4828 1.8 christos xchg %ax, %ax <-- LP64 mode. 4829 1.1 christos nopl (%rax) <-- X32 mode. 4830 1.8 christos */ 4831 1.8 christos 4832 1.8 christos unsigned int prefix = 0; 4833 1.10 christos if (!ABI_64_P (input_bfd)) 4834 1.8 christos { 4835 1.8 christos /* Check for call *x@tlscall(%eax). */ 4836 1.8 christos if (contents[roff] == 0x67) 4837 1.8 christos prefix = 1; 4838 1.8 christos } 4839 1.8 christos if (prefix) 4840 1.8 christos { 4841 1.8 christos bfd_put_8 (output_bfd, 0x0f, contents + roff); 4842 1.8 christos bfd_put_8 (output_bfd, 0x1f, contents + roff + 1); 4843 1.8 christos bfd_put_8 (output_bfd, 0x00, contents + roff + 2); 4844 1.8 christos } 4845 1.8 christos else 4846 1.8 christos { 4847 1.8 christos bfd_put_8 (output_bfd, 0x66, contents + roff); 4848 1.1 christos bfd_put_8 (output_bfd, 0x90, contents + roff + 1); 4849 1.1 christos } 4850 1.1 christos continue; 4851 1.8 christos } 4852 1.1 christos else 4853 1.1 christos BFD_ASSERT (false); 4854 1.1 christos } 4855 1.1 christos break; 4856 1.1 christos 4857 1.1 christos case R_X86_64_TLSLD: 4858 1.1 christos if (! elf_x86_64_tls_transition (info, input_bfd, 4859 1.5 christos input_section, contents, 4860 1.10 christos symtab_hdr, sym_hashes, 4861 1.8 christos &r_type, GOT_UNKNOWN, rel, 4862 1.1 christos relend, h, sym, true)) 4863 1.1 christos return false; 4864 1.1 christos 4865 1.1 christos if (r_type != R_X86_64_TLSLD) 4866 1.5 christos { 4867 1.5 christos /* LD->LE transition: 4868 1.5 christos leaq foo@tlsld(%rip), %rdi 4869 1.5 christos call __tls_get_addr@PLT 4870 1.5 christos For 64bit, we change it into: 4871 1.5 christos .word 0x6666; .byte 0x66; movq %fs:0, %rax 4872 1.5 christos For 32bit, we change it into: 4873 1.5 christos nopl 0x0(%rax); movl %fs:0, %eax 4874 1.5 christos Or 4875 1.5 christos leaq foo@tlsld(%rip), %rdi; 4876 1.5 christos call *__tls_get_addr@GOTPCREL(%rip) 4877 1.1 christos which may be converted to 4878 1.5 christos addr32 call __tls_get_addr 4879 1.1 christos For 64bit, we change it into: 4880 1.5 christos .word 0x6666; .word 0x6666; movq %fs:0, %rax 4881 1.3 christos For 32bit, we change it into: 4882 1.5 christos nopw 0x0(%rax); movl %fs:0, %eax 4883 1.5 christos For largepic, change: 4884 1.5 christos leaq foo@tlsgd(%rip), %rdi 4885 1.5 christos movabsq $__tls_get_addr@pltoff, %rax 4886 1.5 christos addq %rbx, %rax 4887 1.5 christos call *%rax 4888 1.5 christos into 4889 1.1 christos data16 data16 data16 nopw %cs:0x0(%rax,%rax,1) 4890 1.1 christos movq %fs:0, %eax */ 4891 1.5 christos 4892 1.5 christos BFD_ASSERT (r_type == R_X86_64_TPOFF32); 4893 1.7 christos if (ABI_64_P (output_bfd)) 4894 1.7 christos { 4895 1.5 christos if ((rel->r_offset + 5) >= input_section->size) 4896 1.7 christos goto corrupt_input; 4897 1.7 christos if (contents[rel->r_offset + 5] == 0xb8) 4898 1.7 christos { 4899 1.7 christos if (rel->r_offset < 3 4900 1.7 christos || (rel->r_offset - 3 + 22) > input_section->size) 4901 1.7 christos goto corrupt_input; 4902 1.7 christos memcpy (contents + rel->r_offset - 3, 4903 1.7 christos "\x66\x66\x66\x66\x2e\x0f\x1f\x84\0\0\0\0\0" 4904 1.5 christos "\x64\x48\x8b\x04\x25\0\0\0", 22); 4905 1.5 christos } 4906 1.7 christos else if (contents[rel->r_offset + 4] == 0xff 4907 1.7 christos || contents[rel->r_offset + 4] == 0x67) 4908 1.7 christos { 4909 1.7 christos if (rel->r_offset < 3 4910 1.7 christos || (rel->r_offset - 3 + 13) > input_section->size) 4911 1.7 christos goto corrupt_input; 4912 1.7 christos memcpy (contents + rel->r_offset - 3, 4913 1.7 christos "\x66\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 4914 1.7 christos 13); 4915 1.5 christos 4916 1.7 christos } 4917 1.7 christos else 4918 1.7 christos { 4919 1.7 christos if (rel->r_offset < 3 4920 1.7 christos || (rel->r_offset - 3 + 12) > input_section->size) 4921 1.7 christos goto corrupt_input; 4922 1.7 christos memcpy (contents + rel->r_offset - 3, 4923 1.5 christos "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12); 4924 1.1 christos } 4925 1.5 christos } 4926 1.7 christos else 4927 1.7 christos { 4928 1.5 christos if ((rel->r_offset + 4) >= input_section->size) 4929 1.7 christos goto corrupt_input; 4930 1.7 christos if (contents[rel->r_offset + 4] == 0xff) 4931 1.7 christos { 4932 1.7 christos if (rel->r_offset < 3 4933 1.7 christos || (rel->r_offset - 3 + 13) > input_section->size) 4934 1.7 christos goto corrupt_input; 4935 1.7 christos memcpy (contents + rel->r_offset - 3, 4936 1.7 christos "\x66\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 4937 1.5 christos 13); 4938 1.7 christos } 4939 1.7 christos else 4940 1.7 christos { 4941 1.7 christos if (rel->r_offset < 3 4942 1.7 christos || (rel->r_offset - 3 + 12) > input_section->size) 4943 1.7 christos goto corrupt_input; 4944 1.7 christos memcpy (contents + rel->r_offset - 3, 4945 1.5 christos "\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12); 4946 1.5 christos } 4947 1.5 christos } 4948 1.1 christos /* Skip R_X86_64_PC32, R_X86_64_PLT32, R_X86_64_GOTPCRELX 4949 1.3 christos and R_X86_64_PLTOFF64. */ 4950 1.1 christos rel++; 4951 1.1 christos wrel++; 4952 1.1 christos continue; 4953 1.1 christos } 4954 1.1 christos 4955 1.1 christos if (htab->elf.sgot == NULL) 4956 1.6 christos abort (); 4957 1.1 christos 4958 1.1 christos off = htab->tls_ld_or_ldm_got.offset; 4959 1.1 christos if (off & 1) 4960 1.1 christos off &= ~1; 4961 1.1 christos else 4962 1.1 christos { 4963 1.1 christos Elf_Internal_Rela outrel; 4964 1.1 christos 4965 1.1 christos if (htab->elf.srelgot == NULL) 4966 1.1 christos abort (); 4967 1.1 christos 4968 1.1 christos outrel.r_offset = (htab->elf.sgot->output_section->vma 4969 1.1 christos + htab->elf.sgot->output_offset + off); 4970 1.1 christos 4971 1.1 christos bfd_put_64 (output_bfd, 0, 4972 1.1 christos htab->elf.sgot->contents + off); 4973 1.1 christos bfd_put_64 (output_bfd, 0, 4974 1.1 christos htab->elf.sgot->contents + off + GOT_ENTRY_SIZE); 4975 1.1 christos outrel.r_info = htab->r_info (0, R_X86_64_DTPMOD64); 4976 1.1 christos outrel.r_addend = 0; 4977 1.6 christos elf_append_rela (output_bfd, htab->elf.srelgot, 4978 1.1 christos &outrel); 4979 1.1 christos htab->tls_ld_or_ldm_got.offset |= 1; 4980 1.1 christos } 4981 1.8 christos relocation = htab->elf.sgot->output_section->vma 4982 1.1 christos + htab->elf.sgot->output_offset + off; 4983 1.1 christos unresolved_reloc = false; 4984 1.1 christos break; 4985 1.3 christos 4986 1.3 christos case R_X86_64_DTPOFF32: 4987 1.6 christos if (!bfd_link_executable (info) 4988 1.1 christos || (input_section->flags & SEC_CODE) == 0) 4989 1.1 christos relocation -= _bfd_x86_elf_dtpoff_base (info); 4990 1.1 christos else 4991 1.1 christos relocation = elf_x86_64_tpoff (info, relocation); 4992 1.1 christos break; 4993 1.1 christos 4994 1.3 christos case R_X86_64_TPOFF32: 4995 1.1 christos case R_X86_64_TPOFF64: 4996 1.1 christos BFD_ASSERT (bfd_link_executable (info)); 4997 1.1 christos relocation = elf_x86_64_tpoff (info, relocation); 4998 1.3 christos break; 4999 1.3 christos 5000 1.6 christos case R_X86_64_DTPOFF64: 5001 1.3 christos BFD_ASSERT ((input_section->flags & SEC_CODE) == 0); 5002 1.3 christos relocation -= _bfd_x86_elf_dtpoff_base (info); 5003 1.1 christos break; 5004 1.1 christos 5005 1.1 christos default: 5006 1.1 christos break; 5007 1.1 christos } 5008 1.1 christos 5009 1.1 christos /* Dynamic relocs are not propagated for SEC_DEBUGGING sections 5010 1.1 christos because such sections are not SEC_ALLOC and thus ld.so will 5011 1.1 christos not process them. */ 5012 1.1 christos if (unresolved_reloc 5013 1.1 christos && !((input_section->flags & SEC_DEBUGGING) != 0 5014 1.1 christos && h->def_dynamic) 5015 1.1 christos && _bfd_elf_section_offset (output_bfd, info, input_section, 5016 1.6 christos rel->r_offset) != (bfd_vma) -1) 5017 1.6 christos { 5018 1.6 christos switch (r_type) 5019 1.6 christos { 5020 1.8 christos case R_X86_64_32S: 5021 1.6 christos sec = h->root.u.def.section; 5022 1.6 christos if ((info->nocopyreloc || eh->def_protected) 5023 1.6 christos && !(h->root.u.def.section->flags & SEC_CODE)) 5024 1.6 christos return elf_x86_64_need_pic (info, input_bfd, input_section, 5025 1.6 christos h, NULL, NULL, howto); 5026 1.6 christos /* Fall through. */ 5027 1.6 christos 5028 1.6 christos default: 5029 1.6 christos _bfd_error_handler 5030 1.6 christos /* xgettext:c-format */ 5031 1.6 christos (_("%pB(%pA+%#" PRIx64 "): " 5032 1.6 christos "unresolvable %s relocation against symbol `%s'"), 5033 1.6 christos input_bfd, 5034 1.6 christos input_section, 5035 1.6 christos (uint64_t) rel->r_offset, 5036 1.8 christos howto->name, 5037 1.6 christos h->root.root.string); 5038 1.1 christos return false; 5039 1.1 christos } 5040 1.8 christos } 5041 1.1 christos 5042 1.1 christos do_relocation: 5043 1.1 christos r = _bfd_final_link_relocate (howto, input_bfd, input_section, 5044 1.1 christos contents, rel->r_offset, 5045 1.8 christos relocation, rel->r_addend); 5046 1.1 christos 5047 1.1 christos check_relocation_error: 5048 1.1 christos if (r != bfd_reloc_ok) 5049 1.1 christos { 5050 1.1 christos const char *name; 5051 1.1 christos 5052 1.1 christos if (h != NULL) 5053 1.1 christos name = h->root.root.string; 5054 1.1 christos else 5055 1.1 christos { 5056 1.1 christos name = bfd_elf_string_from_elf_section (input_bfd, 5057 1.1 christos symtab_hdr->sh_link, 5058 1.8 christos sym->st_name); 5059 1.1 christos if (name == NULL) 5060 1.7 christos return false; 5061 1.1 christos if (*name == '\0') 5062 1.1 christos name = bfd_section_name (sec); 5063 1.1 christos } 5064 1.6 christos 5065 1.6 christos if (r == bfd_reloc_overflow) 5066 1.6 christos { 5067 1.6 christos if (converted_reloc) 5068 1.8 christos { 5069 1.8 christos info->callbacks->einfo 5070 1.8 christos ("%X%H:", input_bfd, input_section, rel->r_offset); 5071 1.8 christos info->callbacks->einfo 5072 1.8 christos (_(" failed to convert GOTPCREL relocation against " 5073 1.8 christos "'%s'; relink with --no-relax\n"), 5074 1.8 christos name); 5075 1.6 christos status = false; 5076 1.6 christos continue; 5077 1.6 christos } 5078 1.6 christos (*info->callbacks->reloc_overflow) 5079 1.6 christos (info, (h ? &h->root : NULL), name, howto->name, 5080 1.1 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset); 5081 1.1 christos } 5082 1.6 christos else 5083 1.6 christos { 5084 1.6 christos _bfd_error_handler 5085 1.1 christos /* xgettext:c-format */ 5086 1.6 christos (_("%pB(%pA+%#" PRIx64 "): reloc against `%s': error %d"), 5087 1.8 christos input_bfd, input_section, 5088 1.1 christos (uint64_t) rel->r_offset, name, (int) r); 5089 1.1 christos return false; 5090 1.3 christos } 5091 1.3 christos } 5092 1.3 christos 5093 1.3 christos if (wrel != rel) 5094 1.3 christos *wrel = *rel; 5095 1.3 christos } 5096 1.3 christos 5097 1.3 christos if (wrel != rel) 5098 1.3 christos { 5099 1.3 christos Elf_Internal_Shdr *rel_hdr; 5100 1.3 christos size_t deleted = rel - wrel; 5101 1.3 christos 5102 1.3 christos rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); 5103 1.3 christos rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; 5104 1.3 christos if (rel_hdr->sh_size == 0) 5105 1.3 christos { 5106 1.3 christos /* It is too late to remove an empty reloc section. Leave 5107 1.3 christos one NONE reloc. 5108 1.3 christos ??? What is wrong with an empty section??? */ 5109 1.3 christos rel_hdr->sh_size = rel_hdr->sh_entsize; 5110 1.3 christos deleted -= 1; 5111 1.3 christos } 5112 1.3 christos rel_hdr = _bfd_elf_single_rel_hdr (input_section); 5113 1.1 christos rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted; 5114 1.1 christos input_section->reloc_count -= deleted; 5115 1.8 christos } 5116 1.1 christos 5117 1.1 christos return status; 5118 1.1 christos } 5119 1.1 christos 5120 1.1 christos /* Finish up dynamic symbol handling. We set the contents of various 5121 1.8 christos dynamic sections here. */ 5122 1.1 christos 5123 1.1 christos static bool 5124 1.1 christos elf_x86_64_finish_dynamic_symbol (bfd *output_bfd, 5125 1.5 christos struct bfd_link_info *info, 5126 1.1 christos struct elf_link_hash_entry *h, 5127 1.6 christos Elf_Internal_Sym *sym) 5128 1.8 christos { 5129 1.6 christos struct elf_x86_link_hash_table *htab; 5130 1.8 christos bool use_plt_second; 5131 1.1 christos struct elf_x86_link_hash_entry *eh; 5132 1.6 christos bool local_undefweak; 5133 1.1 christos 5134 1.6 christos htab = elf_x86_hash_table (info, X86_64_ELF_DATA); 5135 1.6 christos 5136 1.3 christos /* Use the second PLT section only if there is .plt section. */ 5137 1.6 christos use_plt_second = htab->elf.splt != NULL && htab->plt_second != NULL; 5138 1.6 christos 5139 1.6 christos eh = (struct elf_x86_link_hash_entry *) h; 5140 1.3 christos if (eh->no_finish_dynamic_symbol) 5141 1.5 christos abort (); 5142 1.5 christos 5143 1.5 christos /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for 5144 1.6 christos resolved undefined weak symbols in executable so that their 5145 1.5 christos references have value 0 at run-time. */ 5146 1.1 christos local_undefweak = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh); 5147 1.1 christos 5148 1.1 christos if (h->plt.offset != (bfd_vma) -1) 5149 1.6 christos { 5150 1.1 christos bfd_vma plt_index; 5151 1.1 christos bfd_vma got_offset, plt_offset; 5152 1.3 christos Elf_Internal_Rela rela; 5153 1.1 christos bfd_byte *loc; 5154 1.3 christos asection *plt, *gotplt, *relplt, *resolved_plt; 5155 1.1 christos const struct elf_backend_data *bed; 5156 1.1 christos bfd_vma plt_got_pcrel_offset; 5157 1.1 christos 5158 1.1 christos /* When building a static executable, use .iplt, .igot.plt and 5159 1.1 christos .rela.iplt sections for STT_GNU_IFUNC symbols. */ 5160 1.1 christos if (htab->elf.splt != NULL) 5161 1.1 christos { 5162 1.1 christos plt = htab->elf.splt; 5163 1.1 christos gotplt = htab->elf.sgotplt; 5164 1.1 christos relplt = htab->elf.srelplt; 5165 1.1 christos } 5166 1.1 christos else 5167 1.1 christos { 5168 1.1 christos plt = htab->elf.iplt; 5169 1.1 christos gotplt = htab->elf.igotplt; 5170 1.1 christos relplt = htab->elf.irelplt; 5171 1.6 christos } 5172 1.1 christos 5173 1.1 christos VERIFY_PLT_ENTRY (info, h, plt, gotplt, relplt, local_undefweak) 5174 1.1 christos 5175 1.1 christos /* Get the index in the procedure linkage table which 5176 1.1 christos corresponds to this symbol. This is the index of this symbol 5177 1.1 christos in all the symbols for which we are making plt entries. The 5178 1.1 christos first entry in the procedure linkage table is reserved. 5179 1.1 christos 5180 1.1 christos Get the offset into the .got table of the entry that 5181 1.1 christos corresponds to this function. Each .got entry is GOT_ENTRY_SIZE 5182 1.1 christos bytes. The first three are reserved for the dynamic linker. 5183 1.1 christos 5184 1.1 christos For static executables, we don't reserve anything. */ 5185 1.1 christos 5186 1.6 christos if (plt == htab->elf.splt) 5187 1.6 christos { 5188 1.1 christos got_offset = (h->plt.offset / htab->plt.plt_entry_size 5189 1.1 christos - htab->plt.has_plt0); 5190 1.1 christos got_offset = (got_offset + 3) * GOT_ENTRY_SIZE; 5191 1.1 christos } 5192 1.6 christos else 5193 1.1 christos { 5194 1.1 christos got_offset = h->plt.offset / htab->plt.plt_entry_size; 5195 1.1 christos got_offset = got_offset * GOT_ENTRY_SIZE; 5196 1.6 christos } 5197 1.6 christos 5198 1.6 christos /* Fill in the entry in the procedure linkage table. */ 5199 1.6 christos memcpy (plt->contents + h->plt.offset, htab->plt.plt_entry, 5200 1.6 christos htab->plt.plt_entry_size); 5201 1.6 christos if (use_plt_second) 5202 1.6 christos { 5203 1.6 christos memcpy (htab->plt_second->contents + eh->plt_second.offset, 5204 1.3 christos htab->non_lazy_plt->plt_entry, 5205 1.6 christos htab->non_lazy_plt->plt_entry_size); 5206 1.6 christos 5207 1.3 christos resolved_plt = htab->plt_second; 5208 1.3 christos plt_offset = eh->plt_second.offset; 5209 1.3 christos } 5210 1.3 christos else 5211 1.3 christos { 5212 1.3 christos resolved_plt = plt; 5213 1.1 christos plt_offset = h->plt.offset; 5214 1.1 christos } 5215 1.1 christos 5216 1.1 christos /* Insert the relocation positions of the plt section. */ 5217 1.1 christos 5218 1.3 christos /* Put offset the PC-relative instruction referring to the GOT entry, 5219 1.3 christos subtracting the size of that instruction. */ 5220 1.3 christos plt_got_pcrel_offset = (gotplt->output_section->vma 5221 1.3 christos + gotplt->output_offset 5222 1.3 christos + got_offset 5223 1.3 christos - resolved_plt->output_section->vma 5224 1.6 christos - resolved_plt->output_offset 5225 1.3 christos - plt_offset 5226 1.3 christos - htab->plt.plt_got_insn_size); 5227 1.3 christos 5228 1.6 christos /* Check PC-relative offset overflow in PLT entry. */ 5229 1.10 christos if ((plt_got_pcrel_offset + 0x80000000) > 0xffffffff) 5230 1.3 christos /* xgettext:c-format */ 5231 1.3 christos info->callbacks->fatal (_("%pB: PC-relative offset overflow in PLT entry for `%s'\n"), 5232 1.3 christos output_bfd, h->root.root.string); 5233 1.6 christos 5234 1.6 christos bfd_put_32 (output_bfd, plt_got_pcrel_offset, 5235 1.1 christos (resolved_plt->contents + plt_offset 5236 1.1 christos + htab->plt.plt_got_offset)); 5237 1.5 christos 5238 1.5 christos /* Fill in the entry in the global offset table, initially this 5239 1.5 christos points to the second part of the PLT entry. Leave the entry 5240 1.5 christos as zero for undefined weak symbol in PIE. No PLT relocation 5241 1.5 christos against undefined weak symbol in PIE. */ 5242 1.6 christos if (!local_undefweak) 5243 1.6 christos { 5244 1.6 christos if (htab->plt.has_plt0) 5245 1.6 christos bfd_put_64 (output_bfd, (plt->output_section->vma 5246 1.6 christos + plt->output_offset 5247 1.6 christos + h->plt.offset 5248 1.5 christos + htab->lazy_plt->plt_lazy_offset), 5249 1.5 christos gotplt->contents + got_offset); 5250 1.5 christos 5251 1.5 christos /* Fill in the entry in the .rela.plt section. */ 5252 1.5 christos rela.r_offset = (gotplt->output_section->vma 5253 1.6 christos + gotplt->output_offset 5254 1.5 christos + got_offset); 5255 1.10 christos if (PLT_LOCAL_IFUNC_P (info, h)) 5256 1.10 christos { 5257 1.10 christos if (h->root.u.def.section == NULL) 5258 1.6 christos return false; 5259 1.6 christos 5260 1.6 christos info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"), 5261 1.6 christos h->root.root.string, 5262 1.5 christos h->root.u.def.section->owner); 5263 1.5 christos 5264 1.5 christos /* If an STT_GNU_IFUNC symbol is locally defined, generate 5265 1.5 christos R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT. */ 5266 1.5 christos rela.r_info = htab->r_info (0, R_X86_64_IRELATIVE); 5267 1.5 christos rela.r_addend = (h->root.u.def.value 5268 1.8 christos + h->root.u.def.section->output_section->vma 5269 1.8 christos + h->root.u.def.section->output_offset); 5270 1.8 christos 5271 1.8 christos if (htab->params->report_relative_reloc) 5272 1.8 christos _bfd_x86_elf_link_report_relative_reloc 5273 1.5 christos (info, relplt, h, sym, "R_X86_64_IRELATIVE", &rela); 5274 1.5 christos 5275 1.5 christos /* R_X86_64_IRELATIVE comes last. */ 5276 1.5 christos plt_index = htab->next_irelative_index--; 5277 1.5 christos } 5278 1.5 christos else 5279 1.9 christos { 5280 1.9 christos rela.r_info = htab->r_info (h->dynindx, R_X86_64_JUMP_SLOT); 5281 1.9 christos if (htab->params->mark_plt) 5282 1.9 christos rela.r_addend = (resolved_plt->output_section->vma 5283 1.9 christos + plt_offset 5284 1.9 christos + htab->plt.plt_indirect_branch_offset); 5285 1.5 christos else 5286 1.5 christos rela.r_addend = 0; 5287 1.5 christos plt_index = htab->next_jump_slot_index++; 5288 1.6 christos } 5289 1.6 christos 5290 1.6 christos /* Don't fill the second and third slots in PLT entry for 5291 1.5 christos static executables nor without PLT0. */ 5292 1.6 christos if (plt == htab->elf.splt && htab->plt.has_plt0) 5293 1.6 christos { 5294 1.5 christos bfd_vma plt0_offset 5295 1.5 christos = h->plt.offset + htab->lazy_plt->plt_plt_insn_end; 5296 1.5 christos 5297 1.5 christos /* Put relocation index. */ 5298 1.6 christos bfd_put_32 (output_bfd, plt_index, 5299 1.5 christos (plt->contents + h->plt.offset 5300 1.5 christos + htab->lazy_plt->plt_reloc_offset)); 5301 1.5 christos 5302 1.5 christos /* Put offset for jmp .PLT0 and check for overflow. We don't 5303 1.5 christos check relocation index for overflow since branch displacement 5304 1.6 christos will overflow first. */ 5305 1.10 christos if (plt0_offset > 0x80000000) 5306 1.5 christos /* xgettext:c-format */ 5307 1.5 christos info->callbacks->fatal (_("%pB: branch displacement overflow in PLT entry for `%s'\n"), 5308 1.6 christos output_bfd, h->root.root.string); 5309 1.6 christos bfd_put_32 (output_bfd, - plt0_offset, 5310 1.5 christos (plt->contents + h->plt.offset 5311 1.5 christos + htab->lazy_plt->plt_plt_offset)); 5312 1.5 christos } 5313 1.5 christos 5314 1.5 christos bed = get_elf_backend_data (output_bfd); 5315 1.1 christos loc = relplt->contents + plt_index * bed->s->sizeof_rela; 5316 1.3 christos bed->s->swap_reloca_out (output_bfd, &rela, loc); 5317 1.3 christos } 5318 1.3 christos } 5319 1.6 christos else if (eh->plt_got.offset != (bfd_vma) -1) 5320 1.3 christos { 5321 1.8 christos bfd_vma got_offset, plt_offset; 5322 1.3 christos asection *plt, *got; 5323 1.3 christos bool got_after_plt; 5324 1.3 christos int32_t got_pcrel_offset; 5325 1.3 christos 5326 1.3 christos /* Set the entry in the GOT procedure linkage table. */ 5327 1.3 christos plt = htab->plt_got; 5328 1.1 christos got = htab->elf.sgot; 5329 1.3 christos got_offset = h->got.offset; 5330 1.6 christos 5331 1.3 christos if (got_offset == (bfd_vma) -1 5332 1.3 christos || (h->type == STT_GNU_IFUNC && h->def_regular) 5333 1.3 christos || plt == NULL 5334 1.3 christos || got == NULL) 5335 1.6 christos abort (); 5336 1.3 christos 5337 1.3 christos /* Use the non-lazy PLT entry template for the GOT PLT since they 5338 1.3 christos are the identical. */ 5339 1.3 christos /* Fill in the entry in the GOT procedure linkage table. */ 5340 1.6 christos plt_offset = eh->plt_got.offset; 5341 1.6 christos memcpy (plt->contents + plt_offset, 5342 1.3 christos htab->non_lazy_plt->plt_entry, 5343 1.3 christos htab->non_lazy_plt->plt_entry_size); 5344 1.3 christos 5345 1.3 christos /* Put offset the PC-relative instruction referring to the GOT 5346 1.3 christos entry, subtracting the size of that instruction. */ 5347 1.3 christos got_pcrel_offset = (got->output_section->vma 5348 1.3 christos + got->output_offset 5349 1.3 christos + got_offset 5350 1.3 christos - plt->output_section->vma 5351 1.6 christos - plt->output_offset 5352 1.3 christos - plt_offset 5353 1.3 christos - htab->non_lazy_plt->plt_got_insn_size); 5354 1.3 christos 5355 1.3 christos /* Check PC-relative offset overflow in GOT PLT entry. */ 5356 1.3 christos got_after_plt = got->output_section->vma > plt->output_section->vma; 5357 1.6 christos if ((got_after_plt && got_pcrel_offset < 0) 5358 1.10 christos || (!got_after_plt && got_pcrel_offset > 0)) 5359 1.3 christos /* xgettext:c-format */ 5360 1.3 christos info->callbacks->fatal (_("%pB: PC-relative offset overflow in GOT PLT entry for `%s'\n"), 5361 1.3 christos output_bfd, h->root.root.string); 5362 1.6 christos 5363 1.6 christos bfd_put_32 (output_bfd, got_pcrel_offset, 5364 1.3 christos (plt->contents + plt_offset 5365 1.3 christos + htab->non_lazy_plt->plt_got_offset)); 5366 1.5 christos } 5367 1.5 christos 5368 1.3 christos if (!local_undefweak 5369 1.3 christos && !h->def_regular 5370 1.3 christos && (h->plt.offset != (bfd_vma) -1 5371 1.3 christos || eh->plt_got.offset != (bfd_vma) -1)) 5372 1.3 christos { 5373 1.3 christos /* Mark the symbol as undefined, rather than as defined in 5374 1.3 christos the .plt section. Leave the value if there were any 5375 1.3 christos relocations where pointer equality matters (this is a clue 5376 1.3 christos for the dynamic linker, to make function pointer 5377 1.3 christos comparisons work between an application and shared 5378 1.3 christos library), otherwise set it to zero. If a function is only 5379 1.3 christos called from a binary, there is no need to slow down 5380 1.3 christos shared libraries because of that. */ 5381 1.3 christos sym->st_shndx = SHN_UNDEF; 5382 1.1 christos if (!h->pointer_equality_needed) 5383 1.1 christos sym->st_value = 0; 5384 1.6 christos } 5385 1.6 christos 5386 1.5 christos _bfd_x86_elf_link_fixup_ifunc_symbol (info, htab, h, sym); 5387 1.5 christos 5388 1.1 christos /* Don't generate dynamic GOT relocation against undefined weak 5389 1.6 christos symbol in executable. */ 5390 1.6 christos if (h->got.offset != (bfd_vma) -1 5391 1.5 christos && ! GOT_TLS_GD_ANY_P (elf_x86_hash_entry (h)->tls_type) 5392 1.1 christos && elf_x86_hash_entry (h)->tls_type != GOT_TLS_IE 5393 1.1 christos && !local_undefweak) 5394 1.5 christos { 5395 1.8 christos Elf_Internal_Rela rela; 5396 1.8 christos asection *relgot = htab->elf.srelgot; 5397 1.1 christos const char *relative_reloc_name = NULL; 5398 1.1 christos bool generate_dynamic_reloc = true; 5399 1.1 christos 5400 1.1 christos /* This symbol has an entry in the global offset table. Set it 5401 1.1 christos up. */ 5402 1.1 christos if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL) 5403 1.1 christos abort (); 5404 1.1 christos 5405 1.1 christos rela.r_offset = (htab->elf.sgot->output_section->vma 5406 1.1 christos + htab->elf.sgot->output_offset 5407 1.1 christos + (h->got.offset &~ (bfd_vma) 1)); 5408 1.1 christos 5409 1.1 christos /* If this is a static link, or it is a -Bsymbolic link and the 5410 1.1 christos symbol is defined locally or was forced to be local because 5411 1.1 christos of a version file, we just want to emit a RELATIVE reloc. 5412 1.1 christos The entry in the global offset table will already have been 5413 1.1 christos initialized in the relocate_section function. */ 5414 1.1 christos if (h->def_regular 5415 1.5 christos && h->type == STT_GNU_IFUNC) 5416 1.5 christos { 5417 1.5 christos if (h->plt.offset == (bfd_vma) -1) 5418 1.5 christos { 5419 1.5 christos /* STT_GNU_IFUNC is referenced without PLT. */ 5420 1.5 christos if (htab->elf.splt == NULL) 5421 1.5 christos { 5422 1.5 christos /* use .rel[a].iplt section to store .got relocations 5423 1.5 christos in static executable. */ 5424 1.6 christos relgot = htab->elf.irelplt; 5425 1.5 christos } 5426 1.10 christos if (SYMBOL_REFERENCES_LOCAL_P (info, h)) 5427 1.10 christos { 5428 1.10 christos if (h->root.u.def.section == NULL) 5429 1.6 christos return false; 5430 1.6 christos 5431 1.6 christos info->callbacks->minfo (_("Local IFUNC function `%s' in %pB\n"), 5432 1.6 christos h->root.root.string, 5433 1.5 christos h->root.u.def.section->owner); 5434 1.5 christos 5435 1.5 christos rela.r_info = htab->r_info (0, 5436 1.5 christos R_X86_64_IRELATIVE); 5437 1.5 christos rela.r_addend = (h->root.u.def.value 5438 1.8 christos + h->root.u.def.section->output_section->vma 5439 1.5 christos + h->root.u.def.section->output_offset); 5440 1.5 christos relative_reloc_name = "R_X86_64_IRELATIVE"; 5441 1.5 christos } 5442 1.5 christos else 5443 1.5 christos goto do_glob_dat; 5444 1.1 christos } 5445 1.1 christos else if (bfd_link_pic (info)) 5446 1.1 christos { 5447 1.1 christos /* Generate R_X86_64_GLOB_DAT. */ 5448 1.1 christos goto do_glob_dat; 5449 1.1 christos } 5450 1.1 christos else 5451 1.6 christos { 5452 1.1 christos asection *plt; 5453 1.1 christos bfd_vma plt_offset; 5454 1.1 christos 5455 1.1 christos if (!h->pointer_equality_needed) 5456 1.1 christos abort (); 5457 1.1 christos 5458 1.1 christos /* For non-shared object, we can't use .got.plt, which 5459 1.6 christos contains the real function addres if we need pointer 5460 1.6 christos equality. We load the GOT entry with the PLT entry. */ 5461 1.6 christos if (htab->plt_second != NULL) 5462 1.6 christos { 5463 1.6 christos plt = htab->plt_second; 5464 1.6 christos plt_offset = eh->plt_second.offset; 5465 1.6 christos } 5466 1.6 christos else 5467 1.6 christos { 5468 1.6 christos plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt; 5469 1.1 christos plt_offset = h->plt.offset; 5470 1.1 christos } 5471 1.6 christos bfd_put_64 (output_bfd, (plt->output_section->vma 5472 1.1 christos + plt->output_offset 5473 1.8 christos + plt_offset), 5474 1.1 christos htab->elf.sgot->contents + h->got.offset); 5475 1.1 christos return true; 5476 1.3 christos } 5477 1.6 christos } 5478 1.1 christos else if (bfd_link_pic (info) 5479 1.7 christos && SYMBOL_REFERENCES_LOCAL_P (info, h)) 5480 1.8 christos { 5481 1.1 christos if (!SYMBOL_DEFINED_NON_SHARED_P (h)) 5482 1.8 christos return false; 5483 1.8 christos BFD_ASSERT((h->got.offset & 1) != 0); 5484 1.8 christos if (info->enable_dt_relr) 5485 1.8 christos generate_dynamic_reloc = false; 5486 1.8 christos else 5487 1.8 christos { 5488 1.8 christos rela.r_info = htab->r_info (0, R_X86_64_RELATIVE); 5489 1.8 christos rela.r_addend = (h->root.u.def.value 5490 1.8 christos + h->root.u.def.section->output_section->vma 5491 1.8 christos + h->root.u.def.section->output_offset); 5492 1.1 christos relative_reloc_name = "R_X86_64_RELATIVE"; 5493 1.1 christos } 5494 1.1 christos } 5495 1.1 christos else 5496 1.8 christos { 5497 1.1 christos BFD_ASSERT((h->got.offset & 1) == 0); 5498 1.1 christos do_glob_dat: 5499 1.1 christos bfd_put_64 (output_bfd, (bfd_vma) 0, 5500 1.1 christos htab->elf.sgot->contents + h->got.offset); 5501 1.1 christos rela.r_info = htab->r_info (h->dynindx, R_X86_64_GLOB_DAT); 5502 1.1 christos rela.r_addend = 0; 5503 1.8 christos } 5504 1.8 christos 5505 1.10 christos if (generate_dynamic_reloc) 5506 1.10 christos { 5507 1.10 christos /* If the relgot section has not been created, then 5508 1.10 christos generate an error instead of a reloc. cf PR 32638. */ 5509 1.10 christos if (relgot == NULL || relgot->size == 0) 5510 1.10 christos { 5511 1.10 christos info->callbacks->fatal (_("%pB: Unable to generate dynamic relocs because a suitable section does not exist\n"), 5512 1.10 christos output_bfd); 5513 1.10 christos return false; 5514 1.8 christos } 5515 1.8 christos 5516 1.8 christos if (relative_reloc_name != NULL 5517 1.8 christos && htab->params->report_relative_reloc) 5518 1.8 christos _bfd_x86_elf_link_report_relative_reloc 5519 1.8 christos (info, relgot, h, sym, relative_reloc_name, &rela); 5520 1.8 christos 5521 1.1 christos elf_append_rela (output_bfd, relgot, &rela); 5522 1.1 christos } 5523 1.1 christos } 5524 1.1 christos 5525 1.1 christos if (h->needs_copy) 5526 1.6 christos { 5527 1.1 christos Elf_Internal_Rela rela; 5528 1.1 christos asection *s; 5529 1.6 christos 5530 1.1 christos /* This symbol needs a copy reloc. Set it up. */ 5531 1.1 christos VERIFY_COPY_RELOC (h, htab) 5532 1.1 christos 5533 1.1 christos rela.r_offset = (h->root.u.def.value 5534 1.1 christos + h->root.u.def.section->output_section->vma 5535 1.1 christos + h->root.u.def.section->output_offset); 5536 1.6 christos rela.r_info = htab->r_info (h->dynindx, R_X86_64_COPY); 5537 1.6 christos rela.r_addend = 0; 5538 1.6 christos if (h->root.u.def.section == htab->elf.sdynrelro) 5539 1.6 christos s = htab->elf.sreldynrelro; 5540 1.6 christos else 5541 1.1 christos s = htab->elf.srelbss; 5542 1.1 christos elf_append_rela (output_bfd, s, &rela); 5543 1.8 christos } 5544 1.1 christos 5545 1.1 christos return true; 5546 1.1 christos } 5547 1.1 christos 5548 1.1 christos /* Finish up local dynamic symbol handling. We set the contents of 5549 1.8 christos various dynamic sections here. */ 5550 1.1 christos 5551 1.1 christos static int 5552 1.1 christos elf_x86_64_finish_local_dynamic_symbol (void **slot, void *inf) 5553 1.1 christos { 5554 1.1 christos struct elf_link_hash_entry *h 5555 1.1 christos = (struct elf_link_hash_entry *) *slot; 5556 1.1 christos struct bfd_link_info *info 5557 1.1 christos = (struct bfd_link_info *) inf; 5558 1.6 christos 5559 1.1 christos return elf_x86_64_finish_dynamic_symbol (info->output_bfd, 5560 1.1 christos info, h, NULL); 5561 1.5 christos } 5562 1.5 christos 5563 1.5 christos /* Finish up undefined weak symbol handling in PIE. Fill its PLT entry 5564 1.5 christos here since undefined weak symbol may not be dynamic and may not be 5565 1.8 christos called for elf_x86_64_finish_dynamic_symbol. */ 5566 1.5 christos 5567 1.5 christos static bool 5568 1.5 christos elf_x86_64_pie_finish_undefweak_symbol (struct bfd_hash_entry *bh, 5569 1.5 christos void *inf) 5570 1.5 christos { 5571 1.5 christos struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) bh; 5572 1.5 christos struct bfd_link_info *info = (struct bfd_link_info *) inf; 5573 1.5 christos 5574 1.8 christos if (h->root.type != bfd_link_hash_undefweak 5575 1.5 christos || h->dynindx != -1) 5576 1.5 christos return true; 5577 1.6 christos 5578 1.5 christos return elf_x86_64_finish_dynamic_symbol (info->output_bfd, 5579 1.5 christos info, h, NULL); 5580 1.1 christos } 5581 1.1 christos 5582 1.1 christos /* Used to decide how to sort relocs in an optimal manner for the 5583 1.1 christos dynamic linker, before writing them out. */ 5584 1.3 christos 5585 1.3 christos static enum elf_reloc_type_class 5586 1.3 christos elf_x86_64_reloc_type_class (const struct bfd_link_info *info, 5587 1.1 christos const asection *rel_sec ATTRIBUTE_UNUSED, 5588 1.3 christos const Elf_Internal_Rela *rela) 5589 1.3 christos { 5590 1.6 christos bfd *abfd = info->output_bfd; 5591 1.6 christos const struct elf_backend_data *bed = get_elf_backend_data (abfd); 5592 1.3 christos struct elf_x86_link_hash_table *htab 5593 1.3 christos = elf_x86_hash_table (info, X86_64_ELF_DATA); 5594 1.3 christos 5595 1.3 christos if (htab->elf.dynsym != NULL 5596 1.3 christos && htab->elf.dynsym->contents != NULL) 5597 1.6 christos { 5598 1.3 christos /* Check relocation against STT_GNU_IFUNC symbol if there are 5599 1.5 christos dynamic symbols. */ 5600 1.5 christos unsigned long r_symndx = htab->r_sym (rela->r_info); 5601 1.5 christos if (r_symndx != STN_UNDEF) 5602 1.5 christos { 5603 1.5 christos Elf_Internal_Sym sym; 5604 1.5 christos if (!bed->s->swap_symbol_in (abfd, 5605 1.5 christos (htab->elf.dynsym->contents 5606 1.5 christos + r_symndx * bed->s->sizeof_sym), 5607 1.3 christos 0, &sym)) 5608 1.5 christos abort (); 5609 1.5 christos 5610 1.5 christos if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC) 5611 1.3 christos return reloc_class_ifunc; 5612 1.3 christos } 5613 1.1 christos } 5614 1.1 christos 5615 1.5 christos switch ((int) ELF32_R_TYPE (rela->r_info)) 5616 1.5 christos { 5617 1.1 christos case R_X86_64_IRELATIVE: 5618 1.1 christos return reloc_class_ifunc; 5619 1.1 christos case R_X86_64_RELATIVE: 5620 1.1 christos case R_X86_64_RELATIVE64: 5621 1.1 christos return reloc_class_relative; 5622 1.1 christos case R_X86_64_JUMP_SLOT: 5623 1.1 christos return reloc_class_plt; 5624 1.1 christos case R_X86_64_COPY: 5625 1.1 christos return reloc_class_copy; 5626 1.1 christos default: 5627 1.1 christos return reloc_class_normal; 5628 1.1 christos } 5629 1.1 christos } 5630 1.1 christos 5631 1.8 christos /* Finish up the dynamic sections. */ 5632 1.1 christos 5633 1.1 christos static bool 5634 1.1 christos elf_x86_64_finish_dynamic_sections (bfd *output_bfd, 5635 1.6 christos struct bfd_link_info *info) 5636 1.1 christos { 5637 1.6 christos struct elf_x86_link_hash_table *htab; 5638 1.1 christos 5639 1.8 christos htab = _bfd_x86_elf_finish_dynamic_sections (output_bfd, info); 5640 1.1 christos if (htab == NULL) 5641 1.6 christos return false; 5642 1.8 christos 5643 1.1 christos if (! htab->elf.dynamic_sections_created) 5644 1.6 christos return true; 5645 1.1 christos 5646 1.8 christos if (htab->elf.splt && htab->elf.splt->size > 0) 5647 1.8 christos { 5648 1.10 christos if (bfd_is_abs_section (htab->elf.splt->output_section)) 5649 1.10 christos { 5650 1.8 christos info->callbacks->fatal 5651 1.8 christos (_("%P: discarded output section: `%pA'\n"), 5652 1.8 christos htab->elf.splt); 5653 1.8 christos return false; 5654 1.6 christos } 5655 1.6 christos 5656 1.1 christos elf_section_data (htab->elf.splt->output_section) 5657 1.6 christos ->this_hdr.sh_entsize = htab->plt.plt_entry_size; 5658 1.1 christos 5659 1.6 christos if (htab->plt.has_plt0) 5660 1.6 christos { 5661 1.1 christos /* Fill in the special first entry in the procedure linkage 5662 1.6 christos table. */ 5663 1.6 christos memcpy (htab->elf.splt->contents, 5664 1.1 christos htab->lazy_plt->plt0_entry, 5665 1.1 christos htab->lazy_plt->plt0_entry_size); 5666 1.1 christos /* Add offset for pushq GOT+8(%rip), since the instruction 5667 1.1 christos uses 6 bytes subtract this value. */ 5668 1.1 christos bfd_put_32 (output_bfd, 5669 1.1 christos (htab->elf.sgotplt->output_section->vma 5670 1.1 christos + htab->elf.sgotplt->output_offset 5671 1.1 christos + 8 5672 1.1 christos - htab->elf.splt->output_section->vma 5673 1.6 christos - htab->elf.splt->output_offset 5674 1.6 christos - 6), 5675 1.6 christos (htab->elf.splt->contents 5676 1.6 christos + htab->lazy_plt->plt0_got1_offset)); 5677 1.6 christos /* Add offset for the PC-relative instruction accessing 5678 1.1 christos GOT+16, subtracting the offset to the end of that 5679 1.1 christos instruction. */ 5680 1.1 christos bfd_put_32 (output_bfd, 5681 1.1 christos (htab->elf.sgotplt->output_section->vma 5682 1.1 christos + htab->elf.sgotplt->output_offset 5683 1.1 christos + 16 5684 1.6 christos - htab->elf.splt->output_section->vma 5685 1.6 christos - htab->elf.splt->output_offset 5686 1.6 christos - htab->lazy_plt->plt0_got2_insn_end), 5687 1.1 christos (htab->elf.splt->contents 5688 1.1 christos + htab->lazy_plt->plt0_got2_offset)); 5689 1.8 christos } 5690 1.1 christos 5691 1.6 christos if (htab->elf.tlsdesc_plt) 5692 1.8 christos { 5693 1.1 christos bfd_put_64 (output_bfd, (bfd_vma) 0, 5694 1.8 christos htab->elf.sgot->contents + htab->elf.tlsdesc_got); 5695 1.6 christos 5696 1.6 christos memcpy (htab->elf.splt->contents + htab->elf.tlsdesc_plt, 5697 1.6 christos htab->lazy_plt->plt_tlsdesc_entry, 5698 1.6 christos htab->lazy_plt->plt_tlsdesc_entry_size); 5699 1.6 christos 5700 1.6 christos /* Add offset for pushq GOT+8(%rip), since ENDBR64 uses 4 5701 1.6 christos bytes and the instruction uses 6 bytes, subtract these 5702 1.6 christos values. */ 5703 1.6 christos bfd_put_32 (output_bfd, 5704 1.6 christos (htab->elf.sgotplt->output_section->vma 5705 1.6 christos + htab->elf.sgotplt->output_offset 5706 1.6 christos + 8 5707 1.8 christos - htab->elf.splt->output_section->vma 5708 1.6 christos - htab->elf.splt->output_offset 5709 1.6 christos - htab->elf.tlsdesc_plt 5710 1.8 christos - htab->lazy_plt->plt_tlsdesc_got1_insn_end), 5711 1.6 christos (htab->elf.splt->contents 5712 1.6 christos + htab->elf.tlsdesc_plt 5713 1.6 christos + htab->lazy_plt->plt_tlsdesc_got1_offset)); 5714 1.6 christos /* Add offset for indirect branch via GOT+TDG, where TDG 5715 1.6 christos stands for htab->tlsdesc_got, subtracting the offset 5716 1.6 christos to the end of that instruction. */ 5717 1.6 christos bfd_put_32 (output_bfd, 5718 1.8 christos (htab->elf.sgot->output_section->vma 5719 1.6 christos + htab->elf.sgot->output_offset 5720 1.6 christos + htab->elf.tlsdesc_got 5721 1.8 christos - htab->elf.splt->output_section->vma 5722 1.6 christos - htab->elf.splt->output_offset 5723 1.6 christos - htab->elf.tlsdesc_plt 5724 1.8 christos - htab->lazy_plt->plt_tlsdesc_got2_insn_end), 5725 1.6 christos (htab->elf.splt->contents 5726 1.1 christos + htab->elf.tlsdesc_plt 5727 1.1 christos + htab->lazy_plt->plt_tlsdesc_got2_offset)); 5728 1.1 christos } 5729 1.5 christos } 5730 1.5 christos 5731 1.5 christos /* Fill PLT entries for undefined weak symbols in PIE. */ 5732 1.5 christos if (bfd_link_pie (info)) 5733 1.5 christos bfd_hash_traverse (&info->hash->table, 5734 1.5 christos elf_x86_64_pie_finish_undefweak_symbol, 5735 1.8 christos info); 5736 1.5 christos 5737 1.5 christos return true; 5738 1.5 christos } 5739 1.5 christos 5740 1.5 christos /* Fill PLT/GOT entries and allocate dynamic relocations for local 5741 1.5 christos STT_GNU_IFUNC symbols, which aren't in the ELF linker hash table. 5742 1.5 christos It has to be done before elf_link_sort_relocs is called so that 5743 1.8 christos dynamic relocations are properly sorted. */ 5744 1.5 christos 5745 1.5 christos static bool 5746 1.5 christos elf_x86_64_output_arch_local_syms 5747 1.5 christos (bfd *output_bfd ATTRIBUTE_UNUSED, 5748 1.5 christos struct bfd_link_info *info, 5749 1.5 christos void *flaginfo ATTRIBUTE_UNUSED, 5750 1.5 christos int (*func) (void *, const char *, 5751 1.5 christos Elf_Internal_Sym *, 5752 1.5 christos asection *, 5753 1.6 christos struct elf_link_hash_entry *) ATTRIBUTE_UNUSED) 5754 1.6 christos { 5755 1.5 christos struct elf_x86_link_hash_table *htab 5756 1.8 christos = elf_x86_hash_table (info, X86_64_ELF_DATA); 5757 1.5 christos if (htab == NULL) 5758 1.1 christos return false; 5759 1.1 christos 5760 1.1 christos /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */ 5761 1.1 christos htab_traverse (htab->loc_hash_table, 5762 1.1 christos elf_x86_64_finish_local_dynamic_symbol, 5763 1.8 christos info); 5764 1.1 christos 5765 1.1 christos return true; 5766 1.6 christos } 5767 1.6 christos 5768 1.3 christos /* Similar to _bfd_elf_get_synthetic_symtab. Support PLTs with all 5769 1.6 christos dynamic relocations. */ 5770 1.6 christos 5771 1.6 christos static long 5772 1.6 christos elf_x86_64_get_synthetic_symtab (bfd *abfd, 5773 1.6 christos long symcount ATTRIBUTE_UNUSED, 5774 1.6 christos asymbol **syms ATTRIBUTE_UNUSED, 5775 1.6 christos long dynsymcount, 5776 1.6 christos asymbol **dynsyms, 5777 1.6 christos asymbol **ret) 5778 1.6 christos { 5779 1.3 christos long count, i, n; 5780 1.6 christos int j; 5781 1.6 christos bfd_byte *plt_contents; 5782 1.6 christos long relsize; 5783 1.6 christos const struct elf_x86_lazy_plt_layout *lazy_plt; 5784 1.6 christos const struct elf_x86_non_lazy_plt_layout *non_lazy_plt; 5785 1.10 christos const struct elf_x86_lazy_plt_layout *lazy_bnd_plt; 5786 1.10 christos const struct elf_x86_non_lazy_plt_layout *non_lazy_bnd_plt; 5787 1.6 christos const struct elf_x86_lazy_plt_layout *lazy_bnd_ibt_plt; 5788 1.6 christos const struct elf_x86_non_lazy_plt_layout *non_lazy_bnd_ibt_plt; 5789 1.6 christos const struct elf_x86_lazy_plt_layout *lazy_ibt_plt; 5790 1.6 christos const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt; 5791 1.6 christos asection *plt; 5792 1.6 christos enum elf_x86_plt_type plt_type; 5793 1.6 christos struct elf_x86_plt plts[] = 5794 1.6 christos { 5795 1.6 christos { ".plt", NULL, NULL, plt_unknown, 0, 0, 0, 0 }, 5796 1.6 christos { ".plt.got", NULL, NULL, plt_non_lazy, 0, 0, 0, 0 }, 5797 1.6 christos { ".plt.sec", NULL, NULL, plt_second, 0, 0, 0, 0 }, 5798 1.6 christos { ".plt.bnd", NULL, NULL, plt_second, 0, 0, 0, 0 }, 5799 1.6 christos { NULL, NULL, NULL, plt_non_lazy, 0, 0, 0, 0 } 5800 1.6 christos }; 5801 1.6 christos 5802 1.6 christos *ret = NULL; 5803 1.6 christos 5804 1.6 christos if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0) 5805 1.6 christos return 0; 5806 1.6 christos 5807 1.6 christos if (dynsymcount <= 0) 5808 1.6 christos return 0; 5809 1.6 christos 5810 1.6 christos relsize = bfd_get_dynamic_reloc_upper_bound (abfd); 5811 1.6 christos if (relsize <= 0) 5812 1.8 christos return -1; 5813 1.8 christos 5814 1.10 christos lazy_plt = &elf_x86_64_lazy_plt; 5815 1.10 christos non_lazy_plt = &elf_x86_64_non_lazy_plt; 5816 1.8 christos lazy_ibt_plt = &elf_x86_64_lazy_ibt_plt; 5817 1.6 christos non_lazy_ibt_plt = &elf_x86_64_non_lazy_ibt_plt; 5818 1.10 christos if (ABI_64_P (abfd)) 5819 1.10 christos { 5820 1.10 christos lazy_bnd_ibt_plt = &elf_x86_64_lazy_bnd_ibt_plt; 5821 1.10 christos non_lazy_bnd_ibt_plt = &elf_x86_64_non_lazy_bnd_ibt_plt; 5822 1.6 christos lazy_bnd_plt = &elf_x86_64_lazy_bnd_plt; 5823 1.6 christos non_lazy_bnd_plt = &elf_x86_64_non_lazy_bnd_plt; 5824 1.3 christos } 5825 1.10 christos else 5826 1.10 christos { 5827 1.10 christos lazy_bnd_ibt_plt = NULL; 5828 1.10 christos non_lazy_bnd_ibt_plt = NULL; 5829 1.3 christos lazy_bnd_plt = NULL; 5830 1.3 christos non_lazy_bnd_plt = NULL; 5831 1.6 christos } 5832 1.6 christos 5833 1.3 christos count = 0; 5834 1.6 christos for (j = 0; plts[j].name != NULL; j++) 5835 1.9 christos { 5836 1.9 christos plt = bfd_get_section_by_name (abfd, plts[j].name); 5837 1.9 christos if (plt == NULL 5838 1.6 christos || plt->size == 0 5839 1.3 christos || (plt->flags & SEC_HAS_CONTENTS) == 0) 5840 1.6 christos continue; 5841 1.10 christos 5842 1.6 christos /* Get the PLT section contents. */ 5843 1.3 christos if (!_bfd_elf_mmap_section_contents (abfd, plt, &plt_contents)) 5844 1.6 christos break; 5845 1.6 christos 5846 1.6 christos /* Check what kind of PLT it is. */ 5847 1.6 christos plt_type = plt_unknown; 5848 1.6 christos if (plts[j].type == plt_unknown 5849 1.6 christos && (plt->size >= (lazy_plt->plt_entry_size 5850 1.6 christos + lazy_plt->plt_entry_size))) 5851 1.6 christos { 5852 1.6 christos /* Match lazy PLT first. Need to check the first two 5853 1.6 christos instructions. */ 5854 1.6 christos if ((memcmp (plt_contents, lazy_plt->plt0_entry, 5855 1.6 christos lazy_plt->plt0_got1_offset) == 0) 5856 1.9 christos && (memcmp (plt_contents + 6, lazy_plt->plt0_entry + 6, 5857 1.10 christos 2) == 0)) 5858 1.10 christos { 5859 1.10 christos if (memcmp (plt_contents + lazy_ibt_plt->plt_entry_size, 5860 1.9 christos lazy_ibt_plt->plt_entry, 5861 1.10 christos lazy_ibt_plt->plt_got_offset) == 0) 5862 1.10 christos { 5863 1.9 christos /* The fist entry in the lazy IBT PLT is the same as 5864 1.10 christos the lazy PLT. */ 5865 1.9 christos plt_type = plt_lazy | plt_second; 5866 1.9 christos lazy_plt = lazy_ibt_plt; 5867 1.9 christos } 5868 1.9 christos else 5869 1.6 christos plt_type = plt_lazy; 5870 1.6 christos } 5871 1.6 christos else if (lazy_bnd_plt != NULL 5872 1.6 christos && (memcmp (plt_contents, lazy_bnd_plt->plt0_entry, 5873 1.6 christos lazy_bnd_plt->plt0_got1_offset) == 0) 5874 1.6 christos && (memcmp (plt_contents + 6, 5875 1.6 christos lazy_bnd_plt->plt0_entry + 6, 3) == 0)) 5876 1.10 christos { 5877 1.10 christos plt_type = plt_lazy | plt_second; 5878 1.10 christos /* The fist entry in the lazy BND IBT PLT is the same as 5879 1.10 christos the lazy BND PLT. */ 5880 1.10 christos if (memcmp (plt_contents 5881 1.10 christos + lazy_bnd_ibt_plt->plt_entry_size, 5882 1.10 christos lazy_bnd_ibt_plt->plt_entry, 5883 1.6 christos lazy_bnd_ibt_plt->plt_got_offset) == 0) 5884 1.6 christos lazy_plt = lazy_bnd_ibt_plt; 5885 1.6 christos else 5886 1.6 christos lazy_plt = lazy_bnd_plt; 5887 1.3 christos } 5888 1.6 christos } 5889 1.6 christos 5890 1.6 christos if (non_lazy_plt != NULL 5891 1.6 christos && (plt_type == plt_unknown || plt_type == plt_non_lazy) 5892 1.6 christos && plt->size >= non_lazy_plt->plt_entry_size) 5893 1.6 christos { 5894 1.6 christos /* Match non-lazy PLT. */ 5895 1.6 christos if (memcmp (plt_contents, non_lazy_plt->plt_entry, 5896 1.6 christos non_lazy_plt->plt_got_offset) == 0) 5897 1.3 christos plt_type = plt_non_lazy; 5898 1.6 christos } 5899 1.6 christos 5900 1.10 christos if (plt_type == plt_unknown || plt_type == plt_second) 5901 1.10 christos { 5902 1.10 christos if (plt->size >= non_lazy_ibt_plt->plt_entry_size 5903 1.10 christos && (memcmp (plt_contents, 5904 1.6 christos non_lazy_ibt_plt->plt_entry, 5905 1.6 christos non_lazy_ibt_plt->plt_got_offset) == 0)) 5906 1.6 christos { 5907 1.6 christos /* Match IBT PLT. */ 5908 1.6 christos plt_type = plt_second; 5909 1.10 christos non_lazy_plt = non_lazy_ibt_plt; 5910 1.9 christos } 5911 1.10 christos else if (non_lazy_bnd_plt != NULL) 5912 1.10 christos { 5913 1.10 christos if (plt->size >= non_lazy_bnd_plt->plt_entry_size 5914 1.10 christos && (memcmp (plt_contents, non_lazy_bnd_plt->plt_entry, 5915 1.10 christos non_lazy_bnd_plt->plt_got_offset) == 0)) 5916 1.10 christos { 5917 1.10 christos /* Match BND PLT. */ 5918 1.10 christos plt_type = plt_second; 5919 1.10 christos non_lazy_plt = non_lazy_bnd_plt; 5920 1.10 christos } 5921 1.10 christos else if (plt->size >= non_lazy_bnd_ibt_plt->plt_entry_size 5922 1.10 christos && (memcmp (plt_contents, 5923 1.10 christos non_lazy_bnd_ibt_plt->plt_entry, 5924 1.10 christos non_lazy_bnd_ibt_plt->plt_got_offset) 5925 1.10 christos == 0)) 5926 1.10 christos { 5927 1.10 christos /* Match BND IBT PLT. */ 5928 1.10 christos plt_type = plt_second; 5929 1.9 christos non_lazy_plt = non_lazy_bnd_ibt_plt; 5930 1.6 christos } 5931 1.3 christos } 5932 1.6 christos } 5933 1.6 christos 5934 1.10 christos if (plt_type == plt_unknown) 5935 1.6 christos { 5936 1.6 christos _bfd_elf_munmap_section_contents (plt, plt_contents); 5937 1.3 christos continue; 5938 1.6 christos } 5939 1.6 christos 5940 1.3 christos plts[j].sec = plt; 5941 1.6 christos plts[j].type = plt_type; 5942 1.6 christos 5943 1.6 christos if ((plt_type & plt_lazy)) 5944 1.6 christos { 5945 1.6 christos plts[j].plt_got_offset = lazy_plt->plt_got_offset; 5946 1.6 christos plts[j].plt_got_insn_size = lazy_plt->plt_got_insn_size; 5947 1.6 christos plts[j].plt_entry_size = lazy_plt->plt_entry_size; 5948 1.6 christos /* Skip PLT0 in lazy PLT. */ 5949 1.6 christos i = 1; 5950 1.6 christos } 5951 1.6 christos else 5952 1.6 christos { 5953 1.6 christos plts[j].plt_got_offset = non_lazy_plt->plt_got_offset; 5954 1.6 christos plts[j].plt_got_insn_size = non_lazy_plt->plt_got_insn_size; 5955 1.6 christos plts[j].plt_entry_size = non_lazy_plt->plt_entry_size; 5956 1.3 christos i = 0; 5957 1.6 christos } 5958 1.6 christos 5959 1.6 christos /* Skip lazy PLT when the second PLT is used. */ 5960 1.6 christos if (plt_type == (plt_lazy | plt_second)) 5961 1.6 christos plts[j].count = 0; 5962 1.6 christos else 5963 1.6 christos { 5964 1.6 christos n = plt->size / plts[j].plt_entry_size; 5965 1.3 christos plts[j].count = n; 5966 1.3 christos count += n - i; 5967 1.6 christos } 5968 1.3 christos 5969 1.3 christos plts[j].contents = plt_contents; 5970 1.6 christos } 5971 1.6 christos 5972 1.6 christos return _bfd_x86_elf_get_synthetic_symtab (abfd, count, relsize, 5973 1.1 christos (bfd_vma) 0, plts, dynsyms, 5974 1.1 christos ret); 5975 1.1 christos } 5976 1.1 christos 5977 1.1 christos /* Handle an x86-64 specific section when reading an object file. This 5978 1.8 christos is called when elfcode.h finds a section with an unknown type. */ 5979 1.3 christos 5980 1.3 christos static bool 5981 1.1 christos elf_x86_64_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr, 5982 1.1 christos const char *name, int shindex) 5983 1.8 christos { 5984 1.1 christos if (hdr->sh_type != SHT_X86_64_UNWIND) 5985 1.1 christos return false; 5986 1.8 christos 5987 1.1 christos if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex)) 5988 1.8 christos return false; 5989 1.1 christos 5990 1.1 christos return true; 5991 1.1 christos } 5992 1.1 christos 5993 1.1 christos /* Hook called by the linker routine which adds symbols from an object 5994 1.1 christos file. We use it to put SHN_X86_64_LCOMMON items in .lbss, instead 5995 1.8 christos of .bss. */ 5996 1.1 christos 5997 1.5 christos static bool 5998 1.1 christos elf_x86_64_add_symbol_hook (bfd *abfd, 5999 1.1 christos struct bfd_link_info *info ATTRIBUTE_UNUSED, 6000 1.1 christos Elf_Internal_Sym *sym, 6001 1.1 christos const char **namep ATTRIBUTE_UNUSED, 6002 1.1 christos flagword *flagsp ATTRIBUTE_UNUSED, 6003 1.1 christos asection **secp, 6004 1.1 christos bfd_vma *valp) 6005 1.1 christos { 6006 1.1 christos asection *lcomm; 6007 1.1 christos 6008 1.1 christos switch (sym->st_shndx) 6009 1.1 christos { 6010 1.1 christos case SHN_X86_64_LCOMMON: 6011 1.1 christos lcomm = bfd_get_section_by_name (abfd, "LARGE_COMMON"); 6012 1.1 christos if (lcomm == NULL) 6013 1.1 christos { 6014 1.1 christos lcomm = bfd_make_section_with_flags (abfd, 6015 1.1 christos "LARGE_COMMON", 6016 1.1 christos (SEC_ALLOC 6017 1.1 christos | SEC_IS_COMMON 6018 1.8 christos | SEC_LINKER_CREATED)); 6019 1.1 christos if (lcomm == NULL) 6020 1.1 christos return false; 6021 1.1 christos elf_section_flags (lcomm) |= SHF_X86_64_LARGE; 6022 1.1 christos } 6023 1.8 christos *secp = lcomm; 6024 1.1 christos *valp = sym->st_size; 6025 1.1 christos return true; 6026 1.8 christos } 6027 1.1 christos 6028 1.1 christos return true; 6029 1.1 christos } 6030 1.1 christos 6031 1.1 christos 6032 1.1 christos /* Given a BFD section, try to locate the corresponding ELF section 6033 1.8 christos index. */ 6034 1.1 christos 6035 1.1 christos static bool 6036 1.1 christos elf_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED, 6037 1.1 christos asection *sec, int *index_return) 6038 1.1 christos { 6039 1.1 christos if (sec == &_bfd_elf_large_com_section) 6040 1.8 christos { 6041 1.1 christos *index_return = SHN_X86_64_LCOMMON; 6042 1.8 christos return true; 6043 1.1 christos } 6044 1.1 christos return false; 6045 1.1 christos } 6046 1.1 christos 6047 1.1 christos /* Process a symbol. */ 6048 1.1 christos 6049 1.1 christos static void 6050 1.1 christos elf_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, 6051 1.1 christos asymbol *asym) 6052 1.1 christos { 6053 1.1 christos elf_symbol_type *elfsym = (elf_symbol_type *) asym; 6054 1.1 christos 6055 1.1 christos switch (elfsym->internal_elf_sym.st_shndx) 6056 1.1 christos { 6057 1.1 christos case SHN_X86_64_LCOMMON: 6058 1.1 christos asym->section = &_bfd_elf_large_com_section; 6059 1.1 christos asym->value = elfsym->internal_elf_sym.st_size; 6060 1.1 christos /* Common symbol doesn't set BSF_GLOBAL. */ 6061 1.1 christos asym->flags &= ~BSF_GLOBAL; 6062 1.1 christos break; 6063 1.1 christos } 6064 1.8 christos } 6065 1.1 christos 6066 1.1 christos static bool 6067 1.1 christos elf_x86_64_common_definition (Elf_Internal_Sym *sym) 6068 1.1 christos { 6069 1.1 christos return (sym->st_shndx == SHN_COMMON 6070 1.1 christos || sym->st_shndx == SHN_X86_64_LCOMMON); 6071 1.1 christos } 6072 1.1 christos 6073 1.1 christos static unsigned int 6074 1.1 christos elf_x86_64_common_section_index (asection *sec) 6075 1.1 christos { 6076 1.1 christos if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0) 6077 1.1 christos return SHN_COMMON; 6078 1.1 christos else 6079 1.1 christos return SHN_X86_64_LCOMMON; 6080 1.1 christos } 6081 1.1 christos 6082 1.1 christos static asection * 6083 1.1 christos elf_x86_64_common_section (asection *sec) 6084 1.1 christos { 6085 1.1 christos if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0) 6086 1.1 christos return bfd_com_section_ptr; 6087 1.1 christos else 6088 1.1 christos return &_bfd_elf_large_com_section; 6089 1.8 christos } 6090 1.3 christos 6091 1.3 christos static bool 6092 1.1 christos elf_x86_64_merge_symbol (struct elf_link_hash_entry *h, 6093 1.8 christos const Elf_Internal_Sym *sym, 6094 1.8 christos asection **psec, 6095 1.1 christos bool newdef, 6096 1.3 christos bool olddef, 6097 1.1 christos bfd *oldbfd, 6098 1.1 christos const asection *oldsec) 6099 1.1 christos { 6100 1.1 christos /* A normal common symbol and a large common symbol result in a 6101 1.3 christos normal common symbol. We turn the large common symbol into a 6102 1.1 christos normal one. */ 6103 1.3 christos if (!olddef 6104 1.3 christos && h->root.type == bfd_link_hash_common 6105 1.3 christos && !newdef 6106 1.1 christos && bfd_is_com_section (*psec) 6107 1.1 christos && oldsec != *psec) 6108 1.3 christos { 6109 1.1 christos if (sym->st_shndx == SHN_COMMON 6110 1.1 christos && (elf_section_flags (oldsec) & SHF_X86_64_LARGE) != 0) 6111 1.1 christos { 6112 1.1 christos h->root.u.c.p->section 6113 1.1 christos = bfd_make_section_old_way (oldbfd, "COMMON"); 6114 1.1 christos h->root.u.c.p->section->flags = SEC_ALLOC; 6115 1.3 christos } 6116 1.3 christos else if (sym->st_shndx == SHN_X86_64_LCOMMON 6117 1.1 christos && (elf_section_flags (oldsec) & SHF_X86_64_LARGE) == 0) 6118 1.1 christos *psec = bfd_com_section_ptr; 6119 1.8 christos } 6120 1.1 christos 6121 1.1 christos return true; 6122 1.9 christos } 6123 1.9 christos 6124 1.9 christos static bool 6125 1.9 christos elf_x86_64_section_flags (const Elf_Internal_Shdr *hdr) 6126 1.9 christos { 6127 1.9 christos if ((hdr->sh_flags & SHF_X86_64_LARGE) != 0) 6128 1.9 christos hdr->bfd_section->flags |= SEC_ELF_LARGE; 6129 1.9 christos 6130 1.9 christos return true; 6131 1.9 christos } 6132 1.9 christos 6133 1.9 christos static bool 6134 1.9 christos elf_x86_64_fake_sections (bfd *abfd ATTRIBUTE_UNUSED, 6135 1.9 christos Elf_Internal_Shdr *hdr, asection *sec) 6136 1.9 christos { 6137 1.9 christos if (sec->flags & SEC_ELF_LARGE) 6138 1.9 christos hdr->sh_flags |= SHF_X86_64_LARGE; 6139 1.9 christos 6140 1.9 christos return true; 6141 1.9 christos } 6142 1.9 christos 6143 1.10 christos static bool 6144 1.10 christos elf_x86_64_copy_private_section_data (bfd *ibfd, asection *isec, 6145 1.9 christos bfd *obfd, asection *osec, 6146 1.10 christos struct bfd_link_info *link_info) 6147 1.9 christos { 6148 1.9 christos if (!_bfd_elf_copy_private_section_data (ibfd, isec, obfd, osec, link_info)) 6149 1.9 christos return false; 6150 1.10 christos 6151 1.9 christos /* objcopy --set-section-flags without "large" drops SHF_X86_64_LARGE. */ 6152 1.9 christos if (link_info == NULL && ibfd != obfd) 6153 1.9 christos elf_section_flags (osec) &= ~SHF_X86_64_LARGE; 6154 1.9 christos 6155 1.9 christos return true; 6156 1.1 christos } 6157 1.1 christos 6158 1.1 christos static int 6159 1.1 christos elf_x86_64_additional_program_headers (bfd *abfd, 6160 1.1 christos struct bfd_link_info *info ATTRIBUTE_UNUSED) 6161 1.1 christos { 6162 1.1 christos asection *s; 6163 1.1 christos int count = 0; 6164 1.1 christos 6165 1.1 christos /* Check to see if we need a large readonly segment. */ 6166 1.1 christos s = bfd_get_section_by_name (abfd, ".lrodata"); 6167 1.1 christos if (s && (s->flags & SEC_LOAD)) 6168 1.1 christos count++; 6169 1.1 christos 6170 1.1 christos /* Check to see if we need a large data segment. Since .lbss sections 6171 1.1 christos is placed right after the .bss section, there should be no need for 6172 1.1 christos a large data segment just because of .lbss. */ 6173 1.1 christos s = bfd_get_section_by_name (abfd, ".ldata"); 6174 1.1 christos if (s && (s->flags & SEC_LOAD)) 6175 1.1 christos count++; 6176 1.1 christos 6177 1.1 christos return count; 6178 1.1 christos } 6179 1.1 christos 6180 1.8 christos /* Return TRUE iff relocations for INPUT are compatible with OUTPUT. */ 6181 1.1 christos 6182 1.1 christos static bool 6183 1.1 christos elf_x86_64_relocs_compatible (const bfd_target *input, 6184 1.1 christos const bfd_target *output) 6185 1.1 christos { 6186 1.1 christos return ((xvec_get_elf_backend_data (input)->s->elfclass 6187 1.1 christos == xvec_get_elf_backend_data (output)->s->elfclass) 6188 1.1 christos && _bfd_elf_relocs_compatible (input, output)); 6189 1.6 christos } 6190 1.6 christos 6191 1.6 christos /* Set up x86-64 GNU properties. Return the first relocatable ELF input 6192 1.6 christos with GNU properties if found. Otherwise, return NULL. */ 6193 1.6 christos 6194 1.6 christos static bfd * 6195 1.6 christos elf_x86_64_link_setup_gnu_properties (struct bfd_link_info *info) 6196 1.8 christos { 6197 1.8 christos struct elf_x86_init_table init_table; 6198 1.6 christos const struct elf_backend_data *bed; 6199 1.6 christos struct elf_x86_link_hash_table *htab; 6200 1.6 christos 6201 1.6 christos if ((int) R_X86_64_standard >= (int) R_X86_64_converted_reloc_bit 6202 1.6 christos || (int) R_X86_64_max <= (int) R_X86_64_converted_reloc_bit 6203 1.6 christos || ((int) (R_X86_64_GNU_VTINHERIT | R_X86_64_converted_reloc_bit) 6204 1.6 christos != (int) R_X86_64_GNU_VTINHERIT) 6205 1.6 christos || ((int) (R_X86_64_GNU_VTENTRY | R_X86_64_converted_reloc_bit) 6206 1.6 christos != (int) R_X86_64_GNU_VTENTRY)) 6207 1.6 christos abort (); 6208 1.6 christos 6209 1.6 christos /* This is unused for x86-64. */ 6210 1.8 christos init_table.plt0_pad_byte = 0x90; 6211 1.8 christos 6212 1.8 christos bed = get_elf_backend_data (info->output_bfd); 6213 1.8 christos htab = elf_x86_hash_table (info, bed->target_id); 6214 1.9 christos if (!htab) 6215 1.9 christos abort (); 6216 1.9 christos 6217 1.9 christos init_table.lazy_plt = &elf_x86_64_lazy_plt; 6218 1.10 christos init_table.non_lazy_plt = &elf_x86_64_non_lazy_plt; 6219 1.10 christos 6220 1.6 christos init_table.lazy_ibt_plt = &elf_x86_64_lazy_ibt_plt; 6221 1.8 christos init_table.non_lazy_ibt_plt = &elf_x86_64_non_lazy_ibt_plt; 6222 1.8 christos 6223 1.9 christos if (ABI_64_P (info->output_bfd)) 6224 1.9 christos { 6225 1.10 christos init_table.sframe_lazy_plt = &elf_x86_64_sframe_plt; 6226 1.10 christos init_table.sframe_non_lazy_plt = &elf_x86_64_sframe_non_lazy_plt; 6227 1.6 christos init_table.sframe_lazy_ibt_plt = &elf_x86_64_sframe_ibt_plt; 6228 1.6 christos init_table.sframe_non_lazy_ibt_plt = &elf_x86_64_sframe_non_lazy_ibt_plt; 6229 1.6 christos } 6230 1.9 christos else 6231 1.9 christos { 6232 1.9 christos /* SFrame is not supported for non AMD64. */ 6233 1.6 christos init_table.sframe_lazy_plt = NULL; 6234 1.6 christos init_table.sframe_non_lazy_plt = NULL; 6235 1.6 christos } 6236 1.6 christos 6237 1.6 christos if (ABI_64_P (info->output_bfd)) 6238 1.6 christos { 6239 1.6 christos init_table.r_info = elf64_r_info; 6240 1.6 christos init_table.r_sym = elf64_r_sym; 6241 1.6 christos } 6242 1.6 christos else 6243 1.6 christos { 6244 1.6 christos init_table.r_info = elf32_r_info; 6245 1.6 christos init_table.r_sym = elf32_r_sym; 6246 1.6 christos } 6247 1.6 christos 6248 1.6 christos return _bfd_x86_elf_link_setup_gnu_properties (info, &init_table); 6249 1.9 christos } 6250 1.9 christos 6251 1.9 christos static void 6252 1.9 christos elf_x86_64_add_glibc_version_dependency 6253 1.9 christos (struct elf_find_verdep_info *rinfo) 6254 1.9 christos { 6255 1.9 christos unsigned int i = 0; 6256 1.9 christos const char *version[3] = { NULL, NULL, NULL }; 6257 1.9 christos struct elf_x86_link_hash_table *htab; 6258 1.9 christos 6259 1.9 christos if (rinfo->info->enable_dt_relr) 6260 1.9 christos { 6261 1.9 christos version[i] = "GLIBC_ABI_DT_RELR"; 6262 1.9 christos i++; 6263 1.9 christos } 6264 1.9 christos 6265 1.9 christos htab = elf_x86_hash_table (rinfo->info, X86_64_ELF_DATA); 6266 1.9 christos if (htab != NULL && htab->params->mark_plt) 6267 1.9 christos { 6268 1.9 christos version[i] = "GLIBC_2.36"; 6269 1.9 christos i++; 6270 1.9 christos } 6271 1.9 christos 6272 1.9 christos if (i != 0) 6273 1.9 christos _bfd_elf_link_add_glibc_version_dependency (rinfo, version); 6274 1.1 christos } 6275 1.6 christos 6276 1.1 christos static const struct bfd_elf_special_section 6277 1.1 christos elf_x86_64_special_sections[]= 6278 1.1 christos { 6279 1.1 christos { STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE}, 6280 1.6 christos { STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE}, 6281 1.1 christos { STRING_COMMA_LEN (".gnu.linkonce.lt"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR + SHF_X86_64_LARGE}, 6282 1.1 christos { STRING_COMMA_LEN (".lbss"), -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE}, 6283 1.6 christos { STRING_COMMA_LEN (".ldata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE}, 6284 1.1 christos { STRING_COMMA_LEN (".lrodata"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE}, 6285 1.1 christos { NULL, 0, 0, 0, 0 } 6286 1.3 christos }; 6287 1.1 christos 6288 1.1 christos #define TARGET_LITTLE_SYM x86_64_elf64_vec 6289 1.1 christos #define TARGET_LITTLE_NAME "elf64-x86-64" 6290 1.1 christos #define ELF_ARCH bfd_arch_i386 6291 1.9 christos #define ELF_TARGET_ID X86_64_ELF_DATA 6292 1.1 christos #define ELF_MACHINE_CODE EM_X86_64 6293 1.1 christos #define ELF_MAXPAGESIZE 0x1000 6294 1.1 christos #define ELF_COMMONPAGESIZE 0x1000 6295 1.1 christos 6296 1.1 christos #define elf_backend_can_gc_sections 1 6297 1.1 christos #define elf_backend_can_refcount 1 6298 1.1 christos #define elf_backend_want_got_plt 1 6299 1.1 christos #define elf_backend_plt_readonly 1 6300 1.1 christos #define elf_backend_want_plt_sym 0 6301 1.6 christos #define elf_backend_got_header_size (GOT_ENTRY_SIZE*3) 6302 1.5 christos #define elf_backend_rela_normal 1 6303 1.6 christos #define elf_backend_plt_alignment 4 6304 1.6 christos #define elf_backend_caches_rawsize 1 6305 1.1 christos #define elf_backend_dtrel_excludes_plt 1 6306 1.1 christos #define elf_backend_want_dynrelro 1 6307 1.1 christos 6308 1.9 christos #define elf_info_to_howto elf_x86_64_info_to_howto 6309 1.9 christos 6310 1.1 christos #define bfd_elf64_bfd_copy_private_section_data \ 6311 1.1 christos elf_x86_64_copy_private_section_data 6312 1.1 christos #define bfd_elf64_bfd_reloc_type_lookup elf_x86_64_reloc_type_lookup 6313 1.1 christos #define bfd_elf64_bfd_reloc_name_lookup \ 6314 1.1 christos elf_x86_64_reloc_name_lookup 6315 1.10 christos 6316 1.6 christos #define elf_backend_relocs_compatible elf_x86_64_relocs_compatible 6317 1.1 christos #define elf_backend_early_size_sections elf_x86_64_early_size_sections 6318 1.1 christos #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections 6319 1.5 christos #define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections 6320 1.1 christos #define elf_backend_finish_dynamic_symbol elf_x86_64_finish_dynamic_symbol 6321 1.1 christos #define elf_backend_output_arch_local_syms elf_x86_64_output_arch_local_syms 6322 1.1 christos #define elf_backend_grok_prstatus elf_x86_64_grok_prstatus 6323 1.1 christos #define elf_backend_grok_psinfo elf_x86_64_grok_psinfo 6324 1.1 christos #ifdef CORE_HEADER 6325 1.1 christos #define elf_backend_write_core_note elf_x86_64_write_core_note 6326 1.1 christos #endif 6327 1.1 christos #define elf_backend_reloc_type_class elf_x86_64_reloc_type_class 6328 1.1 christos #define elf_backend_relocate_section elf_x86_64_relocate_section 6329 1.3 christos #define elf_backend_init_index_section _bfd_elf_init_1_index_section 6330 1.1 christos #define elf_backend_object_p elf64_x86_64_elf_object_p 6331 1.1 christos #define bfd_elf64_get_synthetic_symtab elf_x86_64_get_synthetic_symtab 6332 1.1 christos 6333 1.1 christos #define elf_backend_section_from_shdr \ 6334 1.1 christos elf_x86_64_section_from_shdr 6335 1.1 christos 6336 1.1 christos #define elf_backend_section_from_bfd_section \ 6337 1.1 christos elf_x86_64_elf_section_from_bfd_section 6338 1.1 christos #define elf_backend_add_symbol_hook \ 6339 1.1 christos elf_x86_64_add_symbol_hook 6340 1.1 christos #define elf_backend_symbol_processing \ 6341 1.1 christos elf_x86_64_symbol_processing 6342 1.1 christos #define elf_backend_common_section_index \ 6343 1.1 christos elf_x86_64_common_section_index 6344 1.1 christos #define elf_backend_common_section \ 6345 1.1 christos elf_x86_64_common_section 6346 1.1 christos #define elf_backend_common_definition \ 6347 1.1 christos elf_x86_64_common_definition 6348 1.1 christos #define elf_backend_merge_symbol \ 6349 1.1 christos elf_x86_64_merge_symbol 6350 1.9 christos #define elf_backend_special_sections \ 6351 1.9 christos elf_x86_64_special_sections 6352 1.1 christos #define elf_backend_section_flags elf_x86_64_section_flags 6353 1.1 christos #define elf_backend_fake_sections elf_x86_64_fake_sections 6354 1.6 christos #define elf_backend_additional_program_headers \ 6355 1.6 christos elf_x86_64_additional_program_headers 6356 1.6 christos #define elf_backend_setup_gnu_properties \ 6357 1.6 christos elf_x86_64_link_setup_gnu_properties 6358 1.9 christos #define elf_backend_hide_symbol \ 6359 1.9 christos _bfd_x86_elf_hide_symbol 6360 1.6 christos #define elf_backend_add_glibc_version_dependency \ 6361 1.6 christos elf_x86_64_add_glibc_version_dependency 6362 1.6 christos 6363 1.1 christos #undef elf64_bed 6364 1.3 christos #define elf64_bed elf64_x86_64_bed 6365 1.3 christos 6366 1.3 christos #include "elf64-target.h" 6367 1.3 christos 6368 1.6 christos /* CloudABI support. */ 6369 1.3 christos 6370 1.6 christos #undef TARGET_LITTLE_SYM 6371 1.3 christos #define TARGET_LITTLE_SYM x86_64_elf64_cloudabi_vec 6372 1.3 christos #undef TARGET_LITTLE_NAME 6373 1.3 christos #define TARGET_LITTLE_NAME "elf64-x86-64-cloudabi" 6374 1.3 christos 6375 1.3 christos #undef ELF_OSABI 6376 1.6 christos #define ELF_OSABI ELFOSABI_CLOUDABI 6377 1.3 christos 6378 1.1 christos #undef elf64_bed 6379 1.1 christos #define elf64_bed elf64_x86_64_cloudabi_bed 6380 1.1 christos 6381 1.1 christos #include "elf64-target.h" 6382 1.1 christos 6383 1.6 christos /* FreeBSD support. */ 6384 1.3 christos 6385 1.6 christos #undef TARGET_LITTLE_SYM 6386 1.1 christos #define TARGET_LITTLE_SYM x86_64_elf64_fbsd_vec 6387 1.1 christos #undef TARGET_LITTLE_NAME 6388 1.1 christos #define TARGET_LITTLE_NAME "elf64-x86-64-freebsd" 6389 1.1 christos 6390 1.1 christos #undef ELF_OSABI 6391 1.6 christos #define ELF_OSABI ELFOSABI_FREEBSD 6392 1.1 christos 6393 1.1 christos #undef elf64_bed 6394 1.1 christos #define elf64_bed elf64_x86_64_fbsd_bed 6395 1.1 christos 6396 1.1 christos #include "elf64-target.h" 6397 1.1 christos 6398 1.1 christos /* Solaris 2 support. */ 6399 1.3 christos 6400 1.1 christos #undef TARGET_LITTLE_SYM 6401 1.1 christos #define TARGET_LITTLE_SYM x86_64_elf64_sol2_vec 6402 1.1 christos #undef TARGET_LITTLE_NAME 6403 1.8 christos #define TARGET_LITTLE_NAME "elf64-x86-64-sol2" 6404 1.8 christos 6405 1.6 christos #undef ELF_TARGET_OS 6406 1.1 christos #define ELF_TARGET_OS is_solaris 6407 1.1 christos 6408 1.1 christos /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE 6409 1.1 christos objects won't be recognized. */ 6410 1.1 christos #undef ELF_OSABI 6411 1.1 christos 6412 1.1 christos #undef elf64_bed 6413 1.1 christos #define elf64_bed elf64_x86_64_sol2_bed 6414 1.1 christos 6415 1.5 christos /* The 64-bit static TLS arena size is rounded to the nearest 16-byte 6416 1.1 christos boundary. */ 6417 1.1 christos #undef elf_backend_static_tls_alignment 6418 1.1 christos #define elf_backend_static_tls_alignment 16 6419 1.1 christos 6420 1.1 christos /* The Solaris 2 ABI requires a plt symbol on all platforms. 6421 1.1 christos 6422 1.5 christos Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output 6423 1.1 christos File, p.63. */ 6424 1.1 christos #undef elf_backend_want_plt_sym 6425 1.5 christos #define elf_backend_want_plt_sym 1 6426 1.5 christos 6427 1.5 christos #undef elf_backend_strtab_flags 6428 1.8 christos #define elf_backend_strtab_flags SHF_STRINGS 6429 1.5 christos 6430 1.5 christos static bool 6431 1.5 christos elf64_x86_64_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED, 6432 1.5 christos bfd *obfd ATTRIBUTE_UNUSED, 6433 1.5 christos const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED, 6434 1.5 christos Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED) 6435 1.5 christos { 6436 1.8 christos /* PR 19938: FIXME: Need to add code for setting the sh_info 6437 1.5 christos and sh_link fields of Solaris specific section types. */ 6438 1.5 christos return false; 6439 1.5 christos } 6440 1.5 christos 6441 1.5 christos #undef elf_backend_copy_special_section_fields 6442 1.1 christos #define elf_backend_copy_special_section_fields elf64_x86_64_copy_solaris_special_section_fields 6443 1.1 christos 6444 1.1 christos #include "elf64-target.h" 6445 1.1 christos 6446 1.1 christos /* Restore defaults. */ 6447 1.1 christos #undef ELF_OSABI 6448 1.1 christos #undef elf_backend_static_tls_alignment 6449 1.5 christos #undef elf_backend_want_plt_sym 6450 1.5 christos #define elf_backend_want_plt_sym 0 6451 1.1 christos #undef elf_backend_strtab_flags 6452 1.1 christos #undef elf_backend_copy_special_section_fields 6453 1.1 christos 6454 1.1 christos /* 32bit x86-64 support. */ 6455 1.3 christos 6456 1.1 christos #undef TARGET_LITTLE_SYM 6457 1.1 christos #define TARGET_LITTLE_SYM x86_64_elf32_vec 6458 1.1 christos #undef TARGET_LITTLE_NAME 6459 1.8 christos #define TARGET_LITTLE_NAME "elf32-x86-64" 6460 1.1 christos #undef elf32_bed 6461 1.1 christos #define elf32_bed elf32_x86_64_bed 6462 1.1 christos 6463 1.1 christos #undef ELF_ARCH 6464 1.1 christos #define ELF_ARCH bfd_arch_i386 6465 1.1 christos 6466 1.1 christos #undef ELF_MACHINE_CODE 6467 1.8 christos #define ELF_MACHINE_CODE EM_X86_64 6468 1.1 christos 6469 1.1 christos #undef ELF_TARGET_OS 6470 1.9 christos #undef ELF_OSABI 6471 1.9 christos 6472 1.8 christos #define bfd_elf32_bfd_copy_private_section_data \ 6473 1.8 christos elf_x86_64_copy_private_section_data 6474 1.8 christos #define bfd_elf32_bfd_reloc_type_lookup \ 6475 1.8 christos elf_x86_64_reloc_type_lookup 6476 1.8 christos #define bfd_elf32_bfd_reloc_name_lookup \ 6477 1.8 christos elf_x86_64_reloc_name_lookup 6478 1.8 christos #define bfd_elf32_get_synthetic_symtab \ 6479 1.1 christos elf_x86_64_get_synthetic_symtab 6480 1.1 christos 6481 1.1 christos #undef elf_backend_object_p 6482 1.1 christos #define elf_backend_object_p \ 6483 1.1 christos elf32_x86_64_elf_object_p 6484 1.1 christos 6485 1.1 christos #undef elf_backend_bfd_from_remote_memory 6486 1.1 christos #define elf_backend_bfd_from_remote_memory \ 6487 1.1 christos _bfd_elf32_bfd_from_remote_memory 6488 1.1 christos 6489 1.1 christos #undef elf_backend_size_info 6490 1.1 christos #define elf_backend_size_info \ 6491 1.1 christos _bfd_elf32_size_info 6492 6493 #include "elf32-target.h" 6494