ppc64elf.em revision 217395
1255253Ssjg# This shell script emits a C file. -*- C -*-
2255253Ssjg#   Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
3255253Ssjg#
4255253Ssjg# This file is part of GLD, the Gnu Linker.
5255253Ssjg#
6255253Ssjg# This program is free software; you can redistribute it and/or modify
7255253Ssjg# it under the terms of the GNU General Public License as published by
8255253Ssjg# the Free Software Foundation; either version 2 of the License, or
9255253Ssjg# (at your option) any later version.
10255253Ssjg#
11255253Ssjg# This program is distributed in the hope that it will be useful,
12253883Ssjg# but WITHOUT ANY WARRANTY; without even the implied warranty of
13253883Ssjg# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14253883Ssjg# GNU General Public License for more details.
15253883Ssjg#
16253883Ssjg# You should have received a copy of the GNU General Public License
17253883Ssjg# along with this program; if not, write to the Free Software
18253883Ssjg# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19253883Ssjg#
20253883Ssjg
21253883Ssjg# This file is sourced from elf32.em, and defines extra powerpc64-elf
22253883Ssjg# specific routines.
23253883Ssjg#
24253883Ssjgcat >>e${EMULATION_NAME}.c <<EOF
25253883Ssjg
26253883Ssjg#include "ldctor.h"
27250837Ssjg#include "libbfd.h"
28250837Ssjg#include "elf-bfd.h"
29250837Ssjg#include "elf64-ppc.h"
30250837Ssjg
31250837Ssjg/* Fake input file for stubs.  */
32250837Ssjgstatic lang_input_statement_type *stub_file;
33250837Ssjgstatic int stub_added = 0;
34250837Ssjg
35250837Ssjg/* Whether we need to call ppc_layout_sections_again.  */
36250837Ssjgstatic int need_laying_out = 0;
37250837Ssjg
38250837Ssjg/* Maximum size of a group of input sections that can be handled by
39250837Ssjg   one stub section.  A value of +/-1 indicates the bfd back-end
40250837Ssjg   should use a suitable default size.  */
41250837Ssjgstatic bfd_signed_vma group_size = 1;
42250837Ssjg
43250837Ssjg/* Whether to add ".foo" entries for each "foo" in a version script.  */
44250837Ssjgstatic int dotsyms = 1;
45250837Ssjg
46250837Ssjg/* Whether to run tls optimization.  */
47249033Ssjgstatic int notlsopt = 0;
48249033Ssjg
49249033Ssjg/* Whether to emit symbols for stubs.  */
50249033Ssjgstatic int emit_stub_syms = 0;
51249033Ssjg
52249033Ssjgstatic asection *toc_section = 0;
53249033Ssjg
54249033Ssjg
55249033Ssjg/* This is called before the input files are opened.  We create a new
56249033Ssjg   fake input file to hold the stub sections.  */
57249033Ssjg
58249033Ssjgstatic void
59249033Ssjgppc_create_output_section_statements (void)
60249033Ssjg{
61249033Ssjg  extern const bfd_target bfd_elf64_powerpc_vec;
62249033Ssjg  extern const bfd_target bfd_elf64_powerpcle_vec;
63249033Ssjg  asection *sect;
64249033Ssjg
65249033Ssjg  if (link_info.hash->creator != &bfd_elf64_powerpc_vec
66249033Ssjg      && link_info.hash->creator != &bfd_elf64_powerpcle_vec)
67249033Ssjg    return;
68249033Ssjg
69249033Ssjg  link_info.wrap_char = '.';
70249033Ssjg
71249033Ssjg  stub_file = lang_add_input_file ("linker stubs",
72249033Ssjg				   lang_input_file_is_fake_enum,
73249033Ssjg				   NULL);
74249033Ssjg  stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
75249033Ssjg  if (stub_file->the_bfd == NULL
76249033Ssjg      || !bfd_set_arch_mach (stub_file->the_bfd,
77249033Ssjg			     bfd_get_arch (output_bfd),
78249033Ssjg			     bfd_get_mach (output_bfd)))
79249033Ssjg    {
80249033Ssjg      einfo ("%X%P: can not create BFD %E\n");
81249033Ssjg      return;
82249033Ssjg    }
83249033Ssjg
84249033Ssjg  if (bfd_get_section_by_name (stub_file->the_bfd, ".note.GNU-stack") == NULL)
85249033Ssjg    sect = bfd_make_section (stub_file->the_bfd, ".note.GNU-stack");
86249033Ssjg  ldlang_add_file (stub_file);
87249033Ssjg  ppc64_elf_init_stub_bfd (stub_file->the_bfd, &link_info);
88249033Ssjg}
89249033Ssjg
90249033Ssjgstatic void
91249033Ssjgppc_after_open (void)
92249033Ssjg{
93249033Ssjg  if (!ppc64_elf_mark_entry_syms (&link_info))
94249033Ssjg    {
95249033Ssjg      einfo ("%X%P: can not mark entry symbols %E\n");
96249033Ssjg      return;
97249033Ssjg    }
98249033Ssjg
99249033Ssjg  gld${EMULATION_NAME}_after_open ();
100249033Ssjg}
101249033Ssjg
102249033Ssjgstatic void
103249033Ssjgppc_before_allocation (void)
104249033Ssjg{
105249033Ssjg  if (stub_file != NULL)
106249033Ssjg    {
107249033Ssjg      if (!ppc64_elf_edit_opd (output_bfd, &link_info))
108249033Ssjg	{
109249033Ssjg	  einfo ("%X%P: can not edit opd %E\n");
110249033Ssjg	  return;
111249033Ssjg	}
112249033Ssjg
113249033Ssjg      if (ppc64_elf_tls_setup (output_bfd, &link_info) && !notlsopt)
114249033Ssjg	{
115246149Ssjg	  /* Size the sections.  This is premature, but we want to know the
116246149Ssjg	     TLS segment layout so that certain optimizations can be done.  */
117246149Ssjg	  lang_size_sections (stat_ptr->head, abs_output_section,
118246149Ssjg			      &stat_ptr->head, 0, 0, NULL, TRUE);
119246149Ssjg
120246149Ssjg	  if (!ppc64_elf_tls_optimize (output_bfd, &link_info))
121246149Ssjg	    {
122246149Ssjg	      einfo ("%X%P: TLS problem %E\n");
123246149Ssjg	      return;
124246149Ssjg	    }
125246149Ssjg
126246149Ssjg	  /* We must not cache anything from the preliminary sizing.  */
127246149Ssjg	  elf_tdata (output_bfd)->program_header_size = 0;
128246149Ssjg	  lang_reset_memory_regions ();
129246149Ssjg	}
130246149Ssjg    }
131246149Ssjg
132246149Ssjg  gld${EMULATION_NAME}_before_allocation ();
133246149Ssjg}
134246149Ssjg
135246149Ssjgstruct hook_stub_info
136246149Ssjg{
137246149Ssjg  lang_statement_list_type add;
138246149Ssjg  asection *input_section;
139246149Ssjg};
140246149Ssjg
141246149Ssjg/* Traverse the linker tree to find the spot where the stub goes.  */
142246149Ssjg
143246149Ssjgstatic bfd_boolean
144246149Ssjghook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
145246149Ssjg{
146246149Ssjg  lang_statement_union_type *l;
147246149Ssjg  bfd_boolean ret;
148246149Ssjg
149246149Ssjg  for (; (l = *lp) != NULL; lp = &l->header.next)
150246149Ssjg    {
151246149Ssjg      switch (l->header.type)
152246149Ssjg	{
153246149Ssjg	case lang_constructors_statement_enum:
154246149Ssjg	  ret = hook_in_stub (info, &constructor_list.head);
155246149Ssjg	  if (ret)
156246149Ssjg	    return ret;
157246149Ssjg	  break;
158246149Ssjg
159246149Ssjg	case lang_output_section_statement_enum:
160246149Ssjg	  ret = hook_in_stub (info,
161246149Ssjg			      &l->output_section_statement.children.head);
162246149Ssjg	  if (ret)
163246149Ssjg	    return ret;
164246149Ssjg	  break;
165246149Ssjg
166246149Ssjg	case lang_wild_statement_enum:
167246149Ssjg	  ret = hook_in_stub (info, &l->wild_statement.children.head);
168246149Ssjg	  if (ret)
169246149Ssjg	    return ret;
170246149Ssjg	  break;
171246149Ssjg
172246149Ssjg	case lang_group_statement_enum:
173246149Ssjg	  ret = hook_in_stub (info, &l->group_statement.children.head);
174246149Ssjg	  if (ret)
175246149Ssjg	    return ret;
176246149Ssjg	  break;
177246149Ssjg
178246149Ssjg	case lang_input_section_enum:
179246149Ssjg	  if (l->input_section.section == info->input_section)
180246149Ssjg	    {
181246149Ssjg	      /* We've found our section.  Insert the stub immediately
182246149Ssjg		 before its associated input section.  */
183246149Ssjg	      *lp = info->add.head;
184246149Ssjg	      *(info->add.tail) = l;
185246149Ssjg	      return TRUE;
186246149Ssjg	    }
187246149Ssjg	  break;
188246149Ssjg
189246149Ssjg	case lang_data_statement_enum:
190246149Ssjg	case lang_reloc_statement_enum:
191246149Ssjg	case lang_object_symbols_statement_enum:
192246149Ssjg	case lang_output_statement_enum:
193246149Ssjg	case lang_target_statement_enum:
194246149Ssjg	case lang_input_statement_enum:
195246149Ssjg	case lang_assignment_statement_enum:
196246149Ssjg	case lang_padding_statement_enum:
197246149Ssjg	case lang_address_statement_enum:
198246149Ssjg	case lang_fill_statement_enum:
199246149Ssjg	  break;
200246149Ssjg
201246149Ssjg	default:
202246149Ssjg	  FAIL ();
203246149Ssjg	  break;
204246149Ssjg	}
205246149Ssjg    }
206246149Ssjg  return FALSE;
207246149Ssjg}
208246149Ssjg
209246149Ssjg
210246149Ssjg/* Call-back for ppc64_elf_size_stubs.  */
211246149Ssjg
212246149Ssjg/* Create a new stub section, and arrange for it to be linked
213246149Ssjg   immediately before INPUT_SECTION.  */
214246149Ssjg
215246149Ssjgstatic asection *
216246149Ssjgppc_add_stub_section (const char *stub_sec_name, asection *input_section)
217246149Ssjg{
218246149Ssjg  asection *stub_sec;
219246149Ssjg  flagword flags;
220246149Ssjg  asection *output_section;
221246149Ssjg  const char *secname;
222246149Ssjg  lang_output_section_statement_type *os;
223246149Ssjg  struct hook_stub_info info;
224246149Ssjg
225246149Ssjg  stub_sec = bfd_make_section_anyway (stub_file->the_bfd, stub_sec_name);
226246149Ssjg  if (stub_sec == NULL)
227246149Ssjg    goto err_ret;
228246149Ssjg
229246149Ssjg  flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
230246149Ssjg	   | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
231246149Ssjg  if (!bfd_set_section_flags (stub_file->the_bfd, stub_sec, flags))
232246149Ssjg    goto err_ret;
233246149Ssjg
234246149Ssjg  output_section = input_section->output_section;
235246149Ssjg  secname = bfd_get_section_name (output_section->owner, output_section);
236246149Ssjg  os = lang_output_section_find (secname);
237246149Ssjg
238246149Ssjg  info.input_section = input_section;
239246149Ssjg  lang_list_init (&info.add);
240246149Ssjg  lang_add_section (&info.add, stub_sec, os, stub_file);
241246149Ssjg
242246149Ssjg  if (info.add.head == NULL)
243246149Ssjg    goto err_ret;
244246149Ssjg
245246149Ssjg  stub_added = 1;
246246149Ssjg  if (hook_in_stub (&info, &os->children.head))
247246149Ssjg    return stub_sec;
248246149Ssjg
249246149Ssjg err_ret:
250246149Ssjg  einfo ("%X%P: can not make stub section: %E\n");
251246149Ssjg  return NULL;
252246149Ssjg}
253246149Ssjg
254246149Ssjg
255246149Ssjg/* Another call-back for ppc64_elf_size_stubs.  */
256246149Ssjg
257246149Ssjgstatic void
258246149Ssjgppc_layout_sections_again (void)
259246149Ssjg{
260246149Ssjg  /* If we have changed sizes of the stub sections, then we need
261246149Ssjg     to recalculate all the section offsets.  This may mean we need to
262246149Ssjg     add even more stubs.  */
263246149Ssjg  need_laying_out = 0;
264246149Ssjg
265246149Ssjg  lang_reset_memory_regions ();
266246149Ssjg
267246149Ssjg  /* Resize the sections.  */
268246149Ssjg  lang_size_sections (stat_ptr->head, abs_output_section,
269246149Ssjg		      &stat_ptr->head, 0, 0, NULL, TRUE);
270246149Ssjg
271246149Ssjg  /* Recalculate TOC base.  */
272246149Ssjg  ldemul_after_allocation ();
273246149Ssjg
274246149Ssjg  /* Do the assignments again.  */
275246149Ssjg  lang_do_assignments (stat_ptr->head, abs_output_section, NULL, 0);
276246149Ssjg}
277246149Ssjg
278246149Ssjg
279246149Ssjg/* Call the back-end function to set TOC base after we have placed all
280246149Ssjg   the sections.  */
281246149Ssjgstatic void
282246149Ssjggld${EMULATION_NAME}_after_allocation (void)
283246149Ssjg{
284246149Ssjg  if (!link_info.relocatable)
285246149Ssjg    _bfd_set_gp_value (output_bfd, ppc64_elf_toc (output_bfd));
286246149Ssjg}
287246149Ssjg
288246149Ssjg
289246149Ssjgstatic void
290246149Ssjgbuild_toc_list (lang_statement_union_type *statement)
291246149Ssjg{
292246149Ssjg  if (statement->header.type == lang_input_section_enum
293246149Ssjg      && !statement->input_section.ifile->just_syms_flag
294246149Ssjg      && statement->input_section.section->output_section == toc_section)
295246149Ssjg    ppc64_elf_next_toc_section (&link_info, statement->input_section.section);
296246149Ssjg}
297246149Ssjg
298246149Ssjg
299246149Ssjgstatic void
300246149Ssjgbuild_section_lists (lang_statement_union_type *statement)
301246149Ssjg{
302246149Ssjg  if (statement->header.type == lang_input_section_enum
303246149Ssjg      && !statement->input_section.ifile->just_syms_flag
304246149Ssjg      && statement->input_section.section->output_section != NULL
305246149Ssjg      && statement->input_section.section->output_section->owner == output_bfd)
306246149Ssjg    {
307246149Ssjg      if (!ppc64_elf_next_input_section (&link_info,
308246149Ssjg					 statement->input_section.section))
309246149Ssjg	einfo ("%X%P: can not size stub section: %E\n");
310246149Ssjg    }
311246149Ssjg}
312246149Ssjg
313246149Ssjg
314246149Ssjg/* Final emulation specific call.  */
315246149Ssjg
316246149Ssjgstatic void
317246149Ssjggld${EMULATION_NAME}_finish (void)
318246149Ssjg{
319246149Ssjg  /* e_entry on PowerPC64 points to the function descriptor for
320246149Ssjg     _start.  If _start is missing, default to the first function
321246149Ssjg     descriptor in the .opd section.  */
322246149Ssjg  entry_section = ".opd";
323246149Ssjg
324246149Ssjg  /* bfd_elf_discard_info just plays with debugging sections,
325246149Ssjg     ie. doesn't affect any code, so we can delay resizing the
326246149Ssjg     sections.  It's likely we'll resize everything in the process of
327246149Ssjg     adding stubs.  */
328246149Ssjg  if (bfd_elf_discard_info (output_bfd, &link_info))
329246149Ssjg    need_laying_out = 1;
330246149Ssjg
331246149Ssjg  /* If generating a relocatable output file, then we don't have any
332246149Ssjg     stubs.  */
333246149Ssjg  if (stub_file != NULL && !link_info.relocatable)
334246149Ssjg    {
335246149Ssjg      int ret = ppc64_elf_setup_section_lists (output_bfd, &link_info);
336246149Ssjg      if (ret != 0)
337246149Ssjg	{
338246149Ssjg	  if (ret < 0)
339246149Ssjg	    {
340246149Ssjg	      einfo ("%X%P: can not size stub section: %E\n");
341246149Ssjg	      return;
342246149Ssjg	    }
343246149Ssjg
344246149Ssjg	  toc_section = bfd_get_section_by_name (output_bfd, ".got");
345246149Ssjg	  if (toc_section != NULL)
346246149Ssjg	    lang_for_each_statement (build_toc_list);
347246149Ssjg
348246149Ssjg	  ppc64_elf_reinit_toc (output_bfd, &link_info);
349246149Ssjg
350246149Ssjg	  lang_for_each_statement (build_section_lists);
351246149Ssjg
352246149Ssjg	  /* Call into the BFD backend to do the real work.  */
353246149Ssjg	  if (!ppc64_elf_size_stubs (output_bfd,
354246149Ssjg				     &link_info,
355246149Ssjg				     group_size,
356246149Ssjg				     &ppc_add_stub_section,
357246149Ssjg				     &ppc_layout_sections_again))
358246149Ssjg	    {
359246149Ssjg	      einfo ("%X%P: can not size stub section: %E\n");
360246149Ssjg	      return;
361246149Ssjg	    }
362246149Ssjg	}
363246149Ssjg    }
364246149Ssjg
365246149Ssjg  if (need_laying_out)
366246149Ssjg    ppc_layout_sections_again ();
367246149Ssjg
368246149Ssjg  if (stub_added)
369246149Ssjg    {
370246149Ssjg      char *msg = NULL;
371246149Ssjg      char *line, *endline;
372246149Ssjg
373246149Ssjg      if (!ppc64_elf_build_stubs (emit_stub_syms, &link_info,
374246149Ssjg				  config.stats ? &msg : NULL))
375246149Ssjg	einfo ("%X%P: can not build stubs: %E\n");
376246149Ssjg
377246149Ssjg      for (line = msg; line != NULL; line = endline)
378246149Ssjg	{
379246149Ssjg	  endline = strchr (line, '\n');
380246149Ssjg	  if (endline != NULL)
381246149Ssjg	    *endline++ = '\0';
382246149Ssjg	  fprintf (stderr, "%s: %s\n", program_name, line);
383246149Ssjg	}
384246149Ssjg      if (msg != NULL)
385246149Ssjg	free (msg);
386246149Ssjg    }
387246149Ssjg}
388246149Ssjg
389246149Ssjg
390246149Ssjg/* Add a pattern matching ".foo" for every "foo" in a version script.
391246149Ssjg
392246149Ssjg   The reason for doing this is that many shared library version
393246149Ssjg   scripts export a selected set of functions or data symbols, forcing
394246149Ssjg   others local.  eg.
395246149Ssjg
396246149Ssjg   . VERS_1 {
397246149Ssjg   .       global:
398246149Ssjg   .               this; that; some; thing;
399246149Ssjg   .       local:
400246149Ssjg   .               *;
401246149Ssjg   .   };
402246149Ssjg
403246149Ssjg   To make the above work for PowerPC64, we need to export ".this",
404246149Ssjg   ".that" and so on, otherwise only the function descriptor syms are
405246149Ssjg   exported.  Lack of an exported function code sym may cause a
406246149Ssjg   definition to be pulled in from a static library.  */
407246149Ssjg
408246149Ssjgstatic struct bfd_elf_version_expr *
409246149Ssjggld${EMULATION_NAME}_new_vers_pattern (struct bfd_elf_version_expr *entry)
410246149Ssjg{
411246149Ssjg  struct bfd_elf_version_expr *dot_entry;
412246149Ssjg  unsigned int len;
413246149Ssjg  char *dot_pat;
414246149Ssjg
415246149Ssjg  if (!dotsyms || entry->pattern[0] == '*' || entry->pattern[0] == '.')
416246149Ssjg    return entry;
417246149Ssjg
418246149Ssjg  dot_entry = xmalloc (sizeof *dot_entry);
419246149Ssjg  *dot_entry = *entry;
420246149Ssjg  dot_entry->next = entry;
421246149Ssjg  len = strlen (entry->pattern) + 2;
422246149Ssjg  dot_pat = xmalloc (len);
423246149Ssjg  dot_pat[0] = '.';
424246149Ssjg  memcpy (dot_pat + 1, entry->pattern, len - 1);
425246149Ssjg  dot_entry->pattern = dot_pat;
426246149Ssjg  return dot_entry;
427246149Ssjg}
428246149Ssjg
429246149Ssjg
430246149Ssjg/* Avoid processing the fake stub_file in vercheck, stat_needed and
431246149Ssjg   check_needed routines.  */
432246149Ssjg
433246149Ssjgstatic void (*real_func) (lang_input_statement_type *);
434246149Ssjg
435246149Ssjgstatic void ppc_for_each_input_file_wrapper (lang_input_statement_type *l)
436246149Ssjg{
437246149Ssjg  if (l != stub_file)
438246149Ssjg    (*real_func) (l);
439246149Ssjg}
440246149Ssjg
441246149Ssjgstatic void
442246149Ssjgppc_lang_for_each_input_file (void (*func) (lang_input_statement_type *))
443246149Ssjg{
444246149Ssjg  real_func = func;
445246149Ssjg  lang_for_each_input_file (&ppc_for_each_input_file_wrapper);
446246149Ssjg}
447246149Ssjg
448246149Ssjg#define lang_for_each_input_file ppc_lang_for_each_input_file
449246149Ssjg
450246149SsjgEOF
451246149Ssjg
452246149Ssjg# Define some shell vars to insert bits of code into the standard elf
453246149Ssjg# parse_args and list_options functions.
454246149Ssjg#
455246149SsjgPARSE_AND_LIST_PROLOGUE='
456246149Ssjg#define OPTION_STUBGROUP_SIZE		301
457246149Ssjg#define OPTION_STUBSYMS			(OPTION_STUBGROUP_SIZE + 1)
458246149Ssjg#define OPTION_DOTSYMS			(OPTION_STUBSYMS + 1)
459246149Ssjg#define OPTION_NO_DOTSYMS		(OPTION_DOTSYMS + 1)
460246149Ssjg#define OPTION_NO_TLS_OPT		(OPTION_NO_DOTSYMS + 1)
461246149Ssjg'
462246149Ssjg
463246149SsjgPARSE_AND_LIST_LONGOPTS='
464246149Ssjg  { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
465246149Ssjg  { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
466246149Ssjg  { "dotsyms", no_argument, NULL, OPTION_DOTSYMS },
467246149Ssjg  { "no-dotsyms", no_argument, NULL, OPTION_NO_DOTSYMS },
468246149Ssjg  { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
469246149Ssjg'
470246149Ssjg
471246149SsjgPARSE_AND_LIST_OPTIONS='
472246149Ssjg  fprintf (file, _("\
473246149Ssjg  --stub-group-size=N   Maximum size of a group of input sections that can be\n\
474246149Ssjg                          handled by one stub section.  A negative value\n\
475246149Ssjg                          locates all stubs before their branches (with a\n\
476246149Ssjg                          group size of -N), while a positive value allows\n\
477246149Ssjg                          two groups of input sections, one before, and one\n\
478246149Ssjg                          after each stub section.  Values of +/-1 indicate\n\
479246149Ssjg                          the linker should choose suitable defaults.\n"
480246149Ssjg		   ));
481246149Ssjg  fprintf (file, _("\
482246149Ssjg  --emit-stub-syms      Label linker stubs with a symbol.\n"
483246149Ssjg		   ));
484246149Ssjg  fprintf (file, _("\
485246149Ssjg  --dotsyms             For every version pattern \"foo\" in a version script,\n\
486246149Ssjg                          add \".foo\" so that function code symbols are\n\
487246149Ssjg                          treated the same as function descriptor symbols.\n\
488246149Ssjg                          Defaults to on.\n"
489246149Ssjg		   ));
490246149Ssjg  fprintf (file, _("\
491246149Ssjg  --no-dotsyms          Don'\''t do anything special in version scripts.\n"
492246149Ssjg		   ));
493246149Ssjg  fprintf (file, _("\
494246149Ssjg  --no-tls-optimize     Don'\''t try to optimize TLS accesses.\n"
495246149Ssjg		   ));
496246149Ssjg'
497246149Ssjg
498246149SsjgPARSE_AND_LIST_ARGS_CASES='
499246149Ssjg    case OPTION_STUBGROUP_SIZE:
500246149Ssjg      {
501246149Ssjg	const char *end;
502246149Ssjg        group_size = bfd_scan_vma (optarg, &end, 0);
503246149Ssjg        if (*end)
504246149Ssjg	  einfo (_("%P%F: invalid number `%s'\''\n"), optarg);
505246149Ssjg      }
506246149Ssjg      break;
507246149Ssjg
508246149Ssjg    case OPTION_STUBSYMS:
509246149Ssjg      emit_stub_syms = 1;
510246149Ssjg      break;
511246149Ssjg
512246149Ssjg    case OPTION_DOTSYMS:
513246149Ssjg      dotsyms = 1;
514246149Ssjg      break;
515246149Ssjg
516246149Ssjg    case OPTION_NO_DOTSYMS:
517246149Ssjg      dotsyms = 0;
518246149Ssjg      break;
519246149Ssjg
520246149Ssjg    case OPTION_NO_TLS_OPT:
521246149Ssjg      notlsopt = 1;
522246149Ssjg      break;
523246149Ssjg'
524246149Ssjg
525246149Ssjg# Put these extra ppc64elf routines in ld_${EMULATION_NAME}_emulation
526246149Ssjg#
527246149SsjgLDEMUL_AFTER_OPEN=ppc_after_open
528246149SsjgLDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
529246149SsjgLDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
530246149SsjgLDEMUL_FINISH=gld${EMULATION_NAME}_finish
531246149SsjgLDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements
532246149SsjgLDEMUL_NEW_VERS_PATTERN=gld${EMULATION_NAME}_new_vers_pattern
533246149Ssjg