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