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