Fix PR ld/24574
[external/binutils.git] / ld / emultempl / ppc32elf.em
1 # This shell script emits a C file. -*- C -*-
2 #   Copyright (C) 2003-2019 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 elf32.em, and defines extra powerpc32-elf
23 # specific routines.
24 #
25 fragment <<EOF
26
27 #include "elf32-ppc.h"
28 #include "ldlex.h"
29 #include "ldlang.h"
30
31 #define is_ppc_elf(bfd) \
32   (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
33    && elf_object_id (bfd) == PPC32_ELF_DATA)
34
35 /* Whether to run tls optimization.  */
36 static int notlsopt = 0;
37
38 /* Whether to convert inline PLT calls to direct.  */
39 static int no_inline_opt = 0;
40
41 /* Choose the correct place for .got.  */
42 static int old_got = 0;
43
44 static struct ppc_elf_params params = { PLT_UNSET, 0, -1,
45                                         0, 0, 0, 0, 0, 0, 0 };
46
47 static void
48 ppc_after_open_output (void)
49 {
50   if (params.emit_stub_syms < 0)
51     params.emit_stub_syms = (link_info.emitrelocations
52                              || bfd_link_pic (&link_info));
53   if (params.pagesize == 0)
54     params.pagesize = config.commonpagesize;
55   ppc_elf_link_params (&link_info, &params);
56 }
57
58 EOF
59
60 # No --secure-plt, --bss-plt, or --sdata-got for vxworks.
61 if test -z "$VXWORKS_BASE_EM_FILE" ; then
62   fragment <<EOF
63 static void
64 ppc_after_check_relocs (void)
65 {
66   if (is_ppc_elf (link_info.output_bfd))
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
76       new_plt = ppc_elf_select_plt_layout (link_info.output_bfd, &link_info);
77       if (new_plt < 0)
78         einfo (_("%X%P: select_plt_layout problem %E\n"));
79
80       num_got = 0;
81       num_plt = 0;
82       for (os = &lang_os_list.head->output_section_statement;
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
115   after_check_relocs_default ();
116 }
117
118 EOF
119 fi
120 fragment <<EOF
121 static void
122 prelim_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
134 static void
135 ppc_before_allocation (void)
136 {
137   if (is_ppc_elf (link_info.output_bfd))
138     {
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
148       if (ppc_elf_tls_setup (link_info.output_bfd, &link_info)
149           && !notlsopt)
150         {
151           if (!ppc_elf_tls_optimize (link_info.output_bfd, &link_info))
152             {
153               einfo (_("%X%P: TLS problem %E\n"));
154               return;
155             }
156         }
157     }
158
159   gld${EMULATION_NAME}_before_allocation ();
160
161   ppc_elf_maybe_strip_sdata_syms (&link_info);
162
163   if (RELAXATION_ENABLED)
164     params.branch_trampolines = 1;
165
166   /* Turn on relaxation if executable sections have addresses that
167      might make branches overflow.  */
168   else if (!RELAXATION_DISABLED_BY_USER)
169     {
170       bfd_vma low = (bfd_vma) -1;
171       bfd_vma high = 0;
172       asection *o;
173
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;
180       prelim_size_sections ();
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;
186           if (o->rawsize == 0)
187             continue;
188           if (low > o->vma)
189             low = o->vma;
190           if (high < o->vma + o->rawsize - 1)
191             high = o->vma + o->rawsize - 1;
192         }
193       if (high > low && high - low > (1 << 25) - 1)
194         params.branch_trampolines = 1;
195     }
196
197   if (params.branch_trampolines
198       || params.ppc476_workaround
199       || params.pic_fixup > 0)
200     ENABLE_RELAXATION;
201 }
202
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
210 static void
211 no_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
234 static void
235 ppc_finish (void)
236 {
237   if (params.ppc476_workaround)
238     lang_for_each_statement (no_zero_padding);
239   if (!ppc_finish_symbols (&link_info))
240     einfo (_("%X%P: ppc_finish_symbols problem %E\n"));
241   finish_default ();
242 }
243
244 EOF
245
246 if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then
247   fragment <<EOF
248 /* Special handling for embedded SPU executables.  */
249 extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *);
250 static bfd_boolean gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *);
251
252 static bfd_boolean
253 ppc_recognized_file (lang_input_statement_type *entry)
254 {
255   if (embedded_spu_file (entry, "-m32"))
256     return TRUE;
257
258   return gld${EMULATION_NAME}_load_symbols (entry);
259 }
260
261 EOF
262 LDEMUL_RECOGNIZED_FILE=ppc_recognized_file
263 fi
264
265 # Define some shell vars to insert bits of code into the standard elf
266 # parse_args and list_options functions.
267 #
268 PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}'
269 enum ppc32_opt
270 {
271   OPTION_NO_TLS_OPT = 321,
272   OPTION_NO_TLS_GET_ADDR_OPT,
273   OPTION_NEW_PLT,
274   OPTION_OLD_PLT,
275   OPTION_PLT_ALIGN,
276   OPTION_NO_PLT_ALIGN,
277   OPTION_NO_INLINE_OPT,
278   OPTION_OLD_GOT,
279   OPTION_STUBSYMS,
280   OPTION_NO_STUBSYMS,
281   OPTION_PPC476_WORKAROUND,
282   OPTION_NO_PPC476_WORKAROUND,
283   OPTION_NO_PICFIXUP,
284   OPTION_VLE_RELOC_FIXUP
285 };
286 '
287
288 PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
289   { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
290   { "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
291   { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
292   { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },'
293 if test -z "$VXWORKS_BASE_EM_FILE" ; then
294   PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
295   { "secure-plt", no_argument, NULL, OPTION_NEW_PLT },
296   { "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
297   { "plt-align", optional_argument, NULL, OPTION_PLT_ALIGN },
298   { "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
299   { "no-inline-optimize", no_argument, NULL, OPTION_NO_INLINE_OPT },
300   { "sdata-got", no_argument, NULL, OPTION_OLD_GOT },'
301 fi
302 PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
303   { "ppc476-workaround", optional_argument, NULL, OPTION_PPC476_WORKAROUND },
304   { "no-ppc476-workaround", no_argument, NULL, OPTION_NO_PPC476_WORKAROUND },
305   { "no-pic-fixup", no_argument, NULL, OPTION_NO_PICFIXUP },
306   { "vle-reloc-fixup", no_argument, NULL, OPTION_VLE_RELOC_FIXUP },
307 '
308
309 PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
310   fprintf (file, _("\
311   --emit-stub-syms            Label linker stubs with a symbol\n"
312                    ));
313   fprintf (file, _("\
314   --no-emit-stub-syms         Don'\''t label linker stubs with a symbol\n"
315                    ));
316   fprintf (file, _("\
317   --no-tls-optimize           Don'\''t try to optimize TLS accesses\n"
318                    ));
319   fprintf (file, _("\
320   --no-tls-get-addr-optimize  Don'\''t use a special __tls_get_addr call\n"
321                    ));'
322 if test -z "$VXWORKS_BASE_EM_FILE" ; then
323   PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\
324   fprintf (file, _("\
325   --secure-plt                Use new-style PLT if possible\n"
326                    ));
327   fprintf (file, _("\
328   --bss-plt                   Force old-style BSS PLT\n"
329                    ));
330   fprintf (file, _("\
331   --plt-align                 Align PLT call stubs to fit cache lines\n"
332                    ));
333   fprintf (file, _("\
334   --no-plt-align              Dont'\''t align individual PLT call stubs\n"
335                    ));
336   fprintf (file, _("\
337   --no-inline-optimize        Don'\''t convert inline PLT to direct calls\n"
338                    ));
339   fprintf (file, _("\
340   --sdata-got                 Force GOT location just before .sdata\n"
341                    ));'
342 fi
343 PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\
344   fprintf (file, _("\
345   --ppc476-workaround [=pagesize]\n\
346                               Avoid a cache bug on ppc476\n"
347                    ));
348   fprintf (file, _("\
349   --no-ppc476-workaround      Disable workaround\n"
350                    ));
351   fprintf (file, _("\
352   --no-pic-fixup              Don'\''t edit non-pic to pic\n"
353                    ));
354   fprintf (file, _("\
355   --vle-reloc-fixup           Correct old object file 16A/16D relocation\n"
356                    ));
357 '
358
359 PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
360     case OPTION_STUBSYMS:
361       params.emit_stub_syms = 1;
362       break;
363
364     case OPTION_NO_STUBSYMS:
365       params.emit_stub_syms = 0;
366       break;
367
368     case OPTION_NO_TLS_OPT:
369       notlsopt = 1;
370       break;
371
372     case OPTION_NO_TLS_GET_ADDR_OPT:
373       params.no_tls_get_addr_opt = 1;
374       break;
375
376     case OPTION_NEW_PLT:
377       params.plt_style = PLT_NEW;
378       break;
379
380     case OPTION_OLD_PLT:
381       params.plt_style = PLT_OLD;
382       break;
383
384     case OPTION_PLT_ALIGN:
385       if (optarg != NULL)
386         {
387           char *end;
388           unsigned long val = strtoul (optarg, &end, 0);
389           if (*end || val > 5)
390             einfo (_("%F%P: invalid --plt-align `%s'\''\n"), optarg);
391           params.plt_stub_align = val;
392         }
393       else
394         params.plt_stub_align = 5;
395       break;
396
397     case OPTION_NO_PLT_ALIGN:
398       params.plt_stub_align = 0;
399       break;
400
401     case OPTION_NO_INLINE_OPT:
402       no_inline_opt = 1;
403       break;
404
405     case OPTION_OLD_GOT:
406       old_got = 1;
407       break;
408
409     case OPTION_TRADITIONAL_FORMAT:
410       notlsopt = 1;
411       params.no_tls_get_addr_opt = 1;
412       return FALSE;
413
414     case OPTION_PPC476_WORKAROUND:
415       params.ppc476_workaround = 1;
416       if (optarg != NULL)
417         {
418           char *end;
419           params.pagesize = strtoul (optarg, &end, 0);
420           if (*end
421               || (params.pagesize < 4096 && params.pagesize != 0)
422               || params.pagesize != (params.pagesize & -params.pagesize))
423             einfo (_("%F%P: invalid pagesize `%s'\''\n"), optarg);
424         }
425       break;
426
427     case OPTION_NO_PPC476_WORKAROUND:
428       params.ppc476_workaround = 0;
429       break;
430
431     case OPTION_NO_PICFIXUP:
432       params.pic_fixup = -1;
433       break;
434
435     case OPTION_VLE_RELOC_FIXUP:
436       params.vle_reloc_fixup = 1;
437       break;
438 '
439
440 # Put these extra ppc32elf routines in ld_${EMULATION_NAME}_emulation
441 #
442 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_after_open_output
443 if test -z "$VXWORKS_BASE_EM_FILE" ; then
444   LDEMUL_AFTER_CHECK_RELOCS=ppc_after_check_relocs
445 fi
446 LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
447 LDEMUL_FINISH=ppc_finish