elfxx-aarch64.c revision 1.1.1.7
1/* AArch64-specific support for ELF. 2 Copyright (C) 2009-2020 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 32bfd_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 44uint32_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. */ 51static inline uint32_t 52reencode_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 59uint32_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. */ 67static inline uint32_t 68reencode_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. */ 74static inline uint32_t 75reencode_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. */ 81static inline uint32_t 82reencode_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. */ 88static inline uint32_t 89reencode_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. */ 95static inline uint32_t 96reencode_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. */ 102static inline uint32_t 103reencode_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. */ 109static inline uint32_t 110reencode_movzn_to_movz (uint32_t opcode) 111{ 112 return opcode | (1 << 30); 113} 114 115/* Reencode mov[zn] to movn. */ 116static inline uint32_t 117reencode_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 126static bfd_reloc_status_type 127aarch64_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 142static bfd_reloc_status_type 143aarch64_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. */ 158bfd_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 397bfd_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, bfd_boolean weak_undef_p) 402{ 403 bfd_boolean 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 578bfd_boolean 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 610bfd_boolean 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 641char * 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. */ 703bfd * 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. */ 800enum 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. */ 833bfd_boolean 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 bfd_boolean 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. */ 892void 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