]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - ld/emultempl/armelf.em
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / ld / emultempl / armelf.em
CommitLineData
252b5132 1# This shell script emits a C file. -*- C -*-
a2c58332 2# Copyright (C) 1991-2022 Free Software Foundation, Inc.
41392f03 3#
f96b4a7b 4# This file is part of the GNU Binutils.
41392f03
AM
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
f96b4a7b 8# the Free Software Foundation; either version 3 of the License, or
41392f03
AM
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
f96b4a7b
NC
18# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19# MA 02110-1301, USA.
41392f03
AM
20#
21
075a2b89 22# This file is sourced from elf.em, and defines extra arm-elf
41392f03
AM
23# specific routines.
24#
a82644e2 25test -z "$TARGET2_TYPE" && TARGET2_TYPE="rel"
92b93329 26fragment <<EOF
7ca69e9e 27
906e58ca 28#include "ldctor.h"
1d022697 29#include "elf/arm.h"
f37164d7 30#include "elf32-arm.h"
1d022697 31
68c39892
TP
32static struct elf32_arm_params params =
33{
34 NULL, /* thumb_entry_symbol */
35 0, /* byteswap_code */
36 0${TARGET1_IS_REL}, /* target1_is_rel */
37 "${TARGET2_TYPE}", /* target2_type */
38 0, /* fix_v4bx */
39 0, /* use_blx */
40 BFD_ARM_VFP11_FIX_DEFAULT, /* vfp11_denorm_fix */
41 BFD_ARM_STM32L4XX_FIX_NONE, /* stm32l4xx_fix */
42 0, /* no_enum_size_warning */
43 0, /* no_wchar_size_warning */
44 0, /* pic_veneer */
45 -1, /* fix_cortex_a8 */
46 1, /* fix_arm1176 */
47 -1, /* merge_exidx_entries */
48 0, /* cmse_implib */
49 NULL /* in_implib_bfd */
50};
0955507f 51static char *in_implib_filename = NULL;
7ca69e9e 52
252b5132 53static void
0c7a8e5a 54gld${EMULATION_NAME}_before_parse (void)
252b5132
RH
55{
56#ifndef TARGET_ /* I.e., if not generic. */
5e2f1575 57 ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown);
252b5132 58#endif /* not TARGET_ */
f38a2680
AM
59 input_flags.dynamic = ${DYNAMIC_LINK-true};
60 config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo true ; else echo false ; fi`;
61 config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo true ; else echo false ; fi`;
62 link_info.check_relocs_after_open_input = true;
5fd104ad
AM
63EOF
64if test -n "$COMMONPAGESIZE"; then
65fragment <<EOF
576438f0 66 link_info.relro = DEFAULT_LD_Z_RELRO;
5fd104ad
AM
67EOF
68fi
69fragment <<EOF
252b5132
RH
70}
71
3940d2c3
NC
72static void
73gld${EMULATION_NAME}_set_symbols (void)
74{
75 /* PR 19106: The section resizing code in gldarmelf_after_allocation
76 is effectively the same as relaxation, so prevent early memory
77 region checks which produce bogus error messages.
78 Note - this test has nothing to do with symbols. It is just here
79 because this is the first emulation routine that is called after
80 the command line has been parsed. */
81 if (!bfd_link_relocatable (&link_info))
82 TARGET_ENABLE_RELAXATION;
83}
84
1220a729 85static void
0c7a8e5a 86arm_elf_before_allocation (void)
1220a729 87{
68c39892 88 bfd_elf32_arm_set_byteswap_code (&link_info, params.byteswap_code);
d504ffc8 89
c6dd86c6
JB
90 /* Choose type of VFP11 erratum fix, or warn if specified fix is unnecessary
91 due to architecture version. */
f13a99db 92 bfd_elf32_arm_set_vfp11_fix (link_info.output_bfd, &link_info);
c6dd86c6 93
a504d23a
LA
94 /* Choose type of STM32L4XX erratum fix, or warn if specified fix is
95 unnecessary due to architecture version. */
96 bfd_elf32_arm_set_stm32l4xx_fix (link_info.output_bfd, &link_info);
97
48229727
JB
98 /* Auto-select Cortex-A8 erratum fix if it wasn't explicitly specified. */
99 bfd_elf32_arm_set_cortex_a8_fix (link_info.output_bfd, &link_info);
100
daa4adae
TP
101 /* Ensure the output sections of veneers needing a dedicated one is not
102 removed. */
103 bfd_elf32_arm_keep_private_stub_output_sections (&link_info);
104
d504ffc8
DJ
105 /* We should be able to set the size of the interworking stub section. We
106 can't do it until later if we have dynamic sections, though. */
cbc704f3 107 if (elf_hash_table (&link_info)->dynobj == NULL)
d504ffc8
DJ
108 {
109 /* Here we rummage through the found bfds to collect glue information. */
110 LANG_FOR_EACH_INPUT_STATEMENT (is)
111 {
6c19b93b
AM
112 /* Initialise mapping tables for code/data. */
113 bfd_elf32_arm_init_maps (is->the_bfd);
c6dd86c6 114
d504ffc8 115 if (!bfd_elf32_arm_process_before_allocation (is->the_bfd,
c6dd86c6 116 &link_info)
a504d23a
LA
117 || !bfd_elf32_arm_vfp11_erratum_scan (is->the_bfd, &link_info)
118 || !bfd_elf32_arm_stm32l4xx_erratum_scan (is->the_bfd,
119 &link_info))
252b5132 120 /* xgettext:c-format */
df5f2391
AM
121 einfo (_("%P: errors encountered processing file %s\n"),
122 is->filename);
d504ffc8 123 }
3e6b1042
DJ
124
125 /* We have seen it all. Allocate it, and carry on. */
126 bfd_elf32_arm_allocate_interworking_sections (& link_info);
d504ffc8 127 }
252b5132 128
063d4ee1
AM
129 /* Call the standard elf routine. */
130 gld${EMULATION_NAME}_before_allocation ();
252b5132
RH
131}
132
906e58ca
NC
133/* Fake input file for stubs. */
134static lang_input_statement_type *stub_file;
135
136/* Whether we need to call gldarm_layout_sections_again. */
137static int need_laying_out = 0;
138
139/* Maximum size of a group of input sections that can be handled by
140 one stub section. A value of +/-1 indicates the bfd back-end
141 should use a suitable default size. */
142static bfd_signed_vma group_size = 1;
143
144struct hook_stub_info
145{
146 lang_statement_list_type add;
147 asection *input_section;
148};
149
150/* Traverse the linker tree to find the spot where the stub goes. */
151
f38a2680 152static bool
906e58ca
NC
153hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
154{
155 lang_statement_union_type *l;
f38a2680 156 bool ret;
906e58ca
NC
157
158 for (; (l = *lp) != NULL; lp = &l->header.next)
159 {
160 switch (l->header.type)
161 {
162 case lang_constructors_statement_enum:
163 ret = hook_in_stub (info, &constructor_list.head);
164 if (ret)
165 return ret;
166 break;
167
168 case lang_output_section_statement_enum:
169 ret = hook_in_stub (info,
170 &l->output_section_statement.children.head);
171 if (ret)
172 return ret;
173 break;
174
175 case lang_wild_statement_enum:
176 ret = hook_in_stub (info, &l->wild_statement.children.head);
177 if (ret)
178 return ret;
179 break;
180
181 case lang_group_statement_enum:
182 ret = hook_in_stub (info, &l->group_statement.children.head);
183 if (ret)
184 return ret;
185 break;
186
187 case lang_input_section_enum:
188 if (l->input_section.section == info->input_section)
189 {
190 /* We've found our section. Insert the stub immediately
07d72278
DJ
191 after its associated input section. */
192 *(info->add.tail) = l->header.next;
193 l->header.next = info->add.head;
f38a2680 194 return true;
906e58ca
NC
195 }
196 break;
197
198 case lang_data_statement_enum:
199 case lang_reloc_statement_enum:
200 case lang_object_symbols_statement_enum:
201 case lang_output_statement_enum:
202 case lang_target_statement_enum:
203 case lang_input_statement_enum:
204 case lang_assignment_statement_enum:
205 case lang_padding_statement_enum:
206 case lang_address_statement_enum:
207 case lang_fill_statement_enum:
208 break;
209
210 default:
211 FAIL ();
212 break;
213 }
214 }
f38a2680 215 return false;
906e58ca
NC
216}
217
218
219/* Call-back for elf32_arm_size_stubs. */
220
221/* Create a new stub section, and arrange for it to be linked
07d72278 222 immediately after INPUT_SECTION. */
906e58ca
NC
223
224static asection *
7a89b94e 225elf32_arm_add_stub_section (const char * stub_sec_name,
6bde4c52
TP
226 asection * output_section,
227 asection * after_input_section,
7a89b94e 228 unsigned int alignment_power)
906e58ca
NC
229{
230 asection *stub_sec;
231 flagword flags;
906e58ca
NC
232 lang_output_section_statement_type *os;
233 struct hook_stub_info info;
234
906e58ca 235 flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
abf874aa
CL
236 | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP
237 | SEC_LINKER_CREATED);
9795b468
AM
238 stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd,
239 stub_sec_name, flags);
240 if (stub_sec == NULL)
906e58ca
NC
241 goto err_ret;
242
fd361982 243 bfd_set_section_alignment (stub_sec, alignment_power);
906e58ca 244
24ef1aa7 245 os = lang_output_section_get (output_section);
906e58ca 246
6bde4c52 247 info.input_section = after_input_section;
906e58ca 248 lang_list_init (&info.add);
b209b5a6 249 lang_add_section (&info.add, stub_sec, NULL, NULL, os);
906e58ca
NC
250
251 if (info.add.head == NULL)
252 goto err_ret;
253
6bde4c52
TP
254 if (after_input_section == NULL)
255 {
256 lang_statement_union_type **lp = &os->children.head;
257 lang_statement_union_type *l, *lprev = NULL;
258
259 for (; (l = *lp) != NULL; lp = &l->header.next, lprev = l);
260
261 if (lprev)
262 lprev->header.next = info.add.head;
263 else
264 os->children.head = info.add.head;
265
266 return stub_sec;
267 }
268 else
269 {
270 if (hook_in_stub (&info, &os->children.head))
271 return stub_sec;
272 }
906e58ca
NC
273
274 err_ret:
d003af55 275 einfo (_("%X%P: can not make stub section: %E\n"));
906e58ca
NC
276 return NULL;
277}
278
279/* Another call-back for elf_arm_size_stubs. */
280
6f798e5c 281static void
906e58ca
NC
282gldarm_layout_sections_again (void)
283{
284 /* If we have changed sizes of the stub sections, then we need
285 to recalculate all the section offsets. This may mean we need to
286 add even more stubs. */
f38a2680 287 ldelf_map_segments (true);
906e58ca
NC
288 need_laying_out = -1;
289}
290
291static void
292build_section_lists (lang_statement_union_type *statement)
293{
294 if (statement->header.type == lang_input_section_enum)
295 {
296 asection *i = statement->input_section.section;
297
dbaa2011 298 if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
906e58ca
NC
299 && (i->flags & SEC_EXCLUDE) == 0
300 && i->output_section != NULL
301 && i->output_section->owner == link_info.output_bfd)
302 elf32_arm_next_input_section (& link_info, i);
303 }
304}
305
2468f9c9
PB
306static int
307compare_output_sec_vma (const void *a, const void *b)
308{
309 asection *asec = *(asection **) a, *bsec = *(asection **) b;
310 asection *aout = asec->output_section, *bout = bsec->output_section;
311 bfd_vma avma, bvma;
e2caaa1f 312
2468f9c9
PB
313 /* If there's no output section for some reason, compare equal. */
314 if (!aout || !bout)
315 return 0;
e2caaa1f 316
2468f9c9
PB
317 avma = aout->vma + asec->output_offset;
318 bvma = bout->vma + bsec->output_offset;
e2caaa1f 319
2468f9c9
PB
320 if (avma > bvma)
321 return 1;
322 else if (avma < bvma)
323 return -1;
e2caaa1f 324
2468f9c9
PB
325 return 0;
326}
327
906e58ca 328static void
eaeb0a9d 329gld${EMULATION_NAME}_after_allocation (void)
6f798e5c 330{
75938853
AM
331 int ret;
332
491d01d3
YU
333 /* Build a sorted list of input text sections, then use that to process
334 the unwind table index. */
335 unsigned int list_size = 10;
336 asection **sec_list = (asection **)
337 xmalloc (list_size * sizeof (asection *));
338 unsigned int sec_count = 0;
339
340 LANG_FOR_EACH_INPUT_STATEMENT (is)
2468f9c9 341 {
491d01d3
YU
342 bfd *abfd = is->the_bfd;
343 asection *sec;
e2caaa1f 344
491d01d3
YU
345 if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
346 continue;
e2caaa1f 347
491d01d3
YU
348 for (sec = abfd->sections; sec != NULL; sec = sec->next)
349 {
350 asection *out_sec = sec->output_section;
351
352 if (out_sec
353 && elf_section_data (sec)
354 && elf_section_type (sec) == SHT_PROGBITS
355 && (elf_section_flags (sec) & SHF_EXECINSTR) != 0
356 && (sec->flags & SEC_EXCLUDE) == 0
357 && sec->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
358 && out_sec != bfd_abs_section_ptr)
2468f9c9 359 {
491d01d3 360 if (sec_count == list_size)
2468f9c9 361 {
491d01d3
YU
362 list_size *= 2;
363 sec_list = (asection **)
364 xrealloc (sec_list, list_size * sizeof (asection *));
2468f9c9 365 }
491d01d3
YU
366
367 sec_list[sec_count++] = sec;
2468f9c9
PB
368 }
369 }
491d01d3 370 }
e2caaa1f 371
491d01d3 372 qsort (sec_list, sec_count, sizeof (asection *), &compare_output_sec_vma);
e2caaa1f 373
491d01d3 374 if (elf32_arm_fix_exidx_coverage (sec_list, sec_count, &link_info,
68c39892 375 params.merge_exidx_entries))
491d01d3 376 need_laying_out = 1;
e2caaa1f 377
491d01d3 378 free (sec_list);
6f798e5c 379
906e58ca
NC
380 /* bfd_elf32_discard_info just plays with debugging sections,
381 ie. doesn't affect any code, so we can delay resizing the
382 sections. It's likely we'll resize everything in the process of
383 adding stubs. */
75938853
AM
384 ret = bfd_elf_discard_info (link_info.output_bfd, & link_info);
385 if (ret < 0)
386 {
d003af55 387 einfo (_("%X%P: .eh_frame/.stab edit: %E\n"));
75938853
AM
388 return;
389 }
390 else if (ret > 0)
906e58ca
NC
391 need_laying_out = 1;
392
393 /* If generating a relocatable output file, then we don't
394 have to examine the relocs. */
0e1862bb 395 if (stub_file != NULL && !bfd_link_relocatable (&link_info))
906e58ca 396 {
75938853 397 ret = elf32_arm_setup_section_lists (link_info.output_bfd, &link_info);
906e58ca
NC
398 if (ret != 0)
399 {
400 if (ret < 0)
401 {
d003af55
AM
402 einfo (_("%X%P: could not compute sections lists "
403 "for stub generation: %E\n"));
906e58ca
NC
404 return;
405 }
406
407 lang_for_each_statement (build_section_lists);
408
409 /* Call into the BFD backend to do the real work. */
410 if (! elf32_arm_size_stubs (link_info.output_bfd,
411 stub_file->the_bfd,
412 & link_info,
413 group_size,
414 & elf32_arm_add_stub_section,
415 & gldarm_layout_sections_again))
416 {
df5f2391 417 einfo (_("%X%P: can not size stub section: %E\n"));
906e58ca
NC
418 return;
419 }
420 }
421 }
422
423 if (need_laying_out != -1)
d871d478 424 ldelf_map_segments (need_laying_out);
eaeb0a9d
AM
425}
426
427static void
428gld${EMULATION_NAME}_finish (void)
429{
430 struct bfd_link_hash_entry * h;
431
432 {
433 LANG_FOR_EACH_INPUT_STATEMENT (is)
434 {
6c19b93b
AM
435 /* Figure out where VFP11 erratum veneers (and the labels returning
436 from same) have been placed. */
437 bfd_elf32_arm_vfp11_fix_veneer_locations (is->the_bfd, &link_info);
a504d23a
LA
438
439 /* Figure out where STM32L4XX erratum veneers (and the labels returning
440 from them) have been placed. */
441 bfd_elf32_arm_stm32l4xx_fix_veneer_locations (is->the_bfd, &link_info);
eaeb0a9d
AM
442 }
443 }
906e58ca 444
0e1862bb 445 if (!bfd_link_relocatable (&link_info))
906e58ca
NC
446 {
447 /* Now build the linker stubs. */
448 if (stub_file->the_bfd->sections != NULL)
449 {
450 if (! elf32_arm_build_stubs (& link_info))
d003af55 451 einfo (_("%X%P: can not build stubs: %E\n"));
906e58ca
NC
452 }
453 }
454
455 finish_default ();
c56feb2b 456
68c39892 457 if (params.thumb_entry_symbol)
1d022697 458 {
68c39892 459 h = bfd_link_hash_lookup (link_info.hash, params.thumb_entry_symbol,
f38a2680 460 false, false, true);
1d022697
PB
461 }
462 else
463 {
464 struct elf_link_hash_entry * eh;
465
fc304b88 466 if (!entry_symbol.name || !is_elf_hash_table (link_info.hash))
1d022697
PB
467 return;
468
469 h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name,
f38a2680 470 false, false, true);
1d022697 471 eh = (struct elf_link_hash_entry *)h;
39d911fc
TP
472 if (!h || ARM_GET_SYM_BRANCH_TYPE (eh->target_internal)
473 != ST_BRANCH_TO_THUMB)
1d022697
PB
474 return;
475 }
0c7a8e5a 476
6f798e5c
NC
477
478 if (h != (struct bfd_link_hash_entry *) NULL
479 && (h->type == bfd_link_hash_defined
480 || h->type == bfd_link_hash_defweak)
481 && h->u.def.section->output_section != NULL)
482 {
483 static char buffer[32];
88f7bcd5 484 bfd_vma val;
0c7a8e5a 485
88f7bcd5
NC
486 /* Special procesing is required for a Thumb entry symbol. The
487 bottom bit of its address must be set. */
488 val = (h->u.def.value
fd361982 489 + bfd_section_vma (h->u.def.section->output_section)
88f7bcd5 490 + h->u.def.section->output_offset);
0c7a8e5a 491
88f7bcd5 492 val |= 1;
6f798e5c 493
88f7bcd5 494 /* Now convert this value into a string and store it in entry_symbol
0c7a8e5a 495 where the lang_finish() function will pick it up. */
88f7bcd5
NC
496 buffer[0] = '0';
497 buffer[1] = 'x';
0c7a8e5a 498
88f7bcd5 499 sprintf_vma (buffer + 2, val);
6f798e5c 500
68c39892 501 if (params.thumb_entry_symbol != NULL && entry_symbol.name != NULL
1d022697 502 && entry_from_cmdline)
88f7bcd5 503 einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
68c39892 504 params.thumb_entry_symbol, entry_symbol.name);
88f7bcd5 505 entry_symbol.name = buffer;
6f798e5c 506 }
88f7bcd5 507 else
6241fe3d 508 einfo (_("%P: warning: cannot find thumb start symbol %s\n"),
f5a1cdde 509 h->root.string);
6f798e5c
NC
510}
511
bf21ed78 512/* This is a convenient point to tell BFD about target specific flags.
3674e28a
PB
513 After the output has been created, but before inputs are read. */
514static void
515arm_elf_create_output_section_statements (void)
516{
b8976b05
NC
517 if (strstr (bfd_get_target (link_info.output_bfd), "arm") == NULL)
518 {
519 /* The arm backend needs special fields in the output hash structure.
520 These will only be created if the output format is an arm format,
521 hence we do not support linking and changing output formats at the
522 same time. Use a link followed by objcopy to change output formats. */
df5f2391
AM
523 einfo (_("%F%P: error: cannot change output format "
524 "whilst linking %s binaries\n"), "ARM");
b8976b05
NC
525 return;
526 }
527
0955507f
TP
528 if (in_implib_filename)
529 {
68c39892
TP
530 params.in_implib_bfd = bfd_openr (in_implib_filename,
531 bfd_get_target (link_info.output_bfd));
0955507f 532
68c39892 533 if (params.in_implib_bfd == NULL)
df5f2391 534 einfo (_("%F%P: %s: can't open: %E\n"), in_implib_filename);
0955507f 535
68c39892 536 if (!bfd_check_format (params.in_implib_bfd, bfd_object))
df5f2391 537 einfo (_("%F%P: %s: not a relocatable file: %E\n"), in_implib_filename);
0955507f 538 }
0955507f 539
68c39892 540 bfd_elf32_arm_set_target_params (link_info.output_bfd, &link_info, &params);
906e58ca
NC
541
542 stub_file = lang_add_input_file ("linker stubs",
6c19b93b
AM
543 lang_input_file_is_fake_enum,
544 NULL);
906e58ca
NC
545 stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd);
546 if (stub_file->the_bfd == NULL
547 || ! bfd_set_arch_mach (stub_file->the_bfd,
6c19b93b
AM
548 bfd_get_arch (link_info.output_bfd),
549 bfd_get_mach (link_info.output_bfd)))
906e58ca 550 {
df5f2391 551 einfo (_("%F%P: can not create BFD: %E\n"));
906e58ca
NC
552 return;
553 }
e2caaa1f 554
906e58ca
NC
555 stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
556 ldlang_add_file (stub_file);
3e6b1042
DJ
557
558 /* Also use the stub file for stubs placed in a single output section. */
559 bfd_elf32_arm_add_glue_sections_to_bfd (stub_file->the_bfd, &link_info);
560 bfd_elf32_arm_get_bfd_for_interworking (stub_file->the_bfd, &link_info);
906e58ca
NC
561}
562
252b5132
RH
563EOF
564
41392f03
AM
565# Define some shell vars to insert bits of code into the standard elf
566# parse_args and list_options functions.
567#
568PARSE_AND_LIST_PROLOGUE='
569#define OPTION_THUMB_ENTRY 301
e489d0ae 570#define OPTION_BE8 302
9c504268
PB
571#define OPTION_TARGET1_REL 303
572#define OPTION_TARGET1_ABS 304
3674e28a 573#define OPTION_TARGET2 305
33bfe774
JB
574#define OPTION_FIX_V4BX 306
575#define OPTION_USE_BLX 307
c6dd86c6 576#define OPTION_VFP11_DENORM_FIX 308
bf21ed78 577#define OPTION_NO_ENUM_SIZE_WARNING 309
27e55c4d 578#define OPTION_PIC_VENEER 310
845b51d6 579#define OPTION_FIX_V4BX_INTERWORKING 311
8c45e5ec 580#define OPTION_STUBGROUP_SIZE 312
a9dc9481 581#define OPTION_NO_WCHAR_SIZE_WARNING 313
48229727
JB
582#define OPTION_FIX_CORTEX_A8 314
583#define OPTION_NO_FIX_CORTEX_A8 315
8c45e5ec 584#define OPTION_NO_MERGE_EXIDX_ENTRIES 316
2de70689
MGD
585#define OPTION_FIX_ARM1176 317
586#define OPTION_NO_FIX_ARM1176 318
8c45e5ec 587#define OPTION_LONG_PLT 319
a504d23a 588#define OPTION_STM32L4XX_FIX 320
54ddd295 589#define OPTION_CMSE_IMPLIB 321
0955507f 590#define OPTION_IN_IMPLIB 322
41392f03 591'
252b5132 592
ef5bdbd1 593PARSE_AND_LIST_SHORTOPTS=p
252b5132 594
41392f03
AM
595PARSE_AND_LIST_LONGOPTS='
596 { "no-pipeline-knowledge", no_argument, NULL, '\'p\''},
597 { "thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
e489d0ae 598 { "be8", no_argument, NULL, OPTION_BE8},
9c504268
PB
599 { "target1-rel", no_argument, NULL, OPTION_TARGET1_REL},
600 { "target1-abs", no_argument, NULL, OPTION_TARGET1_ABS},
3674e28a 601 { "target2", required_argument, NULL, OPTION_TARGET2},
319850b4 602 { "fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
845b51d6 603 { "fix-v4bx-interworking", no_argument, NULL, OPTION_FIX_V4BX_INTERWORKING},
33bfe774 604 { "use-blx", no_argument, NULL, OPTION_USE_BLX},
c6dd86c6 605 { "vfp11-denorm-fix", required_argument, NULL, OPTION_VFP11_DENORM_FIX},
a504d23a 606 { "fix-stm32l4xx-629360", optional_argument, NULL, OPTION_STM32L4XX_FIX},
bf21ed78 607 { "no-enum-size-warning", no_argument, NULL, OPTION_NO_ENUM_SIZE_WARNING},
27e55c4d 608 { "pic-veneer", no_argument, NULL, OPTION_PIC_VENEER},
906e58ca 609 { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
a9dc9481 610 { "no-wchar-size-warning", no_argument, NULL, OPTION_NO_WCHAR_SIZE_WARNING},
48229727
JB
611 { "fix-cortex-a8", no_argument, NULL, OPTION_FIX_CORTEX_A8 },
612 { "no-fix-cortex-a8", no_argument, NULL, OPTION_NO_FIX_CORTEX_A8 },
85fdf906 613 { "no-merge-exidx-entries", no_argument, NULL, OPTION_NO_MERGE_EXIDX_ENTRIES },
2de70689
MGD
614 { "fix-arm1176", no_argument, NULL, OPTION_FIX_ARM1176 },
615 { "no-fix-arm1176", no_argument, NULL, OPTION_NO_FIX_ARM1176 },
1db37fe6 616 { "long-plt", no_argument, NULL, OPTION_LONG_PLT },
54ddd295 617 { "cmse-implib", no_argument, NULL, OPTION_CMSE_IMPLIB },
0955507f 618 { "in-implib", required_argument, NULL, OPTION_IN_IMPLIB },
41392f03 619'
252b5132 620
41392f03 621PARSE_AND_LIST_OPTIONS='
442996ee 622 fprintf (file, _(" --thumb-entry=<sym> Set the entry point to be Thumb symbol <sym>\n"));
4a977a31 623 fprintf (file, _(" --be8 Output BE8 format image\n"));
f8266dc4
NC
624 fprintf (file, _(" --target1-rel Interpret R_ARM_TARGET1 as R_ARM_REL32\n"));
625 fprintf (file, _(" --target1-abs Interpret R_ARM_TARGET1 as R_ARM_ABS32\n"));
442996ee
AM
626 fprintf (file, _(" --target2=<type> Specify definition of R_ARM_TARGET2\n"));
627 fprintf (file, _(" --fix-v4bx Rewrite BX rn as MOV pc, rn for ARMv4\n"));
845b51d6 628 fprintf (file, _(" --fix-v4bx-interworking Rewrite BX rn branch to ARMv4 interworking veneer\n"));
442996ee
AM
629 fprintf (file, _(" --use-blx Enable use of BLX instructions\n"));
630 fprintf (file, _(" --vfp11-denorm-fix Specify how to fix VFP11 denorm erratum\n"));
a504d23a 631 fprintf (file, _(" --fix-stm32l4xx-629360 Specify how to fix STM32L4XX 629360 erratum\n"));
893dcb0e 632 fprintf (file, _(" --no-enum-size-warning Don'\''t warn about objects with incompatible\n"
442996ee 633 " enum sizes\n"));
a272e28c 634 fprintf (file, _(" --no-wchar-size-warning Don'\''t warn about objects with incompatible\n"
a9dc9481 635 " wchar_t sizes\n"));
442996ee 636 fprintf (file, _(" --pic-veneer Always generate PIC interworking veneers\n"));
1db37fe6
YG
637 fprintf (file, _(" --long-plt Generate long .plt entries\n"
638 " to handle large .plt/.got displacements\n"));
54ddd295
TP
639 fprintf (file, _(" --cmse-implib Make import library to be a secure gateway import\n"
640 " library as per ARMv8-M Security Extensions\n"));
0955507f
TP
641 fprintf (file, _(" --in-implib Import library whose symbols address must\n"
642 " remain stable\n"));
906e58ca 643 fprintf (file, _("\
a272e28c 644 --stub-group-size=N Maximum size of a group of input sections that\n\
df5f2391
AM
645 can be handled by one stub section. A negative\n\
646 value locates all stubs after their branches\n\
647 (with a group size of -N), while a positive\n\
648 value allows two groups of input sections, one\n\
649 before, and one after each stub section.\n\
650 Values of +/-1 indicate the linker should\n\
651 choose suitable defaults.\n"));
48229727 652 fprintf (file, _(" --[no-]fix-cortex-a8 Disable/enable Cortex-A8 Thumb-2 branch erratum fix\n"));
85fdf906 653 fprintf (file, _(" --no-merge-exidx-entries Disable merging exidx entries\n"));
2de70689 654 fprintf (file, _(" --[no-]fix-arm1176 Disable/enable ARM1176 BLX immediate erratum fix\n"));
41392f03 655'
252b5132 656
41392f03
AM
657PARSE_AND_LIST_ARGS_CASES='
658 case '\'p\'':
dea514f5 659 /* Only here for backwards compatibility. */
41392f03 660 break;
252b5132 661
41392f03 662 case OPTION_THUMB_ENTRY:
68c39892 663 params.thumb_entry_symbol = optarg;
41392f03 664 break;
e489d0ae
PB
665
666 case OPTION_BE8:
68c39892 667 params.byteswap_code = 1;
e489d0ae 668 break;
9c504268
PB
669
670 case OPTION_TARGET1_REL:
68c39892 671 params.target1_is_rel = 1;
9c504268
PB
672 break;
673
674 case OPTION_TARGET1_ABS:
68c39892 675 params.target1_is_rel = 0;
9c504268 676 break;
3674e28a
PB
677
678 case OPTION_TARGET2:
68c39892 679 params.target2_type = optarg;
3674e28a 680 break;
319850b4
JB
681
682 case OPTION_FIX_V4BX:
68c39892 683 params.fix_v4bx = 1;
319850b4 684 break;
33bfe774 685
845b51d6 686 case OPTION_FIX_V4BX_INTERWORKING:
68c39892 687 params.fix_v4bx = 2;
845b51d6
PB
688 break;
689
33bfe774 690 case OPTION_USE_BLX:
68c39892 691 params.use_blx = 1;
33bfe774 692 break;
92b93329 693
c6dd86c6
JB
694 case OPTION_VFP11_DENORM_FIX:
695 if (strcmp (optarg, "none") == 0)
6c19b93b 696 params.vfp11_denorm_fix = BFD_ARM_VFP11_FIX_NONE;
c6dd86c6 697 else if (strcmp (optarg, "scalar") == 0)
6c19b93b 698 params.vfp11_denorm_fix = BFD_ARM_VFP11_FIX_SCALAR;
c6dd86c6 699 else if (strcmp (optarg, "vector") == 0)
6c19b93b 700 params.vfp11_denorm_fix = BFD_ARM_VFP11_FIX_VECTOR;
c6dd86c6 701 else
df5f2391 702 einfo (_("%P: unrecognized VFP11 fix type '\''%s'\''\n"), optarg);
c6dd86c6 703 break;
bf21ed78 704
a504d23a
LA
705 case OPTION_STM32L4XX_FIX:
706 if (!optarg)
6c19b93b 707 params.stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_DEFAULT;
a504d23a 708 else if (strcmp (optarg, "none") == 0)
6c19b93b 709 params.stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_NONE;
a504d23a 710 else if (strcmp (optarg, "default") == 0)
6c19b93b 711 params.stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_DEFAULT;
a504d23a 712 else if (strcmp (optarg, "all") == 0)
6c19b93b 713 params.stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_ALL;
a504d23a 714 else
df5f2391 715 einfo (_("%P: unrecognized STM32L4XX fix type '\''%s'\''\n"), optarg);
a504d23a
LA
716 break;
717
bf21ed78 718 case OPTION_NO_ENUM_SIZE_WARNING:
68c39892 719 params.no_enum_size_warning = 1;
bf21ed78 720 break;
27e55c4d 721
a9dc9481 722 case OPTION_NO_WCHAR_SIZE_WARNING:
68c39892 723 params.no_wchar_size_warning = 1;
a9dc9481
JM
724 break;
725
27e55c4d 726 case OPTION_PIC_VENEER:
68c39892 727 params.pic_veneer = 1;
27e55c4d 728 break;
906e58ca
NC
729
730 case OPTION_STUBGROUP_SIZE:
731 {
732 const char *end;
733
6c19b93b
AM
734 group_size = bfd_scan_vma (optarg, &end, 0);
735 if (*end)
df5f2391 736 einfo (_("%F%P: invalid number `%s'\''\n"), optarg);
906e58ca
NC
737 }
738 break;
48229727
JB
739
740 case OPTION_FIX_CORTEX_A8:
68c39892 741 params.fix_cortex_a8 = 1;
48229727
JB
742 break;
743
744 case OPTION_NO_FIX_CORTEX_A8:
68c39892 745 params.fix_cortex_a8 = 0;
48229727 746 break;
85fdf906
AH
747
748 case OPTION_NO_MERGE_EXIDX_ENTRIES:
68c39892 749 params.merge_exidx_entries = 0;
2de70689 750 break;
85fdf906 751
2de70689 752 case OPTION_FIX_ARM1176:
68c39892 753 params.fix_arm1176 = 1;
2de70689
MGD
754 break;
755
756 case OPTION_NO_FIX_ARM1176:
68c39892 757 params.fix_arm1176 = 0;
2de70689 758 break;
1db37fe6
YG
759
760 case OPTION_LONG_PLT:
761 bfd_elf32_arm_use_long_plt ();
762 break;
54ddd295
TP
763
764 case OPTION_CMSE_IMPLIB:
68c39892 765 params.cmse_implib = 1;
54ddd295 766 break;
0955507f
TP
767
768 case OPTION_IN_IMPLIB:
769 in_implib_filename = optarg;
770 break;
41392f03 771'
252b5132 772
3e6b1042 773# We have our own before_allocation etc. functions, but they call
41392f03 774# the standard routines, so give them a different name.
41392f03 775LDEMUL_BEFORE_ALLOCATION=arm_elf_before_allocation
eaeb0a9d 776LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
3674e28a 777LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=arm_elf_create_output_section_statements
252b5132 778
41392f03
AM
779# Replace the elf before_parse function with our own.
780LDEMUL_BEFORE_PARSE=gld"${EMULATION_NAME}"_before_parse
3940d2c3 781LDEMUL_SET_SYMBOLS=gld"${EMULATION_NAME}"_set_symbols
252b5132 782
41392f03 783# Call the extra arm-elf function
906e58ca 784LDEMUL_FINISH=gld${EMULATION_NAME}_finish