[PATCH 51/57][Arm][OBJDUMP] Add support for MVE instructions: lctp, letp, wlstp and...
[binutils-gdb.git] / ld / emultempl / aarch64elf.em
blobbfe8d1b179230a6ba32be42b2105180f4cd72446
1 # This shell script emits a C file. -*- C -*-
2 #   Copyright (C) 2009-2019 Free Software Foundation, Inc.
3 #   Contributed by ARM Ltd.
5 # This file is part of the GNU Binutils.
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the license, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; see the file COPYING3. If not,
19 # see <http://www.gnu.org/licenses/>.
22 # This file is sourced from elf32.em, and defines extra aarch64-elf
23 # specific routines.
25 fragment <<EOF
27 #include "ldctor.h"
28 #include "elf/aarch64.h"
30 static int no_enum_size_warning = 0;
31 static int no_wchar_size_warning = 0;
32 static int pic_veneer = 0;
33 static int fix_erratum_835769 = 0;
34 static int fix_erratum_843419 = 0;
35 static int no_apply_dynamic_relocs = 0;
36 static aarch64_plt_type plt_type = PLT_NORMAL;
37 static aarch64_enable_bti_type bti_type = BTI_NONE;
39 static void
40 gld${EMULATION_NAME}_before_parse (void)
42 #ifndef TARGET_                 /* I.e., if not generic.  */
43   ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown);
44 #endif /* not TARGET_ */
45   input_flags.dynamic = ${DYNAMIC_LINK-TRUE};
46   config.has_shared = `if test -n "$GENERATE_SHLIB_SCRIPT" ; then echo TRUE ; else echo FALSE ; fi`;
47   config.separate_code = `if test "x${SEPARATE_CODE}" = xyes ; then echo TRUE ; else echo FALSE ; fi`;
48   link_info.check_relocs_after_open_input = TRUE;
49   link_info.relro = DEFAULT_LD_Z_RELRO;
52 static void
53 aarch64_elf_before_allocation (void)
55   /* We should be able to set the size of the interworking stub section.  We
56      can't do it until later if we have dynamic sections, though.  */
57   if (! elf_hash_table (&link_info)->dynamic_sections_created)
58     {
59       /* Here we rummage through the found bfds to collect information.  */
60       LANG_FOR_EACH_INPUT_STATEMENT (is)
61       {
62         /* Initialise mapping tables for code/data.  */
63         bfd_elf${ELFSIZE}_aarch64_init_maps (is->the_bfd);
64       }
65     }
67   /* Call the standard elf routine.  */
68   gld${EMULATION_NAME}_before_allocation ();
71 /* Fake input file for stubs.  */
72 static lang_input_statement_type *stub_file;
74 /* Whether we need to call gldarm_layout_sections_again.  */
75 static int need_laying_out = 0;
77 /* Maximum size of a group of input sections that can be handled by
78    one stub section.  A value of +/-1 indicates the bfd back-end
79    should use a suitable default size.  */
80 static bfd_signed_vma group_size = 1;
82 struct hook_stub_info
84   lang_statement_list_type add;
85   asection *input_section;
88 /* Traverse the linker tree to find the spot where the stub goes.  */
90 static bfd_boolean
91 hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
93   lang_statement_union_type *l;
94   bfd_boolean ret;
96   for (; (l = *lp) != NULL; lp = &l->header.next)
97     {
98       switch (l->header.type)
99         {
100         case lang_constructors_statement_enum:
101           ret = hook_in_stub (info, &constructor_list.head);
102           if (ret)
103             return ret;
104           break;
106         case lang_output_section_statement_enum:
107           ret = hook_in_stub (info,
108                               &l->output_section_statement.children.head);
109           if (ret)
110             return ret;
111           break;
113         case lang_wild_statement_enum:
114           ret = hook_in_stub (info, &l->wild_statement.children.head);
115           if (ret)
116             return ret;
117           break;
119         case lang_group_statement_enum:
120           ret = hook_in_stub (info, &l->group_statement.children.head);
121           if (ret)
122             return ret;
123           break;
125         case lang_input_section_enum:
126           if (l->input_section.section == info->input_section)
127             {
128               /* We've found our section.  Insert the stub immediately
129                  after its associated input section.  */
130               *(info->add.tail) = l->header.next;
131               l->header.next = info->add.head;
132               return TRUE;
133             }
134           break;
136         case lang_data_statement_enum:
137         case lang_reloc_statement_enum:
138         case lang_object_symbols_statement_enum:
139         case lang_output_statement_enum:
140         case lang_target_statement_enum:
141         case lang_input_statement_enum:
142         case lang_assignment_statement_enum:
143         case lang_padding_statement_enum:
144         case lang_address_statement_enum:
145         case lang_fill_statement_enum:
146           break;
148         default:
149           FAIL ();
150           break;
151         }
152     }
153   return FALSE;
157 /* Call-back for elf${ELFSIZE}_aarch64_size_stubs.  */
159 /* Create a new stub section, and arrange for it to be linked
160    immediately after INPUT_SECTION.  */
162 static asection *
163 elf${ELFSIZE}_aarch64_add_stub_section (const char *stub_sec_name,
164                                         asection *input_section)
166   asection *stub_sec;
167   flagword flags;
168   asection *output_section;
169   lang_output_section_statement_type *os;
170   struct hook_stub_info info;
172   flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
173            | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
174   stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd,
175                                                  stub_sec_name, flags);
176   if (stub_sec == NULL)
177     goto err_ret;
179   /* Long branch stubs contain a 64-bit address, so the section requires
180      8 byte alignment.  */
181   bfd_set_section_alignment (stub_file->the_bfd, stub_sec, 3);
183   output_section = input_section->output_section;
184   os = lang_output_section_get (output_section);
186   info.input_section = input_section;
187   lang_list_init (&info.add);
188   lang_add_section (&info.add, stub_sec, NULL, os);
190   if (info.add.head == NULL)
191     goto err_ret;
193   if (hook_in_stub (&info, &os->children.head))
194     return stub_sec;
196  err_ret:
197   einfo (_("%X%P: can not make stub section: %E\n"));
198   return NULL;
201 /* Another call-back for elf${ELFSIZE}_aarch64_size_stubs.  */
203 static void
204 gldaarch64_layout_sections_again (void)
206   /* If we have changed sizes of the stub sections, then we need
207      to recalculate all the section offsets.  This may mean we need to
208      add even more stubs.  */
209   gld${EMULATION_NAME}_map_segments (TRUE);
210   need_laying_out = -1;
213 static void
214 build_section_lists (lang_statement_union_type *statement)
216   if (statement->header.type == lang_input_section_enum)
217     {
218       asection *i = statement->input_section.section;
220       if (!((lang_input_statement_type *) i->owner->usrdata)->flags.just_syms
221           && (i->flags & SEC_EXCLUDE) == 0
222           && i->output_section != NULL
223           && i->output_section->owner == link_info.output_bfd)
224         elf${ELFSIZE}_aarch64_next_input_section (& link_info, i);
225     }
228 static void
229 gld${EMULATION_NAME}_after_allocation (void)
231   int ret;
233   /* bfd_elf32_discard_info just plays with debugging sections,
234      ie. doesn't affect any code, so we can delay resizing the
235      sections.  It's likely we'll resize everything in the process of
236      adding stubs.  */
237   ret = bfd_elf_discard_info (link_info.output_bfd, & link_info);
238   if (ret < 0)
239     {
240       einfo (_("%X%P: .eh_frame/.stab edit: %E\n"));
241       return;
242     }
243   else if (ret > 0)
244     need_laying_out = 1;
246   /* If generating a relocatable output file, then we don't
247      have to examine the relocs.  */
248   if (stub_file != NULL && !bfd_link_relocatable (&link_info))
249     {
250       ret = elf${ELFSIZE}_aarch64_setup_section_lists (link_info.output_bfd,
251                                                        &link_info);
252       if (ret != 0)
253         {
254           if (ret < 0)
255             {
256               einfo (_("%X%P: could not compute sections lists "
257                        "for stub generation: %E\n"));
258               return;
259             }
261           lang_for_each_statement (build_section_lists);
263           /* Call into the BFD backend to do the real work.  */
264           if (! elf${ELFSIZE}_aarch64_size_stubs (link_info.output_bfd,
265                                           stub_file->the_bfd,
266                                           & link_info,
267                                           group_size,
268                                           & elf${ELFSIZE}_aarch64_add_stub_section,
269                                           & gldaarch64_layout_sections_again))
270             {
271               einfo (_("%X%P: can not size stub section: %E\n"));
272               return;
273             }
274         }
275     }
277   if (need_laying_out != -1)
278     gld${EMULATION_NAME}_map_segments (need_laying_out);
281 static void
282 gld${EMULATION_NAME}_finish (void)
284   if (!bfd_link_relocatable (&link_info))
285     {
286       /* Now build the linker stubs.  */
287       if (stub_file->the_bfd->sections != NULL)
288         {
289           if (! elf${ELFSIZE}_aarch64_build_stubs (& link_info))
290             einfo (_("%X%P: can not build stubs: %E\n"));
291         }
292     }
294   finish_default ();
297 /* This is a convenient point to tell BFD about target specific flags.
298    After the output has been created, but before inputs are read.  */
299 static void
300 aarch64_elf_create_output_section_statements (void)
302   if (strstr (bfd_get_target (link_info.output_bfd), "aarch64") == NULL)
303     {
304       /* The arm backend needs special fields in the output hash structure.
305          These will only be created if the output format is an arm format,
306          hence we do not support linking and changing output formats at the
307          same time.  Use a link followed by objcopy to change output formats.  */
308       einfo (_("%F%P: error: cannot change output format "
309                "whilst linking %s binaries\n"), "AArch64");
310       return;
311     }
313   aarch64_bti_pac_info bp_info;
314   bp_info.plt_type = plt_type;
315   bp_info.bti_type = bti_type;
317   bfd_elf${ELFSIZE}_aarch64_set_options (link_info.output_bfd, &link_info,
318                                  no_enum_size_warning,
319                                  no_wchar_size_warning,
320                                  pic_veneer,
321                                  fix_erratum_835769, fix_erratum_843419,
322                                  no_apply_dynamic_relocs,
323                                  bp_info);
325   stub_file = lang_add_input_file ("linker stubs",
326                                    lang_input_file_is_fake_enum,
327                                    NULL);
328   stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd);
329   if (stub_file->the_bfd == NULL
330       || ! bfd_set_arch_mach (stub_file->the_bfd,
331                               bfd_get_arch (link_info.output_bfd),
332                               bfd_get_mach (link_info.output_bfd)))
333     {
334       einfo (_("%F%P: can not create BFD: %E\n"));
335       return;
336     }
338   stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
339   ldlang_add_file (stub_file);
342 /* Avoid processing the fake stub_file in vercheck, stat_needed and
343    check_needed routines.  */
345 static void (*real_func) (lang_input_statement_type *);
347 static void aarch64_for_each_input_file_wrapper (lang_input_statement_type *l)
349   if (l != stub_file)
350     (*real_func) (l);
353 static void
354 aarch64_lang_for_each_input_file (void (*func) (lang_input_statement_type *))
356   real_func = func;
357   lang_for_each_input_file (&aarch64_for_each_input_file_wrapper);
360 #define lang_for_each_input_file aarch64_lang_for_each_input_file
364 # Define some shell vars to insert bits of code into the standard elf
365 # parse_args and list_options functions.
367 PARSE_AND_LIST_PROLOGUE='
368 #define OPTION_NO_ENUM_SIZE_WARNING     309
369 #define OPTION_PIC_VENEER               310
370 #define OPTION_STUBGROUP_SIZE           311
371 #define OPTION_NO_WCHAR_SIZE_WARNING    312
372 #define OPTION_FIX_ERRATUM_835769       313
373 #define OPTION_FIX_ERRATUM_843419       314
374 #define OPTION_NO_APPLY_DYNAMIC_RELOCS  315
375 #define OPTION_FORCE_BTI                316
376 #define OPTION_PAC_PLT                  317
379 PARSE_AND_LIST_SHORTOPTS=p
381 PARSE_AND_LIST_LONGOPTS='
382   { "no-pipeline-knowledge", no_argument, NULL, '\'p\''},
383   { "no-enum-size-warning", no_argument, NULL, OPTION_NO_ENUM_SIZE_WARNING},
384   { "pic-veneer", no_argument, NULL, OPTION_PIC_VENEER},
385   { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
386   { "no-wchar-size-warning", no_argument, NULL, OPTION_NO_WCHAR_SIZE_WARNING},
387   { "fix-cortex-a53-835769", no_argument, NULL, OPTION_FIX_ERRATUM_835769},
388   { "fix-cortex-a53-843419", no_argument, NULL, OPTION_FIX_ERRATUM_843419},
389   { "no-apply-dynamic-relocs", no_argument, NULL, OPTION_NO_APPLY_DYNAMIC_RELOCS},
390   { "force-bti", no_argument, NULL, OPTION_FORCE_BTI},
391   { "pac-plt", no_argument, NULL, OPTION_PAC_PLT},
394 PARSE_AND_LIST_OPTIONS='
395   fprintf (file, _("  --no-enum-size-warning      Don'\''t warn about objects with incompatible\n"
396                    "                                enum sizes\n"));
397   fprintf (file, _("  --no-wchar-size-warning     Don'\''t warn about objects with incompatible\n"
398                    "                                wchar_t sizes\n"));
399   fprintf (file, _("  --pic-veneer                Always generate PIC interworking veneers\n"));
400   fprintf (file, _("\
401   --stub-group-size=N         Maximum size of a group of input sections that\n\
402                                 can be handled by one stub section.  A negative\n\
403                                 value locates all stubs after their branches\n\
404                                 (with a group size of -N), while a positive\n\
405                                 value allows two groups of input sections, one\n\
406                                 before, and one after each stub section.\n\
407                                 Values of +/-1 indicate the linker should\n\
408                                 choose suitable defaults.\n"));
409   fprintf (file, _("  --fix-cortex-a53-835769      Fix erratum 835769\n"));
410   fprintf (file, _("  --fix-cortex-a53-843419      Fix erratum 843419\n"));
411   fprintf (file, _("  --no-apply-dynamic-relocs    Do not apply link-time values for dynamic relocations\n"));
412   fprintf (file, _("  --force-bti                  Turn on Branch Target Identification mechanism and generate PLTs with BTI. Generate warnings for missing BTI on inputs\n"));
413   fprintf (file, _("  --pac-plt                    Protect PLTs with Pointer Authentication.\n"));
416 PARSE_AND_LIST_ARGS_CASES='
417     case '\'p\'':
418       /* Only here for backwards compatibility.  */
419       break;
421     case OPTION_NO_ENUM_SIZE_WARNING:
422       no_enum_size_warning = 1;
423       break;
425     case OPTION_NO_WCHAR_SIZE_WARNING:
426       no_wchar_size_warning = 1;
427       break;
429     case OPTION_PIC_VENEER:
430       pic_veneer = 1;
431       break;
433     case OPTION_FIX_ERRATUM_835769:
434       fix_erratum_835769 = 1;
435       break;
437     case OPTION_FIX_ERRATUM_843419:
438       fix_erratum_843419 = 1;
439       break;
441     case OPTION_NO_APPLY_DYNAMIC_RELOCS:
442       no_apply_dynamic_relocs = 1;
443       break;
445     case OPTION_FORCE_BTI:
446       plt_type |= PLT_BTI;
447       bti_type = BTI_WARN;
448       break;
450     case OPTION_PAC_PLT:
451       plt_type |= PLT_PAC;
452       break;
454     case OPTION_STUBGROUP_SIZE:
455       {
456         const char *end;
458         group_size = bfd_scan_vma (optarg, &end, 0);
459         if (*end)
460           einfo (_("%F%P: invalid number `%s'\''\n"), optarg);
461       }
462       break;
465 # We have our own before_allocation etc. functions, but they call
466 # the standard routines, so give them a different name.
467 LDEMUL_BEFORE_ALLOCATION=aarch64_elf_before_allocation
468 LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
469 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=aarch64_elf_create_output_section_statements
471 # Replace the elf before_parse function with our own.
472 LDEMUL_BEFORE_PARSE=gld"${EMULATION_NAME}"_before_parse
474 # Call the extra arm-elf function
475 LDEMUL_FINISH=gld${EMULATION_NAME}_finish