]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - ld/emultempl/ppc32elf.em
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / ld / emultempl / ppc32elf.em
CommitLineData
f9e6bfa8 1# This shell script emits a C file. -*- C -*-
250d07de 2# Copyright (C) 2003-2021 Free Software Foundation, Inc.
f9e6bfa8 3#
f96b4a7b 4# This file is part of the GNU Binutils.
f9e6bfa8
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
f9e6bfa8
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.
f9e6bfa8
AM
20#
21
075a2b89 22# This file is sourced from elf.em, and defines extra powerpc32-elf
f9e6bfa8
AM
23# specific routines.
24#
92b93329 25fragment <<EOF
f9e6bfa8 26
f9e6bfa8 27#include "elf32-ppc.h"
f05eb3b7 28#include "ldlex.h"
b4ab4364 29#include "ldlang.h"
f9e6bfa8 30
5503fea1
AM
31#define is_ppc_elf(bfd) \
32 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
4dfe6ac6 33 && elf_object_id (bfd) == PPC32_ELF_DATA)
c9a2f333 34
f9e6bfa8
AM
35/* Whether to run tls optimization. */
36static int notlsopt = 0;
37
3e04d765
AM
38/* Whether to convert inline PLT calls to direct. */
39static int no_inline_opt = 0;
40
5446cbdf 41/* Choose the correct place for .got. */
0cf7d72c
AM
42static int old_got = 0;
43
407aa07c 44static struct ppc_elf_params params = { PLT_UNSET, 0, -1,
9e390558 45 0, 0, 0, 0, 0, 0, 0 };
5446cbdf
AM
46
47static void
48ppc_after_open_output (void)
49{
50 if (params.emit_stub_syms < 0)
0e1862bb
L
51 params.emit_stub_syms = (link_info.emitrelocations
52 || bfd_link_pic (&link_info));
76e7a751 53 if (params.pagesize == 0)
c410035d 54 params.pagesize = link_info.commonpagesize;
5446cbdf
AM
55 ppc_elf_link_params (&link_info, &params);
56}
57
db434ba0
AM
58EOF
59
60# No --secure-plt, --bss-plt, or --sdata-got for vxworks.
61if test -z "$VXWORKS_BASE_EM_FILE" ; then
62 fragment <<EOF
0cf7d72c 63static void
5c3261b0 64ppc_after_check_relocs (void)
0cf7d72c 65{
5503fea1 66 if (is_ppc_elf (link_info.output_bfd))
0cf7d72c
AM
67 {
68 int new_plt;
69 int keep_new;
70 unsigned int num_plt;
71 unsigned int num_got;
72 lang_output_section_statement_type *os;
73 lang_output_section_statement_type *plt_os[2];
74 lang_output_section_statement_type *got_os[2];
75
5446cbdf 76 new_plt = ppc_elf_select_plt_layout (link_info.output_bfd, &link_info);
0cf7d72c 77 if (new_plt < 0)
d003af55 78 einfo (_("%X%P: select_plt_layout problem %E\n"));
0cf7d72c
AM
79
80 num_got = 0;
81 num_plt = 0;
8ce18f9c 82 for (os = (void *) lang_os_list.head;
0cf7d72c
AM
83 os != NULL;
84 os = os->next)
85 {
86 if (os->constraint == SPECIAL && strcmp (os->name, ".plt") == 0)
87 {
88 if (num_plt < 2)
89 plt_os[num_plt] = os;
90 ++num_plt;
91 }
92 if (os->constraint == SPECIAL && strcmp (os->name, ".got") == 0)
93 {
94 if (num_got < 2)
95 got_os[num_got] = os;
96 ++num_got;
97 }
98 }
99
100 keep_new = new_plt == 1 ? 0 : -1;
101 if (num_plt == 2)
102 {
103 plt_os[0]->constraint = keep_new;
104 plt_os[1]->constraint = ~keep_new;
105 }
106 if (num_got == 2)
107 {
108 if (old_got)
109 keep_new = -1;
110 got_os[0]->constraint = keep_new;
111 got_os[1]->constraint = ~keep_new;
112 }
113 }
114
5c3261b0 115 after_check_relocs_default ();
0cf7d72c
AM
116}
117
db434ba0
AM
118EOF
119fi
120fragment <<EOF
3e04d765
AM
121static void
122prelim_size_sections (void)
123{
124 if (expld.phase != lang_mark_phase_enum)
125 {
126 expld.phase = lang_mark_phase_enum;
127 expld.dataseg.phase = exp_seg_none;
128 one_lang_size_sections_pass (NULL, FALSE);
129 /* We must not cache anything from the preliminary sizing. */
130 lang_reset_memory_regions ();
131 }
132}
133
f9e6bfa8 134static void
7e5d8d48 135ppc_before_allocation (void)
f9e6bfa8 136{
5503fea1 137 if (is_ppc_elf (link_info.output_bfd))
f9e6bfa8 138 {
3e04d765
AM
139 if (!no_inline_opt
140 && !bfd_link_relocatable (&link_info))
141 {
142 prelim_size_sections ();
143
144 if (!ppc_elf_inline_plt (&link_info))
145 einfo (_("%X%P: inline PLT: %E\n"));
146 }
147
5446cbdf 148 if (ppc_elf_tls_setup (link_info.output_bfd, &link_info)
a7f2871e 149 && !notlsopt)
f9e6bfa8 150 {
f13a99db 151 if (!ppc_elf_tls_optimize (link_info.output_bfd, &link_info))
f9e6bfa8 152 {
d003af55 153 einfo (_("%X%P: TLS problem %E\n"));
f9e6bfa8
AM
154 return;
155 }
156 }
157 }
4135c73b 158
f9e6bfa8 159 gld${EMULATION_NAME}_before_allocation ();
4135c73b 160
93d1b056
AM
161 ppc_elf_maybe_strip_sdata_syms (&link_info);
162
5446cbdf
AM
163 if (RELAXATION_ENABLED)
164 params.branch_trampolines = 1;
165
4135c73b
AM
166 /* Turn on relaxation if executable sections have addresses that
167 might make branches overflow. */
5446cbdf 168 else if (!RELAXATION_DISABLED_BY_USER)
4135c73b
AM
169 {
170 bfd_vma low = (bfd_vma) -1;
171 bfd_vma high = 0;
172 asection *o;
173
7df6aecc
AM
174 /* Run lang_size_sections even if already done, so as to pick
175 up gld${EMULATION_NAME}_before_allocation sizing. This
176 matters when we have an executable bss plt which will
177 typically be laid out near the end of the image, ie. worst
178 case for branches at the start of .text. */
179 expld.phase = lang_first_phase_enum;
3e04d765 180 prelim_size_sections ();
4135c73b
AM
181
182 for (o = link_info.output_bfd->sections; o != NULL; o = o->next)
183 {
184 if ((o->flags & (SEC_ALLOC | SEC_CODE)) != (SEC_ALLOC | SEC_CODE))
185 continue;
07088e95 186 if (o->rawsize == 0)
4135c73b
AM
187 continue;
188 if (low > o->vma)
189 low = o->vma;
07088e95
AM
190 if (high < o->vma + o->rawsize - 1)
191 high = o->vma + o->rawsize - 1;
4135c73b
AM
192 }
193 if (high > low && high - low > (1 << 25) - 1)
5446cbdf 194 params.branch_trampolines = 1;
4135c73b 195 }
5446cbdf 196
d3e454b9
AM
197 if (params.branch_trampolines
198 || params.ppc476_workaround
199 || params.pic_fixup > 0)
5446cbdf 200 ENABLE_RELAXATION;
f9e6bfa8
AM
201}
202
b4ab4364
AM
203/* Replaces default zero fill padding in executable sections with
204 "ba 0" instructions. This works around the ppc476 icache bug if we
205 have a function pointer tail call near the end of a page, some
206 small amount of padding, then the function called at the beginning
207 of the next page. If the "ba 0" is ever executed we should hit a
208 segv, so it's almost as good as an illegal instruction (zero). */
209
210static void
211no_zero_padding (lang_statement_union_type *l)
212{
213 if (l->header.type == lang_padding_statement_enum
214 && l->padding_statement.size != 0
215 && l->padding_statement.output_section != NULL
216 && (l->padding_statement.output_section->flags & SEC_CODE) != 0
217 && l->padding_statement.fill->size == 0)
218 {
219 struct _ppc_fill_type
220 {
221 size_t size;
222 unsigned char data[4];
223 };
224 static struct _ppc_fill_type fill_be = { 4, {0x48, 0, 0, 2} };
225 static struct _ppc_fill_type fill_le = { 4, {2, 0, 0, 0x48} };
226
227 if (bfd_big_endian (link_info.output_bfd))
228 l->padding_statement.fill = (struct _fill_type *) &fill_be;
229 else
230 l->padding_statement.fill = (struct _fill_type *) &fill_le;
231 }
232}
233
234static void
235ppc_finish (void)
236{
237 if (params.ppc476_workaround)
238 lang_for_each_statement (no_zero_padding);
49c09209
AM
239 if (!ppc_finish_symbols (&link_info))
240 einfo (_("%X%P: ppc_finish_symbols problem %E\n"));
b4ab4364
AM
241 finish_default ();
242}
243
f9e6bfa8
AM
244EOF
245
dc27aea4 246if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then
92b93329 247 fragment <<EOF
dc27aea4
AM
248/* Special handling for embedded SPU executables. */
249extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *);
dc27aea4
AM
250
251static bfd_boolean
252ppc_recognized_file (lang_input_statement_type *entry)
253{
254 if (embedded_spu_file (entry, "-m32"))
255 return TRUE;
256
d871d478 257 return ldelf_load_symbols (entry);
dc27aea4
AM
258}
259
260EOF
261LDEMUL_RECOGNIZED_FILE=ppc_recognized_file
262fi
263
f9e6bfa8
AM
264# Define some shell vars to insert bits of code into the standard elf
265# parse_args and list_options functions.
266#
58d180e8 267PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}'
9e390558
AM
268enum ppc32_opt
269{
270 OPTION_NO_TLS_OPT = 321,
271 OPTION_NO_TLS_GET_ADDR_OPT,
272 OPTION_NEW_PLT,
273 OPTION_OLD_PLT,
274 OPTION_PLT_ALIGN,
275 OPTION_NO_PLT_ALIGN,
3e04d765 276 OPTION_NO_INLINE_OPT,
9e390558
AM
277 OPTION_OLD_GOT,
278 OPTION_STUBSYMS,
279 OPTION_NO_STUBSYMS,
280 OPTION_PPC476_WORKAROUND,
281 OPTION_NO_PPC476_WORKAROUND,
282 OPTION_NO_PICFIXUP,
283 OPTION_VLE_RELOC_FIXUP
284};
f9e6bfa8
AM
285'
286
58d180e8 287PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
0ba07910 288 { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
b02c4cfa 289 { "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
f9e6bfa8 290 { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
db434ba0
AM
291 { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },'
292if test -z "$VXWORKS_BASE_EM_FILE" ; then
293 PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
016687f8 294 { "secure-plt", no_argument, NULL, OPTION_NEW_PLT },
0cf7d72c 295 { "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
691d2e9a 296 { "plt-align", optional_argument, NULL, OPTION_PLT_ALIGN },
9e390558 297 { "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
3e04d765 298 { "no-inline-optimize", no_argument, NULL, OPTION_NO_INLINE_OPT },
db434ba0
AM
299 { "sdata-got", no_argument, NULL, OPTION_OLD_GOT },'
300fi
301PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
5446cbdf
AM
302 { "ppc476-workaround", optional_argument, NULL, OPTION_PPC476_WORKAROUND },
303 { "no-ppc476-workaround", no_argument, NULL, OPTION_NO_PPC476_WORKAROUND },
d3e454b9 304 { "no-pic-fixup", no_argument, NULL, OPTION_NO_PICFIXUP },
08dc996f 305 { "vle-reloc-fixup", no_argument, NULL, OPTION_VLE_RELOC_FIXUP },
f9e6bfa8
AM
306'
307
58d180e8 308PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
f9e6bfa8 309 fprintf (file, _("\
df5f2391 310 --emit-stub-syms Label linker stubs with a symbol\n"
9e390558
AM
311 ));
312 fprintf (file, _("\
df5f2391 313 --no-emit-stub-syms Don'\''t label linker stubs with a symbol\n"
9e390558
AM
314 ));
315 fprintf (file, _("\
df5f2391 316 --no-tls-optimize Don'\''t try to optimize TLS accesses\n"
9e390558
AM
317 ));
318 fprintf (file, _("\
df5f2391 319 --no-tls-get-addr-optimize Don'\''t use a special __tls_get_addr call\n"
9e390558 320 ));'
db434ba0
AM
321if test -z "$VXWORKS_BASE_EM_FILE" ; then
322 PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\
9e390558 323 fprintf (file, _("\
df5f2391 324 --secure-plt Use new-style PLT if possible\n"
9e390558
AM
325 ));
326 fprintf (file, _("\
df5f2391 327 --bss-plt Force old-style BSS PLT\n"
9e390558
AM
328 ));
329 fprintf (file, _("\
df5f2391 330 --plt-align Align PLT call stubs to fit cache lines\n"
9e390558
AM
331 ));
332 fprintf (file, _("\
df5f2391 333 --no-plt-align Dont'\''t align individual PLT call stubs\n"
9e390558
AM
334 ));
335 fprintf (file, _("\
3e04d765
AM
336 --no-inline-optimize Don'\''t convert inline PLT to direct calls\n"
337 ));
338 fprintf (file, _("\
df5f2391 339 --sdata-got Force GOT location just before .sdata\n"
9e390558 340 ));'
db434ba0
AM
341fi
342PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\
9e390558 343 fprintf (file, _("\
5446cbdf 344 --ppc476-workaround [=pagesize]\n\
df5f2391 345 Avoid a cache bug on ppc476\n"
9e390558
AM
346 ));
347 fprintf (file, _("\
df5f2391 348 --no-ppc476-workaround Disable workaround\n"
9e390558
AM
349 ));
350 fprintf (file, _("\
df5f2391 351 --no-pic-fixup Don'\''t edit non-pic to pic\n"
9e390558
AM
352 ));
353 fprintf (file, _("\
df5f2391 354 --vle-reloc-fixup Correct old object file 16A/16D relocation\n"
f9e6bfa8
AM
355 ));
356'
357
58d180e8 358PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
0ba07910 359 case OPTION_STUBSYMS:
5446cbdf 360 params.emit_stub_syms = 1;
0ba07910
AM
361 break;
362
b02c4cfa 363 case OPTION_NO_STUBSYMS:
5446cbdf 364 params.emit_stub_syms = 0;
b02c4cfa
AM
365 break;
366
f9e6bfa8
AM
367 case OPTION_NO_TLS_OPT:
368 notlsopt = 1;
369 break;
0cf7d72c 370
a7f2871e 371 case OPTION_NO_TLS_GET_ADDR_OPT:
5446cbdf 372 params.no_tls_get_addr_opt = 1;
a7f2871e
AM
373 break;
374
016687f8 375 case OPTION_NEW_PLT:
5446cbdf 376 params.plt_style = PLT_NEW;
016687f8
AM
377 break;
378
0cf7d72c 379 case OPTION_OLD_PLT:
5446cbdf 380 params.plt_style = PLT_OLD;
0cf7d72c
AM
381 break;
382
9e390558 383 case OPTION_PLT_ALIGN:
691d2e9a
AM
384 if (optarg != NULL)
385 {
386 char *end;
387 unsigned long val = strtoul (optarg, &end, 0);
388 if (*end || val > 5)
df5f2391 389 einfo (_("%F%P: invalid --plt-align `%s'\''\n"), optarg);
691d2e9a
AM
390 params.plt_stub_align = val;
391 }
392 else
393 params.plt_stub_align = 5;
9e390558
AM
394 break;
395
396 case OPTION_NO_PLT_ALIGN:
397 params.plt_stub_align = 0;
398 break;
399
3e04d765
AM
400 case OPTION_NO_INLINE_OPT:
401 no_inline_opt = 1;
402 break;
403
0cf7d72c
AM
404 case OPTION_OLD_GOT:
405 old_got = 1;
406 break;
f05eb3b7
AM
407
408 case OPTION_TRADITIONAL_FORMAT:
409 notlsopt = 1;
5446cbdf 410 params.no_tls_get_addr_opt = 1;
f05eb3b7 411 return FALSE;
5446cbdf
AM
412
413 case OPTION_PPC476_WORKAROUND:
414 params.ppc476_workaround = 1;
415 if (optarg != NULL)
416 {
417 char *end;
76e7a751 418 params.pagesize = strtoul (optarg, &end, 0);
5446cbdf 419 if (*end
76e7a751
AM
420 || (params.pagesize < 4096 && params.pagesize != 0)
421 || params.pagesize != (params.pagesize & -params.pagesize))
df5f2391 422 einfo (_("%F%P: invalid pagesize `%s'\''\n"), optarg);
5446cbdf
AM
423 }
424 break;
425
426 case OPTION_NO_PPC476_WORKAROUND:
427 params.ppc476_workaround = 0;
428 break;
d3e454b9
AM
429
430 case OPTION_NO_PICFIXUP:
431 params.pic_fixup = -1;
432 break;
08dc996f
AM
433
434 case OPTION_VLE_RELOC_FIXUP:
435 params.vle_reloc_fixup = 1;
436 break;
f9e6bfa8
AM
437'
438
c9a2f333 439# Put these extra ppc32elf routines in ld_${EMULATION_NAME}_emulation
f9e6bfa8 440#
5446cbdf 441LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_after_open_output
db434ba0 442if test -z "$VXWORKS_BASE_EM_FILE" ; then
5c3261b0 443 LDEMUL_AFTER_CHECK_RELOCS=ppc_after_check_relocs
db434ba0 444fi
f9e6bfa8 445LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
b4ab4364 446LDEMUL_FINISH=ppc_finish