Implement tp_richcompare for gdb.Block
[binutils-gdb.git] / ld / emultempl / ppc32elf.em
blob12476f44fcf0c4e1e5ed9658deb2071a01f234b5
1 # This shell script emits a C file. -*- C -*-
2 #   Copyright (C) 2003-2024 Free Software Foundation, Inc.
4 # This file is part of the GNU Binutils.
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.
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.
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.
22 # This file is sourced from elf.em, and defines extra powerpc32-elf
23 # specific routines.
25 fragment <<EOF
27 #include "elf32-ppc.h"
28 #include "ldlex.h"
29 #include "ldlang.h"
31 #define is_ppc_elf(bfd) \
32   (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
33    && elf_object_id (bfd) == PPC32_ELF_DATA)
35 /* Whether to run tls optimization.  */
36 static int notlsopt = 0;
38 /* Whether to convert inline PLT calls to direct.  */
39 static int no_inline_opt = 0;
41 /* Choose the correct place for .got.  */
42 static int old_got = 0;
44 static struct ppc_elf_params params = { PLT_UNSET, 0, -1,
45                                         0, 0, 0, 0, 0, 0, 0 };
47 static void
48 ppc_after_open_output (void)
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 = link_info.commonpagesize;
55   ppc_elf_link_params (&link_info, &params);
58 EOF
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)
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];
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"));
80       num_got = 0;
81       num_plt = 0;
82       for (os = (void *) lang_os_list.head;
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         }
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     }
115   after_check_relocs_default ();
120 fragment <<EOF
121 static void
122 prelim_size_sections (void)
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     }
134 static void
135 ppc_before_allocation (void)
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 ();
144           if (!ppc_elf_inline_plt (&link_info))
145             einfo (_("%X%P: inline PLT: %E\n"));
146         }
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     }
159   gld${EMULATION_NAME}_before_allocation ();
161   ppc_elf_maybe_strip_sdata_syms (&link_info);
163   if (RELAXATION_ENABLED)
164     params.branch_trampolines = 1;
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;
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 ();
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     }
197   if (params.branch_trampolines
198       || params.ppc476_workaround
199       || params.pic_fixup > 0)
200     ENABLE_RELAXATION;
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).  */
210 static void
211 no_zero_padding (lang_statement_union_type *l)
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} };
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     }
234 static void
235 ppc_finish (void)
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 ();
246 if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then
247   fragment <<EOF
248 /* Special handling for embedded SPU executables.  */
249 extern bool embedded_spu_file (lang_input_statement_type *, const char *);
251 static bool
252 ppc_recognized_file (lang_input_statement_type *entry)
254   if (embedded_spu_file (entry, "-m32"))
255     return true;
257   return ldelf_load_symbols (entry);
261 LDEMUL_RECOGNIZED_FILE=ppc_recognized_file
264 # Define some shell vars to insert bits of code into the standard elf
265 # parse_args and list_options functions.
267 PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
268   { "emit-stub-syms", no_argument, NULL, OPTION_STUBSYMS },
269   { "no-emit-stub-syms", no_argument, NULL, OPTION_NO_STUBSYMS },
270   { "no-tls-optimize", no_argument, NULL, OPTION_NO_TLS_OPT },
271   { "no-tls-get-addr-optimize", no_argument, NULL, OPTION_NO_TLS_GET_ADDR_OPT },'
272 if test -z "$VXWORKS_BASE_EM_FILE" ; then
273   PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
274   { "secure-plt", no_argument, NULL, OPTION_NEW_PLT },
275   { "bss-plt", no_argument, NULL, OPTION_OLD_PLT },
276   { "plt-align", optional_argument, NULL, OPTION_PLT_ALIGN },
277   { "no-plt-align", no_argument, NULL, OPTION_NO_PLT_ALIGN },
278   { "no-inline-optimize", no_argument, NULL, OPTION_NO_INLINE_OPT },
279   { "sdata-got", no_argument, NULL, OPTION_OLD_GOT },'
281 PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
282   { "ppc476-workaround", optional_argument, NULL, OPTION_PPC476_WORKAROUND },
283   { "no-ppc476-workaround", no_argument, NULL, OPTION_NO_PPC476_WORKAROUND },
284   { "no-pic-fixup", no_argument, NULL, OPTION_NO_PICFIXUP },
285   { "vle-reloc-fixup", no_argument, NULL, OPTION_VLE_RELOC_FIXUP },
288 PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
289   fprintf (file, _("\
290   --emit-stub-syms            Label linker stubs with a symbol\n"
291                    ));
292   fprintf (file, _("\
293   --no-emit-stub-syms         Don'\''t label linker stubs with a symbol\n"
294                    ));
295   fprintf (file, _("\
296   --no-tls-optimize           Don'\''t try to optimize TLS accesses\n"
297                    ));
298   fprintf (file, _("\
299   --no-tls-get-addr-optimize  Don'\''t use a special __tls_get_addr call\n"
300                    ));'
301 if test -z "$VXWORKS_BASE_EM_FILE" ; then
302   PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\
303   fprintf (file, _("\
304   --secure-plt                Use new-style PLT if possible\n"
305                    ));
306   fprintf (file, _("\
307   --bss-plt                   Force old-style BSS PLT\n"
308                    ));
309   fprintf (file, _("\
310   --plt-align                 Align PLT call stubs to fit cache lines\n"
311                    ));
312   fprintf (file, _("\
313   --no-plt-align              Dont'\''t align individual PLT call stubs\n"
314                    ));
315   fprintf (file, _("\
316   --no-inline-optimize        Don'\''t convert inline PLT to direct calls\n"
317                    ));
318   fprintf (file, _("\
319   --sdata-got                 Force GOT location just before .sdata\n"
320                    ));'
322 PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\
323   fprintf (file, _("\
324   --ppc476-workaround [=pagesize]\n\
325                               Avoid a cache bug on ppc476\n"
326                    ));
327   fprintf (file, _("\
328   --no-ppc476-workaround      Disable workaround\n"
329                    ));
330   fprintf (file, _("\
331   --no-pic-fixup              Don'\''t edit non-pic to pic\n"
332                    ));
333   fprintf (file, _("\
334   --vle-reloc-fixup           Correct old object file 16A/16D relocation\n"
335                    ));
338 PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
339     case OPTION_STUBSYMS:
340       params.emit_stub_syms = 1;
341       break;
343     case OPTION_NO_STUBSYMS:
344       params.emit_stub_syms = 0;
345       break;
347     case OPTION_NO_TLS_OPT:
348       notlsopt = 1;
349       break;
351     case OPTION_NO_TLS_GET_ADDR_OPT:
352       params.no_tls_get_addr_opt = 1;
353       break;
355     case OPTION_NEW_PLT:
356       params.plt_style = PLT_NEW;
357       break;
359     case OPTION_OLD_PLT:
360       params.plt_style = PLT_OLD;
361       break;
363     case OPTION_PLT_ALIGN:
364       if (optarg != NULL)
365         {
366           char *end;
367           unsigned long val = strtoul (optarg, &end, 0);
368           if (*end || val > 5)
369             einfo (_("%F%P: invalid --plt-align `%s'\''\n"), optarg);
370           params.plt_stub_align = val;
371         }
372       else
373         params.plt_stub_align = 5;
374       break;
376     case OPTION_NO_PLT_ALIGN:
377       params.plt_stub_align = 0;
378       break;
380     case OPTION_NO_INLINE_OPT:
381       no_inline_opt = 1;
382       break;
384     case OPTION_OLD_GOT:
385       old_got = 1;
386       break;
388     case OPTION_TRADITIONAL_FORMAT:
389       notlsopt = 1;
390       params.no_tls_get_addr_opt = 1;
391       return false;
393     case OPTION_PPC476_WORKAROUND:
394       params.ppc476_workaround = 1;
395       if (optarg != NULL)
396         {
397           char *end;
398           params.pagesize = strtoul (optarg, &end, 0);
399           if (*end
400               || (params.pagesize < 4096 && params.pagesize != 0)
401               || params.pagesize != (params.pagesize & -params.pagesize))
402             einfo (_("%F%P: invalid pagesize `%s'\''\n"), optarg);
403         }
404       break;
406     case OPTION_NO_PPC476_WORKAROUND:
407       params.ppc476_workaround = 0;
408       break;
410     case OPTION_NO_PICFIXUP:
411       params.pic_fixup = -1;
412       break;
414     case OPTION_VLE_RELOC_FIXUP:
415       params.vle_reloc_fixup = 1;
416       break;
419 # Put these extra ppc32elf routines in ld_${EMULATION_NAME}_emulation
421 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_after_open_output
422 if test -z "$VXWORKS_BASE_EM_FILE" ; then
423   LDEMUL_AFTER_CHECK_RELOCS=ppc_after_check_relocs
425 LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation
426 LDEMUL_FINISH=ppc_finish