X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=ld%2Femultempl%2Fppc32elf.em;h=56148132df83285f9f3af4923f8dde9d2d488c66;hb=74e315dbfe5200c473b226e937935fb8ce391489;hp=cb27161f7171a52bfbe53f2d7f09f33d12cc7315;hpb=75be928bd2cbcc431c59bb3b9f20a7c002fc2022;p=binutils-gdb.git diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em index cb27161f717..56148132df8 100644 --- a/ld/emultempl/ppc32elf.em +++ b/ld/emultempl/ppc32elf.em @@ -1,11 +1,11 @@ # This shell script emits a C file. -*- C -*- -# Copyright 2003, 2005 Free Software Foundation, Inc. +# Copyright (C) 2003-2022 Free Software Foundation, Inc. # -# This file is part of GLD, the Gnu Linker. +# This file is part of the GNU Binutils. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or +# the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, @@ -15,32 +15,55 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. # -# This file is sourced from elf32.em, and defines extra powerpc32-elf +# This file is sourced from elf.em, and defines extra powerpc32-elf # specific routines. # -cat >>e${EMULATION_NAME}.c <creator == &bfd_elf32_powerpc_vec - || link_info.hash->creator == &bfd_elf32_powerpcle_vec) + if (is_ppc_elf (link_info.output_bfd)) { int new_plt; int keep_new; @@ -50,13 +73,13 @@ ppc_after_open (void) lang_output_section_statement_type *plt_os[2]; lang_output_section_statement_type *got_os[2]; - new_plt = ppc_elf_select_plt_layout (output_bfd, &link_info, old_plt); + new_plt = ppc_elf_select_plt_layout (link_info.output_bfd, &link_info); if (new_plt < 0) - einfo ("%X%P: select_plt_layout problem %E\n"); + einfo (_("%X%P: select_plt_layout problem %E\n")); num_got = 0; num_plt = 0; - for (os = &lang_output_section_statement.head->output_section_statement; + for (os = (void *) lang_os_list.head; os != NULL; os = os->next) { @@ -89,79 +112,335 @@ ppc_after_open (void) } } - gld${EMULATION_NAME}_after_open (); + after_check_relocs_default (); +} + +EOF +fi +fragment <creator == &bfd_elf32_powerpc_vec - || link_info.hash->creator == &bfd_elf32_powerpcle_vec) + if (is_ppc_elf (link_info.output_bfd)) { - if (ppc_elf_tls_setup (output_bfd, &link_info) && !notlsopt) + if (!no_inline_opt + && !bfd_link_relocatable (&link_info)) + { + prelim_size_sections (); + + if (!ppc_elf_inline_plt (&link_info)) + einfo (_("%X%P: inline PLT: %E\n")); + } + + if (ppc_elf_tls_setup (link_info.output_bfd, &link_info) + && !notlsopt) { - if (!ppc_elf_tls_optimize (output_bfd, &link_info)) + if (!ppc_elf_tls_optimize (link_info.output_bfd, &link_info)) { - einfo ("%X%P: TLS problem %E\n"); + einfo (_("%X%P: TLS problem %E\n")); return; } } } + gld${EMULATION_NAME}_before_allocation (); + + ppc_elf_maybe_strip_sdata_syms (&link_info); + + if (RELAXATION_ENABLED) + params.branch_trampolines = 1; + + /* Turn on relaxation if executable sections have addresses that + might make branches overflow. */ + else if (!RELAXATION_DISABLED_BY_USER) + { + bfd_vma low = (bfd_vma) -1; + bfd_vma high = 0; + asection *o; + + /* Run lang_size_sections even if already done, so as to pick + up gld${EMULATION_NAME}_before_allocation sizing. This + matters when we have an executable bss plt which will + typically be laid out near the end of the image, ie. worst + case for branches at the start of .text. */ + expld.phase = lang_first_phase_enum; + prelim_size_sections (); + + for (o = link_info.output_bfd->sections; o != NULL; o = o->next) + { + if ((o->flags & (SEC_ALLOC | SEC_CODE)) != (SEC_ALLOC | SEC_CODE)) + continue; + if (o->rawsize == 0) + continue; + if (low > o->vma) + low = o->vma; + if (high < o->vma + o->rawsize - 1) + high = o->vma + o->rawsize - 1; + } + if (high > low && high - low > (1 << 25) - 1) + params.branch_trampolines = 1; + } + + if (params.branch_trampolines + || params.ppc476_workaround + || params.pic_fixup > 0) + ENABLE_RELAXATION; } +/* Replaces default zero fill padding in executable sections with + "ba 0" instructions. This works around the ppc476 icache bug if we + have a function pointer tail call near the end of a page, some + small amount of padding, then the function called at the beginning + of the next page. If the "ba 0" is ever executed we should hit a + segv, so it's almost as good as an illegal instruction (zero). */ + static void -gld${EMULATION_NAME}_after_allocation (void) +no_zero_padding (lang_statement_union_type *l) { - if (link_info.hash->creator == &bfd_elf32_powerpc_vec - || link_info.hash->creator == &bfd_elf32_powerpcle_vec) + if (l->header.type == lang_padding_statement_enum + && l->padding_statement.size != 0 + && l->padding_statement.output_section != NULL + && (l->padding_statement.output_section->flags & SEC_CODE) != 0 + && l->padding_statement.fill->size == 0) { - if (!ppc_elf_set_sdata_syms (output_bfd, &link_info)) - einfo ("%X%P: cannot set sdata syms %E\n"); + struct _ppc_fill_type + { + size_t size; + unsigned char data[4]; + }; + static struct _ppc_fill_type fill_be = { 4, {0x48, 0, 0, 2} }; + static struct _ppc_fill_type fill_le = { 4, {2, 0, 0, 0x48} }; + + if (bfd_big_endian (link_info.output_bfd)) + l->padding_statement.fill = (struct _fill_type *) &fill_be; + else + l->padding_statement.fill = (struct _fill_type *) &fill_le; } } +static void +ppc_finish (void) +{ + if (params.ppc476_workaround) + lang_for_each_statement (no_zero_padding); + if (!ppc_finish_symbols (&link_info)) + einfo (_("%X%P: ppc_finish_symbols problem %E\n")); + finish_default (); +} + EOF +if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then + fragment < 5) + einfo (_("%F%P: invalid --plt-align `%s'\''\n"), optarg); + params.plt_stub_align = val; + } + else + params.plt_stub_align = 5; + break; + + case OPTION_NO_PLT_ALIGN: + params.plt_stub_align = 0; + break; + + case OPTION_NO_INLINE_OPT: + no_inline_opt = 1; break; case OPTION_OLD_GOT: old_got = 1; break; + + case OPTION_TRADITIONAL_FORMAT: + notlsopt = 1; + params.no_tls_get_addr_opt = 1; + return false; + + case OPTION_PPC476_WORKAROUND: + params.ppc476_workaround = 1; + if (optarg != NULL) + { + char *end; + params.pagesize = strtoul (optarg, &end, 0); + if (*end + || (params.pagesize < 4096 && params.pagesize != 0) + || params.pagesize != (params.pagesize & -params.pagesize)) + einfo (_("%F%P: invalid pagesize `%s'\''\n"), optarg); + } + break; + + case OPTION_NO_PPC476_WORKAROUND: + params.ppc476_workaround = 0; + break; + + case OPTION_NO_PICFIXUP: + params.pic_fixup = -1; + break; + + case OPTION_VLE_RELOC_FIXUP: + params.vle_reloc_fixup = 1; + break; ' # Put these extra ppc32elf routines in ld_${EMULATION_NAME}_emulation # -LDEMUL_AFTER_OPEN=ppc_after_open +LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=ppc_after_open_output +if test -z "$VXWORKS_BASE_EM_FILE" ; then + LDEMUL_AFTER_CHECK_RELOCS=ppc_after_check_relocs +fi LDEMUL_BEFORE_ALLOCATION=ppc_before_allocation -LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation +LDEMUL_FINISH=ppc_finish