]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - ld/emultempl/ppc64elf.em
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / ld / emultempl / ppc64elf.em
CommitLineData
1f808cd5 1# This shell script emits a C file. -*- C -*-
250d07de 2# Copyright (C) 2002-2021 Free Software Foundation, Inc.
1f808cd5 3#
f96b4a7b 4# This file is part of the GNU Binutils.
1f808cd5
AM
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
f96b4a7b 8# the Free Software Foundation; either version 3 of the License, or
1f808cd5
AM
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
f96b4a7b
NC
18# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19# MA 02110-1301, USA.
1f808cd5
AM
20#
21
075a2b89 22# This file is sourced from elf.em, and defines extra powerpc64-elf
1f808cd5
AM
23# specific routines.
24#
92b93329 25fragment <<EOF
1f808cd5 26
9c1d81c1 27#include "ldctor.h"
83490352 28#include "elf-bfd.h"
1f808cd5 29#include "elf64-ppc.h"
f05eb3b7 30#include "ldlex.h"
7341d5e2 31#include "elf/ppc64.h"
1f808cd5 32
e7d1c40c
AM
33static asection *ppc_add_stub_section (const char *, asection *);
34static void ppc_layout_sections_again (void);
c9405344 35static void ppc_edit (void);
e7d1c40c
AM
36
37static struct ppc64_elf_params params = { NULL,
38 &ppc_add_stub_section,
39 &ppc_layout_sections_again,
c9405344 40 &ppc_edit,
9e7028aa 41 1, -1, -1, 0,
2420fff6 42 ${DEFAULT_PLT_STATIC_CHAIN-0}, -1, 5,
6738c8a7 43 -1, -1, 0, 0, -1, -1, 0};
e7d1c40c 44
9c1d81c1
AM
45/* Fake input file for stubs. */
46static lang_input_statement_type *stub_file;
47
deb04cdb
AM
48/* Whether we need to call ppc_layout_sections_again. */
49static int need_laying_out = 0;
50
fac1652d
AM
51/* Whether to add ".foo" entries for each "foo" in a version script. */
52static int dotsyms = 1;
53
e5096e3f 54/* Whether to run tls optimization. */
c5614fa4
AM
55static int no_tls_opt = 0;
56
57/* Whether to run opd optimization. */
58static int no_opd_opt = 0;
59
3e04d765
AM
60/* Whether to convert inline PLT calls to direct. */
61static int no_inline_opt = 0;
62
c5614fa4
AM
63/* Whether to run toc optimization. */
64static int no_toc_opt = 0;
e5096e3f 65
d43d0b53
AM
66/* Whether to sort input toc and got sections. */
67static int no_toc_sort = 0;
68
6c2573b7
AM
69/* Input .toc sections will be placed in this output section. */
70static const char *toc_section_name = ".got";
0b9a4d73
AM
71static asection *toc_section = 0;
72
9c1d81c1
AM
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
7d8a3a28 77ppc_create_output_section_statements (void)
9c1d81c1 78{
5503fea1 79 if (!(bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
4dfe6ac6 80 && elf_object_id (link_info.output_bfd) == PPC64_ELF_DATA))
a015f5ec
AM
81 return;
82
b9cf773d
AM
83 link_info.wrap_char = '.';
84
9c1d81c1
AM
85 stub_file = lang_add_input_file ("linker stubs",
86 lang_input_file_is_fake_enum,
87 NULL);
f13a99db 88 stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd);
9c1d81c1
AM
89 if (stub_file->the_bfd == NULL
90 || !bfd_set_arch_mach (stub_file->the_bfd,
f13a99db
AM
91 bfd_get_arch (link_info.output_bfd),
92 bfd_get_mach (link_info.output_bfd)))
9c1d81c1 93 {
d003af55 94 einfo (_("%F%P: can not create BFD: %E\n"));
9c1d81c1
AM
95 return;
96 }
97
d457dcf6 98 stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
9c1d81c1 99 ldlang_add_file (stub_file);
e7d1c40c 100 params.stub_bfd = stub_file->the_bfd;
7d4c687d 101 if (params.save_restore_funcs < 0)
0e1862bb 102 params.save_restore_funcs = !bfd_link_relocatable (&link_info);
e7d1c40c 103 if (!ppc64_elf_init_stub_bfd (&link_info, &params))
d003af55 104 einfo (_("%F%P: can not init BFD: %E\n"));
9c1d81c1
AM
105}
106
dbd1e97e
AM
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 }
6c2573b7
AM
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";
dbd1e97e
AM
137 }
138 }
139 gld${EMULATION_NAME}_after_open ();
140}
141
d43d0b53
AM
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
ba761f19
AM
268static void
269prelim_size_sections (void)
270{
271 if (expld.phase != lang_mark_phase_enum)
272 {
273 expld.phase = lang_mark_phase_enum;
58e6cc77 274 expld.dataseg.phase = exp_seg_none;
ba761f19
AM
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
836c6af1 281static void
7d8a3a28 282ppc_before_allocation (void)
836c6af1 283{
a015f5ec 284 if (stub_file != NULL)
e0468e59 285 {
74f0fb50 286 if (!no_opd_opt
e7d1c40c 287 && !ppc64_elf_edit_opd (&link_info))
d003af55 288 einfo (_("%X%P: can not edit %s: %E\n"), "opd");
e5096e3f 289
3e04d765
AM
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
c9405344
AM
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
f13a99db 312 && !no_tls_opt)
a015f5ec
AM
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. */
ba761f19 316 prelim_size_sections ();
a015f5ec 317
33c0ec9d 318 if (!ppc64_elf_tls_optimize (&link_info))
d003af55 319 einfo (_("%X%P: TLS problem %E\n"));
a015f5ec 320 }
c5614fa4
AM
321
322 if (!no_toc_opt
0e1862bb 323 && !bfd_link_relocatable (&link_info))
ba761f19
AM
324 {
325 prelim_size_sections ();
326
327 if (!ppc64_elf_edit_toc (&link_info))
d003af55 328 einfo (_("%X%P: can not edit %s: %E\n"), "toc");
ba761f19 329 }
d43d0b53
AM
330
331 if (!no_toc_sort)
332 {
333 lang_output_section_statement_type *toc_os;
334
6c2573b7 335 toc_os = lang_output_section_find (toc_section_name);
d43d0b53
AM
336 if (toc_os != NULL)
337 sort_toc_sections (&toc_os->children, NULL, NULL);
338 }
e0468e59 339 }
836c6af1
AM
340}
341
9c1d81c1
AM
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
b34976b6 350static bfd_boolean
7d8a3a28 351hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
9c1d81c1
AM
352{
353 lang_statement_union_type *l;
b34976b6 354 bfd_boolean ret;
9c1d81c1
AM
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;
b34976b6 392 return TRUE;
9c1d81c1
AM
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 }
b34976b6 413 return FALSE;
9c1d81c1
AM
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 *
7d8a3a28 423ppc_add_stub_section (const char *stub_sec_name, asection *input_section)
9c1d81c1
AM
424{
425 asection *stub_sec;
426 flagword flags;
427 asection *output_section;
9c1d81c1
AM
428 lang_output_section_statement_type *os;
429 struct hook_stub_info info;
430
9c1d81c1 431 flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
e4e0193e 432 | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_KEEP);
9795b468
AM
433 stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd,
434 stub_sec_name, flags);
bd518033 435 if (stub_sec == NULL
fd361982
AM
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)))
9c1d81c1
AM
441 goto err_ret;
442
443 output_section = input_section->output_section;
24ef1aa7 444 os = lang_output_section_get (output_section);
9c1d81c1
AM
445
446 info.input_section = input_section;
447 lang_list_init (&info.add);
b9c361e0 448 lang_add_section (&info.add, stub_sec, NULL, os);
9c1d81c1
AM
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:
d003af55 457 einfo (_("%X%P: can not make stub section: %E\n"));
9c1d81c1
AM
458 return NULL;
459}
460
461
462/* Another call-back for ppc64_elf_size_stubs. */
463
464static void
7d8a3a28 465ppc_layout_sections_again (void)
9c1d81c1
AM
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. */
d871d478 470 ldelf_map_segments (TRUE);
1f808cd5 471
0e1862bb 472 if (!bfd_link_relocatable (&link_info))
1c865ab2 473 ppc64_elf_set_toc (&link_info, link_info.output_bfd);
eaeb0a9d
AM
474
475 need_laying_out = -1;
1f808cd5
AM
476}
477
9c1d81c1 478
0b9a4d73 479static void
7d8a3a28 480build_toc_list (lang_statement_union_type *statement)
0b9a4d73 481{
7b986e99
AM
482 if (statement->header.type == lang_input_section_enum)
483 {
484 asection *i = statement->input_section.section;
485
dbaa2011 486 if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
7b986e99
AM
487 && (i->flags & SEC_EXCLUDE) == 0
488 && i->output_section == toc_section)
927be08e
AM
489 {
490 if (!ppc64_elf_next_toc_section (&link_info, i))
d003af55 491 einfo (_("%X%P: linker script separates .got and .toc\n"));
927be08e 492 }
7b986e99 493 }
0b9a4d73
AM
494}
495
496
9c1d81c1 497static void
7d8a3a28 498build_section_lists (lang_statement_union_type *statement)
9c1d81c1 499{
7b986e99 500 if (statement->header.type == lang_input_section_enum)
9c1d81c1 501 {
7b986e99
AM
502 asection *i = statement->input_section.section;
503
00f93c44 504 if (!bfd_input_just_syms (i->owner)
7b986e99
AM
505 && (i->flags & SEC_EXCLUDE) == 0
506 && i->output_section != NULL
f13a99db 507 && i->output_section->owner == link_info.output_bfd)
7b986e99
AM
508 {
509 if (!ppc64_elf_next_input_section (&link_info, i))
d003af55 510 einfo (_("%X%P: can not size stub section: %E\n"));
7b986e99 511 }
9c1d81c1
AM
512 }
513}
514
fac1652d 515
eaeb0a9d
AM
516/* Call the back-end function to set TOC base after we have placed all
517 the sections. */
1f808cd5 518static void
eaeb0a9d 519gld${EMULATION_NAME}_after_allocation (void)
1f808cd5 520{
75938853
AM
521 int ret;
522
836c6af1
AM
523 /* If generating a relocatable output file, then we don't have any
524 stubs. */
0e1862bb 525 if (stub_file != NULL && !bfd_link_relocatable (&link_info))
1f808cd5 526 {
75938853 527 ret = ppc64_elf_setup_section_lists (&link_info);
92b7a70f 528 if (ret < 0)
d003af55 529 einfo (_("%X%P: can not size stub section: %E\n"));
da44f4e5 530 else
9c1d81c1 531 {
927be08e
AM
532 ppc64_elf_start_multitoc_partition (&link_info);
533
e7d1c40c 534 if (!params.no_multi_toc)
927be08e
AM
535 {
536 toc_section = bfd_get_section_by_name (link_info.output_bfd,
6c2573b7 537 toc_section_name);
927be08e
AM
538 if (toc_section != NULL)
539 lang_for_each_statement (build_toc_list);
540 }
541
542 if (ppc64_elf_layout_multitoc (&link_info)
e7d1c40c 543 && !params.no_multi_toc
927be08e 544 && toc_section != NULL)
0b9a4d73
AM
545 lang_for_each_statement (build_toc_list);
546
927be08e 547 ppc64_elf_finish_multitoc_partition (&link_info);
0b9a4d73 548
836c6af1 549 lang_for_each_statement (build_section_lists);
9c1d81c1 550
70cc837d 551 if (!ppc64_elf_check_init_fini (&link_info))
d003af55 552 einfo (_("%P: .init/.fini fragments use differing TOC pointers\n"));
70cc837d 553
836c6af1 554 /* Call into the BFD backend to do the real work. */
e7d1c40c 555 if (!ppc64_elf_size_stubs (&link_info))
d003af55 556 einfo (_("%X%P: can not size stub section: %E\n"));
1f808cd5 557 }
9c1d81c1 558 }
1f808cd5 559
da44f4e5
AM
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 {
d003af55 567 einfo (_("%X%P: .eh_frame/.stab edit: %E\n"));
da44f4e5
AM
568 return;
569 }
570 else if (ret > 0)
571 need_laying_out = 1;
572
44bd1acd
AM
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. */
d871d478 579 ldelf_map_segments (need_laying_out > 0);
44bd1acd 580
0e1862bb 581 if (need_laying_out != -1 && !bfd_link_relocatable (&link_info))
44bd1acd 582 ppc64_elf_set_toc (&link_info, link_info.output_bfd);
eaeb0a9d
AM
583}
584
585
586/* Final emulation specific call. */
587
588static void
589gld${EMULATION_NAME}_finish (void)
590{
7341d5e2
AM
591 char *msg = NULL;
592 char *line, *endline;
593
eaeb0a9d
AM
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. */
459609d6
AM
597 if (stub_file != NULL
598 && (elf_elfheader (link_info.output_bfd)->e_flags & EF_PPC64_ABI) == 1)
7341d5e2
AM
599 entry_section = ".opd";
600
601 if (params.emit_stub_syms < 0)
602 params.emit_stub_syms = 1;
603 if (stub_file != NULL
0e1862bb 604 && !bfd_link_relocatable (&link_info)
7341d5e2 605 && !ppc64_elf_build_stubs (&link_info, config.stats ? &msg : NULL))
d003af55 606 einfo (_("%X%P: can not build stubs: %E\n"));
7341d5e2
AM
607
608 fflush (stdout);
609 for (line = msg; line != NULL; line = endline)
9c1d81c1 610 {
7341d5e2
AM
611 endline = strchr (line, '\n');
612 if (endline != NULL)
613 *endline++ = '\0';
614 fprintf (stderr, "%s: %s\n", program_name, line);
9c1d81c1 615 }
7341d5e2 616 fflush (stderr);
5e2ab612 617 free (msg);
99877b66 618
1e035701 619 finish_default ();
9c1d81c1 620}
1f808cd5 621
76dc39fe 622
fac1652d
AM
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
7d8a3a28
AM
641static struct bfd_elf_version_expr *
642gld${EMULATION_NAME}_new_vers_pattern (struct bfd_elf_version_expr *entry)
fac1652d
AM
643{
644 struct bfd_elf_version_expr *dot_entry;
fac1652d
AM
645 unsigned int len;
646 char *dot_pat;
647
b7b7fe3f 648 if (!dotsyms
ae5a3597
AM
649 || entry->pattern[0] == '.'
650 || (!entry->literal && entry->pattern[0] == '*'))
fac1652d
AM
651 return entry;
652
7d8a3a28 653 dot_entry = xmalloc (sizeof *dot_entry);
108ba305 654 *dot_entry = *entry;
fac1652d 655 dot_entry->next = entry;
ae5a3597
AM
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;
71755fdf 661 dot_entry->script = 1;
fac1652d
AM
662 return dot_entry;
663}
664
1f808cd5
AM
665EOF
666
dc27aea4 667if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then
92b93329 668 fragment <<EOF
dc27aea4
AM
669/* Special handling for embedded SPU executables. */
670extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *);
dc27aea4
AM
671
672static bfd_boolean
673ppc64_recognized_file (lang_input_statement_type *entry)
674{
675 if (embedded_spu_file (entry, "-m64"))
676 return TRUE;
677
d871d478 678 return ldelf_load_symbols (entry);
dc27aea4
AM
679}
680EOF
681LDEMUL_RECOGNIZED_FILE=ppc64_recognized_file
682fi
683
9c1d81c1
AM
684# Define some shell vars to insert bits of code into the standard elf
685# parse_args and list_options functions.
686#
58d180e8 687PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}'
f378ab09
AM
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,
d3b10ee7
AM
699 OPTION_POWER10_STUBS,
700 OPTION_NO_POWER10_STUBS,
6738c8a7 701 OPTION_NO_PCREL_OPT,
f378ab09
AM
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,
9e7028aa
AM
711 OPTION_TLS_GET_ADDR_REGSAVE,
712 OPTION_NO_TLS_GET_ADDR_REGSAVE,
f378ab09 713 OPTION_NO_OPD_OPT,
3e04d765 714 OPTION_NO_INLINE_OPT,
f378ab09
AM
715 OPTION_NO_TOC_OPT,
716 OPTION_NO_MULTI_TOC,
717 OPTION_NO_TOC_SORT,
718 OPTION_NON_OVERLAPPING_OPD
719};
9c1d81c1
AM
720'
721
58d180e8 722PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
9c1d81c1 723 { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
9df0ef5f
AM
724 { "plt-static-chain", no_argument, NULL, OPTION_PLT_STATIC_CHAIN },
725 { "no-plt-static-chain", no_argument, NULL, OPTION_NO_PLT_STATIC_CHAIN },
794e51c0
AM
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 },
f378ab09
AM
730 { "plt-localentry", optional_argument, NULL, OPTION_PLT_LOCALENTRY },
731 { "no-plt-localentry", no_argument, NULL, OPTION_NO_PLT_LOCALENTRY },
e10a07b3 732 { "power10-stubs", optional_argument, NULL, OPTION_POWER10_STUBS },
6738c8a7 733 { "no-pcrel-optimize", no_argument, NULL, OPTION_NO_PCREL_OPT },
d3b10ee7 734 { "no-power10-stubs", no_argument, NULL, OPTION_NO_POWER10_STUBS },
0b9a4d73 735 { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
b02c4cfa 736 { "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
fac1652d
AM
737 { "dotsyms", no_argument, NULL, OPTION_DOTSYMS },
738 { "no-dotsyms", no_argument, NULL, OPTION_NO_DOTSYMS },
7d4c687d
AM
739 { "save-restore-funcs", no_argument, NULL, OPTION_SAVRES },
740 { "no-save-restore-funcs", no_argument, NULL, OPTION_NO_SAVRES },
e5096e3f 741 { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
7c9cf415 742 { "tls-get-addr-optimize", no_argument, NULL, OPTION_TLS_GET_ADDR_OPT },
a7f2871e 743 { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },
9e7028aa
AM
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},
c5614fa4 746 { "no-opd-optimize", no_argument, NULL, OPTION_NO_OPD_OPT },
3e04d765 747 { "no-inline-optimize", no_argument, NULL, OPTION_NO_INLINE_OPT },
c5614fa4 748 { "no-toc-optimize", no_argument, NULL, OPTION_NO_TOC_OPT },
4c52953f 749 { "no-multi-toc", no_argument, NULL, OPTION_NO_MULTI_TOC },
d43d0b53 750 { "no-toc-sort", no_argument, NULL, OPTION_NO_TOC_SORT },
3f764659 751 { "non-overlapping-opd", no_argument, NULL, OPTION_NON_OVERLAPPING_OPD },
9c1d81c1
AM
752'
753
58d180e8 754PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
9c1d81c1 755 fprintf (file, _("\
442996ee
AM
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"
9c1d81c1 764 ));
fac1652d 765 fprintf (file, _("\
df5f2391 766 --plt-static-chain PLT call stubs should load r11'${DEFAULT_PLT_STATIC_CHAIN- (default)}'\n"
794e51c0
AM
767 ));
768 fprintf (file, _("\
df5f2391 769 --no-plt-static-chain PLT call stubs should not load r11'${DEFAULT_PLT_STATIC_CHAIN+ (default)}'\n"
794e51c0
AM
770 ));
771 fprintf (file, _("\
df5f2391 772 --plt-thread-safe PLT call stubs with load-load barrier\n"
794e51c0
AM
773 ));
774 fprintf (file, _("\
df5f2391 775 --no-plt-thread-safe PLT call stubs without barrier\n"
794e51c0
AM
776 ));
777 fprintf (file, _("\
df5f2391 778 --plt-align [=<align>] Align PLT call stubs to fit cache lines\n"
9df0ef5f
AM
779 ));
780 fprintf (file, _("\
df5f2391 781 --no-plt-align Dont'\''t align individual PLT call stubs\n"
9df0ef5f
AM
782 ));
783 fprintf (file, _("\
df5f2391 784 --plt-localentry Optimize calls to ELFv2 localentry:0 functions\n"
f378ab09
AM
785 ));
786 fprintf (file, _("\
df5f2391 787 --no-plt-localentry Don'\''t optimize ELFv2 calls\n"
f378ab09
AM
788 ));
789 fprintf (file, _("\
e10a07b3 790 --power10-stubs [=auto] Use Power10 PLT call stubs (default auto)\n"
d3b10ee7
AM
791 ));
792 fprintf (file, _("\
6738c8a7
AM
793 --no-pcrel-optimize Don'\''t perform R_PPC64_PCREL_OPT optimization\n"
794 ));
795 fprintf (file, _("\
d3b10ee7
AM
796 --no-power10-stubs Don'\''t use Power10 PLT call stubs\n"
797 ));
798 fprintf (file, _("\
df5f2391 799 --emit-stub-syms Label linker stubs with a symbol\n"
0b9a4d73
AM
800 ));
801 fprintf (file, _("\
df5f2391 802 --no-emit-stub-syms Don'\''t label linker stubs with a symbol\n"
b02c4cfa
AM
803 ));
804 fprintf (file, _("\
442996ee
AM
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"
fac1652d
AM
809 ));
810 fprintf (file, _("\
df5f2391 811 --no-dotsyms Don'\''t do anything special in version scripts\n"
fac1652d 812 ));
e5096e3f 813 fprintf (file, _("\
7d4c687d
AM
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, _("\
df5f2391 819 --no-save-restore-funcs Don'\''t provide these routines\n"
7d4c687d
AM
820 ));
821 fprintf (file, _("\
df5f2391 822 --no-tls-optimize Don'\''t try to optimize TLS accesses\n"
e5096e3f 823 ));
3f764659 824 fprintf (file, _("\
df5f2391 825 --tls-get-addr-optimize Force use of special __tls_get_addr call\n"
7c9cf415
AM
826 ));
827 fprintf (file, _("\
df5f2391 828 --no-tls-get-addr-optimize Don'\''t use a special __tls_get_addr call\n"
a7f2871e
AM
829 ));
830 fprintf (file, _("\
9e7028aa
AM
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, _("\
df5f2391 837 --no-opd-optimize Don'\''t optimize the OPD section\n"
c5614fa4
AM
838 ));
839 fprintf (file, _("\
3e04d765
AM
840 --no-inline-optimize Don'\''t convert inline PLT to direct calls\n"
841 ));
842 fprintf (file, _("\
df5f2391 843 --no-toc-optimize Don'\''t optimize the TOC section\n"
c5614fa4
AM
844 ));
845 fprintf (file, _("\
df5f2391 846 --no-multi-toc Disallow automatic multiple toc sections\n"
4c52953f
AM
847 ));
848 fprintf (file, _("\
df5f2391 849 --no-toc-sort Don'\''t sort TOC and GOT sections\n"
d43d0b53
AM
850 ));
851 fprintf (file, _("\
442996ee 852 --non-overlapping-opd Canonicalize .opd, so that there are no\n\
df5f2391 853 overlapping .opd entries\n"
3f764659 854 ));
9c1d81c1
AM
855'
856
58d180e8 857PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
9c1d81c1
AM
858 case OPTION_STUBGROUP_SIZE:
859 {
860 const char *end;
6c19b93b
AM
861 params.group_size = bfd_scan_vma (optarg, &end, 0);
862 if (*end)
df5f2391 863 einfo (_("%F%P: invalid number `%s'\''\n"), optarg);
9c1d81c1
AM
864 }
865 break;
fac1652d 866
9df0ef5f 867 case OPTION_PLT_STATIC_CHAIN:
e7d1c40c 868 params.plt_static_chain = 1;
9df0ef5f
AM
869 break;
870
871 case OPTION_NO_PLT_STATIC_CHAIN:
e7d1c40c 872 params.plt_static_chain = 0;
9df0ef5f
AM
873 break;
874
794e51c0 875 case OPTION_PLT_THREAD_SAFE:
e7d1c40c 876 params.plt_thread_safe = 1;
794e51c0
AM
877 break;
878
879 case OPTION_NO_PLT_THREAD_SAFE:
e7d1c40c 880 params.plt_thread_safe = 0;
794e51c0
AM
881 break;
882
883 case OPTION_PLT_ALIGN:
884 if (optarg != NULL)
885 {
886 char *end;
691d2e9a
AM
887 long val = strtol (optarg, &end, 0);
888 if (*end || (unsigned long) val + 8 > 16)
df5f2391 889 einfo (_("%F%P: invalid --plt-align `%s'\''\n"), optarg);
e05fa0ba 890 params.plt_stub_align = val;
794e51c0
AM
891 }
892 else
e05fa0ba 893 params.plt_stub_align = 5;
794e51c0
AM
894 break;
895
896 case OPTION_NO_PLT_ALIGN:
e05fa0ba 897 params.plt_stub_align = 0;
794e51c0
AM
898 break;
899
f378ab09
AM
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
d3b10ee7 908 case OPTION_POWER10_STUBS:
e10a07b3
AM
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;
d3b10ee7
AM
923 break;
924
925 case OPTION_NO_POWER10_STUBS:
926 params.power10_stubs = 0;
927 break;
928
6738c8a7
AM
929 case OPTION_NO_PCREL_OPT:
930 params.no_pcrel_opt = 1;
931 break;
932
0b9a4d73 933 case OPTION_STUBSYMS:
e7d1c40c 934 params.emit_stub_syms = 1;
0b9a4d73
AM
935 break;
936
b02c4cfa 937 case OPTION_NO_STUBSYMS:
e7d1c40c 938 params.emit_stub_syms = 0;
b02c4cfa
AM
939 break;
940
fac1652d 941 case OPTION_DOTSYMS:
e5096e3f 942 dotsyms = 1;
fac1652d
AM
943 break;
944
945 case OPTION_NO_DOTSYMS:
e5096e3f
AM
946 dotsyms = 0;
947 break;
948
7d4c687d
AM
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
e5096e3f 957 case OPTION_NO_TLS_OPT:
c5614fa4
AM
958 no_tls_opt = 1;
959 break;
960
7c9cf415
AM
961 case OPTION_TLS_GET_ADDR_OPT:
962 params.tls_get_addr_opt = 1;
963 break;
964
a7f2871e 965 case OPTION_NO_TLS_GET_ADDR_OPT:
7c9cf415 966 params.tls_get_addr_opt = 0;
a7f2871e
AM
967 break;
968
9e7028aa
AM
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
c5614fa4
AM
977 case OPTION_NO_OPD_OPT:
978 no_opd_opt = 1;
979 break;
980
3e04d765
AM
981 case OPTION_NO_INLINE_OPT:
982 no_inline_opt = 1;
983 break;
984
c5614fa4
AM
985 case OPTION_NO_TOC_OPT:
986 no_toc_opt = 1;
fac1652d 987 break;
3f764659 988
4c52953f 989 case OPTION_NO_MULTI_TOC:
e7d1c40c 990 params.no_multi_toc = 1;
4c52953f
AM
991 break;
992
d43d0b53
AM
993 case OPTION_NO_TOC_SORT:
994 no_toc_sort = 1;
995 break;
996
3f764659 997 case OPTION_NON_OVERLAPPING_OPD:
e7d1c40c 998 params.non_overlapping_opd = 1;
3f764659 999 break;
f05eb3b7
AM
1000
1001 case OPTION_TRADITIONAL_FORMAT:
1002 no_tls_opt = 1;
7c9cf415 1003 params.tls_get_addr_opt = 0;
f05eb3b7
AM
1004 no_opd_opt = 1;
1005 no_toc_opt = 1;
e7d1c40c 1006 params.no_multi_toc = 1;
f05eb3b7 1007 no_toc_sort = 1;
e7d1c40c 1008 params.plt_static_chain = 1;
6738c8a7 1009 params.no_pcrel_opt = 1;
f05eb3b7 1010 return FALSE;
9c1d81c1
AM
1011'
1012
1f808cd5
AM
1013# Put these extra ppc64elf routines in ld_${EMULATION_NAME}_emulation
1014#
dbd1e97e
AM
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
836c6af1 1018LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
1f808cd5 1019LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
8ded5a0f 1020LDEMUL_FINISH=gld${EMULATION_NAME}_finish