* lib/ld-lib.exp (run_dump_test): Add -L$srcdir/$subdir.
[external/binutils.git] / ld / emultempl / ppc64elf.em
1 # This shell script emits a C file. -*- C -*-
2 #   Copyright 2002 Free Software Foundation, Inc.
3 #
4 # This file is part of GLD, the Gnu Linker.
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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 #
20
21 # This file is sourced from elf32.em, and defines extra powerpc64-elf
22 # specific routines.
23 #
24 cat >>e${EMULATION_NAME}.c <<EOF
25
26 #include "ldctor.h"
27 #include "libbfd.h"
28 #include "elf64-ppc.h"
29
30 /* Fake input file for stubs.  */
31 static lang_input_statement_type *stub_file;
32
33 /* Whether we need to call ppc_layout_sections_again.  */
34 static int need_laying_out = 0;
35
36 /* Maximum size of a group of input sections that can be handled by
37    one stub section.  A value of +/-1 indicates the bfd back-end
38    should use a suitable default size.  */
39 static bfd_signed_vma group_size = 1;
40
41 static void ppc_create_output_section_statements PARAMS ((void));
42 static asection *ppc_add_stub_section PARAMS ((const char *, asection *));
43 static void ppc_layout_sections_again PARAMS ((void));
44 static void gld${EMULATION_NAME}_after_allocation PARAMS ((void));
45 static void build_section_lists PARAMS ((lang_statement_union_type *));
46
47 /* This is called before the input files are opened.  We create a new
48    fake input file to hold the stub sections.  */
49
50 static void
51 ppc_create_output_section_statements ()
52 {
53   stub_file = lang_add_input_file ("linker stubs",
54                                    lang_input_file_is_fake_enum,
55                                    NULL);
56   stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
57   if (stub_file->the_bfd == NULL
58       || !bfd_set_arch_mach (stub_file->the_bfd,
59                              bfd_get_arch (output_bfd),
60                              bfd_get_mach (output_bfd)))
61     {
62       einfo ("%X%P: can not create BFD %E\n");
63       return;
64     }
65
66   ldlang_add_file (stub_file);
67 }
68
69
70 struct hook_stub_info
71 {
72   lang_statement_list_type add;
73   asection *input_section;
74 };
75
76 /* Traverse the linker tree to find the spot where the stub goes.  */
77
78 static boolean hook_in_stub
79   PARAMS ((struct hook_stub_info *, lang_statement_union_type **));
80
81 static boolean
82 hook_in_stub (info, lp)
83      struct hook_stub_info *info;
84      lang_statement_union_type **lp;
85 {
86   lang_statement_union_type *l;
87   boolean ret;
88
89   for (; (l = *lp) != NULL; lp = &l->header.next)
90     {
91       switch (l->header.type)
92         {
93         case lang_constructors_statement_enum:
94           ret = hook_in_stub (info, &constructor_list.head);
95           if (ret)
96             return ret;
97           break;
98
99         case lang_output_section_statement_enum:
100           ret = hook_in_stub (info,
101                               &l->output_section_statement.children.head);
102           if (ret)
103             return ret;
104           break;
105
106         case lang_wild_statement_enum:
107           ret = hook_in_stub (info, &l->wild_statement.children.head);
108           if (ret)
109             return ret;
110           break;
111
112         case lang_group_statement_enum:
113           ret = hook_in_stub (info, &l->group_statement.children.head);
114           if (ret)
115             return ret;
116           break;
117
118         case lang_input_section_enum:
119           if (l->input_section.section == info->input_section)
120             {
121               /* We've found our section.  Insert the stub immediately
122                  before its associated input section.  */
123               *lp = info->add.head;
124               *(info->add.tail) = l;
125               return true;
126             }
127           break;
128
129         case lang_data_statement_enum:
130         case lang_reloc_statement_enum:
131         case lang_object_symbols_statement_enum:
132         case lang_output_statement_enum:
133         case lang_target_statement_enum:
134         case lang_input_statement_enum:
135         case lang_assignment_statement_enum:
136         case lang_padding_statement_enum:
137         case lang_address_statement_enum:
138         case lang_fill_statement_enum:
139           break;
140
141         default:
142           FAIL ();
143           break;
144         }
145     }
146   return false;
147 }
148
149
150 /* Call-back for ppc64_elf_size_stubs.  */
151
152 /* Create a new stub section, and arrange for it to be linked
153    immediately before INPUT_SECTION.  */
154
155 static asection *
156 ppc_add_stub_section (stub_sec_name, input_section)
157      const char *stub_sec_name;
158      asection *input_section;
159 {
160   asection *stub_sec;
161   flagword flags;
162   asection *output_section;
163   const char *secname;
164   lang_output_section_statement_type *os;
165   struct hook_stub_info info;
166
167   stub_sec = bfd_make_section_anyway (stub_file->the_bfd, stub_sec_name);
168   if (stub_sec == NULL)
169     goto err_ret;
170
171   flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
172            | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
173   if (!bfd_set_section_flags (stub_file->the_bfd, stub_sec, flags))
174     goto err_ret;
175
176   output_section = input_section->output_section;
177   secname = bfd_get_section_name (output_section->owner, output_section);
178   os = lang_output_section_find (secname);
179
180   info.input_section = input_section;
181   lang_list_init (&info.add);
182   lang_add_section (&info.add, stub_sec, os, stub_file);
183
184   if (info.add.head == NULL)
185     goto err_ret;
186
187   if (hook_in_stub (&info, &os->children.head))
188     return stub_sec;
189
190  err_ret:
191   einfo ("%X%P: can not make stub section: %E\n");
192   return NULL;
193 }
194
195
196 /* Another call-back for ppc64_elf_size_stubs.  */
197
198 static void
199 ppc_layout_sections_again ()
200 {
201   /* If we have changed sizes of the stub sections, then we need
202      to recalculate all the section offsets.  This may mean we need to
203      add even more stubs.  */
204   need_laying_out = 0;
205
206   lang_reset_memory_regions ();
207
208   /* Resize the sections.  */
209   lang_size_sections (stat_ptr->head, abs_output_section,
210                       &stat_ptr->head, 0, (bfd_vma) 0, NULL);
211
212   /* Recalculate TOC base.  */
213   ldemul_after_allocation ();
214
215   /* Do the assignments again.  */
216   lang_do_assignments (stat_ptr->head, abs_output_section,
217                        (fill_type *) 0, (bfd_vma) 0);
218 }
219
220
221 /* Call the back-end function to set TOC base after we have placed all
222    the sections.  */
223 static void
224 gld${EMULATION_NAME}_after_allocation ()
225 {
226   if (!link_info.relocateable)
227     _bfd_set_gp_value (output_bfd, ppc64_elf_toc (output_bfd));
228 }
229
230
231 static void
232 build_section_lists (statement)
233      lang_statement_union_type *statement;
234 {
235   if (statement->header.type == lang_input_section_enum
236       && !statement->input_section.ifile->just_syms_flag
237       && statement->input_section.section->output_section != NULL
238       && statement->input_section.section->output_section->owner == output_bfd)
239     {
240       ppc64_elf_next_input_section (&link_info,
241                                     statement->input_section.section);
242     }
243 }
244
245 /* Final emulation specific call.  */
246
247 static void
248 gld${EMULATION_NAME}_finish ()
249 {
250   int ret;
251
252   /* e_entry on PowerPC64 points to the function descriptor for
253      _start.  If _start is missing, default to the first function
254      descriptor in the .opd section.  */
255   entry_section = ".opd";
256
257   /* If generating a relocatable output file, then we don't have any
258      stubs.  */
259   if (link_info.relocateable)
260     return;
261
262   /* bfd_elf64_discard_info just plays with debugging sections,
263      ie. doesn't affect any code, so we can delay resizing the
264      sections.  It's likely we'll resize everything in the process of
265      adding stubs.  */
266   if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info))
267     need_laying_out = 1;
268
269   ret = ppc64_elf_setup_section_lists (output_bfd, &link_info);
270   if (ret != 0)
271     {
272       if (ret < 0)
273         {
274           einfo ("%X%P: can not size stub section: %E\n");
275           return;
276         }
277
278       lang_for_each_statement (build_section_lists);
279
280       /* Call into the BFD backend to do the real work.  */
281       if (!ppc64_elf_size_stubs (output_bfd,
282                                  stub_file->the_bfd,
283                                  &link_info,
284                                  group_size,
285                                  &ppc_add_stub_section,
286                                  &ppc_layout_sections_again))
287         {
288           einfo ("%X%P: can not size stub section: %E\n");
289           return;
290         }
291     }
292
293   if (need_laying_out)
294     ppc_layout_sections_again ();
295
296   if (stub_file->the_bfd->sections != NULL)
297     {
298       if (!ppc64_elf_build_stubs (&link_info))
299         einfo ("%X%P: can not build stubs: %E\n");
300     }
301 }
302
303
304 /* Avoid processing the fake stub_file in vercheck, stat_needed and
305    check_needed routines.  */
306
307 static void ppc_for_each_input_file_wrapper
308   PARAMS ((lang_input_statement_type *));
309 static void ppc_lang_for_each_input_file
310   PARAMS ((void (*) (lang_input_statement_type *)));
311
312 static void (*real_func) PARAMS ((lang_input_statement_type *));
313
314 static void ppc_for_each_input_file_wrapper (l)
315      lang_input_statement_type *l;
316 {
317   if (l != stub_file)
318     (*real_func) (l);
319 }
320
321 static void
322 ppc_lang_for_each_input_file (func)
323      void (*func) PARAMS ((lang_input_statement_type *));
324 {
325   real_func = func;
326   lang_for_each_input_file (&ppc_for_each_input_file_wrapper);
327 }
328
329 #define lang_for_each_input_file ppc_lang_for_each_input_file
330
331 EOF
332
333 # Define some shell vars to insert bits of code into the standard elf
334 # parse_args and list_options functions.
335 #
336 PARSE_AND_LIST_PROLOGUE='
337 #define OPTION_STUBGROUP_SIZE           301
338 '
339
340 # The options are repeated below so that no abbreviations are allowed.
341 # Otherwise -s matches stub-group-size
342 PARSE_AND_LIST_LONGOPTS='
343   { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
344   { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
345 '
346
347 PARSE_AND_LIST_OPTIONS='
348   fprintf (file, _("\
349   --stub-group-size=N   Maximum size of a group of input sections that can be\n\
350                           handled by one stub section.  A negative value\n\
351                           locates all stubs before their branches (with a\n\
352                           group size of -N), while a positive value allows\n\
353                           two groups of input sections, one before, and one\n\
354                           after each stub section.  Values of +/-1 indicate\n\
355                           the linker should choose suitable defaults.\n"
356                    ));
357 '
358
359 PARSE_AND_LIST_ARGS_CASES='
360     case OPTION_STUBGROUP_SIZE:
361       {
362         const char *end;
363         group_size = bfd_scan_vma (optarg, &end, 0);
364         if (*end)
365           einfo (_("%P%F: invalid number `%s'\''\n"), optarg);
366       }
367       break;
368 '
369
370 # Put these extra ppc64elf routines in ld_${EMULATION_NAME}_emulation
371 #
372 LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
373 LDEMUL_FINISH=gld${EMULATION_NAME}_finish
374 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements