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