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