Handle array- and string-like values in no-op pretty printers
[binutils-gdb.git] / bfd / coff-aarch64.c
1 /* BFD back-end for AArch64 COFF files.
2 Copyright (C) 2021-2023 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
20
21
22 #ifndef COFF_WITH_peAArch64
23 #define COFF_WITH_peAArch64
24 #endif
25
26 #include "sysdep.h"
27 #include "bfd.h"
28 #include "libbfd.h"
29 #include "coff/aarch64.h"
30 #include "coff/internal.h"
31 #include "coff/pe.h"
32 #include "libcoff.h"
33 #include "libiberty.h"
34
35 /* For these howto special functions,
36 output_bfd == NULL => final link, or objdump -W and other calls to
37 bfd_simple_get_relocated_section_contents
38 output_bfd != NULL && output_bfd != abfd => ld -r
39 output_bfd != NULL && output_bfd == abfd => gas.
40 FIXME: ld -r is punted to bfd_perform_relocation. This won't be
41 correct for cases where the addend needs to be adjusted, eg. for
42 relocations against section symbols, and the field is split because
43 bfd_perform_relocation can't write addends to split relocation fields. */
44
45 static bfd_reloc_status_type
46 coff_aarch64_rel21_reloc (bfd *abfd,
47 arelent *reloc_entry,
48 asymbol *symbol,
49 void *data,
50 asection *input_section,
51 bfd *output_bfd,
52 char **error_message ATTRIBUTE_UNUSED)
53 {
54 if (output_bfd != NULL && output_bfd != abfd)
55 return bfd_reloc_continue;
56
57 if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
58 input_section, reloc_entry->address))
59 return bfd_reloc_outofrange;
60
61 uint32_t op = bfd_getl32 (data + reloc_entry->address);
62 bfd_vma relocation = reloc_entry->addend;
63 bfd_reloc_status_type ret = bfd_reloc_ok;
64 if (output_bfd == NULL)
65 {
66 if (bfd_is_und_section (symbol->section))
67 {
68 if ((symbol->flags & BSF_WEAK) == 0)
69 ret = bfd_reloc_undefined;
70 }
71 else if (!bfd_is_com_section (symbol->section))
72 relocation += (symbol->value
73 + symbol->section->output_offset
74 + symbol->section->output_section->vma);
75 bfd_vma addend = ((op >> 3) & 0x1ffffc) | ((op >> 29) & 0x3);
76 addend = (addend ^ 0x100000) - 0x100000;
77 relocation += addend;
78 relocation -= (reloc_entry->address
79 + input_section->output_offset
80 + input_section->output_section->vma);
81 relocation = (bfd_signed_vma) relocation >> reloc_entry->howto->rightshift;
82 }
83 if (relocation + 0x100000 > 0x1fffff)
84 ret = bfd_reloc_overflow;
85
86 op &= 0x9f00001f;
87 op |= (relocation & 0x1ffffc) << 3;
88 op |= (relocation & 0x3) << 29;
89
90 bfd_putl32 (op, data + reloc_entry->address);
91
92 return ret;
93 }
94
95 static bfd_reloc_status_type
96 coff_aarch64_po12l_reloc (bfd *abfd,
97 arelent *reloc_entry,
98 asymbol *symbol ATTRIBUTE_UNUSED,
99 void *data,
100 asection *input_section,
101 bfd *output_bfd,
102 char **error_message ATTRIBUTE_UNUSED)
103 {
104 if (output_bfd != NULL && output_bfd != abfd)
105 return bfd_reloc_continue;
106
107 if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
108 input_section, reloc_entry->address))
109 return bfd_reloc_outofrange;
110
111 uint32_t op = bfd_getl32 (data + reloc_entry->address);
112 bfd_vma relocation = reloc_entry->addend & 0xfff;
113 int shift;
114
115 if ((op & 0xff800000) == 0x3d800000)
116 {
117 /* LDR / STR with q register */
118 shift = 4;
119 }
120 else
121 {
122 /* top two bits represent how much addend should be shifted */
123 shift = op >> 30;
124 }
125
126 bfd_reloc_status_type ret = bfd_reloc_ok;
127 if (output_bfd == NULL)
128 {
129 if (bfd_is_und_section (symbol->section))
130 {
131 if ((symbol->flags & BSF_WEAK) == 0)
132 ret = bfd_reloc_undefined;
133 }
134 else if (!bfd_is_com_section (symbol->section))
135 relocation += (symbol->value
136 + symbol->section->output_offset
137 + symbol->section->output_section->vma);
138 bfd_vma addend = (op >> 10) & 0xfff;
139 addend <<= shift;
140 relocation += addend;
141 }
142
143 if (relocation & ((1 << shift) - 1))
144 ret = bfd_reloc_overflow;
145
146 op &= 0xffc003ff;
147 op |= (relocation >> shift << 10) & 0x3ffc00;
148
149 bfd_putl32 (op, data + reloc_entry->address);
150
151 return ret;
152 }
153
154 static bfd_reloc_status_type
155 coff_aarch64_addr32nb_reloc (bfd *abfd,
156 arelent *reloc_entry,
157 asymbol *symbol ATTRIBUTE_UNUSED,
158 void *data,
159 asection *input_section,
160 bfd *output_bfd,
161 char **error_message)
162 {
163 if (output_bfd != NULL && output_bfd != abfd)
164 return bfd_reloc_continue;
165
166 if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
167 input_section, reloc_entry->address))
168 return bfd_reloc_outofrange;
169
170 bfd_vma relocation = reloc_entry->addend;
171 bfd_reloc_status_type ret = bfd_reloc_ok;
172 if (output_bfd == NULL)
173 {
174 if (bfd_is_und_section (symbol->section))
175 {
176 if ((symbol->flags & BSF_WEAK) == 0)
177 ret = bfd_reloc_undefined;
178 }
179 else if (!bfd_is_com_section (symbol->section))
180 relocation += (symbol->value
181 + symbol->section->output_offset
182 + symbol->section->output_section->vma);
183 bfd_vma addend = bfd_getl_signed_32 (data + reloc_entry->address);
184 relocation += addend;
185 bfd *obfd = input_section->output_section->owner;
186 if (bfd_get_flavour (obfd) == bfd_target_coff_flavour
187 && obj_pe (obfd))
188 relocation -= pe_data (obfd)->pe_opthdr.ImageBase;
189 else
190 {
191 *error_message = "unsupported";
192 return bfd_reloc_dangerous;
193 }
194 }
195
196 if (relocation + 0x80000000 > 0xffffffff)
197 ret = bfd_reloc_overflow;
198
199 bfd_putl32 (relocation, data + reloc_entry->address);
200
201 return ret;
202 }
203
204 static bfd_reloc_status_type
205 coff_aarch64_secrel_reloc (bfd *abfd,
206 arelent *reloc_entry,
207 asymbol *symbol ATTRIBUTE_UNUSED,
208 void *data,
209 asection *input_section,
210 bfd *output_bfd,
211 char **error_message ATTRIBUTE_UNUSED)
212 {
213 if (output_bfd != NULL && output_bfd != abfd)
214 return bfd_reloc_continue;
215
216 if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
217 input_section, reloc_entry->address))
218 return bfd_reloc_outofrange;
219
220 bfd_vma relocation = reloc_entry->addend;
221 bfd_reloc_status_type ret = bfd_reloc_ok;
222 if (output_bfd == NULL)
223 {
224 if (bfd_is_und_section (symbol->section))
225 {
226 if ((symbol->flags & BSF_WEAK) == 0)
227 ret = bfd_reloc_undefined;
228 }
229 else if (!bfd_is_com_section (symbol->section))
230 relocation += (symbol->value
231 + symbol->section->output_offset);
232 bfd_vma addend = bfd_getl_signed_32 (data + reloc_entry->address);
233 relocation += addend;
234 }
235 if (relocation > 0xffffffff)
236 ret = bfd_reloc_overflow;
237
238 bfd_putl32 (relocation, data + reloc_entry->address);
239
240 return ret;
241 }
242
243 #define coff_aarch64_NULL NULL
244 #undef HOWTO_INSTALL_ADDEND
245 #define HOWTO_INSTALL_ADDEND 1
246 #define HOW(type, right, size, bits, pcrel, left, ovf, func, mask) \
247 HOWTO (type, right, size, bits, pcrel, left, complain_overflow_##ovf, \
248 coff_aarch64_##func, #type, true, mask, mask, false)
249
250 static const reloc_howto_type arm64_reloc_howto_abs
251 = HOW (IMAGE_REL_ARM64_ABSOLUTE,
252 0, 0, 0, false, 0, dont, NULL, 0);
253
254 static const reloc_howto_type arm64_reloc_howto_64
255 = HOW (IMAGE_REL_ARM64_ADDR64,
256 0, 8, 64, false, 0, dont, NULL, UINT64_C (-1));
257
258 static const reloc_howto_type arm64_reloc_howto_32
259 = HOW (IMAGE_REL_ARM64_ADDR32,
260 0, 4, 32, false, 0, signed, NULL, 0xffffffff);
261
262 static const reloc_howto_type arm64_reloc_howto_32_pcrel
263 = HOW (IMAGE_REL_ARM64_REL32,
264 0, 4, 32, true, 0, signed, NULL, 0xffffffff);
265
266 static const reloc_howto_type arm64_reloc_howto_branch26
267 = HOW (IMAGE_REL_ARM64_BRANCH26,
268 2, 4, 26, true, 0, signed, NULL, 0x3ffffff);
269
270 static const reloc_howto_type arm64_reloc_howto_page21
271 = HOW (IMAGE_REL_ARM64_PAGEBASE_REL21,
272 12, 4, 21, true, 0, signed, rel21_reloc, 0x1fffff);
273
274 static const reloc_howto_type arm64_reloc_howto_lo21
275 = HOW (IMAGE_REL_ARM64_REL21,
276 0, 4, 21, true, 0, signed, rel21_reloc, 0x1fffff);
277
278 static const reloc_howto_type arm64_reloc_howto_pgoff12l
279 = HOW (IMAGE_REL_ARM64_PAGEOFFSET_12L,
280 0, 4, 12, true, 10, signed, po12l_reloc, 0x3ffc00);
281
282 static const reloc_howto_type arm64_reloc_howto_branch19
283 = HOW (IMAGE_REL_ARM64_BRANCH19,
284 2, 4, 19, true, 5, signed, NULL, 0xffffe0);
285
286 static const reloc_howto_type arm64_reloc_howto_branch14
287 = HOW (IMAGE_REL_ARM64_BRANCH14,
288 2, 4, 14, true, 5, signed, NULL, 0x7ffe0);
289
290 static const reloc_howto_type arm64_reloc_howto_pgoff12a
291 = HOW (IMAGE_REL_ARM64_PAGEOFFSET_12A,
292 0, 4, 12, true, 10, dont, NULL, 0x3ffc00);
293
294 static const reloc_howto_type arm64_reloc_howto_32nb
295 = HOW (IMAGE_REL_ARM64_ADDR32NB,
296 0, 4, 32, false, 0, signed, addr32nb_reloc, 0xffffffff);
297
298 static const reloc_howto_type arm64_reloc_howto_secrel
299 = HOW (IMAGE_REL_ARM64_SECREL,
300 0, 4, 32, false, 0, dont, secrel_reloc, 0xffffffff);
301
302 static const reloc_howto_type arm64_reloc_howto_secidx
303 = HOW (IMAGE_REL_ARM64_SECTION,
304 0, 2, 16, false, 0, dont, NULL, 0xffff);
305
306 static const reloc_howto_type* const arm64_howto_table[] = {
307 &arm64_reloc_howto_abs,
308 &arm64_reloc_howto_64,
309 &arm64_reloc_howto_32,
310 &arm64_reloc_howto_32_pcrel,
311 &arm64_reloc_howto_branch26,
312 &arm64_reloc_howto_page21,
313 &arm64_reloc_howto_lo21,
314 &arm64_reloc_howto_pgoff12l,
315 &arm64_reloc_howto_branch19,
316 &arm64_reloc_howto_branch14,
317 &arm64_reloc_howto_pgoff12a,
318 &arm64_reloc_howto_32nb,
319 &arm64_reloc_howto_secrel,
320 &arm64_reloc_howto_secidx
321 };
322
323 /* No adjustment to addends should be needed. The actual relocation
324 addend is in the section contents. Unfortunately this means actual
325 addends are not shown by objdump -r, but that's true for most
326 COFF/PE targets where arelent.addend is an adjustment. */
327 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
328 cache_ptr->addend = 0;
329
330 #ifndef NUM_ELEM
331 #define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0]))
332 #endif
333
334 #define NUM_RELOCS NUM_ELEM (arm64_howto_table)
335
336 #define coff_bfd_reloc_type_lookup coff_aarch64_reloc_type_lookup
337 #define coff_bfd_reloc_name_lookup coff_aarch64_reloc_name_lookup
338
339 static reloc_howto_type *
340 coff_aarch64_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, bfd_reloc_code_real_type code)
341 {
342 switch (code)
343 {
344 case BFD_RELOC_64:
345 return &arm64_reloc_howto_64;
346 case BFD_RELOC_32:
347 return &arm64_reloc_howto_32;
348 case BFD_RELOC_32_PCREL:
349 return &arm64_reloc_howto_32_pcrel;
350 case BFD_RELOC_AARCH64_CALL26:
351 case BFD_RELOC_AARCH64_JUMP26:
352 return &arm64_reloc_howto_branch26;
353 case BFD_RELOC_AARCH64_ADR_HI21_PCREL:
354 case BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL:
355 return &arm64_reloc_howto_page21;
356 case BFD_RELOC_AARCH64_TSTBR14:
357 return &arm64_reloc_howto_branch14;
358 case BFD_RELOC_AARCH64_ADR_LO21_PCREL:
359 return &arm64_reloc_howto_lo21;
360 case BFD_RELOC_AARCH64_ADD_LO12:
361 return &arm64_reloc_howto_pgoff12a;
362 case BFD_RELOC_AARCH64_LDST8_LO12:
363 case BFD_RELOC_AARCH64_LDST16_LO12:
364 case BFD_RELOC_AARCH64_LDST32_LO12:
365 case BFD_RELOC_AARCH64_LDST64_LO12:
366 case BFD_RELOC_AARCH64_LDST128_LO12:
367 return &arm64_reloc_howto_pgoff12l;
368 case BFD_RELOC_AARCH64_BRANCH19:
369 return &arm64_reloc_howto_branch19;
370 case BFD_RELOC_RVA:
371 return &arm64_reloc_howto_32nb;
372 case BFD_RELOC_32_SECREL:
373 return &arm64_reloc_howto_secrel;
374 case BFD_RELOC_16_SECIDX:
375 return &arm64_reloc_howto_secidx;
376 default:
377 BFD_FAIL ();
378 return NULL;
379 }
380
381 return NULL;
382 }
383
384 static reloc_howto_type *
385 coff_aarch64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
386 const char *r_name)
387 {
388 unsigned int i;
389
390 for (i = 0; i < NUM_RELOCS; i++)
391 if (arm64_howto_table[i]->name != NULL
392 && strcasecmp (arm64_howto_table[i]->name, r_name) == 0)
393 return arm64_howto_table[i];
394
395 return NULL;
396 }
397
398 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
399 #define COFF_PAGE_SIZE 0x1000
400
401 static reloc_howto_type *
402 coff_aarch64_rtype_lookup (unsigned int code)
403 {
404 switch (code)
405 {
406 case IMAGE_REL_ARM64_ABSOLUTE:
407 return &arm64_reloc_howto_abs;
408 case IMAGE_REL_ARM64_ADDR64:
409 return &arm64_reloc_howto_64;
410 case IMAGE_REL_ARM64_ADDR32:
411 return &arm64_reloc_howto_32;
412 case IMAGE_REL_ARM64_REL32:
413 return &arm64_reloc_howto_32_pcrel;
414 case IMAGE_REL_ARM64_BRANCH26:
415 return &arm64_reloc_howto_branch26;
416 case IMAGE_REL_ARM64_PAGEBASE_REL21:
417 return &arm64_reloc_howto_page21;
418 case IMAGE_REL_ARM64_REL21:
419 return &arm64_reloc_howto_lo21;
420 case IMAGE_REL_ARM64_PAGEOFFSET_12L:
421 return &arm64_reloc_howto_pgoff12l;
422 case IMAGE_REL_ARM64_BRANCH19:
423 return &arm64_reloc_howto_branch19;
424 case IMAGE_REL_ARM64_BRANCH14:
425 return &arm64_reloc_howto_branch14;
426 case IMAGE_REL_ARM64_PAGEOFFSET_12A:
427 return &arm64_reloc_howto_pgoff12a;
428 case IMAGE_REL_ARM64_ADDR32NB:
429 return &arm64_reloc_howto_32nb;
430 case IMAGE_REL_ARM64_SECREL:
431 return &arm64_reloc_howto_secrel;
432 case IMAGE_REL_ARM64_SECTION:
433 return &arm64_reloc_howto_secidx;
434 default:
435 return NULL;
436 }
437
438 return NULL;
439 }
440
441 #define RTYPE2HOWTO(cache_ptr, dst) \
442 ((cache_ptr)->howto = coff_aarch64_rtype_lookup((dst)->r_type))
443
444 static reloc_howto_type *
445 coff_aarch64_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
446 asection *sec ATTRIBUTE_UNUSED,
447 struct internal_reloc *rel,
448 struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
449 struct internal_syment *sym ATTRIBUTE_UNUSED,
450 bfd_vma *addendp)
451 {
452 reloc_howto_type *howto = coff_aarch64_rtype_lookup (rel->r_type);
453
454 /* Cancel out code in _bfd_coff_generic_relocate_section. */
455 *addendp = 0;
456
457 return howto;
458 }
459
460 #define coff_rtype_to_howto coff_aarch64_rtype_to_howto
461
462 #define SELECT_RELOC(x,howto) { (x).r_type = (howto)->type; }
463
464 #ifndef bfd_pe_print_pdata
465 #define bfd_pe_print_pdata NULL
466 #endif
467
468 #ifdef COFF_WITH_PE
469 /* Return TRUE if this relocation should
470 appear in the output .reloc section. */
471
472 static bool
473 in_reloc_p (bfd * abfd ATTRIBUTE_UNUSED,
474 reloc_howto_type * howto)
475 {
476 return !howto->pc_relative;
477 }
478 #endif
479
480 static bool
481 coff_pe_aarch64_relocate_section (bfd *output_bfd,
482 struct bfd_link_info *info,
483 bfd *input_bfd,
484 asection *input_section,
485 bfd_byte *contents,
486 struct internal_reloc *relocs,
487 struct internal_syment *syms,
488 asection **sections)
489 {
490 struct internal_reloc *rel;
491 struct internal_reloc *relend;
492
493 if (bfd_link_relocatable (info))
494 return true;
495
496 rel = relocs;
497 relend = rel + input_section->reloc_count;
498
499 /* The addend for a relocation is stored in the immediate bits of each
500 opcode. So for each relocation, we need to extract the immediate value,
501 use this to calculate what it should be for the symbol, and rewrite the
502 opcode into the section stream. */
503
504 for (; rel < relend; rel++)
505 {
506 long symndx;
507 struct coff_link_hash_entry *h;
508 bfd_vma sym_value;
509 asection *sec = NULL;
510 uint64_t dest_vma;
511
512 /* skip trivial relocations */
513 if (rel->r_type == IMAGE_REL_ARM64_ADDR32
514 || rel->r_type == IMAGE_REL_ARM64_ADDR64
515 || rel->r_type == IMAGE_REL_ARM64_ABSOLUTE)
516 continue;
517
518 symndx = rel->r_symndx;
519 sym_value = syms[symndx].n_value;
520
521 h = obj_coff_sym_hashes (input_bfd)[symndx];
522
523 if (h && h->root.type == bfd_link_hash_defined)
524 {
525 sec = h->root.u.def.section;
526 sym_value = h->root.u.def.value;
527 }
528 else
529 {
530 sec = sections[symndx];
531 }
532
533 if (!sec)
534 continue;
535
536 if (bfd_is_und_section (sec))
537 continue;
538
539 if (discarded_section (sec))
540 continue;
541
542 dest_vma = sec->output_section->vma + sec->output_offset + sym_value;
543
544 if (symndx < 0
545 || (unsigned long) symndx >= obj_raw_syment_count (input_bfd))
546 continue;
547
548 /* All the relocs handled below operate on 4 bytes. */
549 if (input_section->size < rel->r_vaddr
550 || input_section->size - rel->r_vaddr < 4)
551 {
552 _bfd_error_handler
553 /* xgettext: c-format */
554 (_("%pB: bad reloc address %#" PRIx64 " in section `%pA'"),
555 input_bfd, (uint64_t) rel->r_vaddr, input_section);
556 continue;
557 }
558
559 switch (rel->r_type)
560 {
561 case IMAGE_REL_ARM64_ADDR32NB:
562 {
563 uint64_t val;
564 int32_t addend;
565
566 addend = bfd_getl32 (contents + rel->r_vaddr);
567
568 dest_vma += addend;
569
570 val = dest_vma;
571 val -= pe_data (output_bfd)->pe_opthdr.ImageBase;
572
573 if (val > 0xffffffff)
574 (*info->callbacks->reloc_overflow)
575 (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
576 "IMAGE_REL_ARM64_ADDR32NB", addend, input_bfd,
577 input_section, rel->r_vaddr - input_section->vma);
578
579 bfd_putl32 (val, contents + rel->r_vaddr);
580 rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
581
582 break;
583 }
584
585 case IMAGE_REL_ARM64_BRANCH26:
586 {
587 uint64_t cur_vma;
588 uint32_t opcode;
589 int64_t addend, val;
590
591 opcode = bfd_getl32 (contents + rel->r_vaddr);
592
593 addend = (opcode & 0x3ffffff) << 2;
594
595 if (addend & 0x8000000)
596 addend |= 0xfffffffff0000000;
597
598 dest_vma += addend;
599 cur_vma = input_section->output_section->vma
600 + input_section->output_offset
601 + rel->r_vaddr;
602
603 val = (dest_vma >> 2) - (cur_vma >> 2);
604
605 if (val > 0x1ffffff || val < -0x2000000)
606 (*info->callbacks->reloc_overflow)
607 (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
608 "IMAGE_REL_ARM64_BRANCH26", addend, input_bfd,
609 input_section, rel->r_vaddr - input_section->vma);
610
611 opcode &= 0xfc000000;
612 opcode |= val & 0x3ffffff;
613
614 bfd_putl32 (opcode, contents + rel->r_vaddr);
615 rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
616
617 break;
618 }
619
620 case IMAGE_REL_ARM64_BRANCH19:
621 {
622 uint64_t cur_vma;
623 uint32_t opcode;
624 int64_t addend, val;
625
626 opcode = bfd_getl32 (contents + rel->r_vaddr);
627
628 addend = (opcode & 0xffffe0) >> 3;
629
630 if (addend & 0x100000)
631 addend |= 0xffffffffffe00000;
632
633 dest_vma += addend;
634 cur_vma = input_section->output_section->vma
635 + input_section->output_offset
636 + rel->r_vaddr;
637
638 val = (dest_vma >> 2) - (cur_vma >> 2);
639
640 if (val > 0x3ffff || val < -0x40000)
641 (*info->callbacks->reloc_overflow)
642 (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
643 "IMAGE_REL_ARM64_BRANCH19", addend, input_bfd,
644 input_section, rel->r_vaddr - input_section->vma);
645
646 opcode &= 0xff00001f;
647 opcode |= (val & 0x7ffff) << 5;
648
649 bfd_putl32 (opcode, contents + rel->r_vaddr);
650 rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
651
652 break;
653 }
654
655 case IMAGE_REL_ARM64_BRANCH14:
656 {
657 uint64_t cur_vma;
658 uint32_t opcode;
659 int64_t addend, val;
660
661 opcode = bfd_getl32 (contents + rel->r_vaddr);
662
663 addend = (opcode & 0x7ffe0) >> 3;
664
665 if (addend & 0x8000)
666 addend |= 0xffffffffffff0000;
667
668 dest_vma += addend;
669 cur_vma = input_section->output_section->vma
670 + input_section->output_offset
671 + rel->r_vaddr;
672
673 val = (dest_vma >> 2) - (cur_vma >> 2);
674
675 if (val > 0x1fff || val < -0x2000)
676 (*info->callbacks->reloc_overflow)
677 (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
678 "IMAGE_REL_ARM64_BRANCH14", addend, input_bfd,
679 input_section, rel->r_vaddr - input_section->vma);
680
681 opcode &= 0xfff8001f;
682 opcode |= (val & 0x3fff) << 5;
683
684 bfd_putl32 (opcode, contents + rel->r_vaddr);
685 rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
686
687 break;
688 }
689
690 case IMAGE_REL_ARM64_PAGEBASE_REL21:
691 {
692 uint64_t cur_vma;
693 uint32_t opcode;
694 int64_t addend, val;
695
696 opcode = bfd_getl32 (contents + rel->r_vaddr);
697
698 addend = ((opcode & 0xffffe0) >> 3)
699 | ((opcode & 0x60000000) >> 29);
700
701 if (addend & 0x100000)
702 addend |= 0xffffffffffe00000;
703
704 dest_vma += addend;
705 cur_vma = input_section->output_section->vma
706 + input_section->output_offset
707 + rel->r_vaddr;
708
709 val = (dest_vma >> 12) - (cur_vma >> 12);
710
711 if (val > 0xfffff || val < -0x100000)
712 (*info->callbacks->reloc_overflow)
713 (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
714 "IMAGE_REL_ARM64_PAGEBASE_REL21", addend, input_bfd,
715 input_section, rel->r_vaddr - input_section->vma);
716
717 opcode &= 0x9f00001f;
718 opcode |= (val & 0x3) << 29;
719 opcode |= (val & 0x1ffffc) << 3;
720
721 bfd_putl32 (opcode, contents + rel->r_vaddr);
722 rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
723
724 break;
725 }
726
727 case IMAGE_REL_ARM64_REL21:
728 {
729 uint64_t cur_vma;
730 uint32_t opcode;
731 int64_t addend, val;
732
733 opcode = bfd_getl32 (contents + rel->r_vaddr);
734
735 addend = ((opcode & 0xffffe0) >> 3)
736 | ((opcode & 0x60000000) >> 29);
737
738 if (addend & 0x100000)
739 addend |= 0xffffffffffe00000;
740
741 dest_vma += addend;
742 cur_vma = input_section->output_section->vma
743 + input_section->output_offset
744 + rel->r_vaddr;
745
746 val = dest_vma - cur_vma;
747
748 if (val > 0xfffff || val < -0x100000)
749 (*info->callbacks->reloc_overflow)
750 (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
751 "IMAGE_REL_ARM64_REL21", addend, input_bfd,
752 input_section, rel->r_vaddr - input_section->vma);
753
754 opcode &= 0x9f00001f;
755 opcode |= (val & 0x3) << 29;
756 opcode |= (val & 0x1ffffc) << 3;
757
758 bfd_putl32 (opcode, contents + rel->r_vaddr);
759 rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
760
761 break;
762 }
763
764 case IMAGE_REL_ARM64_PAGEOFFSET_12L:
765 {
766 uint32_t opcode, val;
767 uint8_t shift;
768 int32_t addend;
769
770 opcode = bfd_getl32 (contents + rel->r_vaddr);
771
772 addend = (opcode & 0x3ffc00) >> 10;
773
774 if ((opcode & 0xff800000) == 0x3d800000)
775 {
776 /* LDR / STR with q register */
777 shift = 4;
778 }
779 else
780 {
781 /* top two bits represent how much addend should be shifted */
782 shift = opcode >> 30;
783 }
784
785 addend <<= shift;
786
787 dest_vma += addend;
788
789 /* only interested in bottom 12 bits */
790 val = dest_vma & 0xfff;
791
792 if (val & ((1 << shift) - 1))
793 (*info->callbacks->reloc_overflow)
794 (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
795 "IMAGE_REL_ARM64_PAGEOFFSET_12L", addend, input_bfd,
796 input_section, rel->r_vaddr - input_section->vma);
797
798 val >>= shift;
799
800 opcode &= 0xffc003ff;
801 opcode |= val << 10;
802
803 bfd_putl32 (opcode, contents + rel->r_vaddr);
804 rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
805
806 break;
807 }
808
809 case IMAGE_REL_ARM64_PAGEOFFSET_12A:
810 {
811 uint32_t opcode, val;
812 int32_t addend;
813
814 opcode = bfd_getl32 (contents + rel->r_vaddr);
815
816 addend = (opcode & 0x3ffc00) >> 10;
817
818 dest_vma += addend;
819
820 /* only interested in bottom 12 bits */
821 val = dest_vma & 0xfff;
822
823 opcode &= 0xffc003ff;
824 opcode |= val << 10;
825
826 bfd_putl32 (opcode, contents + rel->r_vaddr);
827 rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
828
829 break;
830 }
831
832 case IMAGE_REL_ARM64_SECREL:
833 {
834 uint64_t val;
835 int32_t addend;
836
837 addend = bfd_getl32 (contents + rel->r_vaddr);
838
839 val = sec->output_offset + sym_value + addend;
840
841 if (val > 0xffffffff)
842 (*info->callbacks->reloc_overflow)
843 (info, h ? &h->root : NULL, syms[symndx]._n._n_name,
844 "IMAGE_REL_ARM64_SECREL", addend, input_bfd,
845 input_section, rel->r_vaddr - input_section->vma);
846
847 bfd_putl32 (val, contents + rel->r_vaddr);
848 rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
849
850 break;
851 }
852
853 case IMAGE_REL_ARM64_SECTION:
854 {
855 uint16_t idx = 0, i = 1;
856 asection *s;
857
858 s = output_bfd->sections;
859 while (s)
860 {
861 if (s == sec->output_section)
862 {
863 idx = i;
864 break;
865 }
866
867 i++;
868 s = s->next;
869 }
870
871
872 bfd_putl16 (idx, contents + rel->r_vaddr);
873 rel->r_type = IMAGE_REL_ARM64_ABSOLUTE;
874
875 break;
876 }
877
878 default:
879 info->callbacks->einfo (_("%F%P: Unhandled relocation type %u\n"),
880 rel->r_type);
881 BFD_FAIL ();
882 return false;
883 }
884 }
885
886 return _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
887 input_section, contents,
888 relocs, syms, sections);
889 }
890
891 #define coff_relocate_section coff_pe_aarch64_relocate_section
892
893 #include "coffcode.h"
894
895 /* Prevent assertion in md_apply_fix by forcing use_rela_p on for new
896 sections. */
897 static bool
898 coff_aarch64_new_section_hook (bfd *abfd, asection *section)
899 {
900 if (!coff_new_section_hook (abfd, section))
901 return false;
902
903 section->use_rela_p = 1;
904
905 return true;
906 }
907
908 #define coff_aarch64_close_and_cleanup coff_close_and_cleanup
909 #define coff_aarch64_bfd_free_cached_info coff_bfd_free_cached_info
910 #define coff_aarch64_get_section_contents coff_get_section_contents
911 #define coff_aarch64_get_section_contents_in_window coff_get_section_contents_in_window
912
913 /* Target vectors. */
914 const bfd_target
915 #ifdef TARGET_SYM
916 TARGET_SYM =
917 #else
918 # error "target symbol name not specified"
919 #endif
920 {
921 #ifdef TARGET_NAME
922 TARGET_NAME,
923 #else
924 # error "target name not specified"
925 #endif
926 bfd_target_coff_flavour,
927 BFD_ENDIAN_LITTLE, /* Data byte order is little. */
928 BFD_ENDIAN_LITTLE, /* Header byte order is little. */
929
930 (HAS_RELOC | EXEC_P /* Object flags. */
931 | HAS_LINENO | HAS_DEBUG
932 | HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS),
933
934 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags. */
935 #if defined(COFF_WITH_PE)
936 | SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_READONLY | SEC_DEBUGGING
937 #endif
938 | SEC_CODE | SEC_DATA | SEC_EXCLUDE ),
939
940 #ifdef TARGET_UNDERSCORE
941 TARGET_UNDERSCORE, /* Leading underscore. */
942 #else
943 0, /* Leading underscore. */
944 #endif
945 '/', /* Ar_pad_char. */
946 15, /* Ar_max_namelen. */
947 0, /* match priority. */
948 TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols. */
949
950 /* Data conversion functions. */
951 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
952 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
953 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Data. */
954 /* Header conversion functions. */
955 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
956 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
957 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Hdrs. */
958
959 /* Note that we allow an object file to be treated as a core file as well. */
960 { /* bfd_check_format. */
961 _bfd_dummy_target,
962 coff_object_p,
963 bfd_generic_archive_p,
964 coff_object_p
965 },
966 { /* bfd_set_format. */
967 _bfd_bool_bfd_false_error,
968 coff_mkobject,
969 _bfd_generic_mkarchive,
970 _bfd_bool_bfd_false_error
971 },
972 { /* bfd_write_contents. */
973 _bfd_bool_bfd_false_error,
974 coff_write_object_contents,
975 _bfd_write_archive_contents,
976 _bfd_bool_bfd_false_error
977 },
978
979 BFD_JUMP_TABLE_GENERIC (coff_aarch64),
980 BFD_JUMP_TABLE_COPY (coff),
981 BFD_JUMP_TABLE_CORE (_bfd_nocore),
982 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
983 BFD_JUMP_TABLE_SYMBOLS (coff),
984 BFD_JUMP_TABLE_RELOCS (coff),
985 BFD_JUMP_TABLE_WRITE (coff),
986 BFD_JUMP_TABLE_LINK (coff),
987 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
988
989 NULL,
990
991 COFF_SWAP_TABLE
992 };