convert to_teardown_btrace
[deliverable/binutils-gdb.git] / ld / emultempl / ppc64elf.em
CommitLineData
1f808cd5 1# This shell script emits a C file. -*- C -*-
794e51c0 2# Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
74f0fb50 3# Free Software Foundation, Inc.
1f808cd5 4#
f96b4a7b 5# This file is part of the GNU Binutils.
1f808cd5
AM
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
f96b4a7b 9# the Free Software Foundation; either version 3 of the License, or
1f808cd5
AM
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
f96b4a7b
NC
19# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20# MA 02110-1301, USA.
1f808cd5
AM
21#
22
23# This file is sourced from elf32.em, and defines extra powerpc64-elf
24# specific routines.
25#
92b93329 26fragment <<EOF
1f808cd5 27
9c1d81c1 28#include "ldctor.h"
805fc799 29#include "libbfd.h"
83490352 30#include "elf-bfd.h"
1f808cd5 31#include "elf64-ppc.h"
f05eb3b7 32#include "ldlex.h"
1f808cd5 33
e7d1c40c
AM
34static asection *ppc_add_stub_section (const char *, asection *);
35static void ppc_layout_sections_again (void);
36
37static struct ppc64_elf_params params = { NULL,
38 &ppc_add_stub_section,
39 &ppc_layout_sections_again,
40 1, 0, 0,
41 ${DEFAULT_PLT_STATIC_CHAIN-0}, -1, 0,
7d4c687d 42 0, -1, -1};
e7d1c40c 43
9c1d81c1
AM
44/* Fake input file for stubs. */
45static lang_input_statement_type *stub_file;
68f8ff14 46static int stub_added = 0;
9c1d81c1 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
60/* Whether to run toc optimization. */
61static int no_toc_opt = 0;
e5096e3f 62
d43d0b53
AM
63/* Whether to sort input toc and got sections. */
64static int no_toc_sort = 0;
65
794e51c0
AM
66/* Set if individual PLT call stubs should be aligned. */
67static int plt_stub_align = 0;
68
0b9a4d73
AM
69static asection *toc_section = 0;
70
9c1d81c1
AM
71/* This is called before the input files are opened. We create a new
72 fake input file to hold the stub sections. */
73
74static void
7d8a3a28 75ppc_create_output_section_statements (void)
9c1d81c1 76{
5503fea1 77 if (!(bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
4dfe6ac6 78 && elf_object_id (link_info.output_bfd) == PPC64_ELF_DATA))
a015f5ec
AM
79 return;
80
b9cf773d
AM
81 link_info.wrap_char = '.';
82
9c1d81c1
AM
83 stub_file = lang_add_input_file ("linker stubs",
84 lang_input_file_is_fake_enum,
85 NULL);
f13a99db 86 stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd);
9c1d81c1
AM
87 if (stub_file->the_bfd == NULL
88 || !bfd_set_arch_mach (stub_file->the_bfd,
f13a99db
AM
89 bfd_get_arch (link_info.output_bfd),
90 bfd_get_mach (link_info.output_bfd)))
9c1d81c1 91 {
f7c46796 92 einfo ("%F%P: can not create BFD: %E\n");
9c1d81c1
AM
93 return;
94 }
95
d457dcf6 96 stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
9c1d81c1 97 ldlang_add_file (stub_file);
e7d1c40c 98 params.stub_bfd = stub_file->the_bfd;
7d4c687d
AM
99 if (params.save_restore_funcs < 0)
100 params.save_restore_funcs = !link_info.relocatable;
e7d1c40c 101 if (!ppc64_elf_init_stub_bfd (&link_info, &params))
bfeb4a28 102 einfo ("%F%P: can not init BFD: %E\n");
9c1d81c1
AM
103}
104
d43d0b53
AM
105/* Move the input section statement at *U which happens to be on LIST
106 to be just before *TO. */
107
108static void
109move_input_section (lang_statement_list_type *list,
110 lang_statement_union_type **u,
111 lang_statement_union_type **to)
112{
113 lang_statement_union_type *s = *u;
114 asection *i = s->input_section.section;
115 asection *p, *n;
116
117 /* Snip the input section from the statement list. If it was the
118 last statement, fix the list tail pointer. */
119 *u = s->header.next;
120 if (*u == NULL)
121 list->tail = u;
122 /* Add it back in the new position. */
123 s->header.next = *to;
124 *to = s;
125 if (list->tail == to)
126 list->tail = &s->header.next;
127
128 /* Trim I off the bfd map_head/map_tail doubly linked lists. */
129 n = i->map_head.s;
130 p = i->map_tail.s;
131 (p != NULL ? p : i->output_section)->map_head.s = n;
132 (n != NULL ? n : i->output_section)->map_tail.s = p;
133
134 /* Add I back on in its new position. */
135 if (s->header.next->header.type == lang_input_section_enum)
136 {
137 n = s->header.next->input_section.section;
138 p = n->map_tail.s;
139 }
140 else
141 {
142 /* If the next statement is not an input section statement then
143 TO must point at the previous input section statement
144 header.next field. */
145 lang_input_section_type *prev = (lang_input_section_type *)
146 ((char *) to - offsetof (lang_statement_union_type, header.next));
147
148 ASSERT (prev->header.type == lang_input_section_enum);
149 p = prev->section;
150 n = p->map_head.s;
151 }
152 i->map_head.s = n;
153 i->map_tail.s = p;
154 (p != NULL ? p : i->output_section)->map_head.s = i;
155 (n != NULL ? n : i->output_section)->map_tail.s = i;
156}
157
158/* Sort input section statements in the linker script tree rooted at
159 LIST so that those whose owning bfd happens to have a section
160 called .init or .fini are placed first. Place any TOC sections
161 referenced by small TOC relocs next, with TOC sections referenced
162 only by bigtoc relocs last. */
163
164static void
165sort_toc_sections (lang_statement_list_type *list,
166 lang_statement_union_type **ini,
167 lang_statement_union_type **small)
168{
169 lang_statement_union_type *s, **u;
170 asection *i;
171
172 u = &list->head;
173 while ((s = *u) != NULL)
174 {
175 switch (s->header.type)
176 {
177 case lang_wild_statement_enum:
178 sort_toc_sections (&s->wild_statement.children, ini, small);
179 break;
180
181 case lang_group_statement_enum:
182 sort_toc_sections (&s->group_statement.children, ini, small);
183 break;
184
185 case lang_input_section_enum:
186 i = s->input_section.section;
187 /* Leave the stub_file .got where it is. We put the .got
188 header there. */
189 if (i->owner == stub_file->the_bfd)
190 break;
191 if (bfd_get_section_by_name (i->owner, ".init") != NULL
192 || bfd_get_section_by_name (i->owner, ".fini") != NULL)
193 {
194 if (ini != NULL && *ini != s)
195 {
196 move_input_section (list, u, ini);
197 if (small == ini)
198 small = &s->header.next;
199 ini = &s->header.next;
200 continue;
201 }
202 if (small == ini)
203 small = &s->header.next;
204 ini = &s->header.next;
205 break;
206 }
207 else if (ini == NULL)
208 ini = u;
209
210 if (ppc64_elf_has_small_toc_reloc (i))
211 {
212 if (small != NULL && *small != s)
213 {
214 move_input_section (list, u, small);
215 small = &s->header.next;
216 continue;
217 }
218 small = &s->header.next;
219 }
220 else if (small == NULL)
221 small = u;
222 break;
223
224 default:
225 break;
226 }
227 u = &s->header.next;
228 }
229}
230
ba761f19
AM
231static void
232prelim_size_sections (void)
233{
234 if (expld.phase != lang_mark_phase_enum)
235 {
236 expld.phase = lang_mark_phase_enum;
237 expld.dataseg.phase = exp_dataseg_none;
238 one_lang_size_sections_pass (NULL, FALSE);
239 /* We must not cache anything from the preliminary sizing. */
240 lang_reset_memory_regions ();
241 }
242}
243
836c6af1 244static void
7d8a3a28 245ppc_before_allocation (void)
836c6af1 246{
a015f5ec 247 if (stub_file != NULL)
e0468e59 248 {
74f0fb50 249 if (!no_opd_opt
e7d1c40c 250 && !ppc64_elf_edit_opd (&link_info))
f7c46796 251 einfo ("%X%P: can not edit %s: %E\n", "opd");
e5096e3f 252
e7d1c40c 253 if (ppc64_elf_tls_setup (&link_info)
f13a99db 254 && !no_tls_opt)
a015f5ec
AM
255 {
256 /* Size the sections. This is premature, but we want to know the
257 TLS segment layout so that certain optimizations can be done. */
ba761f19 258 prelim_size_sections ();
a015f5ec 259
33c0ec9d 260 if (!ppc64_elf_tls_optimize (&link_info))
92b7a70f 261 einfo ("%X%P: TLS problem %E\n");
a015f5ec 262 }
c5614fa4
AM
263
264 if (!no_toc_opt
ba761f19
AM
265 && !link_info.relocatable)
266 {
267 prelim_size_sections ();
268
269 if (!ppc64_elf_edit_toc (&link_info))
f7c46796 270 einfo ("%X%P: can not edit %s: %E\n", "toc");
ba761f19 271 }
d43d0b53
AM
272
273 if (!no_toc_sort)
274 {
275 lang_output_section_statement_type *toc_os;
276
277 toc_os = lang_output_section_find (".got");
278 if (toc_os != NULL)
279 sort_toc_sections (&toc_os->children, NULL, NULL);
280 }
e0468e59
AM
281 }
282
836c6af1
AM
283 gld${EMULATION_NAME}_before_allocation ();
284}
285
9c1d81c1
AM
286struct hook_stub_info
287{
288 lang_statement_list_type add;
289 asection *input_section;
290};
291
292/* Traverse the linker tree to find the spot where the stub goes. */
293
b34976b6 294static bfd_boolean
7d8a3a28 295hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp)
9c1d81c1
AM
296{
297 lang_statement_union_type *l;
b34976b6 298 bfd_boolean ret;
9c1d81c1
AM
299
300 for (; (l = *lp) != NULL; lp = &l->header.next)
301 {
302 switch (l->header.type)
303 {
304 case lang_constructors_statement_enum:
305 ret = hook_in_stub (info, &constructor_list.head);
306 if (ret)
307 return ret;
308 break;
309
310 case lang_output_section_statement_enum:
311 ret = hook_in_stub (info,
312 &l->output_section_statement.children.head);
313 if (ret)
314 return ret;
315 break;
316
317 case lang_wild_statement_enum:
318 ret = hook_in_stub (info, &l->wild_statement.children.head);
319 if (ret)
320 return ret;
321 break;
322
323 case lang_group_statement_enum:
324 ret = hook_in_stub (info, &l->group_statement.children.head);
325 if (ret)
326 return ret;
327 break;
328
329 case lang_input_section_enum:
330 if (l->input_section.section == info->input_section)
331 {
332 /* We've found our section. Insert the stub immediately
333 before its associated input section. */
334 *lp = info->add.head;
335 *(info->add.tail) = l;
b34976b6 336 return TRUE;
9c1d81c1
AM
337 }
338 break;
339
340 case lang_data_statement_enum:
341 case lang_reloc_statement_enum:
342 case lang_object_symbols_statement_enum:
343 case lang_output_statement_enum:
344 case lang_target_statement_enum:
345 case lang_input_statement_enum:
346 case lang_assignment_statement_enum:
347 case lang_padding_statement_enum:
348 case lang_address_statement_enum:
349 case lang_fill_statement_enum:
350 break;
351
352 default:
353 FAIL ();
354 break;
355 }
356 }
b34976b6 357 return FALSE;
9c1d81c1
AM
358}
359
360
361/* Call-back for ppc64_elf_size_stubs. */
362
363/* Create a new stub section, and arrange for it to be linked
364 immediately before INPUT_SECTION. */
365
366static asection *
7d8a3a28 367ppc_add_stub_section (const char *stub_sec_name, asection *input_section)
9c1d81c1
AM
368{
369 asection *stub_sec;
370 flagword flags;
371 asection *output_section;
9c1d81c1
AM
372 lang_output_section_statement_type *os;
373 struct hook_stub_info info;
374
9c1d81c1 375 flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
e4e0193e 376 | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_KEEP);
9795b468
AM
377 stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd,
378 stub_sec_name, flags);
bd518033 379 if (stub_sec == NULL
794e51c0
AM
380 || !bfd_set_section_alignment (stub_file->the_bfd, stub_sec,
381 plt_stub_align > 5 ? plt_stub_align : 5))
9c1d81c1
AM
382 goto err_ret;
383
384 output_section = input_section->output_section;
24ef1aa7 385 os = lang_output_section_get (output_section);
9c1d81c1
AM
386
387 info.input_section = input_section;
388 lang_list_init (&info.add);
b9c361e0 389 lang_add_section (&info.add, stub_sec, NULL, os);
9c1d81c1
AM
390
391 if (info.add.head == NULL)
392 goto err_ret;
393
68f8ff14 394 stub_added = 1;
9c1d81c1
AM
395 if (hook_in_stub (&info, &os->children.head))
396 return stub_sec;
397
398 err_ret:
399 einfo ("%X%P: can not make stub section: %E\n");
400 return NULL;
401}
402
403
404/* Another call-back for ppc64_elf_size_stubs. */
405
406static void
7d8a3a28 407ppc_layout_sections_again (void)
9c1d81c1
AM
408{
409 /* If we have changed sizes of the stub sections, then we need
410 to recalculate all the section offsets. This may mean we need to
411 add even more stubs. */
8ded5a0f 412 gld${EMULATION_NAME}_map_segments (TRUE);
1f808cd5 413
1049f94e 414 if (!link_info.relocatable)
1c865ab2 415 ppc64_elf_set_toc (&link_info, link_info.output_bfd);
eaeb0a9d
AM
416
417 need_laying_out = -1;
1f808cd5
AM
418}
419
9c1d81c1 420
0b9a4d73 421static void
7d8a3a28 422build_toc_list (lang_statement_union_type *statement)
0b9a4d73 423{
7b986e99
AM
424 if (statement->header.type == lang_input_section_enum)
425 {
426 asection *i = statement->input_section.section;
427
dbaa2011 428 if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
7b986e99
AM
429 && (i->flags & SEC_EXCLUDE) == 0
430 && i->output_section == toc_section)
927be08e
AM
431 {
432 if (!ppc64_elf_next_toc_section (&link_info, i))
433 einfo ("%X%P: linker script separates .got and .toc\n");
434 }
7b986e99 435 }
0b9a4d73
AM
436}
437
438
9c1d81c1 439static void
7d8a3a28 440build_section_lists (lang_statement_union_type *statement)
9c1d81c1 441{
7b986e99 442 if (statement->header.type == lang_input_section_enum)
9c1d81c1 443 {
7b986e99
AM
444 asection *i = statement->input_section.section;
445
66be1055 446 if (!((lang_input_statement_type *) i->owner->usrdata)->flags.just_syms
7b986e99
AM
447 && (i->flags & SEC_EXCLUDE) == 0
448 && i->output_section != NULL
f13a99db 449 && i->output_section->owner == link_info.output_bfd)
7b986e99
AM
450 {
451 if (!ppc64_elf_next_input_section (&link_info, i))
452 einfo ("%X%P: can not size stub section: %E\n");
453 }
9c1d81c1
AM
454 }
455}
456
fac1652d 457
eaeb0a9d
AM
458/* Call the back-end function to set TOC base after we have placed all
459 the sections. */
1f808cd5 460static void
eaeb0a9d 461gld${EMULATION_NAME}_after_allocation (void)
1f808cd5 462{
eaeb0a9d
AM
463 /* bfd_elf_discard_info just plays with data and debugging sections,
464 ie. doesn't affect code size, so we can delay resizing the
deb04cdb
AM
465 sections. It's likely we'll resize everything in the process of
466 adding stubs. */
f13a99db 467 if (bfd_elf_discard_info (link_info.output_bfd, &link_info))
deb04cdb
AM
468 need_laying_out = 1;
469
836c6af1
AM
470 /* If generating a relocatable output file, then we don't have any
471 stubs. */
1049f94e 472 if (stub_file != NULL && !link_info.relocatable)
1f808cd5 473 {
e7d1c40c 474 int ret = ppc64_elf_setup_section_lists (&link_info);
92b7a70f
AM
475 if (ret < 0)
476 einfo ("%X%P: can not size stub section: %E\n");
477 else if (ret > 0)
9c1d81c1 478 {
927be08e
AM
479 ppc64_elf_start_multitoc_partition (&link_info);
480
e7d1c40c 481 if (!params.no_multi_toc)
927be08e
AM
482 {
483 toc_section = bfd_get_section_by_name (link_info.output_bfd,
484 ".got");
485 if (toc_section != NULL)
486 lang_for_each_statement (build_toc_list);
487 }
488
489 if (ppc64_elf_layout_multitoc (&link_info)
e7d1c40c 490 && !params.no_multi_toc
927be08e 491 && toc_section != NULL)
0b9a4d73
AM
492 lang_for_each_statement (build_toc_list);
493
927be08e 494 ppc64_elf_finish_multitoc_partition (&link_info);
0b9a4d73 495
836c6af1 496 lang_for_each_statement (build_section_lists);
9c1d81c1 497
70cc837d
AM
498 if (!ppc64_elf_check_init_fini (&link_info))
499 einfo ("%P: .init/.fini fragments use differing TOC pointers\n");
500
836c6af1 501 /* Call into the BFD backend to do the real work. */
e7d1c40c 502 if (!ppc64_elf_size_stubs (&link_info))
92b7a70f 503 einfo ("%X%P: can not size stub section: %E\n");
1f808cd5 504 }
9c1d81c1 505 }
1f808cd5 506
8ded5a0f 507 if (need_laying_out != -1)
eaeb0a9d
AM
508 {
509 gld${EMULATION_NAME}_map_segments (need_laying_out);
510
511 if (!link_info.relocatable)
1c865ab2 512 ppc64_elf_set_toc (&link_info, link_info.output_bfd);
eaeb0a9d
AM
513 }
514}
515
516
517/* Final emulation specific call. */
518
519static void
520gld${EMULATION_NAME}_finish (void)
521{
522 /* e_entry on PowerPC64 points to the function descriptor for
523 _start. If _start is missing, default to the first function
524 descriptor in the .opd section. */
525 entry_section = ".opd";
deb04cdb 526
68f8ff14 527 if (stub_added)
9c1d81c1 528 {
bda6c678
AM
529 char *msg = NULL;
530 char *line, *endline;
531
e7d1c40c
AM
532 if (params.emit_stub_syms < 0)
533 params.emit_stub_syms = 1;
534 if (!ppc64_elf_build_stubs (&link_info, config.stats ? &msg : NULL))
9c1d81c1 535 einfo ("%X%P: can not build stubs: %E\n");
bda6c678 536
e922bcab 537 fflush (stdout);
bda6c678
AM
538 for (line = msg; line != NULL; line = endline)
539 {
540 endline = strchr (line, '\n');
541 if (endline != NULL)
542 *endline++ = '\0';
543 fprintf (stderr, "%s: %s\n", program_name, line);
544 }
e922bcab 545 fflush (stderr);
bda6c678
AM
546 if (msg != NULL)
547 free (msg);
9c1d81c1 548 }
99877b66
AM
549
550 ppc64_elf_restore_symbols (&link_info);
1e035701 551 finish_default ();
9c1d81c1 552}
1f808cd5 553
76dc39fe 554
fac1652d
AM
555/* Add a pattern matching ".foo" for every "foo" in a version script.
556
557 The reason for doing this is that many shared library version
558 scripts export a selected set of functions or data symbols, forcing
559 others local. eg.
560
561 . VERS_1 {
562 . global:
563 . this; that; some; thing;
564 . local:
565 . *;
566 . };
567
568 To make the above work for PowerPC64, we need to export ".this",
569 ".that" and so on, otherwise only the function descriptor syms are
570 exported. Lack of an exported function code sym may cause a
571 definition to be pulled in from a static library. */
572
7d8a3a28
AM
573static struct bfd_elf_version_expr *
574gld${EMULATION_NAME}_new_vers_pattern (struct bfd_elf_version_expr *entry)
fac1652d
AM
575{
576 struct bfd_elf_version_expr *dot_entry;
fac1652d
AM
577 unsigned int len;
578 char *dot_pat;
579
b7b7fe3f 580 if (!dotsyms
ae5a3597
AM
581 || entry->pattern[0] == '.'
582 || (!entry->literal && entry->pattern[0] == '*'))
fac1652d
AM
583 return entry;
584
7d8a3a28 585 dot_entry = xmalloc (sizeof *dot_entry);
108ba305 586 *dot_entry = *entry;
fac1652d 587 dot_entry->next = entry;
ae5a3597
AM
588 len = strlen (entry->pattern) + 2;
589 dot_pat = xmalloc (len);
590 dot_pat[0] = '.';
591 memcpy (dot_pat + 1, entry->pattern, len - 1);
592 dot_entry->pattern = dot_pat;
71755fdf 593 dot_entry->script = 1;
fac1652d
AM
594 return dot_entry;
595}
596
597
9c1d81c1
AM
598/* Avoid processing the fake stub_file in vercheck, stat_needed and
599 check_needed routines. */
1f808cd5 600
7d8a3a28 601static void (*real_func) (lang_input_statement_type *);
1f808cd5 602
7d8a3a28 603static void ppc_for_each_input_file_wrapper (lang_input_statement_type *l)
9c1d81c1
AM
604{
605 if (l != stub_file)
606 (*real_func) (l);
1f808cd5 607}
9c1d81c1
AM
608
609static void
7d8a3a28 610ppc_lang_for_each_input_file (void (*func) (lang_input_statement_type *))
9c1d81c1
AM
611{
612 real_func = func;
613 lang_for_each_input_file (&ppc_for_each_input_file_wrapper);
614}
615
616#define lang_for_each_input_file ppc_lang_for_each_input_file
617
1f808cd5
AM
618EOF
619
dc27aea4 620if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then
92b93329 621 fragment <<EOF
dc27aea4
AM
622/* Special handling for embedded SPU executables. */
623extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *);
624static bfd_boolean gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *);
625
626static bfd_boolean
627ppc64_recognized_file (lang_input_statement_type *entry)
628{
629 if (embedded_spu_file (entry, "-m64"))
630 return TRUE;
631
632 return gld${EMULATION_NAME}_load_symbols (entry);
633}
634EOF
635LDEMUL_RECOGNIZED_FILE=ppc64_recognized_file
636fi
637
9c1d81c1
AM
638# Define some shell vars to insert bits of code into the standard elf
639# parse_args and list_options functions.
640#
58d180e8
AM
641PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}'
642#define OPTION_STUBGROUP_SIZE 321
9df0ef5f
AM
643#define OPTION_PLT_STATIC_CHAIN (OPTION_STUBGROUP_SIZE + 1)
644#define OPTION_NO_PLT_STATIC_CHAIN (OPTION_PLT_STATIC_CHAIN + 1)
794e51c0
AM
645#define OPTION_PLT_THREAD_SAFE (OPTION_NO_PLT_STATIC_CHAIN + 1)
646#define OPTION_NO_PLT_THREAD_SAFE (OPTION_PLT_THREAD_SAFE + 1)
647#define OPTION_PLT_ALIGN (OPTION_NO_PLT_THREAD_SAFE + 1)
648#define OPTION_NO_PLT_ALIGN (OPTION_PLT_ALIGN + 1)
649#define OPTION_STUBSYMS (OPTION_NO_PLT_ALIGN + 1)
b02c4cfa 650#define OPTION_NO_STUBSYMS (OPTION_STUBSYMS + 1)
7d4c687d
AM
651#define OPTION_SAVRES (OPTION_NO_STUBSYMS + 1)
652#define OPTION_NO_SAVRES (OPTION_SAVRES + 1)
653#define OPTION_DOTSYMS (OPTION_NO_SAVRES + 1)
fac1652d 654#define OPTION_NO_DOTSYMS (OPTION_DOTSYMS + 1)
e5096e3f 655#define OPTION_NO_TLS_OPT (OPTION_NO_DOTSYMS + 1)
a7f2871e
AM
656#define OPTION_NO_TLS_GET_ADDR_OPT (OPTION_NO_TLS_OPT + 1)
657#define OPTION_NO_OPD_OPT (OPTION_NO_TLS_GET_ADDR_OPT + 1)
c5614fa4 658#define OPTION_NO_TOC_OPT (OPTION_NO_OPD_OPT + 1)
4c52953f 659#define OPTION_NO_MULTI_TOC (OPTION_NO_TOC_OPT + 1)
d43d0b53
AM
660#define OPTION_NO_TOC_SORT (OPTION_NO_MULTI_TOC + 1)
661#define OPTION_NON_OVERLAPPING_OPD (OPTION_NO_TOC_SORT + 1)
9c1d81c1
AM
662'
663
58d180e8 664PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
9c1d81c1 665 { "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
9df0ef5f
AM
666 { "plt-static-chain", no_argument, NULL, OPTION_PLT_STATIC_CHAIN },
667 { "no-plt-static-chain", no_argument, NULL, OPTION_NO_PLT_STATIC_CHAIN },
794e51c0
AM
668 { "plt-thread-safe", no_argument, NULL, OPTION_PLT_THREAD_SAFE },
669 { "no-plt-thread-safe", no_argument, NULL, OPTION_NO_PLT_THREAD_SAFE },
670 { "plt-align", optional_argument, NULL, OPTION_PLT_ALIGN },
671 { "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
0b9a4d73 672 { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
b02c4cfa 673 { "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
fac1652d
AM
674 { "dotsyms", no_argument, NULL, OPTION_DOTSYMS },
675 { "no-dotsyms", no_argument, NULL, OPTION_NO_DOTSYMS },
7d4c687d
AM
676 { "save-restore-funcs", no_argument, NULL, OPTION_SAVRES },
677 { "no-save-restore-funcs", no_argument, NULL, OPTION_NO_SAVRES },
e5096e3f 678 { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
a7f2871e 679 { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },
c5614fa4
AM
680 { "no-opd-optimize", no_argument, NULL, OPTION_NO_OPD_OPT },
681 { "no-toc-optimize", no_argument, NULL, OPTION_NO_TOC_OPT },
4c52953f 682 { "no-multi-toc", no_argument, NULL, OPTION_NO_MULTI_TOC },
d43d0b53 683 { "no-toc-sort", no_argument, NULL, OPTION_NO_TOC_SORT },
3f764659 684 { "non-overlapping-opd", no_argument, NULL, OPTION_NON_OVERLAPPING_OPD },
9c1d81c1
AM
685'
686
58d180e8 687PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
9c1d81c1 688 fprintf (file, _("\
442996ee
AM
689 --stub-group-size=N Maximum size of a group of input sections that\n\
690 can be handled by one stub section. A negative\n\
691 value locates all stubs before their branches\n\
692 (with a group size of -N), while a positive\n\
693 value allows two groups of input sections, one\n\
694 before, and one after each stub section.\n\
695 Values of +/-1 indicate the linker should\n\
696 choose suitable defaults.\n"
9c1d81c1 697 ));
fac1652d 698 fprintf (file, _("\
794e51c0
AM
699 --plt-static-chain PLT call stubs should load r11.${DEFAULT_PLT_STATIC_CHAIN- (default)}\n"
700 ));
701 fprintf (file, _("\
702 --no-plt-static-chain PLT call stubs should not load r11.${DEFAULT_PLT_STATIC_CHAIN+ (default)}\n"
703 ));
704 fprintf (file, _("\
705 --plt-thread-safe PLT call stubs with load-load barrier.\n"
706 ));
707 fprintf (file, _("\
708 --no-plt-thread-safe PLT call stubs without barrier.\n"
709 ));
710 fprintf (file, _("\
711 --plt-align [=<align>] Align PLT call stubs to fit cache lines.\n"
9df0ef5f
AM
712 ));
713 fprintf (file, _("\
794e51c0 714 --no-plt-align Dont'\''t align individual PLT call stubs.\n"
9df0ef5f
AM
715 ));
716 fprintf (file, _("\
442996ee 717 --emit-stub-syms Label linker stubs with a symbol.\n"
0b9a4d73
AM
718 ));
719 fprintf (file, _("\
b02c4cfa
AM
720 --no-emit-stub-syms Don'\''t label linker stubs with a symbol.\n"
721 ));
722 fprintf (file, _("\
442996ee
AM
723 --dotsyms For every version pattern \"foo\" in a version\n\
724 script, add \".foo\" so that function code\n\
725 symbols are treated the same as function\n\
726 descriptor symbols. Defaults to on.\n"
fac1652d
AM
727 ));
728 fprintf (file, _("\
442996ee 729 --no-dotsyms Don'\''t do anything special in version scripts.\n"
fac1652d 730 ));
e5096e3f 731 fprintf (file, _("\
7d4c687d
AM
732 --save-restore-funcs Provide register save and restore routines used\n\
733 by gcc -Os code. Defaults to on for normal\n\
734 final link, off for ld -r.\n"
735 ));
736 fprintf (file, _("\
737 --no-save-restore-funcs Don'\''t provide these routines.\n"
738 ));
739 fprintf (file, _("\
442996ee 740 --no-tls-optimize Don'\''t try to optimize TLS accesses.\n"
e5096e3f 741 ));
3f764659 742 fprintf (file, _("\
a7f2871e
AM
743 --no-tls-get-addr-optimize Don'\''t use a special __tls_get_addr call.\n"
744 ));
745 fprintf (file, _("\
442996ee 746 --no-opd-optimize Don'\''t optimize the OPD section.\n"
c5614fa4
AM
747 ));
748 fprintf (file, _("\
442996ee 749 --no-toc-optimize Don'\''t optimize the TOC section.\n"
c5614fa4
AM
750 ));
751 fprintf (file, _("\
442996ee 752 --no-multi-toc Disallow automatic multiple toc sections.\n"
4c52953f
AM
753 ));
754 fprintf (file, _("\
d43d0b53
AM
755 --no-toc-sort Don'\''t sort TOC and GOT sections.\n"
756 ));
757 fprintf (file, _("\
442996ee
AM
758 --non-overlapping-opd Canonicalize .opd, so that there are no\n\
759 overlapping .opd entries.\n"
3f764659 760 ));
9c1d81c1
AM
761'
762
58d180e8 763PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
9c1d81c1
AM
764 case OPTION_STUBGROUP_SIZE:
765 {
766 const char *end;
e7d1c40c 767 params.group_size = bfd_scan_vma (optarg, &end, 0);
9c1d81c1
AM
768 if (*end)
769 einfo (_("%P%F: invalid number `%s'\''\n"), optarg);
770 }
771 break;
fac1652d 772
9df0ef5f 773 case OPTION_PLT_STATIC_CHAIN:
e7d1c40c 774 params.plt_static_chain = 1;
9df0ef5f
AM
775 break;
776
777 case OPTION_NO_PLT_STATIC_CHAIN:
e7d1c40c 778 params.plt_static_chain = 0;
9df0ef5f
AM
779 break;
780
794e51c0 781 case OPTION_PLT_THREAD_SAFE:
e7d1c40c 782 params.plt_thread_safe = 1;
794e51c0
AM
783 break;
784
785 case OPTION_NO_PLT_THREAD_SAFE:
e7d1c40c 786 params.plt_thread_safe = 0;
794e51c0
AM
787 break;
788
789 case OPTION_PLT_ALIGN:
790 if (optarg != NULL)
791 {
792 char *end;
793 unsigned long val = strtoul (optarg, &end, 0);
794 if (*end || val > 8)
795 einfo (_("%P%F: invalid --plt-align `%s'\''\n"), optarg);
796 plt_stub_align = val;
797 }
798 else
799 plt_stub_align = 5;
800 break;
801
802 case OPTION_NO_PLT_ALIGN:
803 plt_stub_align = 0;
804 break;
805
0b9a4d73 806 case OPTION_STUBSYMS:
e7d1c40c 807 params.emit_stub_syms = 1;
0b9a4d73
AM
808 break;
809
b02c4cfa 810 case OPTION_NO_STUBSYMS:
e7d1c40c 811 params.emit_stub_syms = 0;
b02c4cfa
AM
812 break;
813
fac1652d 814 case OPTION_DOTSYMS:
e5096e3f 815 dotsyms = 1;
fac1652d
AM
816 break;
817
818 case OPTION_NO_DOTSYMS:
e5096e3f
AM
819 dotsyms = 0;
820 break;
821
7d4c687d
AM
822 case OPTION_SAVRES:
823 params.save_restore_funcs = 1;
824 break;
825
826 case OPTION_NO_SAVRES:
827 params.save_restore_funcs = 0;
828 break;
829
e5096e3f 830 case OPTION_NO_TLS_OPT:
c5614fa4
AM
831 no_tls_opt = 1;
832 break;
833
a7f2871e 834 case OPTION_NO_TLS_GET_ADDR_OPT:
e7d1c40c 835 params.no_tls_get_addr_opt = 1;
a7f2871e
AM
836 break;
837
c5614fa4
AM
838 case OPTION_NO_OPD_OPT:
839 no_opd_opt = 1;
840 break;
841
842 case OPTION_NO_TOC_OPT:
843 no_toc_opt = 1;
fac1652d 844 break;
3f764659 845
4c52953f 846 case OPTION_NO_MULTI_TOC:
e7d1c40c 847 params.no_multi_toc = 1;
4c52953f
AM
848 break;
849
d43d0b53
AM
850 case OPTION_NO_TOC_SORT:
851 no_toc_sort = 1;
852 break;
853
3f764659 854 case OPTION_NON_OVERLAPPING_OPD:
e7d1c40c 855 params.non_overlapping_opd = 1;
3f764659 856 break;
f05eb3b7
AM
857
858 case OPTION_TRADITIONAL_FORMAT:
859 no_tls_opt = 1;
e7d1c40c 860 params.no_tls_get_addr_opt = 1;
f05eb3b7
AM
861 no_opd_opt = 1;
862 no_toc_opt = 1;
e7d1c40c 863 params.no_multi_toc = 1;
f05eb3b7 864 no_toc_sort = 1;
e7d1c40c 865 params.plt_static_chain = 1;
f05eb3b7 866 return FALSE;
9c1d81c1
AM
867'
868
1f808cd5
AM
869# Put these extra ppc64elf routines in ld_${EMULATION_NAME}_emulation
870#
836c6af1 871LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
1f808cd5 872LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
8ded5a0f 873LDEMUL_FINISH=gld${EMULATION_NAME}_finish
9c1d81c1 874LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_create_output_section_statements
fac1652d 875LDEMUL_NEW_VERS_PATTERN=gld${EMULATION_NAME}_new_vers_pattern
This page took 0.537266 seconds and 4 git commands to generate.