]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - contrib/binutils/ld/emultempl/ppc64elf.em
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / contrib / binutils / ld / emultempl / ppc64elf.em
1 # This shell script emits a C file. -*- C -*-
2 #   Copyright 2002, 2003, 2004 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 "elf-bfd.h"
29 #include "elf64-ppc.h"
30
31 /* Fake input file for stubs.  */
32 static lang_input_statement_type *stub_file;
33 static int stub_added = 0;
34
35 /* Whether we need to call ppc_layout_sections_again.  */
36 static int need_laying_out = 0;
37
38 /* Maximum size of a group of input sections that can be handled by
39    one stub section.  A value of +/-1 indicates the bfd back-end
40    should use a suitable default size.  */
41 static bfd_signed_vma group_size = 1;
42
43 /* Whether to add ".foo" entries for each "foo" in a version script.  */
44 static int dotsyms = 1;
45
46 /* Whether to run tls optimization.  */
47 static int notlsopt = 0;
48
49 /* Whether to emit symbols for stubs.  */
50 static int emit_stub_syms = 0;
51
52 static asection *toc_section = 0;
53
54
55 /* This is called before the input files are opened.  We create a new
56    fake input file to hold the stub sections.  */
57
58 static void
59 ppc_create_output_section_statements (void)
60 {
61   extern const bfd_target bfd_elf64_powerpc_vec;
62   extern const bfd_target bfd_elf64_powerpcle_vec;
63
64   if (link_info.hash->creator != &bfd_elf64_powerpc_vec
65       && link_info.hash->creator != &bfd_elf64_powerpcle_vec)
66     return;
67
68   link_info.wrap_char = '.';
69
70   stub_file = lang_add_input_file ("linker stubs",
71                                    lang_input_file_is_fake_enum,
72                                    NULL);
73   stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
74   if (stub_file->the_bfd == NULL
75       || !bfd_set_arch_mach (stub_file->the_bfd,
76                              bfd_get_arch (output_bfd),
77                              bfd_get_mach (output_bfd)))
78     {
79       einfo ("%X%P: can not create BFD %E\n");
80       return;
81     }
82
83   ldlang_add_file (stub_file);
84   ppc64_elf_init_stub_bfd (stub_file->the_bfd, &link_info);
85 }
86
87 static void
88 ppc_after_open (void)
89 {
90   if (!ppc64_elf_mark_entry_syms (&link_info))
91     {
92       einfo ("%X%P: can not mark entry symbols %E\n");
93       return;
94     }
95
96   gld${EMULATION_NAME}_after_open ();
97 }
98
99 static void
100 ppc_before_allocation (void)
101 {
102   if (stub_file != NULL)
103     {
104       if (!ppc64_elf_edit_opd (output_bfd, &link_info))
105         {
106           einfo ("%X%P: can not edit opd %E\n");
107           return;
108         }
109
110       if (ppc64_elf_tls_setup (output_bfd, &link_info) && !notlsopt)
111         {
112           /* Size the sections.  This is premature, but we want to know the
113              TLS segment layout so that certain optimizations can be done.  */
114           lang_size_sections (stat_ptr->head, abs_output_section,
115                               &stat_ptr->head, 0, 0, NULL, TRUE);
116
117           if (!ppc64_elf_tls_optimize (output_bfd, &link_info))
118             {
119               einfo ("%X%P: TLS problem %E\n");
120               return;
121             }
122
123           /* We must not cache anything from the preliminary sizing.  */
124           elf_tdata (output_bfd)->program_header_size = 0;
125           lang_reset_memory_regions ();
126         }
127     }
128
129   gld${EMULATION_NAME}_before_allocation ();
130 }
131
132 struct hook_stub_info
133 {
134   lang_statement_list_type add;
135   asection *input_section;
136 };
137
138 /* Traverse the linker tree to find the spot where the stub goes.  */
139
140 static bfd_boolean
141 hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
142 {
143   lang_statement_union_type *l;
144   bfd_boolean ret;
145
146   for (; (l = *lp) != NULL; lp = &l->header.next)
147     {
148       switch (l->header.type)
149         {
150         case lang_constructors_statement_enum:
151           ret = hook_in_stub (info, &constructor_list.head);
152           if (ret)
153             return ret;
154           break;
155
156         case lang_output_section_statement_enum:
157           ret = hook_in_stub (info,
158                               &l->output_section_statement.children.head);
159           if (ret)
160             return ret;
161           break;
162
163         case lang_wild_statement_enum:
164           ret = hook_in_stub (info, &l->wild_statement.children.head);
165           if (ret)
166             return ret;
167           break;
168
169         case lang_group_statement_enum:
170           ret = hook_in_stub (info, &l->group_statement.children.head);
171           if (ret)
172             return ret;
173           break;
174
175         case lang_input_section_enum:
176           if (l->input_section.section == info->input_section)
177             {
178               /* We've found our section.  Insert the stub immediately
179                  before its associated input section.  */
180               *lp = info->add.head;
181               *(info->add.tail) = l;
182               return TRUE;
183             }
184           break;
185
186         case lang_data_statement_enum:
187         case lang_reloc_statement_enum:
188         case lang_object_symbols_statement_enum:
189         case lang_output_statement_enum:
190         case lang_target_statement_enum:
191         case lang_input_statement_enum:
192         case lang_assignment_statement_enum:
193         case lang_padding_statement_enum:
194         case lang_address_statement_enum:
195         case lang_fill_statement_enum:
196           break;
197
198         default:
199           FAIL ();
200           break;
201         }
202     }
203   return FALSE;
204 }
205
206
207 /* Call-back for ppc64_elf_size_stubs.  */
208
209 /* Create a new stub section, and arrange for it to be linked
210    immediately before INPUT_SECTION.  */
211
212 static asection *
213 ppc_add_stub_section (const char *stub_sec_name, asection *input_section)
214 {
215   asection *stub_sec;
216   flagword flags;
217   asection *output_section;
218   const char *secname;
219   lang_output_section_statement_type *os;
220   struct hook_stub_info info;
221
222   stub_sec = bfd_make_section_anyway (stub_file->the_bfd, stub_sec_name);
223   if (stub_sec == NULL)
224     goto err_ret;
225
226   flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
227            | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
228   if (!bfd_set_section_flags (stub_file->the_bfd, stub_sec, flags))
229     goto err_ret;
230
231   output_section = input_section->output_section;
232   secname = bfd_get_section_name (output_section->owner, output_section);
233   os = lang_output_section_find (secname);
234
235   info.input_section = input_section;
236   lang_list_init (&info.add);
237   lang_add_section (&info.add, stub_sec, os, stub_file);
238
239   if (info.add.head == NULL)
240     goto err_ret;
241
242   stub_added = 1;
243   if (hook_in_stub (&info, &os->children.head))
244     return stub_sec;
245
246  err_ret:
247   einfo ("%X%P: can not make stub section: %E\n");
248   return NULL;
249 }
250
251
252 /* Another call-back for ppc64_elf_size_stubs.  */
253
254 static void
255 ppc_layout_sections_again (void)
256 {
257   /* If we have changed sizes of the stub sections, then we need
258      to recalculate all the section offsets.  This may mean we need to
259      add even more stubs.  */
260   need_laying_out = 0;
261
262   lang_reset_memory_regions ();
263
264   /* Resize the sections.  */
265   lang_size_sections (stat_ptr->head, abs_output_section,
266                       &stat_ptr->head, 0, 0, NULL, TRUE);
267
268   /* Recalculate TOC base.  */
269   ldemul_after_allocation ();
270
271   /* Do the assignments again.  */
272   lang_do_assignments (stat_ptr->head, abs_output_section, NULL, 0);
273 }
274
275
276 /* Call the back-end function to set TOC base after we have placed all
277    the sections.  */
278 static void
279 gld${EMULATION_NAME}_after_allocation (void)
280 {
281   if (!link_info.relocatable)
282     _bfd_set_gp_value (output_bfd, ppc64_elf_toc (output_bfd));
283 }
284
285
286 static void
287 build_toc_list (lang_statement_union_type *statement)
288 {
289   if (statement->header.type == lang_input_section_enum
290       && !statement->input_section.ifile->just_syms_flag
291       && statement->input_section.section->output_section == toc_section)
292     ppc64_elf_next_toc_section (&link_info, statement->input_section.section);
293 }
294
295
296 static void
297 build_section_lists (lang_statement_union_type *statement)
298 {
299   if (statement->header.type == lang_input_section_enum
300       && !statement->input_section.ifile->just_syms_flag
301       && statement->input_section.section->output_section != NULL
302       && statement->input_section.section->output_section->owner == output_bfd)
303     {
304       if (!ppc64_elf_next_input_section (&link_info,
305                                          statement->input_section.section))
306         einfo ("%X%P: can not size stub section: %E\n");
307     }
308 }
309
310
311 /* Final emulation specific call.  */
312
313 static void
314 gld${EMULATION_NAME}_finish (void)
315 {
316   /* e_entry on PowerPC64 points to the function descriptor for
317      _start.  If _start is missing, default to the first function
318      descriptor in the .opd section.  */
319   entry_section = ".opd";
320
321   /* bfd_elf_discard_info just plays with debugging sections,
322      ie. doesn't affect any code, so we can delay resizing the
323      sections.  It's likely we'll resize everything in the process of
324      adding stubs.  */
325   if (bfd_elf_discard_info (output_bfd, &link_info))
326     need_laying_out = 1;
327
328   /* If generating a relocatable output file, then we don't have any
329      stubs.  */
330   if (stub_file != NULL && !link_info.relocatable)
331     {
332       int ret = ppc64_elf_setup_section_lists (output_bfd, &link_info);
333       if (ret != 0)
334         {
335           if (ret < 0)
336             {
337               einfo ("%X%P: can not size stub section: %E\n");
338               return;
339             }
340
341           toc_section = bfd_get_section_by_name (output_bfd, ".got");
342           if (toc_section != NULL)
343             lang_for_each_statement (build_toc_list);
344
345           ppc64_elf_reinit_toc (output_bfd, &link_info);
346
347           lang_for_each_statement (build_section_lists);
348
349           /* Call into the BFD backend to do the real work.  */
350           if (!ppc64_elf_size_stubs (output_bfd,
351                                      &link_info,
352                                      group_size,
353                                      &ppc_add_stub_section,
354                                      &ppc_layout_sections_again))
355             {
356               einfo ("%X%P: can not size stub section: %E\n");
357               return;
358             }
359         }
360     }
361
362   if (need_laying_out)
363     ppc_layout_sections_again ();
364
365   if (stub_added)
366     {
367       char *msg = NULL;
368       char *line, *endline;
369
370       if (!ppc64_elf_build_stubs (emit_stub_syms, &link_info,
371                                   config.stats ? &msg : NULL))
372         einfo ("%X%P: can not build stubs: %E\n");
373
374       for (line = msg; line != NULL; line = endline)
375         {
376           endline = strchr (line, '\n');
377           if (endline != NULL)
378             *endline++ = '\0';
379           fprintf (stderr, "%s: %s\n", program_name, line);
380         }
381       if (msg != NULL)
382         free (msg);
383     }
384 }
385
386
387 /* Add a pattern matching ".foo" for every "foo" in a version script.
388
389    The reason for doing this is that many shared library version
390    scripts export a selected set of functions or data symbols, forcing
391    others local.  eg.
392
393    . VERS_1 {
394    .       global:
395    .               this; that; some; thing;
396    .       local:
397    .               *;
398    .   };
399
400    To make the above work for PowerPC64, we need to export ".this",
401    ".that" and so on, otherwise only the function descriptor syms are
402    exported.  Lack of an exported function code sym may cause a
403    definition to be pulled in from a static library.  */
404
405 static struct bfd_elf_version_expr *
406 gld${EMULATION_NAME}_new_vers_pattern (struct bfd_elf_version_expr *entry)
407 {
408   struct bfd_elf_version_expr *dot_entry;
409   unsigned int len;
410   char *dot_pat;
411
412   if (!dotsyms || entry->pattern[0] == '*' || entry->pattern[0] == '.')
413     return entry;
414
415   dot_entry = xmalloc (sizeof *dot_entry);
416   *dot_entry = *entry;
417   dot_entry->next = entry;
418   len = strlen (entry->pattern) + 2;
419   dot_pat = xmalloc (len);
420   dot_pat[0] = '.';
421   memcpy (dot_pat + 1, entry->pattern, len - 1);
422   dot_entry->pattern = dot_pat;
423   return dot_entry;
424 }
425
426
427 /* Avoid processing the fake stub_file in vercheck, stat_needed and
428    check_needed routines.  */
429
430 static void (*real_func) (lang_input_statement_type *);
431
432 static void ppc_for_each_input_file_wrapper (lang_input_statement_type *l)
433 {
434   if (l != stub_file)
435     (*real_func) (l);
436 }
437
438 static void
439 ppc_lang_for_each_input_file (void (*func) (lang_input_statement_type *))
440 {
441   real_func = func;
442   lang_for_each_input_file (&ppc_for_each_input_file_wrapper);
443 }
444
445 #define lang_for_each_input_file ppc_lang_for_each_input_file
446
447 EOF
448
449 # Define some shell vars to insert bits of code into the standard elf
450 # parse_args and list_options functions.
451 #
452 PARSE_AND_LIST_PROLOGUE='
453 #define OPTION_STUBGROUP_SIZE           301
454 #define OPTION_STUBSYMS                 (OPTION_STUBGROUP_SIZE + 1)
455 #define OPTION_DOTSYMS                  (OPTION_STUBSYMS + 1)
456 #define OPTION_NO_DOTSYMS               (OPTION_DOTSYMS + 1)
457 #define OPTION_NO_TLS_OPT               (OPTION_NO_DOTSYMS + 1)
458 '
459
460 PARSE_AND_LIST_LONGOPTS='
461   { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
462   { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
463   { "dotsyms", no_argument, NULL, OPTION_DOTSYMS },
464   { "no-dotsyms", no_argument, NULL, OPTION_NO_DOTSYMS },
465   { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
466 '
467
468 PARSE_AND_LIST_OPTIONS='
469   fprintf (file, _("\
470   --stub-group-size=N   Maximum size of a group of input sections that can be\n\
471                           handled by one stub section.  A negative value\n\
472                           locates all stubs before their branches (with a\n\
473                           group size of -N), while a positive value allows\n\
474                           two groups of input sections, one before, and one\n\
475                           after each stub section.  Values of +/-1 indicate\n\
476                           the linker should choose suitable defaults.\n"
477                    ));
478   fprintf (file, _("\
479   --emit-stub-syms      Label linker stubs with a symbol.\n"
480                    ));
481   fprintf (file, _("\
482   --dotsyms             For every version pattern \"foo\" in a version script,\n\
483                           add \".foo\" so that function code symbols are\n\
484                           treated the same as function descriptor symbols.\n\
485                           Defaults to on.\n"
486                    ));
487   fprintf (file, _("\
488   --no-dotsyms          Don'\''t do anything special in version scripts.\n"
489                    ));
490   fprintf (file, _("\
491   --no-tls-optimize     Don'\''t try to optimize TLS accesses.\n"
492                    ));
493 '
494
495 PARSE_AND_LIST_ARGS_CASES='
496     case OPTION_STUBGROUP_SIZE:
497       {
498         const char *end;
499         group_size = bfd_scan_vma (optarg, &end, 0);
500         if (*end)
501           einfo (_("%P%F: invalid number `%s'\''\n"), optarg);
502       }
503       break;
504
505     case OPTION_STUBSYMS:
506       emit_stub_syms = 1;
507       break;
508
509     case OPTION_DOTSYMS:
510       dotsyms = 1;
511       break;
512
513     case OPTION_NO_DOTSYMS:
514       dotsyms = 0;
515       break;
516
517     case OPTION_NO_TLS_OPT:
518       notlsopt = 1;
519       break;
520 '
521
522 # Put these extra ppc64elf routines in ld_${EMULATION_NAME}_emulation
523 #
524 LDEMUL_AFTER_OPEN=ppc_after_open
525 LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
526 LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
527 LDEMUL_FINISH=gld${EMULATION_NAME}_finish
528 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements
529 LDEMUL_NEW_VERS_PATTERN=gld${EMULATION_NAME}_new_vers_pattern