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#
24cat >>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.  */
32static lang_input_statement_type *stub_file;
33static int stub_added = 0;
34
35/* Whether we need to call ppc_layout_sections_again.  */
36static 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.  */
41static bfd_signed_vma group_size = 1;
42
43/* Whether to add ".foo" entries for each "foo" in a version script.  */
44static int dotsyms = 1;
45
46/* Whether to run tls optimization.  */
47static int notlsopt = 0;
48
49/* Whether to emit symbols for stubs.  */
50static int emit_stub_syms = 0;
51
52static 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
58static void
59ppc_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
87static void
88ppc_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
99static void
100ppc_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
132struct 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
140static bfd_boolean
141hook_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
212static asection *
213ppc_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
254static void
255ppc_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.  */
278static void
279gld${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
286static void
287build_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
296static void
297build_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
313static void
314gld${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
405static struct bfd_elf_version_expr *
406gld${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
430static void (*real_func) (lang_input_statement_type *);
431
432static void ppc_for_each_input_file_wrapper (lang_input_statement_type *l)
433{
434  if (l != stub_file)
435    (*real_func) (l);
436}
437
438static void
439ppc_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
447EOF
448
449# Define some shell vars to insert bits of code into the standard elf
450# parse_args and list_options functions.
451#
452PARSE_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
460PARSE_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
468PARSE_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
495PARSE_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#
524LDEMUL_AFTER_OPEN=ppc_after_open
525LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
526LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
527LDEMUL_FINISH=gld${EMULATION_NAME}_finish
528LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements
529LDEMUL_NEW_VERS_PATTERN=gld${EMULATION_NAME}_new_vers_pattern
530