Add translations for various sub-directories
[binutils-gdb.git] / ld / emultempl / kvxelf.em
blobcbfde0ed24ced86a9ce4ba1aedc341aded18473f
1 # This shell script emits a C file. -*- C -*-
2 #   Copyright (C) 2009-2025 Free Software Foundation, Inc.
3 #   Contributed by Kalray Inc.
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 kvx-elf
23 # specific routines.
25 fragment <<EOF
27 #include "ldctor.h"
28 #include "elf/kvx.h"
29 #include "elfxx-kvx.h"
32 static void
33 elf${ELFSIZE}_kvx_before_allocation (void)
35 EOF
36 if test x"${EMULATION_NAME}" != x"elf64kvx_linux"; then
37 fragment <<EOF
38   if (bfd_link_pie (&link_info)) {
39           einfo (_("%F:%P: -pie not supported\n"));
40   }
41 EOF
43 fragment <<EOF
45   /* Call the standard elf routine.  */
46   gld${EMULATION_NAME}_before_allocation ();
51 /* Fake input file for stubs.  */
52 static lang_input_statement_type *stub_file;
54 /* Whether we need to call gldarm_layout_sections_again.  */
55 static int need_laying_out = 0;
57 /* Maximum size of a group of input sections that can be handled by
58    one stub section.  A value of +/-1 indicates the bfd back-end
59    should use a suitable default size.  */
60 static bfd_signed_vma group_size = -1;
62 struct hook_stub_info
64   lang_statement_list_type add;
65   asection *input_section;
68 /* Traverse the linker tree to find the spot where the stub goes.  */
70 static bool
71 hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
73   lang_statement_union_type *l;
74   bool ret;
76   for (; (l = *lp) != NULL; lp = &l->header.next)
77     {
78       switch (l->header.type)
79         {
80         case lang_constructors_statement_enum:
81           ret = hook_in_stub (info, &constructor_list.head);
82           if (ret)
83             return ret;
84           break;
86         case lang_output_section_statement_enum:
87           ret = hook_in_stub (info,
88                   &l->output_section_statement.children.head);
90           if (ret)
91             return ret;
92           break;
94         case lang_wild_statement_enum:
95           ret = hook_in_stub (info, &l->wild_statement.children.head);
96           if (ret)
97             return ret;
98           break;
100         case lang_group_statement_enum:
101           ret = hook_in_stub (info, &l->group_statement.children.head);
102           if (ret)
103             return ret;
104           break;
106         case lang_input_section_enum:
107           if (l->input_section.section == info->input_section)
108             {
109               /* We've found our section.  Insert the stub immediately
110                  after its associated input section.  */
111               *(info->add.tail) = l->header.next;
112               l->header.next = info->add.head;
113               return true;
114             }
116           break;
118         case lang_data_statement_enum:
119         case lang_reloc_statement_enum:
120         case lang_object_symbols_statement_enum:
121         case lang_output_statement_enum:
122         case lang_target_statement_enum:
123         case lang_input_statement_enum:
124         case lang_assignment_statement_enum:
125         case lang_padding_statement_enum:
126         case lang_address_statement_enum:
127         case lang_fill_statement_enum:
128           break;
130         default:
131           FAIL ();
132           break;
133         }
134     }
135   return false;
139 /* Call-back for elf${ELFSIZE}_kvx_size_stubs.  */
141 /* Create a new stub section, and arrange for it to be linked
142    immediately after INPUT_SECTION.  */
144 static asection *
145 elf${ELFSIZE}_kvx_add_stub_section (const char *stub_sec_name,
146                                     asection *input_section)
148   asection *stub_sec;
149   flagword flags;
150   asection *output_section;
151   lang_output_section_statement_type *os;
152   struct hook_stub_info info;
154   flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
155            | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
156   stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd,
157                                                  stub_sec_name, flags);
158   if (stub_sec == NULL)
159     goto err_ret;
161   bfd_set_section_alignment (stub_sec, 2);
163   output_section = input_section->output_section;
164   os = lang_output_section_get (output_section);
166   info.input_section = input_section;
167   lang_list_init (&info.add);
168   lang_add_section (&info.add, stub_sec, NULL, NULL, os);
170   if (info.add.head == NULL)
171     goto err_ret;
173   if (hook_in_stub (&info, &os->children.head))
174     return stub_sec;
176  err_ret:
177   einfo ("%X%P: can not make stub section: %E\n");
178   return NULL;
181 /* Another call-back for elf${ELFSIZE}_kvx_size_stubs.  */
183 static void
184 gldkvx_layout_sections_again (void)
186   /* If we have changed sizes of the stub sections, then we need
187      to recalculate all the section offsets.  This may mean we need to
188      add even more stubs.  */
189   ldelf_map_segments (true);
190   need_laying_out = -1;
193 static void
194 build_section_lists (lang_statement_union_type *statement)
196   if (statement->header.type == lang_input_section_enum)
197     {
198       asection *i = statement->input_section.section;
200       if (!((lang_input_statement_type *) i->owner->usrdata)->flags.just_syms
201           && (i->flags & SEC_EXCLUDE) == 0
202           && i->output_section != NULL
203           && i->output_section->owner == link_info.output_bfd)
204         elf${ELFSIZE}_kvx_next_input_section (& link_info, i);
205     }
208 static void
209 gld${EMULATION_NAME}_after_allocation (void)
211   int ret;
213   /* bfd_elf32_discard_info just plays with debugging sections,
214      ie. doesn't affect any code, so we can delay resizing the
215      sections.  It's likely we'll resize everything in the process of
216      adding stubs.  */
217   ret = bfd_elf_discard_info (link_info.output_bfd, & link_info);
218   if (ret < 0)
219     {
220       einfo ("%X%P: .eh_frame/.stab edit: %E\n");
221       return;
222     }
223   else if (ret > 0)
224     need_laying_out = 1;
226   /* If generating a relocatable output file, then we don't
227      have to examine the relocs.  */
228   if (stub_file != NULL && !bfd_link_relocatable (&link_info))
229     {
230       ret = elf${ELFSIZE}_kvx_setup_section_lists (link_info.output_bfd,
231                                                        &link_info);
232       if (ret != 0)
233         {
234           if (ret < 0)
235             {
236               einfo ("%X%P: could not compute sections lists for stub generation: %E\n");
237               return;
238             }
240           lang_for_each_statement (build_section_lists);
242           /* Call into the BFD backend to do the real work.  */
243           if (! elf${ELFSIZE}_kvx_size_stubs (link_info.output_bfd,
244                                           stub_file->the_bfd,
245                                           & link_info,
246                                           group_size,
247                                           & elf${ELFSIZE}_kvx_add_stub_section,
248                                           & gldkvx_layout_sections_again))
249             {
250               einfo ("%X%P: cannot size stub section: %E\n");
251               return;
252             }
253         }
254     }
256   if (need_laying_out != -1)
257     ldelf_map_segments (need_laying_out);
260 static void
261 gld${EMULATION_NAME}_finish (void)
263   if (!bfd_link_relocatable (&link_info))
264     {
265       /* Now build the linker stubs.  */
266       if (stub_file != NULL
267           && stub_file->the_bfd->sections != NULL)
268         {
269           if (! elf${ELFSIZE}_kvx_build_stubs (& link_info))
270             einfo ("%X%P: can not build stubs: %E\n");
271         }
272     }
274   finish_default ();
277 /* This is a convenient point to tell BFD about target specific flags.
278    After the output has been created, but before inputs are read.  */
279 static void
280 kvx_elf_create_output_section_statements (void)
282   if (!(bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
283         && elf_object_id (link_info.output_bfd) == KVX_ELF_DATA))
284     return;
286   stub_file = lang_add_input_file ("linker stubs",
287                                    lang_input_file_is_fake_enum,
288                                    NULL);
289   stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd);
290   if (stub_file->the_bfd == NULL
291       || ! bfd_set_arch_mach (stub_file->the_bfd,
292                               bfd_get_arch (link_info.output_bfd),
293                               bfd_get_mach (link_info.output_bfd)))
294     {
295       einfo ("%X%P: can not create BFD %E\n");
296       return;
297     }
299   stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
300   ldlang_add_file (stub_file);
302   if (!kvx_elf${ELFSIZE}_init_stub_bfd (&link_info, stub_file->the_bfd))
303     einfo ("%F%P: can not init BFD: %E\n");
307 #define lang_for_each_input_file kvx_lang_for_each_input_file
311 LDEMUL_BEFORE_ALLOCATION=elf${ELFSIZE}_kvx_before_allocation
312 LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
313 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=kvx_elf_create_output_section_statements
315 # Call the extra arm-elf function
316 LDEMUL_FINISH=gld${EMULATION_NAME}_finish