8sa1-binutils-gdb/ld/emultempl/armcoff.em
H.J. Lu 5c3261b0e8 ELF: Call check_relocs after opening all inputs
For all ELF targers, call check_relocs after opening all inputs and
garbage collection.  Since the symbol resolution is known, check_relocs
can be simplified.  Also garbage collection doesn't need to undo what
check_relocs has done for symbols which have been garbage collected.
Since ELF targets never see the removed sections, gc_sweep_hook can be
removed from elf_backend_data and we can avoid GOT/PLT with garbage
collection now.

Set link_info.check_relocs_after_open_input to TRUE for all linker
targets which use ELF linker and update garbage collection tests to
remove unused GOT section.

ldemul_after_check_relocs is added for powerpc to support --secure-plt,
--bss-plt and --sdata-got.

Tested natively without regressions on i686, x86-64 and x32.  Tested
cross binutils on x86-64 without regressions for aarch64-linux,
alpha-linux, arm-linux, bfin-elf, cr16-elf, cris-elf, crx-elf, frv-linux,
hppa64-linux, hppa-linux, ia64-linux, lm32-elf, m32r-elf, m68k-linux,
mcore-elf, metag-elf, microblaze-linux, mips-linux, mmix, mn10300-elf,
nds32le-linux, nios2-linux, or1k-elf, powerpc64-linux, powerpc-linux,
riscv32-linux, riscv64-linux, s390-linux, s390x-linux, score-elf,
sh3-linux, sparc64-linux, sparc-linux, tic6x-elf, tilegx-linux,
tilepro-linux, vax-linux, x86_64-mingw32 and xtensa-linux.

bfd/

	* elf-bfd.h (elf_backend_data): Remove gc_sweep_hook.
	* elf32-arm.c (elf32_arm_gc_sweep_hook): Removed.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-bfin.c (bfin_gc_sweep_hook): Likewise.
	(bfinfdpic_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-cr16.c (elf32_cr16_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-cris.c (cris_elf_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-hppa.c (elf32_hppa_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-lm32.c (lm32_elf_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-m32r.c (m32r_elf_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-m68k.c (elf_m68k_got_entry): Remove elf_m68k_gc_sweep_hook
	from comments.
	(elf_m68k_remove_got_entry_type): Removed.
	(elf_m68k_find_got_entry_ptr): Likewise.
	(elf_m68k_remove_got_entry): Likewise.
	(elf_m68k_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-mcore.c (mcore_elf_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-metag.c (elf_metag_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-microblaze.c (elf_backend_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-mips.c (elf_backend_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-nds32.c (nds32_elf_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-nios2.c (nios2_elf32_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-or1k.c (or1k_elf_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-ppc.c (ppc_elf_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-s390.c (elf_s390_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-sparc.c (elf_backend_gc_sweep_hook): Likewise.
	* elf32-tic6x.c (elf32_tic6x_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-tilegx.c (elf_backend_gc_sweep_hook): Likewise.
	* elf32-tilepro.c (tilepro_elf_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-vax.c (elf_vax_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf32-xtensa.c (elf_xtensa_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf64-alpha.c (elf64_alpha_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf64-mips.c (elf_backend_gc_sweep_hook): Likewise.
	* elf64-mmix.c (mmix_elf_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf64-ppc.c (elf_backend_gc_sweep_hook): Likewise.
	(ppc64_elf_gc_sweep_hook): Likewise.
	* elf64-s390.c (elf_s390_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elf64-sparc.c (elf_backend_gc_sweep_hook): Likewise.
	* elf64-tilegx.c (elf_backend_gc_sweep_hook): Likewise.
	* elflink.c (elf_link_add_object_symbols): Don't call
	_bfd_elf_link_check_relocs here.
	(gc_sweep_hook_fn): Removed.
	(elf_gc_sweep): Remove gc_sweep_hook.
	* elfnn-aarch64.c (elfNN_aarch64_gc_sweep_hook): Removed.
	(elf_backend_gc_sweep_hook): Likewise.
	* elfnn-riscv.c (riscv_elf_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elfxx-mips.c (_bfd_mips_elf_gc_sweep_hook): Likewise.
	* elfxx-mips.h (_bfd_mips_elf_gc_sweep_hook): Likewise.
	(elf_backend_gc_sweep_hook): Likewise.
	* elfxx-sparc.c (_bfd_sparc_elf_gc_sweep_hook): Likewise.
	* elfxx-sparc.h (_bfd_sparc_elf_gc_sweep_hook): Likewise.
	* elfxx-target.h (elf_backend_gc_sweep_hook): Likewise.
	(elfNN_bed): Remove elf_backend_gc_sweep_hook.
	* elfxx-tilegx.c (tilegx_elf_gc_sweep_hook): Removed.
	* elfxx-tilegx.h (tilegx_elf_gc_sweep_hook): Likewise.

ld/

	* emulparams/elf32_x86_64.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Removed.
	* emulparams/elf_i386_be.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/elf_i386_chaos.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/elf_i386_ldso.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/elf_i386_vxworks.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/elf_iamcu.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/elf_k1om.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/elf_l1om.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/elf_x86_64.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/i386lynx.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/i386moss.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/i386nto.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/i386nw.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/shelf.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/shelf32.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/shelf_nto.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/shelf_vxworks.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/shlelf32_linux.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/shlelf_linux.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emulparams/shlelf_nto.sh (CHECK_RELOCS_AFTER_OPEN_INPUT):
	Likewise.
	* emultempl/aarch64elf.em (gld${EMULATION_NAME}_before_parse):
	Set link_info.check_relocs_after_open_input to TRUE.
	* emultempl/armelf.em (gld${EMULATION_NAME}_before_parse):
	Likewise.
	* emultempl/scoreelf.em (gld${EMULATION_NAME}_before_parse):
	Likewise.
	* emultempl/aix.em (ld_${EMULATION_NAME}_emulation): Add
	after_parse_default.
	* emultempl/armcoff.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/beos.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/generic.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/gld960.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/gld960c.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/lnk960.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/m68kcoff.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/msp430.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/pe.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/pep.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/sunos.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/ticoff.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/vanilla.em (ld_${EMULATION_NAME}_emulation): Likewise.
	* emultempl/elf32.em (gld${EMULATION_NAME}_before_parse): Always
	set link_info.check_relocs_after_open_input to TRUE.
	(ld_${EMULATION_NAME}_emulation): Add $LDEMUL_AFTER_CHECK_RELOCS.
	* emultempl/linux.em (gld${EMULATION_NAME}_before_parse):
	Set link_info.check_relocs_after_open_input to TRUE.
	(ld_${EMULATION_NAME}_emulation): Add after_check_relocs_default.
	* emultempl/mmix-elfnmmo.em (mmix_before_parse): New function.
	(LDEMUL_BEFORE_PARSE): New.
	* emultempl/mmixelf.em (elfmmix_before_parse): Replace
	gld${EMULATION_NAME}_before_parse with mmix_before_parse.
	* emultempl/ppc32elf.em (ppc_after_open): Renamed to ...
	(ppc_after_check_relocs): This.  Call after_check_relocs_default
	instead of gld${EMULATION_NAME}_after_open.
	(LDEMUL_AFTER_OPEN): Removed.
	(LDEMUL_AFTER_CHECK_RELOCS): New.
	* ldemul.c (ldemul_after_check_relocs): New.
	(after_check_relocs_default): Likewise.
	* ldemul.h (ldemul_after_check_relocs): Likewise.
	(after_check_relocs_default): Likewise.
	(ld_emulation_xfer_struct): Add after_check_relocs.
	* ldlang.c (lang_process): Call ldemul_after_check_relocs after
	lang_check_relocs.
	* testsuite/ld-aarch64/gc-got-relocs.d: Don't expect GOT section.
	* testsuite/ld-aarch64/gc-tls-relocs.d: Likewise.
	* testsuite/ld-cris/tls-gc-68.d: Likewise.
	* testsuite/ld-cris/tls-gc-69.d: Likewise.
	* testsuite/ld-cris/tls-gc-70.d: Likewise.
	* testsuite/ld-cris/tls-gc-75.d: Likewise.
	* testsuite/ld-cris/tls-gc-79.d: Likewise.
	* testsuite/ld-mmix/bpo-10.d: Don't expect .MMIX.reg_contents
	section.
2017-10-16 03:50:13 -07:00

288 lines
8.1 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# This shell script emits a C file. -*- C -*-
# It does some substitutions.
fragment <<EOF
/* This file is is generated by a shell script. DO NOT EDIT! */
/* emulate the original gld for the given ${EMULATION_NAME}
Copyright (C) 1991-2017 Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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. */
#define TARGET_IS_${EMULATION_NAME}
#include "sysdep.h"
#include "bfd.h"
#include "bfdlink.h"
#include "getopt.h"
#include "ld.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldfile.h"
#include "ldemul.h"
/* If TRUE, then interworking stubs which support calls to old,
non-interworking aware ARM code should be generated. */
static int support_old_code = 0;
static char * thumb_entry_symbol = NULL;
#define OPTION_SUPPORT_OLD_CODE 300
#define OPTION_THUMB_ENTRY 301
static void
gld${EMULATION_NAME}_add_options
(int ns ATTRIBUTE_UNUSED, char **shortopts ATTRIBUTE_UNUSED, int nl,
struct option **longopts, int nrl ATTRIBUTE_UNUSED,
struct option **really_longopts ATTRIBUTE_UNUSED)
{
static const struct option xtra_long[] = {
{"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
{"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
{NULL, no_argument, NULL, 0}
};
*longopts = xrealloc (*longopts,
nl * sizeof (struct option) + sizeof (xtra_long));
memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
}
static void
gld${EMULATION_NAME}_list_options (FILE *file)
{
fprintf (file, _(" --support-old-code Support interworking with old code\n"));
fprintf (file, _(" --thumb-entry=<sym> Set the entry point to be Thumb symbol <sym>\n"));
}
static bfd_boolean
gld${EMULATION_NAME}_handle_option (int optc)
{
switch (optc)
{
default:
return FALSE;
case OPTION_SUPPORT_OLD_CODE:
support_old_code = 1;
break;
case OPTION_THUMB_ENTRY:
thumb_entry_symbol = optarg;
break;
}
return TRUE;
}
static void
gld${EMULATION_NAME}_before_parse (void)
{
#ifndef TARGET_ /* I.e., if not generic. */
ldfile_set_output_arch ("`echo ${ARCH}`", bfd_arch_unknown);
#endif /* not TARGET_ */
}
/* This is called after the sections have been attached to output
sections, but before any sizes or addresses have been set. */
static void
gld${EMULATION_NAME}_before_allocation (void)
{
/* we should be able to set the size of the interworking stub section */
/* Here we rummage through the found bfds to collect glue information */
/* FIXME: should this be based on a command line option? krk@cygnus.com */
{
LANG_FOR_EACH_INPUT_STATEMENT (is)
{
if (! bfd_arm_process_before_allocation
(is->the_bfd, & link_info, support_old_code))
{
/* xgettext:c-format */
einfo (_("Errors encountered processing file %s"), is->filename);
}
}
}
/* We have seen it all. Allocate it, and carry on */
bfd_arm_allocate_interworking_sections (& link_info);
before_allocation_default ();
}
static void
gld${EMULATION_NAME}_after_open (void)
{
after_open_default ();
if (strstr (bfd_get_target (link_info.output_bfd), "arm") == NULL)
{
/* The arm backend needs special fields in the output hash structure.
These will only be created if the output format is an arm format,
hence we do not support linking and changing output formats at the
same time. Use a link followed by objcopy to change output formats. */
einfo (_("%F%X%P: error: cannot change output format "
"whilst linking ARM binaries\n"));
return;
}
{
LANG_FOR_EACH_INPUT_STATEMENT (is)
{
if (bfd_arm_get_bfd_for_interworking (is->the_bfd, & link_info))
break;
}
}
}
static void
gld${EMULATION_NAME}_finish (void)
{
if (thumb_entry_symbol != NULL)
{
struct bfd_link_hash_entry * h;
h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol,
FALSE, FALSE, TRUE);
if (h != (struct bfd_link_hash_entry *) NULL
&& (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak)
&& h->u.def.section->output_section != NULL)
{
static char buffer[32];
bfd_vma val;
/* Special procesing is required for a Thumb entry symbol. The
bottom bit of its address must be set. */
val = (h->u.def.value
+ bfd_get_section_vma (link_info.output_bfd,
h->u.def.section->output_section)
+ h->u.def.section->output_offset);
val |= 1;
/* Now convert this value into a string and store it in entry_symbol
where the lang_finish() function will pick it up. */
buffer[0] = '0';
buffer[1] = 'x';
sprintf_vma (buffer + 2, val);
if (entry_symbol.name != NULL && entry_from_cmdline)
einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
thumb_entry_symbol, entry_symbol.name);
entry_symbol.name = buffer;
}
else
einfo (_("%P: warning: cannot find thumb start symbol %s\n"),
thumb_entry_symbol);
}
finish_default ();
}
static char *
gld${EMULATION_NAME}_get_script (int *isfile)
EOF
if test x"$COMPILE_IN" = xyes
then
# Scripts compiled in.
# sed commands to quote an ld script as a C string.
sc="-f stringify.sed"
fragment <<EOF
{
*isfile = 0;
if (bfd_link_relocatable (&link_info) && config.build_constructors)
return
EOF
sed $sc ldscripts/${EMULATION_NAME}.xu >> e${EMULATION_NAME}.c
echo ' ; else if (bfd_link_relocatable (&link_info)) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xr >> e${EMULATION_NAME}.c
echo ' ; else if (!config.text_read_only) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xbn >> e${EMULATION_NAME}.c
echo ' ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.xn >> e${EMULATION_NAME}.c
echo ' ; else return' >> e${EMULATION_NAME}.c
sed $sc ldscripts/${EMULATION_NAME}.x >> e${EMULATION_NAME}.c
echo '; }' >> e${EMULATION_NAME}.c
else
# Scripts read from the filesystem.
fragment <<EOF
{
*isfile = 1;
if (bfd_link_relocatable (&link_info) && config.build_constructors)
return "ldscripts/${EMULATION_NAME}.xu";
else if (bfd_link_relocatable (&link_info))
return "ldscripts/${EMULATION_NAME}.xr";
else if (!config.text_read_only)
return "ldscripts/${EMULATION_NAME}.xbn";
else if (!config.magic_demand_paged)
return "ldscripts/${EMULATION_NAME}.xn";
else
return "ldscripts/${EMULATION_NAME}.x";
}
EOF
fi
fragment <<EOF
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
{
gld${EMULATION_NAME}_before_parse,
syslib_default,
hll_default,
after_parse_default,
gld${EMULATION_NAME}_after_open,
after_check_relocs_default,
after_allocation_default,
set_output_arch_default,
ldemul_default_target,
gld${EMULATION_NAME}_before_allocation,
gld${EMULATION_NAME}_get_script,
"${EMULATION_NAME}",
"${OUTPUT_FORMAT}",
gld${EMULATION_NAME}_finish,
NULL, /* create output section statements */
NULL, /* open dynamic archive */
NULL, /* place orphan */
NULL, /* set symbols */
NULL, /* parse_args */
gld${EMULATION_NAME}_add_options,
gld${EMULATION_NAME}_handle_option,
NULL, /* unrecognised file */
gld${EMULATION_NAME}_list_options,
NULL, /* recognized file */
NULL, /* find_potential_libraries */
NULL, /* new_vers_pattern */
NULL /* extra_map_file_text */
};
EOF