1# This shell script emits a C file. -*- C -*-
2# Copyright (C) 2002-2022 Free Software Foundation, Inc.
3#
4# This file is part of the GNU Binutils.
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 3 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., 51 Franklin Street - Fifth Floor, Boston,
19# MA 02110-1301, USA.
20#
21
22# This file is sourced from elf.em, and defines extra powerpc64-elf
23# specific routines.
24#
25fragment <<EOF
26
27#include "ldctor.h"
28#include "elf-bfd.h"
29#include "elf64-ppc.h"
30#include "ldlex.h"
31#include "elf/ppc64.h"
32
33static asection *ppc_add_stub_section (const char *, asection *);
34static void ppc_layout_sections_again (void);
35static void ppc_edit (void);
36
37static struct ppc64_elf_params params = { NULL,
38					  &ppc_add_stub_section,
39					  &ppc_layout_sections_again,
40					  &ppc_edit,
41					  1, -1, -1, 0,
42					  ${DEFAULT_PLT_STATIC_CHAIN-0}, -1, 5,
43					  -1, -1, 0, 0, -1, -1, 0};
44
45/* Fake input file for stubs.  */
46static lang_input_statement_type *stub_file;
47
48/* Whether we need to call ppc_layout_sections_again.  */
49static int need_laying_out = 0;
50
51/* Whether to add ".foo" entries for each "foo" in a version script.  */
52static int dotsyms = 1;
53
54/* Whether to run tls optimization.  */
55static int no_tls_opt = 0;
56
57/* Whether to run opd optimization.  */
58static int no_opd_opt = 0;
59
60/* Whether to convert inline PLT calls to direct.  */
61static int no_inline_opt = 0;
62
63/* Whether to run toc optimization.  */
64static int no_toc_opt = 0;
65
66/* Whether to sort input toc and got sections.  */
67static int no_toc_sort = 0;
68
69/* Input .toc sections will be placed in this output section.  */
70static const char *toc_section_name = ".got";
71static asection *toc_section = 0;
72
73/* This is called before the input files are opened.  We create a new
74   fake input file to hold the stub sections.  */
75
76static void
77ppc_create_output_section_statements (void)
78{
79  if (!(bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
80	&& elf_object_id (link_info.output_bfd) == PPC64_ELF_DATA))
81    return;
82
83  link_info.wrap_char = '.';
84
85  stub_file = lang_add_input_file ("linker stubs",
86				   lang_input_file_is_fake_enum,
87				   NULL);
88  stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd);
89  if (stub_file->the_bfd == NULL
90      || !bfd_set_arch_mach (stub_file->the_bfd,
91			     bfd_get_arch (link_info.output_bfd),
92			     bfd_get_mach (link_info.output_bfd)))
93    {
94      einfo (_("%F%P: can not create BFD: %E\n"));
95      return;
96    }
97
98  stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
99  ldlang_add_file (stub_file);
100  params.stub_bfd = stub_file->the_bfd;
101  if (params.save_restore_funcs < 0)
102    params.save_restore_funcs = !bfd_link_relocatable (&link_info);
103  if (!ppc64_elf_init_stub_bfd (&link_info, &params))
104    einfo (_("%F%P: can not init BFD: %E\n"));
105}
106
107/* Called after opening files but before mapping sections.  */
108
109static void
110ppc_after_open (void)
111{
112  if (stub_file != NULL && link_info.relro && params.object_in_toc)
113    {
114      /* We have a .toc section that might be written to at run time.
115	 Don't put .toc into the .got output section.  */
116      lang_output_section_statement_type *got;
117
118      got = lang_output_section_find (".got");
119      if (got != NULL)
120	{
121	  lang_statement_union_type *s;
122	  for (s = got->children.head; s != NULL; s = s->header.next)
123	    if (s->header.type == lang_wild_statement_enum
124		&& s->wild_statement.filename == NULL)
125	      {
126		struct wildcard_list **i = &s->wild_statement.section_list;
127		while (*i != NULL)
128		  if (strcmp ((*i)->spec.name, ".toc") == 0)
129		    *i = (*i)->next;
130		  else
131		    i = &(*i)->next;
132	      }
133	  /* Instead, .toc input sections will be mapped to the
134	     read/write .toc output section.  If user scripts don't
135	     provide one then we'll lose toc sorting and multi-toc.  */
136	  toc_section_name = ".toc";
137	}
138    }
139  gld${EMULATION_NAME}_after_open ();
140}
141
142/* Move the input section statement at *U which happens to be on LIST
143   to be just before *TO.  */
144
145static void
146move_input_section (lang_statement_list_type *list,
147		    lang_statement_union_type **u,
148		    lang_statement_union_type **to)
149{
150  lang_statement_union_type *s = *u;
151  asection *i = s->input_section.section;
152  asection *p, *n;
153
154  /* Snip the input section from the statement list.  If it was the
155     last statement, fix the list tail pointer.  */
156  *u = s->header.next;
157  if (*u == NULL)
158    list->tail = u;
159  /* Add it back in the new position.  */
160  s->header.next = *to;
161  *to = s;
162  if (list->tail == to)
163    list->tail = &s->header.next;
164
165  /* Trim I off the bfd map_head/map_tail doubly linked lists.  */
166  n = i->map_head.s;
167  p = i->map_tail.s;
168  (p != NULL ? p : i->output_section)->map_head.s = n;
169  (n != NULL ? n : i->output_section)->map_tail.s = p;
170
171  /* Add I back on in its new position.  */
172  if (s->header.next->header.type == lang_input_section_enum)
173    {
174      n = s->header.next->input_section.section;
175      p = n->map_tail.s;
176    }
177  else
178    {
179      /* If the next statement is not an input section statement then
180	 TO must point at the previous input section statement
181	 header.next field.  */
182      lang_input_section_type *prev = (lang_input_section_type *)
183	((char *) to - offsetof (lang_statement_union_type, header.next));
184
185      ASSERT (prev->header.type == lang_input_section_enum);
186      p = prev->section;
187      n = p->map_head.s;
188    }
189  i->map_head.s = n;
190  i->map_tail.s = p;
191  (p != NULL ? p : i->output_section)->map_head.s = i;
192  (n != NULL ? n : i->output_section)->map_tail.s = i;
193}
194
195/* Sort input section statements in the linker script tree rooted at
196   LIST so that those whose owning bfd happens to have a section
197   called .init or .fini are placed first.  Place any TOC sections
198   referenced by small TOC relocs next, with TOC sections referenced
199   only by bigtoc relocs last.  */
200
201static void
202sort_toc_sections (lang_statement_list_type *list,
203		   lang_statement_union_type **ini,
204		   lang_statement_union_type **small)
205{
206  lang_statement_union_type *s, **u;
207  asection *i;
208
209  u = &list->head;
210  while ((s = *u) != NULL)
211    {
212      switch (s->header.type)
213	{
214	case lang_wild_statement_enum:
215	  sort_toc_sections (&s->wild_statement.children, ini, small);
216	  break;
217
218	case lang_group_statement_enum:
219	  sort_toc_sections (&s->group_statement.children, ini, small);
220	  break;
221
222	case lang_input_section_enum:
223	  i = s->input_section.section;
224	  /* Leave the stub_file .got where it is.  We put the .got
225	     header there.  */
226	  if (i->owner == stub_file->the_bfd)
227	    break;
228	  if (bfd_get_section_by_name (i->owner, ".init") != NULL
229	      || bfd_get_section_by_name (i->owner, ".fini") != NULL)
230	    {
231	      if (ini != NULL && *ini != s)
232		{
233		  move_input_section (list, u, ini);
234		  if (small == ini)
235		    small = &s->header.next;
236		  ini = &s->header.next;
237		  continue;
238		}
239	      if (small == ini)
240		small = &s->header.next;
241	      ini = &s->header.next;
242	      break;
243	    }
244	  else if (ini == NULL)
245	    ini = u;
246
247	  if (ppc64_elf_has_small_toc_reloc (i))
248	    {
249	      if (small != NULL && *small != s)
250		{
251		  move_input_section (list, u, small);
252		  small = &s->header.next;
253		  continue;
254		}
255	      small = &s->header.next;
256	    }
257	  else if (small == NULL)
258	    small = u;
259	  break;
260
261	default:
262	  break;
263	}
264      u = &s->header.next;
265    }
266}
267
268static void
269prelim_size_sections (void)
270{
271  if (expld.phase != lang_mark_phase_enum)
272    {
273      expld.phase = lang_mark_phase_enum;
274      expld.dataseg.phase = exp_seg_none;
275      one_lang_size_sections_pass (NULL, false);
276      /* We must not cache anything from the preliminary sizing.  */
277      lang_reset_memory_regions ();
278    }
279}
280
281static void
282ppc_before_allocation (void)
283{
284  if (stub_file != NULL)
285    {
286      if (!no_opd_opt
287	  && !ppc64_elf_edit_opd (&link_info))
288	einfo (_("%X%P: can not edit %s: %E\n"), "opd");
289
290      if (!no_inline_opt
291	  && !bfd_link_relocatable (&link_info))
292	{
293	  prelim_size_sections ();
294
295	  if (!ppc64_elf_inline_plt (&link_info))
296	    einfo (_("%X%P: inline PLT: %E\n"));
297	}
298
299      if (!ppc64_elf_tls_setup (&link_info))
300	einfo (_("%X%P: TLS problem %E\n"));
301    }
302
303  gld${EMULATION_NAME}_before_allocation ();
304}
305
306static void
307ppc_edit (void)
308{
309  if (stub_file != NULL)
310    {
311      if (elf_hash_table (&link_info)->tls_sec != NULL
312	  && !no_tls_opt)
313	{
314	  /* Size the sections.  This is premature, but we want to know the
315	     TLS segment layout so that certain optimizations can be done.  */
316	  prelim_size_sections ();
317
318	  if (!ppc64_elf_tls_optimize (&link_info))
319	    einfo (_("%X%P: TLS problem %E\n"));
320	}
321
322      if (!no_toc_opt
323	  && !bfd_link_relocatable (&link_info))
324	{
325	  prelim_size_sections ();
326
327	  if (!ppc64_elf_edit_toc (&link_info))
328	    einfo (_("%X%P: can not edit %s: %E\n"), "toc");
329	}
330
331      if (!no_toc_sort)
332	{
333	  lang_output_section_statement_type *toc_os;
334
335	  toc_os = lang_output_section_find (toc_section_name);
336	  if (toc_os != NULL)
337	    sort_toc_sections (&toc_os->children, NULL, NULL);
338	}
339    }
340}
341
342struct hook_stub_info
343{
344  lang_statement_list_type add;
345  asection *input_section;
346};
347
348/* Traverse the linker tree to find the spot where the stub goes.  */
349
350static bool
351hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
352{
353  lang_statement_union_type *l;
354  bool ret;
355
356  for (; (l = *lp) != NULL; lp = &l->header.next)
357    {
358      switch (l->header.type)
359	{
360	case lang_constructors_statement_enum:
361	  ret = hook_in_stub (info, &constructor_list.head);
362	  if (ret)
363	    return ret;
364	  break;
365
366	case lang_output_section_statement_enum:
367	  ret = hook_in_stub (info,
368			      &l->output_section_statement.children.head);
369	  if (ret)
370	    return ret;
371	  break;
372
373	case lang_wild_statement_enum:
374	  ret = hook_in_stub (info, &l->wild_statement.children.head);
375	  if (ret)
376	    return ret;
377	  break;
378
379	case lang_group_statement_enum:
380	  ret = hook_in_stub (info, &l->group_statement.children.head);
381	  if (ret)
382	    return ret;
383	  break;
384
385	case lang_input_section_enum:
386	  if (l->input_section.section == info->input_section)
387	    {
388	      /* We've found our section.  Insert the stub immediately
389		 before its associated input section.  */
390	      *lp = info->add.head;
391	      *(info->add.tail) = l;
392	      return true;
393	    }
394	  break;
395
396	case lang_data_statement_enum:
397	case lang_reloc_statement_enum:
398	case lang_object_symbols_statement_enum:
399	case lang_output_statement_enum:
400	case lang_target_statement_enum:
401	case lang_input_statement_enum:
402	case lang_assignment_statement_enum:
403	case lang_padding_statement_enum:
404	case lang_address_statement_enum:
405	case lang_fill_statement_enum:
406	  break;
407
408	default:
409	  FAIL ();
410	  break;
411	}
412    }
413  return false;
414}
415
416
417/* Call-back for ppc64_elf_size_stubs.  */
418
419/* Create a new stub section, and arrange for it to be linked
420   immediately before INPUT_SECTION.  */
421
422static asection *
423ppc_add_stub_section (const char *stub_sec_name, asection *input_section)
424{
425  asection *stub_sec;
426  flagword flags;
427  asection *output_section;
428  lang_output_section_statement_type *os;
429  struct hook_stub_info info;
430
431  flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
432	   | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_KEEP);
433  stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd,
434						 stub_sec_name, flags);
435  if (stub_sec == NULL
436      || !bfd_set_section_alignment (stub_sec, (params.plt_stub_align > 5
437						? params.plt_stub_align
438						: params.plt_stub_align < -5
439						? -params.plt_stub_align
440						: 5)))
441    goto err_ret;
442
443  output_section = input_section->output_section;
444  os = lang_output_section_get (output_section);
445
446  info.input_section = input_section;
447  lang_list_init (&info.add);
448  lang_add_section (&info.add, stub_sec, NULL, NULL, os);
449
450  if (info.add.head == NULL)
451    goto err_ret;
452
453  if (hook_in_stub (&info, &os->children.head))
454    return stub_sec;
455
456 err_ret:
457  einfo (_("%X%P: can not make stub section: %E\n"));
458  return NULL;
459}
460
461
462/* Another call-back for ppc64_elf_size_stubs.  */
463
464static void
465ppc_layout_sections_again (void)
466{
467  /* If we have changed sizes of the stub sections, then we need
468     to recalculate all the section offsets.  This may mean we need to
469     add even more stubs.  */
470  ldelf_map_segments (true);
471
472  if (!bfd_link_relocatable (&link_info))
473    ppc64_elf_set_toc (&link_info, link_info.output_bfd);
474
475  need_laying_out = -1;
476}
477
478
479static void
480build_toc_list (lang_statement_union_type *statement)
481{
482  if (statement->header.type == lang_input_section_enum)
483    {
484      asection *i = statement->input_section.section;
485
486      if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
487	  && (i->flags & SEC_EXCLUDE) == 0
488	  && i->output_section == toc_section)
489	{
490	  if (!ppc64_elf_next_toc_section (&link_info, i))
491	    einfo (_("%X%P: linker script separates .got and .toc\n"));
492	}
493    }
494}
495
496
497static void
498build_section_lists (lang_statement_union_type *statement)
499{
500  if (statement->header.type == lang_input_section_enum)
501    {
502      asection *i = statement->input_section.section;
503
504      if (!bfd_input_just_syms (i->owner)
505	  && (i->flags & SEC_EXCLUDE) == 0
506	  && i->output_section != NULL
507	  && i->output_section->owner == link_info.output_bfd)
508	{
509	  if (!ppc64_elf_next_input_section (&link_info, i))
510	    einfo (_("%X%P: can not size stub section: %E\n"));
511	}
512    }
513}
514
515
516/* Call the back-end function to set TOC base after we have placed all
517   the sections.  */
518static void
519gld${EMULATION_NAME}_after_allocation (void)
520{
521  int ret;
522
523  /* If generating a relocatable output file, then we don't have any
524     stubs.  */
525  if (stub_file != NULL && !bfd_link_relocatable (&link_info))
526    {
527      ret = ppc64_elf_setup_section_lists (&link_info);
528      if (ret < 0)
529	einfo (_("%X%P: can not size stub section: %E\n"));
530      else
531	{
532	  ppc64_elf_start_multitoc_partition (&link_info);
533
534	  if (!params.no_multi_toc)
535	    {
536	      toc_section = bfd_get_section_by_name (link_info.output_bfd,
537						     toc_section_name);
538	      if (toc_section != NULL)
539		lang_for_each_statement (build_toc_list);
540	    }
541
542	  if (ppc64_elf_layout_multitoc (&link_info)
543	      && !params.no_multi_toc
544	      && toc_section != NULL)
545	    lang_for_each_statement (build_toc_list);
546
547	  ppc64_elf_finish_multitoc_partition (&link_info);
548
549	  lang_for_each_statement (build_section_lists);
550
551	  if (!ppc64_elf_check_init_fini (&link_info))
552	    einfo (_("%P: .init/.fini fragments use differing TOC pointers\n"));
553
554	  /* Call into the BFD backend to do the real work.  */
555	  if (!ppc64_elf_size_stubs (&link_info))
556	    einfo (_("%X%P: can not size stub section: %E\n"));
557	}
558    }
559
560  /* We can't parse and merge .eh_frame until the glink .eh_frame has
561     been generated.  Otherwise the glink .eh_frame CIE won't be
562     merged with other CIEs, and worse, the glink .eh_frame FDEs won't
563     be listed in .eh_frame_hdr.  */
564  ret = bfd_elf_discard_info (link_info.output_bfd, &link_info);
565  if (ret < 0)
566    {
567      einfo (_("%X%P: .eh_frame/.stab edit: %E\n"));
568      return;
569    }
570  else if (ret > 0)
571    need_laying_out = 1;
572
573  /* Call map_segments regardless of the state of need_laying_out.
574     need_laying_out set to -1 means we have just laid everything out,
575     but ppc64_elf_size_stubs strips .branch_lt and .eh_frame if
576     unneeded, after ppc_layout_sections_again.  Another call removes
577     these sections from the segment map.  Their presence is
578     innocuous except for confusing ELF_SECTION_IN_SEGMENT.  */
579  ldelf_map_segments (need_laying_out > 0);
580
581  if (need_laying_out != -1 && !bfd_link_relocatable (&link_info))
582    ppc64_elf_set_toc (&link_info, link_info.output_bfd);
583}
584
585
586/* Final emulation specific call.  */
587
588static void
589gld${EMULATION_NAME}_finish (void)
590{
591  char *msg = NULL;
592  char *line, *endline;
593
594  /* e_entry on PowerPC64 points to the function descriptor for
595     _start.  If _start is missing, default to the first function
596     descriptor in the .opd section.  */
597  if (stub_file != NULL
598      && (elf_elfheader (link_info.output_bfd)->e_flags & EF_PPC64_ABI) == 1)
599    entry_section = ".opd";
600
601  if (params.emit_stub_syms < 0)
602    params.emit_stub_syms = 1;
603  if (stub_file != NULL
604      && !bfd_link_relocatable (&link_info)
605      && !ppc64_elf_build_stubs (&link_info, config.stats ? &msg : NULL))
606    einfo (_("%X%P: can not build stubs: %E\n"));
607
608  fflush (stdout);
609  for (line = msg; line != NULL; line = endline)
610    {
611      endline = strchr (line, '\n');
612      if (endline != NULL)
613	*endline++ = '\0';
614      fprintf (stderr, "%s: %s\n", program_name, line);
615    }
616  fflush (stderr);
617  free (msg);
618
619  finish_default ();
620}
621
622
623/* Add a pattern matching ".foo" for every "foo" in a version script.
624
625   The reason for doing this is that many shared library version
626   scripts export a selected set of functions or data symbols, forcing
627   others local.  eg.
628
629   . VERS_1 {
630   .       global:
631   .               this; that; some; thing;
632   .       local:
633   .               *;
634   .   };
635
636   To make the above work for PowerPC64, we need to export ".this",
637   ".that" and so on, otherwise only the function descriptor syms are
638   exported.  Lack of an exported function code sym may cause a
639   definition to be pulled in from a static library.  */
640
641static struct bfd_elf_version_expr *
642gld${EMULATION_NAME}_new_vers_pattern (struct bfd_elf_version_expr *entry)
643{
644  struct bfd_elf_version_expr *dot_entry;
645  unsigned int len;
646  char *dot_pat;
647
648  if (!dotsyms
649      || entry->pattern[0] == '.'
650      || (!entry->literal && entry->pattern[0] == '*'))
651    return entry;
652
653  dot_entry = xmalloc (sizeof *dot_entry);
654  *dot_entry = *entry;
655  dot_entry->next = entry;
656  len = strlen (entry->pattern) + 2;
657  dot_pat = xmalloc (len);
658  dot_pat[0] = '.';
659  memcpy (dot_pat + 1, entry->pattern, len - 1);
660  dot_entry->pattern = dot_pat;
661  dot_entry->script = 1;
662  return dot_entry;
663}
664
665EOF
666
667if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then
668  fragment <<EOF
669/* Special handling for embedded SPU executables.  */
670extern bool embedded_spu_file (lang_input_statement_type *, const char *);
671
672static bool
673ppc64_recognized_file (lang_input_statement_type *entry)
674{
675  if (embedded_spu_file (entry, "-m64"))
676    return true;
677
678  return ldelf_load_symbols (entry);
679}
680EOF
681LDEMUL_RECOGNIZED_FILE=ppc64_recognized_file
682fi
683
684# Define some shell vars to insert bits of code into the standard elf
685# parse_args and list_options functions.
686#
687PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}'
688enum ppc64_opt
689{
690  OPTION_STUBGROUP_SIZE = 321,
691  OPTION_PLT_STATIC_CHAIN,
692  OPTION_NO_PLT_STATIC_CHAIN,
693  OPTION_PLT_THREAD_SAFE,
694  OPTION_NO_PLT_THREAD_SAFE,
695  OPTION_PLT_ALIGN,
696  OPTION_NO_PLT_ALIGN,
697  OPTION_PLT_LOCALENTRY,
698  OPTION_NO_PLT_LOCALENTRY,
699  OPTION_POWER10_STUBS,
700  OPTION_NO_POWER10_STUBS,
701  OPTION_NO_PCREL_OPT,
702  OPTION_STUBSYMS,
703  OPTION_NO_STUBSYMS,
704  OPTION_SAVRES,
705  OPTION_NO_SAVRES,
706  OPTION_DOTSYMS,
707  OPTION_NO_DOTSYMS,
708  OPTION_NO_TLS_OPT,
709  OPTION_TLS_GET_ADDR_OPT,
710  OPTION_NO_TLS_GET_ADDR_OPT,
711  OPTION_TLS_GET_ADDR_REGSAVE,
712  OPTION_NO_TLS_GET_ADDR_REGSAVE,
713  OPTION_NO_OPD_OPT,
714  OPTION_NO_INLINE_OPT,
715  OPTION_NO_TOC_OPT,
716  OPTION_NO_MULTI_TOC,
717  OPTION_NO_TOC_SORT,
718  OPTION_NON_OVERLAPPING_OPD
719};
720'
721
722PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
723  { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
724  { "plt-static-chain", no_argument, NULL, OPTION_PLT_STATIC_CHAIN },
725  { "no-plt-static-chain", no_argument, NULL, OPTION_NO_PLT_STATIC_CHAIN },
726  { "plt-thread-safe", no_argument, NULL, OPTION_PLT_THREAD_SAFE },
727  { "no-plt-thread-safe", no_argument, NULL, OPTION_NO_PLT_THREAD_SAFE },
728  { "plt-align", optional_argument, NULL, OPTION_PLT_ALIGN },
729  { "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
730  { "plt-localentry", optional_argument, NULL, OPTION_PLT_LOCALENTRY },
731  { "no-plt-localentry", no_argument, NULL, OPTION_NO_PLT_LOCALENTRY },
732  { "power10-stubs", optional_argument, NULL, OPTION_POWER10_STUBS },
733  { "no-pcrel-optimize", no_argument, NULL, OPTION_NO_PCREL_OPT },
734  { "no-power10-stubs", no_argument, NULL, OPTION_NO_POWER10_STUBS },
735  { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
736  { "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
737  { "dotsyms", no_argument, NULL, OPTION_DOTSYMS },
738  { "no-dotsyms", no_argument, NULL, OPTION_NO_DOTSYMS },
739  { "save-restore-funcs", no_argument, NULL, OPTION_SAVRES },
740  { "no-save-restore-funcs", no_argument, NULL, OPTION_NO_SAVRES },
741  { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
742  { "tls-get-addr-optimize", no_argument, NULL, OPTION_TLS_GET_ADDR_OPT },
743  { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },
744  { "tls-get-addr-regsave", no_argument, NULL, OPTION_TLS_GET_ADDR_REGSAVE },
745  { "no-tls-get-addr-regsave", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_REGSAVE},
746  { "no-opd-optimize", no_argument, NULL, OPTION_NO_OPD_OPT },
747  { "no-inline-optimize", no_argument, NULL, OPTION_NO_INLINE_OPT },
748  { "no-toc-optimize", no_argument, NULL, OPTION_NO_TOC_OPT },
749  { "no-multi-toc", no_argument, NULL, OPTION_NO_MULTI_TOC },
750  { "no-toc-sort", no_argument, NULL, OPTION_NO_TOC_SORT },
751  { "non-overlapping-opd", no_argument, NULL, OPTION_NON_OVERLAPPING_OPD },
752'
753
754PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
755  fprintf (file, _("\
756  --stub-group-size=N         Maximum size of a group of input sections that\n\
757                                can be handled by one stub section.  A negative\n\
758                                value locates all stubs before their branches\n\
759                                (with a group size of -N), while a positive\n\
760                                value allows two groups of input sections, one\n\
761                                before, and one after each stub section.\n\
762                                Values of +/-1 indicate the linker should\n\
763                                choose suitable defaults.\n"
764		   ));
765  fprintf (file, _("\
766  --plt-static-chain          PLT call stubs should load r11'${DEFAULT_PLT_STATIC_CHAIN- (default)}'\n"
767		   ));
768  fprintf (file, _("\
769  --no-plt-static-chain       PLT call stubs should not load r11'${DEFAULT_PLT_STATIC_CHAIN+ (default)}'\n"
770		   ));
771  fprintf (file, _("\
772  --plt-thread-safe           PLT call stubs with load-load barrier\n"
773		   ));
774  fprintf (file, _("\
775  --no-plt-thread-safe        PLT call stubs without barrier\n"
776		   ));
777  fprintf (file, _("\
778  --plt-align [=<align>]      Align PLT call stubs to fit cache lines\n"
779		   ));
780  fprintf (file, _("\
781  --no-plt-align              Dont'\''t align individual PLT call stubs\n"
782		   ));
783  fprintf (file, _("\
784  --plt-localentry            Optimize calls to ELFv2 localentry:0 functions\n"
785		   ));
786  fprintf (file, _("\
787  --no-plt-localentry         Don'\''t optimize ELFv2 calls\n"
788		   ));
789  fprintf (file, _("\
790  --power10-stubs [=auto]     Use Power10 PLT call stubs (default auto)\n"
791		   ));
792  fprintf (file, _("\
793  --no-pcrel-optimize         Don'\''t perform R_PPC64_PCREL_OPT optimization\n"
794		   ));
795  fprintf (file, _("\
796  --no-power10-stubs          Don'\''t use Power10 PLT call stubs\n"
797		   ));
798  fprintf (file, _("\
799  --emit-stub-syms            Label linker stubs with a symbol\n"
800		   ));
801  fprintf (file, _("\
802  --no-emit-stub-syms         Don'\''t label linker stubs with a symbol\n"
803		   ));
804  fprintf (file, _("\
805  --dotsyms                   For every version pattern \"foo\" in a version\n\
806                                script, add \".foo\" so that function code\n\
807                                symbols are treated the same as function\n\
808                                descriptor symbols.  Defaults to on.\n"
809		   ));
810  fprintf (file, _("\
811  --no-dotsyms                Don'\''t do anything special in version scripts\n"
812		   ));
813  fprintf (file, _("\
814  --save-restore-funcs        Provide register save and restore routines used\n\
815                                by gcc -Os code.  Defaults to on for normal\n\
816                                final link, off for ld -r.\n"
817		   ));
818  fprintf (file, _("\
819  --no-save-restore-funcs     Don'\''t provide these routines\n"
820		   ));
821  fprintf (file, _("\
822  --no-tls-optimize           Don'\''t try to optimize TLS accesses\n"
823		   ));
824  fprintf (file, _("\
825  --tls-get-addr-optimize     Force use of special __tls_get_addr call\n"
826		   ));
827  fprintf (file, _("\
828  --no-tls-get-addr-optimize  Don'\''t use a special __tls_get_addr call\n"
829		   ));
830  fprintf (file, _("\
831  --tls-get-addr-regsave      Force register save __tls_get_addr stub\n"
832		   ));
833  fprintf (file, _("\
834  --no-tls-get-addr-regsave   Don'\''t use register save __tls_get_addr stub\n"
835		   ));
836  fprintf (file, _("\
837  --no-opd-optimize           Don'\''t optimize the OPD section\n"
838		   ));
839  fprintf (file, _("\
840  --no-inline-optimize        Don'\''t convert inline PLT to direct calls\n"
841		   ));
842  fprintf (file, _("\
843  --no-toc-optimize           Don'\''t optimize the TOC section\n"
844		   ));
845  fprintf (file, _("\
846  --no-multi-toc              Disallow automatic multiple toc sections\n"
847		   ));
848  fprintf (file, _("\
849  --no-toc-sort               Don'\''t sort TOC and GOT sections\n"
850		   ));
851  fprintf (file, _("\
852  --non-overlapping-opd       Canonicalize .opd, so that there are no\n\
853                                overlapping .opd entries\n"
854		   ));
855'
856
857PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
858    case OPTION_STUBGROUP_SIZE:
859      {
860	const char *end;
861	params.group_size = bfd_scan_vma (optarg, &end, 0);
862	if (*end)
863	  einfo (_("%F%P: invalid number `%s'\''\n"), optarg);
864      }
865      break;
866
867    case OPTION_PLT_STATIC_CHAIN:
868      params.plt_static_chain = 1;
869      break;
870
871    case OPTION_NO_PLT_STATIC_CHAIN:
872      params.plt_static_chain = 0;
873      break;
874
875    case OPTION_PLT_THREAD_SAFE:
876      params.plt_thread_safe = 1;
877      break;
878
879    case OPTION_NO_PLT_THREAD_SAFE:
880      params.plt_thread_safe = 0;
881      break;
882
883    case OPTION_PLT_ALIGN:
884      if (optarg != NULL)
885	{
886	  char *end;
887	  long val = strtol (optarg, &end, 0);
888	  if (*end || (unsigned long) val + 8 > 16)
889	    einfo (_("%F%P: invalid --plt-align `%s'\''\n"), optarg);
890	  params.plt_stub_align = val;
891	}
892      else
893	params.plt_stub_align = 5;
894      break;
895
896    case OPTION_NO_PLT_ALIGN:
897      params.plt_stub_align = 0;
898      break;
899
900    case OPTION_PLT_LOCALENTRY:
901      params.plt_localentry0 = 1;
902      break;
903
904    case OPTION_NO_PLT_LOCALENTRY:
905      params.plt_localentry0 = 0;
906      break;
907
908    case OPTION_POWER10_STUBS:
909      if (optarg != NULL)
910	{
911	  if (strcasecmp (optarg, "auto") == 0)
912	    params.power10_stubs = -1;
913	  else if (strcasecmp (optarg, "yes") == 0)
914	    params.power10_stubs = 1;
915	  else if (strcasecmp (optarg, "no") == 0)
916	    params.power10_stubs = 0;
917	  else
918	    einfo (_("%F%P: invalid --power10-stubs argument `%s'\''\n"),
919		   optarg);
920	}
921      else
922	params.power10_stubs = 1;
923      break;
924
925    case OPTION_NO_POWER10_STUBS:
926      params.power10_stubs = 0;
927      break;
928
929    case OPTION_NO_PCREL_OPT:
930      params.no_pcrel_opt = 1;
931      break;
932
933    case OPTION_STUBSYMS:
934      params.emit_stub_syms = 1;
935      break;
936
937    case OPTION_NO_STUBSYMS:
938      params.emit_stub_syms = 0;
939      break;
940
941    case OPTION_DOTSYMS:
942      dotsyms = 1;
943      break;
944
945    case OPTION_NO_DOTSYMS:
946      dotsyms = 0;
947      break;
948
949    case OPTION_SAVRES:
950      params.save_restore_funcs = 1;
951      break;
952
953    case OPTION_NO_SAVRES:
954      params.save_restore_funcs = 0;
955      break;
956
957    case OPTION_NO_TLS_OPT:
958      no_tls_opt = 1;
959      break;
960
961    case OPTION_TLS_GET_ADDR_OPT:
962      params.tls_get_addr_opt = 1;
963      break;
964
965    case OPTION_NO_TLS_GET_ADDR_OPT:
966      params.tls_get_addr_opt = 0;
967      break;
968
969    case OPTION_TLS_GET_ADDR_REGSAVE:
970      params.no_tls_get_addr_regsave = 0;
971      break;
972
973    case OPTION_NO_TLS_GET_ADDR_REGSAVE:
974      params.no_tls_get_addr_regsave = 1;
975      break;
976
977    case OPTION_NO_OPD_OPT:
978      no_opd_opt = 1;
979      break;
980
981    case OPTION_NO_INLINE_OPT:
982      no_inline_opt = 1;
983      break;
984
985    case OPTION_NO_TOC_OPT:
986      no_toc_opt = 1;
987      break;
988
989    case OPTION_NO_MULTI_TOC:
990      params.no_multi_toc = 1;
991      break;
992
993    case OPTION_NO_TOC_SORT:
994      no_toc_sort = 1;
995      break;
996
997    case OPTION_NON_OVERLAPPING_OPD:
998      params.non_overlapping_opd = 1;
999      break;
1000
1001    case OPTION_TRADITIONAL_FORMAT:
1002      no_tls_opt = 1;
1003      params.tls_get_addr_opt = 0;
1004      no_opd_opt = 1;
1005      no_toc_opt = 1;
1006      params.no_multi_toc = 1;
1007      no_toc_sort = 1;
1008      params.plt_static_chain = 1;
1009      params.no_pcrel_opt = 1;
1010      return false;
1011'
1012
1013# Put these extra ppc64elf routines in ld_${EMULATION_NAME}_emulation
1014#
1015LDEMUL_NEW_VERS_PATTERN=gld${EMULATION_NAME}_new_vers_pattern
1016LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements
1017LDEMUL_AFTER_OPEN=ppc_after_open
1018LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
1019LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
1020LDEMUL_FINISH=gld${EMULATION_NAME}_finish
1021