1 /* BFD back-end for AArch64 COFF files.
2 Copyright (C) 2021-2022 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
22 #ifndef COFF_WITH_peAArch64
23 #define COFF_WITH_peAArch64
26 /* Note we have to make sure not to include headers twice.
27 Not all headers are wrapped in #ifdef guards, so we define
28 PEI_HEADERS to prevent double including here. */
33 #include "coff/aarch64.h"
34 #include "coff/internal.h"
37 #include "libiberty.h"
42 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
43 #define MINUS_ONE (~ (bfd_vma) 0)
45 static const reloc_howto_type arm64_reloc_howto_64
= HOWTO(IMAGE_REL_ARM64_ADDR64
, 0, 8, 64, false, 0,
46 complain_overflow_bitfield
,
48 false, MINUS_ONE
, MINUS_ONE
, false);
50 static const reloc_howto_type arm64_reloc_howto_32
= HOWTO (IMAGE_REL_ARM64_ADDR32
, 0, 4, 32, false, 0,
51 complain_overflow_bitfield
,
53 false, 0xffffffff, 0xffffffff, false);
55 static const reloc_howto_type arm64_reloc_howto_32_pcrel
= HOWTO (IMAGE_REL_ARM64_REL32
, 0, 4, 32, true, 0,
56 complain_overflow_bitfield
,
58 false, 0xffffffff, 0xffffffff, true);
60 static const reloc_howto_type arm64_reloc_howto_branch26
= HOWTO (IMAGE_REL_ARM64_BRANCH26
, 0, 4, 26, true, 0,
61 complain_overflow_bitfield
,
63 false, 0x03ffffff, 0x03ffffff, true);
65 static const reloc_howto_type arm64_reloc_howto_page21
= HOWTO (IMAGE_REL_ARM64_PAGEBASE_REL21
, 12, 4, 21, true, 0,
66 complain_overflow_signed
,
68 false, 0x1fffff, 0x1fffff, false);
70 static const reloc_howto_type arm64_reloc_howto_lo21
= HOWTO (IMAGE_REL_ARM64_REL21
, 0, 4, 21, true, 0,
71 complain_overflow_signed
,
73 false, 0x1fffff, 0x1fffff, true);
75 static const reloc_howto_type arm64_reloc_howto_pgoff12
= HOWTO (IMAGE_REL_ARM64_PAGEOFFSET_12L
, 1, 4, 12, true, 0,
76 complain_overflow_signed
,
78 false, 0xffe, 0xffe, true);
80 static const reloc_howto_type arm64_reloc_howto_branch19
= HOWTO (IMAGE_REL_ARM64_BRANCH19
, 2, 4, 19, true, 0,
81 complain_overflow_signed
,
83 false, 0x7ffff, 0x7ffff, true);
86 static const reloc_howto_type
* const arm64_howto_table
[] = {
87 &arm64_reloc_howto_64
,
88 &arm64_reloc_howto_32
,
89 &arm64_reloc_howto_32_pcrel
,
90 &arm64_reloc_howto_branch26
,
91 &arm64_reloc_howto_page21
,
92 &arm64_reloc_howto_lo21
,
93 &arm64_reloc_howto_pgoff12
,
94 &arm64_reloc_howto_branch19
98 #define NUM_ELEM(a) ((sizeof (a)) / sizeof ((a)[0]))
101 #define NUM_RELOCS NUM_ELEM (arm64_howto_table)
103 #define coff_bfd_reloc_type_lookup coff_aarch64_reloc_type_lookup
104 #define coff_bfd_reloc_name_lookup coff_aarch64_reloc_name_lookup
106 static reloc_howto_type
*
107 coff_aarch64_reloc_type_lookup (bfd
* abfd ATTRIBUTE_UNUSED
, bfd_reloc_code_real_type code
)
112 return &arm64_reloc_howto_64
;
114 return &arm64_reloc_howto_32
;
115 case BFD_RELOC_32_PCREL
:
116 return &arm64_reloc_howto_32_pcrel
;
117 case BFD_RELOC_AARCH64_CALL26
:
118 case BFD_RELOC_AARCH64_JUMP26
:
119 return &arm64_reloc_howto_branch26
;
120 case BFD_RELOC_AARCH64_ADR_HI21_PCREL
:
121 return &arm64_reloc_howto_page21
;
122 case BFD_RELOC_AARCH64_ADR_LO21_PCREL
:
123 return &arm64_reloc_howto_lo21
;
124 case BFD_RELOC_AARCH64_LDST16_LO12
:
125 return &arm64_reloc_howto_pgoff12
;
126 case BFD_RELOC_AARCH64_BRANCH19
:
127 return &arm64_reloc_howto_branch19
;
136 static reloc_howto_type
*
137 coff_aarch64_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
142 for (i
= 0; i
< NUM_RELOCS
; i
++)
143 if (arm64_howto_table
[i
]->name
!= NULL
144 && strcasecmp (arm64_howto_table
[i
]->name
, r_name
) == 0)
145 return arm64_howto_table
[i
];
150 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER 2
151 #define COFF_PAGE_SIZE 0x1000
153 static reloc_howto_type
*
154 coff_aarch64_rtype_lookup (unsigned int code
)
158 case IMAGE_REL_ARM64_ADDR64
:
159 return &arm64_reloc_howto_64
;
160 case IMAGE_REL_ARM64_ADDR32
:
161 return &arm64_reloc_howto_32
;
162 case IMAGE_REL_ARM64_REL32
:
163 return &arm64_reloc_howto_32_pcrel
;
164 case IMAGE_REL_ARM64_BRANCH26
:
165 return &arm64_reloc_howto_branch26
;
166 case IMAGE_REL_ARM64_PAGEBASE_REL21
:
167 return &arm64_reloc_howto_page21
;
168 case IMAGE_REL_ARM64_REL21
:
169 return &arm64_reloc_howto_lo21
;
170 case IMAGE_REL_ARM64_PAGEOFFSET_12L
:
171 return &arm64_reloc_howto_pgoff12
;
172 case IMAGE_REL_ARM64_BRANCH19
:
173 return &arm64_reloc_howto_branch19
;
182 #define RTYPE2HOWTO(cache_ptr, dst) \
183 ((cache_ptr)->howto = coff_aarch64_rtype_lookup((dst)->r_type))
185 #define SELECT_RELOC(x,howto) { (x).r_type = (howto)->type; }
187 #ifndef bfd_pe_print_pdata
188 #define bfd_pe_print_pdata NULL
191 /* Handle include/coff/aarch64.h external_reloc. */
192 #define SWAP_IN_RELOC_OFFSET H_GET_32
193 #define SWAP_OUT_RELOC_OFFSET H_PUT_32
195 /* Return TRUE if this relocation should
196 appear in the output .reloc section. */
199 in_reloc_p (bfd
* abfd ATTRIBUTE_UNUSED
,
200 reloc_howto_type
* howto
)
202 return !howto
->pc_relative
;
205 #include "coffcode.h"
207 /* Target vectors. */
212 # error "target symbol name not specified"
218 # error "target name not specified"
220 bfd_target_coff_flavour
,
221 BFD_ENDIAN_LITTLE
, /* Data byte order is little. */
222 BFD_ENDIAN_LITTLE
, /* Header byte order is little. */
224 (HAS_RELOC
| EXEC_P
/* Object flags. */
225 | HAS_LINENO
| HAS_DEBUG
226 | HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
| BFD_COMPRESS
| BFD_DECOMPRESS
),
228 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
/* Section flags. */
229 #if defined(COFF_WITH_PE)
230 | SEC_LINK_ONCE
| SEC_LINK_DUPLICATES
| SEC_READONLY
| SEC_DEBUGGING
232 | SEC_CODE
| SEC_DATA
| SEC_EXCLUDE
),
234 #ifdef TARGET_UNDERSCORE
235 TARGET_UNDERSCORE
, /* Leading underscore. */
237 0, /* Leading underscore. */
239 '/', /* Ar_pad_char. */
240 15, /* Ar_max_namelen. */
241 0, /* match priority. */
242 TARGET_KEEP_UNUSED_SECTION_SYMBOLS
, /* keep unused section symbols. */
244 /* Data conversion functions. */
245 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
246 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
247 bfd_getl16
, bfd_getl_signed_16
, bfd_putl16
, /* Data. */
248 /* Header conversion functions. */
249 bfd_getl64
, bfd_getl_signed_64
, bfd_putl64
,
250 bfd_getl32
, bfd_getl_signed_32
, bfd_putl32
,
251 bfd_getl16
, bfd_getl_signed_16
, bfd_putl16
, /* Hdrs. */
253 /* Note that we allow an object file to be treated as a core file as well. */
254 { /* bfd_check_format. */
257 bfd_generic_archive_p
,
260 { /* bfd_set_format. */
261 _bfd_bool_bfd_false_error
,
263 _bfd_generic_mkarchive
,
264 _bfd_bool_bfd_false_error
266 { /* bfd_write_contents. */
267 _bfd_bool_bfd_false_error
,
268 coff_write_object_contents
,
269 _bfd_write_archive_contents
,
270 _bfd_bool_bfd_false_error
273 BFD_JUMP_TABLE_GENERIC (coff
),
274 BFD_JUMP_TABLE_COPY (coff
),
275 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
276 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff
),
277 BFD_JUMP_TABLE_SYMBOLS (coff
),
278 BFD_JUMP_TABLE_RELOCS (coff
),
279 BFD_JUMP_TABLE_WRITE (coff
),
280 BFD_JUMP_TABLE_LINK (coff
),
281 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),