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