xref: /netbsd-src/external/gpl3/binutils.old/dist/ld/emultempl/armelf.em (revision e992f068c547fd6e84b3f104dc2340adcc955732)
1# This shell script emits a C file. -*- C -*-
2#   Copyright (C) 1991-2022 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      buffer[0] = '0';
503      buffer[1] = 'x';
504
505      sprintf_vma (buffer + 2, val);
506
507      if (params.thumb_entry_symbol != NULL && entry_symbol.name != NULL
508	  && entry_from_cmdline)
509	einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
510	       params.thumb_entry_symbol, entry_symbol.name);
511      entry_symbol.name = buffer;
512    }
513  else
514    einfo (_("%P: warning: cannot find thumb start symbol %s\n"),
515	   h->root.string);
516}
517
518/* This is a convenient point to tell BFD about target specific flags.
519   After the output has been created, but before inputs are read.  */
520static void
521arm_elf_create_output_section_statements (void)
522{
523  if (strstr (bfd_get_target (link_info.output_bfd), "arm") == NULL)
524    {
525      /* The arm backend needs special fields in the output hash structure.
526	 These will only be created if the output format is an arm format,
527	 hence we do not support linking and changing output formats at the
528	 same time.  Use a link followed by objcopy to change output formats.  */
529      einfo (_("%F%P: error: cannot change output format "
530	       "whilst linking %s binaries\n"), "ARM");
531      return;
532    }
533
534  if (in_implib_filename)
535    {
536      params.in_implib_bfd = bfd_openr (in_implib_filename,
537					bfd_get_target (link_info.output_bfd));
538
539      if (params.in_implib_bfd == NULL)
540	einfo (_("%F%P: %s: can't open: %E\n"), in_implib_filename);
541
542      if (!bfd_check_format (params.in_implib_bfd, bfd_object))
543	einfo (_("%F%P: %s: not a relocatable file: %E\n"), in_implib_filename);
544    }
545
546  bfd_elf32_arm_set_target_params (link_info.output_bfd, &link_info, &params);
547
548  stub_file = lang_add_input_file ("linker stubs",
549				   lang_input_file_is_fake_enum,
550				   NULL);
551  stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd);
552  if (stub_file->the_bfd == NULL
553      || ! bfd_set_arch_mach (stub_file->the_bfd,
554			      bfd_get_arch (link_info.output_bfd),
555			      bfd_get_mach (link_info.output_bfd)))
556    {
557      einfo (_("%F%P: can not create BFD: %E\n"));
558      return;
559    }
560
561  stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
562  ldlang_add_file (stub_file);
563
564  /* Also use the stub file for stubs placed in a single output section.  */
565  bfd_elf32_arm_add_glue_sections_to_bfd (stub_file->the_bfd, &link_info);
566  bfd_elf32_arm_get_bfd_for_interworking (stub_file->the_bfd, &link_info);
567}
568
569EOF
570
571# Define some shell vars to insert bits of code into the standard elf
572# parse_args and list_options functions.
573#
574PARSE_AND_LIST_PROLOGUE='
575#define OPTION_THUMB_ENTRY		301
576#define OPTION_BE8			302
577#define OPTION_TARGET1_REL		303
578#define OPTION_TARGET1_ABS		304
579#define OPTION_TARGET2			305
580#define OPTION_FIX_V4BX			306
581#define OPTION_USE_BLX			307
582#define OPTION_VFP11_DENORM_FIX		308
583#define OPTION_NO_ENUM_SIZE_WARNING	309
584#define OPTION_PIC_VENEER		310
585#define OPTION_FIX_V4BX_INTERWORKING	311
586#define OPTION_STUBGROUP_SIZE		312
587#define OPTION_NO_WCHAR_SIZE_WARNING	313
588#define OPTION_FIX_CORTEX_A8		314
589#define OPTION_NO_FIX_CORTEX_A8		315
590#define OPTION_NO_MERGE_EXIDX_ENTRIES	316
591#define OPTION_FIX_ARM1176		317
592#define OPTION_NO_FIX_ARM1176		318
593#define OPTION_LONG_PLT			319
594#define OPTION_STM32L4XX_FIX		320
595#define OPTION_CMSE_IMPLIB		321
596#define OPTION_IN_IMPLIB		322
597'
598
599PARSE_AND_LIST_SHORTOPTS=p
600
601PARSE_AND_LIST_LONGOPTS='
602  { "no-pipeline-knowledge", no_argument, NULL, '\'p\''},
603  { "thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
604  { "be8", no_argument, NULL, OPTION_BE8},
605  { "target1-rel", no_argument, NULL, OPTION_TARGET1_REL},
606  { "target1-abs", no_argument, NULL, OPTION_TARGET1_ABS},
607  { "target2", required_argument, NULL, OPTION_TARGET2},
608  { "fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
609  { "fix-v4bx-interworking", no_argument, NULL, OPTION_FIX_V4BX_INTERWORKING},
610  { "use-blx", no_argument, NULL, OPTION_USE_BLX},
611  { "vfp11-denorm-fix", required_argument, NULL, OPTION_VFP11_DENORM_FIX},
612  { "fix-stm32l4xx-629360", optional_argument, NULL, OPTION_STM32L4XX_FIX},
613  { "no-enum-size-warning", no_argument, NULL, OPTION_NO_ENUM_SIZE_WARNING},
614  { "pic-veneer", no_argument, NULL, OPTION_PIC_VENEER},
615  { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
616  { "no-wchar-size-warning", no_argument, NULL, OPTION_NO_WCHAR_SIZE_WARNING},
617  { "fix-cortex-a8", no_argument, NULL, OPTION_FIX_CORTEX_A8 },
618  { "no-fix-cortex-a8", no_argument, NULL, OPTION_NO_FIX_CORTEX_A8 },
619  { "no-merge-exidx-entries", no_argument, NULL, OPTION_NO_MERGE_EXIDX_ENTRIES },
620  { "fix-arm1176", no_argument, NULL, OPTION_FIX_ARM1176 },
621  { "no-fix-arm1176", no_argument, NULL, OPTION_NO_FIX_ARM1176 },
622  { "long-plt", no_argument, NULL, OPTION_LONG_PLT },
623  { "cmse-implib", no_argument, NULL, OPTION_CMSE_IMPLIB },
624  { "in-implib", required_argument, NULL, OPTION_IN_IMPLIB },
625'
626
627PARSE_AND_LIST_OPTIONS='
628  fprintf (file, _("  --thumb-entry=<sym>         Set the entry point to be Thumb symbol <sym>\n"));
629  fprintf (file, _("  --be8                       Output BE8 format image\n"));
630  fprintf (file, _("  --target1-rel               Interpret R_ARM_TARGET1 as R_ARM_REL32\n"));
631  fprintf (file, _("  --target1-abs               Interpret R_ARM_TARGET1 as R_ARM_ABS32\n"));
632  fprintf (file, _("  --target2=<type>            Specify definition of R_ARM_TARGET2\n"));
633  fprintf (file, _("  --fix-v4bx                  Rewrite BX rn as MOV pc, rn for ARMv4\n"));
634  fprintf (file, _("  --fix-v4bx-interworking     Rewrite BX rn branch to ARMv4 interworking veneer\n"));
635  fprintf (file, _("  --use-blx                   Enable use of BLX instructions\n"));
636  fprintf (file, _("  --vfp11-denorm-fix          Specify how to fix VFP11 denorm erratum\n"));
637  fprintf (file, _("  --fix-stm32l4xx-629360      Specify how to fix STM32L4XX 629360 erratum\n"));
638  fprintf (file, _("  --no-enum-size-warning      Don'\''t warn about objects with incompatible\n"
639		   "                                enum sizes\n"));
640  fprintf (file, _("  --no-wchar-size-warning     Don'\''t warn about objects with incompatible\n"
641		   "                                wchar_t sizes\n"));
642  fprintf (file, _("  --pic-veneer                Always generate PIC interworking veneers\n"));
643  fprintf (file, _("  --long-plt                  Generate long .plt entries\n"
644           "                              to handle large .plt/.got displacements\n"));
645  fprintf (file, _("  --cmse-implib               Make import library to be a secure gateway import\n"
646                   "                                library as per ARMv8-M Security Extensions\n"));
647  fprintf (file, _("  --in-implib                 Import library whose symbols address must\n"
648                   "                                remain stable\n"));
649  fprintf (file, _("\
650  --stub-group-size=N         Maximum size of a group of input sections that\n\
651                                can be handled by one stub section.  A negative\n\
652                                value locates all stubs after their branches\n\
653                                (with a group size of -N), while a positive\n\
654                                value allows two groups of input sections, one\n\
655                                before, and one after each stub section.\n\
656                                Values of +/-1 indicate the linker should\n\
657                                choose suitable defaults.\n"));
658  fprintf (file, _("  --[no-]fix-cortex-a8        Disable/enable Cortex-A8 Thumb-2 branch erratum fix\n"));
659  fprintf (file, _("  --no-merge-exidx-entries    Disable merging exidx entries\n"));
660  fprintf (file, _("  --[no-]fix-arm1176          Disable/enable ARM1176 BLX immediate erratum fix\n"));
661'
662
663PARSE_AND_LIST_ARGS_CASES='
664    case '\'p\'':
665      /* Only here for backwards compatibility.  */
666      break;
667
668    case OPTION_THUMB_ENTRY:
669      params.thumb_entry_symbol = optarg;
670      break;
671
672    case OPTION_BE8:
673      params.byteswap_code = 1;
674      break;
675
676    case OPTION_TARGET1_REL:
677      params.target1_is_rel = 1;
678      break;
679
680    case OPTION_TARGET1_ABS:
681      params.target1_is_rel = 0;
682      break;
683
684    case OPTION_TARGET2:
685      params.target2_type = optarg;
686      break;
687
688    case OPTION_FIX_V4BX:
689      params.fix_v4bx = 1;
690      break;
691
692    case OPTION_FIX_V4BX_INTERWORKING:
693      params.fix_v4bx = 2;
694      break;
695
696    case OPTION_USE_BLX:
697      params.use_blx = 1;
698      break;
699
700    case OPTION_VFP11_DENORM_FIX:
701      if (strcmp (optarg, "none") == 0)
702	params.vfp11_denorm_fix = BFD_ARM_VFP11_FIX_NONE;
703      else if (strcmp (optarg, "scalar") == 0)
704	params.vfp11_denorm_fix = BFD_ARM_VFP11_FIX_SCALAR;
705      else if (strcmp (optarg, "vector") == 0)
706	params.vfp11_denorm_fix = BFD_ARM_VFP11_FIX_VECTOR;
707      else
708	einfo (_("%P: unrecognized VFP11 fix type '\''%s'\''\n"), optarg);
709      break;
710
711    case OPTION_STM32L4XX_FIX:
712      if (!optarg)
713	params.stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_DEFAULT;
714      else if (strcmp (optarg, "none") == 0)
715	params.stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_NONE;
716      else if (strcmp (optarg, "default") == 0)
717	params.stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_DEFAULT;
718      else if (strcmp (optarg, "all") == 0)
719	params.stm32l4xx_fix = BFD_ARM_STM32L4XX_FIX_ALL;
720      else
721	einfo (_("%P: unrecognized STM32L4XX fix type '\''%s'\''\n"), optarg);
722      break;
723
724    case OPTION_NO_ENUM_SIZE_WARNING:
725      params.no_enum_size_warning = 1;
726      break;
727
728    case OPTION_NO_WCHAR_SIZE_WARNING:
729      params.no_wchar_size_warning = 1;
730      break;
731
732    case OPTION_PIC_VENEER:
733      params.pic_veneer = 1;
734      break;
735
736    case OPTION_STUBGROUP_SIZE:
737      {
738	const char *end;
739
740	group_size = bfd_scan_vma (optarg, &end, 0);
741	if (*end)
742	  einfo (_("%F%P: invalid number `%s'\''\n"), optarg);
743      }
744      break;
745
746    case OPTION_FIX_CORTEX_A8:
747      params.fix_cortex_a8 = 1;
748      break;
749
750    case OPTION_NO_FIX_CORTEX_A8:
751      params.fix_cortex_a8 = 0;
752      break;
753
754   case OPTION_NO_MERGE_EXIDX_ENTRIES:
755      params.merge_exidx_entries = 0;
756      break;
757
758   case OPTION_FIX_ARM1176:
759      params.fix_arm1176 = 1;
760      break;
761
762   case OPTION_NO_FIX_ARM1176:
763      params.fix_arm1176 = 0;
764      break;
765
766   case OPTION_LONG_PLT:
767      bfd_elf32_arm_use_long_plt ();
768      break;
769
770   case OPTION_CMSE_IMPLIB:
771      params.cmse_implib = 1;
772      break;
773
774   case OPTION_IN_IMPLIB:
775      in_implib_filename = optarg;
776      break;
777'
778
779# We have our own before_allocation etc. functions, but they call
780# the standard routines, so give them a different name.
781LDEMUL_BEFORE_ALLOCATION=arm_elf_before_allocation
782LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
783LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=arm_elf_create_output_section_statements
784
785# Replace the elf before_parse function with our own.
786LDEMUL_BEFORE_PARSE=gld"${EMULATION_NAME}"_before_parse
787LDEMUL_SET_SYMBOLS=gld"${EMULATION_NAME}"_set_symbols
788
789# Call the extra arm-elf function
790LDEMUL_FINISH=gld${EMULATION_NAME}_finish
791