1 /* AArch64-specific support for ELF. 2 Copyright (C) 2009-2024 Free Software Foundation, Inc. 3 Contributed by ARM Ltd. 4 5 This file is part of BFD, the Binary File Descriptor library. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; see the file COPYING3. If not, 19 see <http://www.gnu.org/licenses/>. */ 20 21 #include "sysdep.h" 22 #include "bfd.h" 23 #include "elf-bfd.h" 24 #include "elfxx-aarch64.h" 25 #include <stdarg.h> 26 #include <string.h> 27 28 #define MASK(n) ((1u << (n)) - 1) 29 30 /* Sign-extend VALUE, which has the indicated number of BITS. */ 31 32 bfd_signed_vma 33 _bfd_aarch64_sign_extend (bfd_vma value, int bits) 34 { 35 if (value & ((bfd_vma) 1 << (bits - 1))) 36 /* VALUE is negative. */ 37 value |= ((bfd_vma) - 1) << bits; 38 39 return value; 40 } 41 42 /* Decode the IMM field of ADRP. */ 43 44 uint32_t 45 _bfd_aarch64_decode_adrp_imm (uint32_t insn) 46 { 47 return (((insn >> 5) & MASK (19)) << 2) | ((insn >> 29) & MASK (2)); 48 } 49 50 /* Reencode the imm field of add immediate. */ 51 static inline uint32_t 52 reencode_add_imm (uint32_t insn, uint32_t imm) 53 { 54 return (insn & ~(MASK (12) << 10)) | ((imm & MASK (12)) << 10); 55 } 56 57 /* Reencode the IMM field of ADR. */ 58 59 uint32_t 60 _bfd_aarch64_reencode_adr_imm (uint32_t insn, uint32_t imm) 61 { 62 return (insn & ~((MASK (2) << 29) | (MASK (19) << 5))) 63 | ((imm & MASK (2)) << 29) | ((imm & (MASK (19) << 2)) << 3); 64 } 65 66 /* Reencode the imm field of ld/st pos immediate. */ 67 static inline uint32_t 68 reencode_ldst_pos_imm (uint32_t insn, uint32_t imm) 69 { 70 return (insn & ~(MASK (12) << 10)) | ((imm & MASK (12)) << 10); 71 } 72 73 /* Encode the 26-bit offset of unconditional branch. */ 74 static inline uint32_t 75 reencode_branch_ofs_26 (uint32_t insn, uint32_t ofs) 76 { 77 return (insn & ~MASK (26)) | (ofs & MASK (26)); 78 } 79 80 /* Encode the 19-bit offset of conditional branch and compare & branch. */ 81 static inline uint32_t 82 reencode_cond_branch_ofs_19 (uint32_t insn, uint32_t ofs) 83 { 84 return (insn & ~(MASK (19) << 5)) | ((ofs & MASK (19)) << 5); 85 } 86 87 /* Decode the 19-bit offset of load literal. */ 88 static inline uint32_t 89 reencode_ld_lit_ofs_19 (uint32_t insn, uint32_t ofs) 90 { 91 return (insn & ~(MASK (19) << 5)) | ((ofs & MASK (19)) << 5); 92 } 93 94 /* Encode the 14-bit offset of test & branch. */ 95 static inline uint32_t 96 reencode_tst_branch_ofs_14 (uint32_t insn, uint32_t ofs) 97 { 98 return (insn & ~(MASK (14) << 5)) | ((ofs & MASK (14)) << 5); 99 } 100 101 /* Reencode the imm field of move wide. */ 102 static inline uint32_t 103 reencode_movw_imm (uint32_t insn, uint32_t imm) 104 { 105 return (insn & ~(MASK (16) << 5)) | ((imm & MASK (16)) << 5); 106 } 107 108 /* Reencode mov[zn] to movz. */ 109 static inline uint32_t 110 reencode_movzn_to_movz (uint32_t opcode) 111 { 112 return opcode | (1 << 30); 113 } 114 115 /* Reencode mov[zn] to movn. */ 116 static inline uint32_t 117 reencode_movzn_to_movn (uint32_t opcode) 118 { 119 return opcode & ~(1 << 30); 120 } 121 122 /* Return non-zero if the indicated VALUE has overflowed the maximum 123 range expressible by a unsigned number with the indicated number of 124 BITS. */ 125 126 static bfd_reloc_status_type 127 aarch64_unsigned_overflow (bfd_vma value, unsigned int bits) 128 { 129 bfd_vma lim; 130 if (bits >= sizeof (bfd_vma) * 8) 131 return bfd_reloc_ok; 132 lim = (bfd_vma) 1 << bits; 133 if (value >= lim) 134 return bfd_reloc_overflow; 135 return bfd_reloc_ok; 136 } 137 138 /* Return non-zero if the indicated VALUE has overflowed the maximum 139 range expressible by an signed number with the indicated number of 140 BITS. */ 141 142 static bfd_reloc_status_type 143 aarch64_signed_overflow (bfd_vma value, unsigned int bits) 144 { 145 bfd_signed_vma svalue = (bfd_signed_vma) value; 146 bfd_signed_vma lim; 147 148 if (bits >= sizeof (bfd_vma) * 8) 149 return bfd_reloc_ok; 150 lim = (bfd_signed_vma) 1 << (bits - 1); 151 if (svalue < -lim || svalue >= lim) 152 return bfd_reloc_overflow; 153 return bfd_reloc_ok; 154 } 155 156 /* Insert the addend/value into the instruction or data object being 157 relocated. */ 158 bfd_reloc_status_type 159 _bfd_aarch64_elf_put_addend (bfd *abfd, 160 bfd_byte *address, bfd_reloc_code_real_type r_type, 161 reloc_howto_type *howto, bfd_signed_vma addend) 162 { 163 bfd_reloc_status_type status = bfd_reloc_ok; 164 bfd_signed_vma old_addend = addend; 165 bfd_vma contents; 166 int size; 167 168 size = bfd_get_reloc_size (howto); 169 switch (size) 170 { 171 case 0: 172 return status; 173 case 2: 174 contents = bfd_get_16 (abfd, address); 175 break; 176 case 4: 177 if (howto->src_mask != 0xffffffff) 178 /* Must be 32-bit instruction, always little-endian. */ 179 contents = bfd_getl32 (address); 180 else 181 /* Must be 32-bit data (endianness dependent). */ 182 contents = bfd_get_32 (abfd, address); 183 break; 184 case 8: 185 contents = bfd_get_64 (abfd, address); 186 break; 187 default: 188 abort (); 189 } 190 191 switch (howto->complain_on_overflow) 192 { 193 case complain_overflow_dont: 194 break; 195 case complain_overflow_signed: 196 status = aarch64_signed_overflow (addend, 197 howto->bitsize + howto->rightshift); 198 break; 199 case complain_overflow_unsigned: 200 status = aarch64_unsigned_overflow (addend, 201 howto->bitsize + howto->rightshift); 202 break; 203 case complain_overflow_bitfield: 204 default: 205 abort (); 206 } 207 208 addend >>= howto->rightshift; 209 210 switch (r_type) 211 { 212 case BFD_RELOC_AARCH64_CALL26: 213 case BFD_RELOC_AARCH64_JUMP26: 214 contents = reencode_branch_ofs_26 (contents, addend); 215 break; 216 217 case BFD_RELOC_AARCH64_BRANCH19: 218 contents = reencode_cond_branch_ofs_19 (contents, addend); 219 break; 220 221 case BFD_RELOC_AARCH64_TSTBR14: 222 contents = reencode_tst_branch_ofs_14 (contents, addend); 223 break; 224 225 case BFD_RELOC_AARCH64_GOT_LD_PREL19: 226 case BFD_RELOC_AARCH64_LD_LO19_PCREL: 227 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19: 228 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19: 229 if (old_addend & ((1 << howto->rightshift) - 1)) 230 return bfd_reloc_overflow; 231 contents = reencode_ld_lit_ofs_19 (contents, addend); 232 break; 233 234 case BFD_RELOC_AARCH64_TLSDESC_CALL: 235 break; 236 237 case BFD_RELOC_AARCH64_ADR_GOT_PAGE: 238 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL: 239 case BFD_RELOC_AARCH64_ADR_HI21_PCREL: 240 case BFD_RELOC_AARCH64_ADR_LO21_PCREL: 241 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: 242 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21: 243 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21: 244 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21: 245 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 246 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21: 247 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21: 248 contents = _bfd_aarch64_reencode_adr_imm (contents, addend); 249 break; 250 251 case BFD_RELOC_AARCH64_ADD_LO12: 252 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: 253 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: 254 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12: 255 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12: 256 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC: 257 case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC: 258 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12: 259 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12: 260 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 261 /* Corresponds to: add rd, rn, #uimm12 to provide the low order 262 12 bits of the page offset following 263 BFD_RELOC_AARCH64_ADR_HI21_PCREL which computes the 264 (pc-relative) page base. */ 265 contents = reencode_add_imm (contents, addend); 266 break; 267 268 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14: 269 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC: 270 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15: 271 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15: 272 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC: 273 case BFD_RELOC_AARCH64_LDST128_LO12: 274 case BFD_RELOC_AARCH64_LDST16_LO12: 275 case BFD_RELOC_AARCH64_LDST32_LO12: 276 case BFD_RELOC_AARCH64_LDST64_LO12: 277 case BFD_RELOC_AARCH64_LDST8_LO12: 278 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: 279 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12: 280 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC: 281 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 282 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12: 283 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC: 284 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12: 285 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC: 286 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12: 287 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC: 288 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12: 289 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC: 290 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12: 291 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: 292 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12: 293 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: 294 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12: 295 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: 296 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12: 297 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: 298 if (old_addend & ((1 << howto->rightshift) - 1)) 299 return bfd_reloc_overflow; 300 /* Used for ldr*|str* rt, [rn, #uimm12] to provide the low order 301 12 bits address offset. */ 302 contents = reencode_ldst_pos_imm (contents, addend); 303 break; 304 305 /* Group relocations to create high bits of a 16, 32, 48 or 64 306 bit signed data or abs address inline. Will change 307 instruction to MOVN or MOVZ depending on sign of calculated 308 value. */ 309 310 case BFD_RELOC_AARCH64_MOVW_G0_S: 311 case BFD_RELOC_AARCH64_MOVW_G1_S: 312 case BFD_RELOC_AARCH64_MOVW_G2_S: 313 case BFD_RELOC_AARCH64_MOVW_PREL_G0: 314 case BFD_RELOC_AARCH64_MOVW_PREL_G1: 315 case BFD_RELOC_AARCH64_MOVW_PREL_G2: 316 case BFD_RELOC_AARCH64_MOVW_PREL_G3: 317 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0: 318 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1: 319 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2: 320 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0: 321 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1: 322 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2: 323 /* NOTE: We can only come here with movz or movn. */ 324 if (addend < 0) 325 { 326 /* Force use of MOVN. */ 327 addend = ~addend; 328 contents = reencode_movzn_to_movn (contents); 329 } 330 else 331 { 332 /* Force use of MOVZ. */ 333 contents = reencode_movzn_to_movz (contents); 334 } 335 /* Fall through. */ 336 337 /* Group relocations to create a 16, 32, 48 or 64 bit unsigned 338 data or abs address inline. */ 339 340 case BFD_RELOC_AARCH64_MOVW_G0: 341 case BFD_RELOC_AARCH64_MOVW_G0_NC: 342 case BFD_RELOC_AARCH64_MOVW_G1: 343 case BFD_RELOC_AARCH64_MOVW_G1_NC: 344 case BFD_RELOC_AARCH64_MOVW_G2: 345 case BFD_RELOC_AARCH64_MOVW_G2_NC: 346 case BFD_RELOC_AARCH64_MOVW_G3: 347 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC: 348 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1: 349 case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC: 350 case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC: 351 case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC: 352 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: 353 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1: 354 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC: 355 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1: 356 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: 357 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1: 358 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC: 359 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC: 360 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC: 361 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC: 362 contents = reencode_movw_imm (contents, addend); 363 break; 364 365 default: 366 /* Repack simple data */ 367 if (howto->dst_mask & (howto->dst_mask + 1)) 368 return bfd_reloc_notsupported; 369 370 contents = ((contents & ~howto->dst_mask) | (addend & howto->dst_mask)); 371 break; 372 } 373 374 switch (size) 375 { 376 case 2: 377 bfd_put_16 (abfd, contents, address); 378 break; 379 case 4: 380 if (howto->dst_mask != 0xffffffff) 381 /* must be 32-bit instruction, always little-endian */ 382 bfd_putl32 (contents, address); 383 else 384 /* must be 32-bit data (endianness dependent) */ 385 bfd_put_32 (abfd, contents, address); 386 break; 387 case 8: 388 bfd_put_64 (abfd, contents, address); 389 break; 390 default: 391 abort (); 392 } 393 394 return status; 395 } 396 397 bfd_vma 398 _bfd_aarch64_elf_resolve_relocation (bfd *input_bfd, 399 bfd_reloc_code_real_type r_type, 400 bfd_vma place, bfd_vma value, 401 bfd_vma addend, bool weak_undef_p) 402 { 403 bool tls_reloc = true; 404 switch (r_type) 405 { 406 case BFD_RELOC_AARCH64_NONE: 407 case BFD_RELOC_AARCH64_TLSDESC_CALL: 408 break; 409 410 case BFD_RELOC_AARCH64_16_PCREL: 411 case BFD_RELOC_AARCH64_32_PCREL: 412 case BFD_RELOC_AARCH64_64_PCREL: 413 case BFD_RELOC_AARCH64_ADR_LO21_PCREL: 414 case BFD_RELOC_AARCH64_BRANCH19: 415 case BFD_RELOC_AARCH64_LD_LO19_PCREL: 416 case BFD_RELOC_AARCH64_MOVW_PREL_G0: 417 case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC: 418 case BFD_RELOC_AARCH64_MOVW_PREL_G1: 419 case BFD_RELOC_AARCH64_MOVW_PREL_G1_NC: 420 case BFD_RELOC_AARCH64_MOVW_PREL_G2: 421 case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC: 422 case BFD_RELOC_AARCH64_MOVW_PREL_G3: 423 case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21: 424 case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19: 425 case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21: 426 case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19: 427 case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21: 428 case BFD_RELOC_AARCH64_TSTBR14: 429 if (weak_undef_p) 430 value = place; 431 value = value + addend - place; 432 break; 433 434 case BFD_RELOC_AARCH64_CALL26: 435 case BFD_RELOC_AARCH64_JUMP26: 436 value = value + addend - place; 437 break; 438 439 case BFD_RELOC_AARCH64_16: 440 case BFD_RELOC_AARCH64_32: 441 case BFD_RELOC_AARCH64_MOVW_G0: 442 case BFD_RELOC_AARCH64_MOVW_G0_NC: 443 case BFD_RELOC_AARCH64_MOVW_G0_S: 444 case BFD_RELOC_AARCH64_MOVW_G1: 445 case BFD_RELOC_AARCH64_MOVW_G1_NC: 446 case BFD_RELOC_AARCH64_MOVW_G1_S: 447 case BFD_RELOC_AARCH64_MOVW_G2: 448 case BFD_RELOC_AARCH64_MOVW_G2_NC: 449 case BFD_RELOC_AARCH64_MOVW_G2_S: 450 case BFD_RELOC_AARCH64_MOVW_G3: 451 tls_reloc = false; 452 /* fall-through. */ 453 case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: 454 case BFD_RELOC_AARCH64_TLSDESC_OFF_G1: 455 case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC: 456 case BFD_RELOC_AARCH64_TLSGD_MOVW_G1: 457 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_HI12: 458 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12: 459 case BFD_RELOC_AARCH64_TLSLD_ADD_DTPREL_LO12_NC: 460 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12: 461 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12: 462 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12: 463 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12: 464 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0: 465 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G0_NC: 466 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1: 467 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC: 468 case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2: 469 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12: 470 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12: 471 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12: 472 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12: 473 /* Weak Symbols and TLS relocations are implementation defined. For this 474 case we choose to emit 0. */ 475 if (weak_undef_p && tls_reloc) 476 { 477 _bfd_error_handler (_("%pB: warning: Weak TLS is implementation " 478 "defined and may not work as expected"), 479 input_bfd); 480 value = place; 481 } 482 value = value + addend; 483 break; 484 485 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL: 486 case BFD_RELOC_AARCH64_ADR_HI21_PCREL: 487 if (weak_undef_p) 488 value = PG (place); 489 value = PG (value + addend) - PG (place); 490 break; 491 492 case BFD_RELOC_AARCH64_GOT_LD_PREL19: 493 value = value + addend - place; 494 break; 495 496 case BFD_RELOC_AARCH64_ADR_GOT_PAGE: 497 case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: 498 case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21: 499 case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 500 case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21: 501 value = PG (value + addend) - PG (place); 502 break; 503 504 /* Caller must make sure addend is the base address of .got section. */ 505 case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14: 506 case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15: 507 addend = PG (addend); 508 /* Fall through. */ 509 case BFD_RELOC_AARCH64_LD64_GOTOFF_LO15: 510 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G0_NC: 511 case BFD_RELOC_AARCH64_MOVW_GOTOFF_G1: 512 value = value - addend; 513 break; 514 515 case BFD_RELOC_AARCH64_ADD_LO12: 516 case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC: 517 case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC: 518 case BFD_RELOC_AARCH64_LDST128_LO12: 519 case BFD_RELOC_AARCH64_LDST16_LO12: 520 case BFD_RELOC_AARCH64_LDST32_LO12: 521 case BFD_RELOC_AARCH64_LDST64_LO12: 522 case BFD_RELOC_AARCH64_LDST8_LO12: 523 case BFD_RELOC_AARCH64_TLSDESC_ADD: 524 case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12: 525 case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: 526 case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12: 527 case BFD_RELOC_AARCH64_TLSDESC_LDR: 528 case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: 529 case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC: 530 case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 531 case BFD_RELOC_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC: 532 case BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC: 533 case BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC: 534 case BFD_RELOC_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC: 535 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 536 case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: 537 case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: 538 case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: 539 case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: 540 value = PG_OFFSET (value + addend); 541 break; 542 543 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12: 544 value = value + addend; 545 break; 546 547 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1: 548 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1: 549 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC: 550 value = (value + addend) & (bfd_vma) 0xffff0000; 551 break; 552 case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12: 553 /* Mask off low 12bits, keep all other high bits, so that the later 554 generic code could check whehter there is overflow. */ 555 value = (value + addend) & ~(bfd_vma) 0xfff; 556 break; 557 558 case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: 559 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0: 560 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC: 561 value = (value + addend) & (bfd_vma) 0xffff; 562 break; 563 564 case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2: 565 value = (value + addend) & ~(bfd_vma) 0xffffffff; 566 value -= place & ~(bfd_vma) 0xffffffff; 567 break; 568 569 default: 570 break; 571 } 572 573 return value; 574 } 575 576 /* Support for core dump NOTE sections. */ 577 578 bool 579 _bfd_aarch64_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) 580 { 581 int offset; 582 size_t size; 583 584 switch (note->descsz) 585 { 586 default: 587 return false; 588 589 case 392: /* sizeof(struct elf_prstatus) on Linux/arm64. */ 590 /* pr_cursig */ 591 elf_tdata (abfd)->core->signal 592 = bfd_get_16 (abfd, note->descdata + 12); 593 594 /* pr_pid */ 595 elf_tdata (abfd)->core->lwpid 596 = bfd_get_32 (abfd, note->descdata + 32); 597 598 /* pr_reg */ 599 offset = 112; 600 size = 272; 601 602 break; 603 } 604 605 /* Make a ".reg/999" section. */ 606 return _bfd_elfcore_make_pseudosection (abfd, ".reg", 607 size, note->descpos + offset); 608 } 609 610 bool 611 _bfd_aarch64_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) 612 { 613 switch (note->descsz) 614 { 615 default: 616 return false; 617 618 case 136: /* This is sizeof(struct elf_prpsinfo) on Linux/aarch64. */ 619 elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24); 620 elf_tdata (abfd)->core->program 621 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16); 622 elf_tdata (abfd)->core->command 623 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80); 624 } 625 626 /* Note that for some reason, a spurious space is tacked 627 onto the end of the args in some (at least one anyway) 628 implementations, so strip it off if it exists. */ 629 630 { 631 char *command = elf_tdata (abfd)->core->command; 632 int n = strlen (command); 633 634 if (0 < n && command[n - 1] == ' ') 635 command[n - 1] = '\0'; 636 } 637 638 return true; 639 } 640 641 char * 642 _bfd_aarch64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, 643 ...) 644 { 645 switch (note_type) 646 { 647 default: 648 return NULL; 649 650 case NT_PRPSINFO: 651 { 652 char data[136] ATTRIBUTE_NONSTRING; 653 va_list ap; 654 655 va_start (ap, note_type); 656 memset (data, 0, sizeof (data)); 657 strncpy (data + 40, va_arg (ap, const char *), 16); 658 #if GCC_VERSION == 8000 || GCC_VERSION == 8001 659 DIAGNOSTIC_PUSH; 660 /* GCC 8.0 and 8.1 warn about 80 equals destination size with 661 -Wstringop-truncation: 662 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85643 663 */ 664 DIAGNOSTIC_IGNORE_STRINGOP_TRUNCATION; 665 #endif 666 strncpy (data + 56, va_arg (ap, const char *), 80); 667 #if GCC_VERSION == 8000 || GCC_VERSION == 8001 668 DIAGNOSTIC_POP; 669 #endif 670 va_end (ap); 671 672 return elfcore_write_note (abfd, buf, bufsiz, "CORE", 673 note_type, data, sizeof (data)); 674 } 675 676 case NT_PRSTATUS: 677 { 678 char data[392]; 679 va_list ap; 680 long pid; 681 int cursig; 682 const void *greg; 683 684 va_start (ap, note_type); 685 memset (data, 0, sizeof (data)); 686 pid = va_arg (ap, long); 687 bfd_put_32 (abfd, pid, data + 32); 688 cursig = va_arg (ap, int); 689 bfd_put_16 (abfd, cursig, data + 12); 690 greg = va_arg (ap, const void *); 691 memcpy (data + 112, greg, 272); 692 va_end (ap); 693 694 return elfcore_write_note (abfd, buf, bufsiz, "CORE", 695 note_type, data, sizeof (data)); 696 } 697 } 698 } 699 700 /* Find the first input bfd with GNU property and merge it with GPROP. If no 701 such input is found, add it to a new section at the last input. Update 702 GPROP accordingly. */ 703 bfd * 704 _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info, 705 uint32_t *gprop) 706 { 707 asection *sec; 708 bfd *pbfd; 709 bfd *ebfd = NULL; 710 elf_property *prop; 711 unsigned align; 712 713 uint32_t gnu_prop = *gprop; 714 715 /* Find a normal input file with GNU property note. */ 716 for (pbfd = info->input_bfds; 717 pbfd != NULL; 718 pbfd = pbfd->link.next) 719 if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour 720 && bfd_count_sections (pbfd) != 0) 721 { 722 ebfd = pbfd; 723 724 if (elf_properties (pbfd) != NULL) 725 break; 726 } 727 728 /* If ebfd != NULL it is either an input with property note or the last 729 input. Either way if we have gnu_prop, we should add it (by creating 730 a section if needed). */ 731 if (ebfd != NULL && gnu_prop) 732 { 733 prop = _bfd_elf_get_property (ebfd, 734 GNU_PROPERTY_AARCH64_FEATURE_1_AND, 735 4); 736 if (gnu_prop & GNU_PROPERTY_AARCH64_FEATURE_1_BTI 737 && !(prop->u.number & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) 738 _bfd_error_handler (_("%pB: warning: BTI turned on by -z force-bti " 739 "when all inputs do not have BTI in NOTE " 740 "section."), ebfd); 741 prop->u.number |= gnu_prop; 742 prop->pr_kind = property_number; 743 744 /* pbfd being NULL implies ebfd is the last input. Create the GNU 745 property note section. */ 746 if (pbfd == NULL) 747 { 748 sec = bfd_make_section_with_flags (ebfd, 749 NOTE_GNU_PROPERTY_SECTION_NAME, 750 (SEC_ALLOC 751 | SEC_LOAD 752 | SEC_IN_MEMORY 753 | SEC_READONLY 754 | SEC_HAS_CONTENTS 755 | SEC_DATA)); 756 if (sec == NULL) 757 info->callbacks->einfo ( 758 _("%F%P: failed to create GNU property section\n")); 759 760 align = (bfd_get_mach (ebfd) & bfd_mach_aarch64_ilp32) ? 2 : 3; 761 if (!bfd_set_section_alignment (sec, align)) 762 info->callbacks->einfo (_("%F%pA: failed to align section\n"), 763 sec); 764 765 elf_section_type (sec) = SHT_NOTE; 766 } 767 } 768 769 pbfd = _bfd_elf_link_setup_gnu_properties (info); 770 771 if (bfd_link_relocatable (info)) 772 return pbfd; 773 774 /* If pbfd has any GNU_PROPERTY_AARCH64_FEATURE_1_AND properties, update 775 gnu_prop accordingly. */ 776 if (pbfd != NULL) 777 { 778 elf_property_list *p; 779 780 /* The property list is sorted in order of type. */ 781 for (p = elf_properties (pbfd); p; p = p->next) 782 { 783 /* Check for all GNU_PROPERTY_AARCH64_FEATURE_1_AND. */ 784 if (GNU_PROPERTY_AARCH64_FEATURE_1_AND == p->property.pr_type) 785 { 786 gnu_prop = (p->property.u.number 787 & (GNU_PROPERTY_AARCH64_FEATURE_1_PAC 788 | GNU_PROPERTY_AARCH64_FEATURE_1_BTI)); 789 break; 790 } 791 else if (GNU_PROPERTY_AARCH64_FEATURE_1_AND < p->property.pr_type) 792 break; 793 } 794 } 795 *gprop = gnu_prop; 796 return pbfd; 797 } 798 799 /* Define elf_backend_parse_gnu_properties for AArch64. */ 800 enum elf_property_kind 801 _bfd_aarch64_elf_parse_gnu_properties (bfd *abfd, unsigned int type, 802 bfd_byte *ptr, unsigned int datasz) 803 { 804 elf_property *prop; 805 806 switch (type) 807 { 808 case GNU_PROPERTY_AARCH64_FEATURE_1_AND: 809 if (datasz != 4) 810 { 811 _bfd_error_handler 812 ( _("error: %pB: <corrupt AArch64 used size: 0x%x>"), 813 abfd, datasz); 814 return property_corrupt; 815 } 816 prop = _bfd_elf_get_property (abfd, type, datasz); 817 /* Combine properties of the same type. */ 818 prop->u.number |= bfd_h_get_32 (abfd, ptr); 819 prop->pr_kind = property_number; 820 break; 821 822 default: 823 return property_ignored; 824 } 825 826 return property_number; 827 } 828 829 /* Merge AArch64 GNU property BPROP with APROP also accounting for PROP. 830 If APROP isn't NULL, merge it with BPROP and/or PROP. Vice-versa if BROP 831 isn't NULL. Return TRUE if there is any update to APROP or if BPROP should 832 be merge with ABFD. */ 833 bool 834 _bfd_aarch64_elf_merge_gnu_properties (struct bfd_link_info *info 835 ATTRIBUTE_UNUSED, 836 bfd *abfd ATTRIBUTE_UNUSED, 837 elf_property *aprop, 838 elf_property *bprop, 839 uint32_t prop) 840 { 841 unsigned int orig_number; 842 bool updated = false; 843 unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type; 844 845 switch (pr_type) 846 { 847 case GNU_PROPERTY_AARCH64_FEATURE_1_AND: 848 { 849 if (aprop != NULL && bprop != NULL) 850 { 851 orig_number = aprop->u.number; 852 aprop->u.number = (orig_number & bprop->u.number) | prop; 853 updated = orig_number != aprop->u.number; 854 /* Remove the property if all feature bits are cleared. */ 855 if (aprop->u.number == 0) 856 aprop->pr_kind = property_remove; 857 break; 858 } 859 /* If either is NULL, the AND would be 0 so, if there is 860 any PROP, asign it to the input that is not NULL. */ 861 if (prop) 862 { 863 if (aprop != NULL) 864 { 865 orig_number = aprop->u.number; 866 aprop->u.number = prop; 867 updated = orig_number != aprop->u.number; 868 } 869 else 870 { 871 bprop->u.number = prop; 872 updated = true; 873 } 874 } 875 /* No PROP and BPROP is NULL, so remove APROP. */ 876 else if (aprop != NULL) 877 { 878 aprop->pr_kind = property_remove; 879 updated = true; 880 } 881 } 882 break; 883 884 default: 885 abort (); 886 } 887 888 return updated; 889 } 890 891 /* Fix up AArch64 GNU properties. */ 892 void 893 _bfd_aarch64_elf_link_fixup_gnu_properties 894 (struct bfd_link_info *info ATTRIBUTE_UNUSED, 895 elf_property_list **listp) 896 { 897 elf_property_list *p, *prev; 898 899 for (p = *listp, prev = *listp; p; p = p->next) 900 { 901 unsigned int type = p->property.pr_type; 902 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) 903 { 904 if (p->property.pr_kind == property_remove) 905 { 906 /* Remove empty property. */ 907 if (prev == p) 908 { 909 *listp = p->next; 910 prev = *listp; 911 } 912 else 913 prev->next = p->next; 914 continue; 915 } 916 prev = p; 917 } 918 else if (type > GNU_PROPERTY_HIPROC) 919 { 920 /* The property list is sorted in order of type. */ 921 break; 922 } 923 } 924 } 925