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