binutils-gdb/ld/emultempl/nds32elf.em
Alan Modra d871d47806 Move elf32.em and elf-generic.em functions
Many ELF linker targets support multiple "emulations" and thus have
multiple copies of elf32.em being compiled and linked into ld.  This
patch moves much of elf32.em and elf-generic.em into files which will
be compiled just once, resulting in a 20% decrease in ld size for
--enable-targets=all.

	* Makefile.am (ALL_EMUL_EXTRA_OFILES): Add ldelf and ldelfgen.
	(CFILES, HFILES, EXTRA_ld_new_SOURCES): Likewise.
	* configure.tgt: Formatting.
	(targ_extra_ofiles): Init to ldelf.o ldelfgen.o, reset to just
	ldelfgen.o for generic ELF targets, and empty for non-ELF.
	* emultempl/aarch64elf.em (gldaarch64_layout_sections_again): Use
	ldelf_map_segments.
	(gld${EMULATION_NAME}_after_allocation): Likewise.
	(real_func, aarch64_for_each_input_file_wrapper),
	(aarch64_lang_for_each_input_file): Delete.
	(lang_for_each_input_file): Don't define.
	* emultempl/alphaelf.em (alpha_after_parse): Use ldelf_map_segments.
	* emultempl/armelf.em (gldarm_layout_sections_again): Likewise.
	(gld${EMULATION_NAME}_after_allocation): Likewise.
	(real_func, arm_for_each_input_file_wrapper),
	(arm_lang_for_each_input_file): Delete.
	(lang_for_each_input_file): Don't define.
	* emultempl/cr16elf.em (cr16elf_after_parse): Use ldelf_map_segments.
	* emultempl/crxelf.em (crxelf_after_parse): Likewise.  Delete
	declaration.
	* emultempl/cskyelf.em (gldcsky_layout_sections_again): Use
	ldelf_map_segments.
	(gld${EMULATION_NAME}_after_allocation): Likewise.
	(real_func, csky_for_each_input_file_wrapper),
	(csky_lang_for_each_input_file): Delete.
	(lang_for_each_input_file): Don't define.
	* emultempl/genelf.em: Include ldelfgen.h.
	(gld${EMULATION_NAME}_before_allocation): Use ldelf_map_segments.
	* emultempl/hppaelf.em (hppaelf_after_parse): Likewise.
	(hppaelf_layout_sections_again): Likewise.
	(gld${EMULATION_NAME}_after_allocation): Likewise.
	(real_func, hppa_for_each_input_file_wrapper),
	(hppa_lang_for_each_input_file): Delete.
	(lang_for_each_input_file): Don't define.
	* emultempl/ia64elf.em (ia64elf_after_parse): Use ldelf_map_segments.
	* emultempl/m68hc1xelf.em (real_func),
	(m68hc11_for_each_input_file_wrapper),
	(m68hc11_lang_for_each_input_file): Delete.
	(lang_for_each_input_file): Don't define.
	* emultempl/metagelf.em (metagelf_layout_sections_again): Use
	ldelf_map_segments.
	(gld${EMULATION_NAME}_after_allocation): Likewise.
	(real_func, metag_for_each_input_file_wrapper),
	(metag_lang_for_each_input_file): Delete.
	(lang_for_each_input_file): Don't define.
	* emultempl/mipself.em (real_func),
	(mips_for_each_input_file_wrapper),
	(mips_lang_for_each_input_file): Delete.
	(lang_for_each_input_file): Don't define.
	* emultempl/mmo.em: Don't include elf-bfd.h, do include ldelfgen.h.
	(gld${EMULATION_NAME}_after_allocation): Use ldelf_map_segments.
	* emultempl/nds32elf.em (nds32_elf_after_parse): Use ldelf_after_parse.
	(nds32_elf_after_allocation): Comment fix.
	* emultempl/nios2elf.em (nios2elf_layout_sections_again): Use
	ldelf_map_segments.
	(gld${EMULATION_NAME}_after_allocation): Likewise.
	(real_func, nios2_for_each_input_file_wrapper),
	(nios2_lang_for_each_input_file): Delete.
	(lang_for_each_input_file): Don't define.
	* emultempl/ppc32elf.em (gld${EMULATION_NAME}_load_symbols): Delete
	declaration.
	(ppc_recognized_file): Call ldelf_load_symbols.
	* emultempl/ppc64elf.em (ppc_layout_sections_again): Likewise.
	(gld${EMULATION_NAME}_after_allocation): Likewise.
	(real_func, ppc_for_each_input_file_wrapper),
	(ppc_lang_for_each_input_file): Delete.
	(lang_for_each_input_file): Don't define.
	(gld${EMULATION_NAME}_load_symbols): Don't declare.
	(ppc64_recognized_file): Call ldelf_load_symbols.
	* emultempl/riscvelf.em (gld${EMULATION_NAME}_after_allocation):
	Use ldelf_map_segments.
	* emultempl/spuelf.em (spu_place_special_section): Use
	ldelf_place_orphan.
	* emultempl/tic6xdsbt.em (gld${EMULATION_NAME}_after_allocation):
	Use ldelf_map_segments.
	* emultempl/vms.em: Include ldelfgen.h.
	(gld${EMULATION_NAME}_after_allocation): Use ldelf_map_segments.
	* emultempl/elf32.em: Remove unnecessary headers, include ldelf.h
	and ldelfgen.h.  Move much of file content to..
	* ldelf.c: ..here.  New file.
	* ldelf.h: New file.
	* emultempl/elf-generic.em: Move gld${EMULATION_NAME}_map_segments..
	* ldelfgen.c: ..to here.
	* ldelfgen.h: New file.
	* ldlang.c (lang_for_each_input_file): Adjust to only call func
	on real files.
	(lang_for_each_file): Likewise.
	* po/SRC-POTFILES.in: Regenerate.
	* Makefile.in: Regenerate.
2019-09-11 13:44:22 +09:30

226 lines
7.7 KiB
Plaintext

# This shell script emits a C file. -*- C -*-
# Copyright (C) 2012-2019 Free Software Foundation, Inc.
# Contributed by Andes Technology Corporation.
#
# 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.
#
fragment <<EOF
#include "elf-bfd.h"
#include "elf/nds32.h"
#include "bfd_stdint.h"
#include "elf32-nds32.h"
static int relax_fp_as_gp = 1; /* --mrelax-omit-fp */
static int eliminate_gc_relocs = 0; /* --meliminate-gc-relocs */
static FILE *sym_ld_script = NULL; /* --mgen-symbol-ld-script=<file> */
static int hyper_relax = 1; /* --mhyper-relax */
static int tls_desc_trampoline = 0; /* --m[no]tlsdesc-trampoline. */
/* Disable if linking a dynamically linked executable. */
static int load_store_relax = 1;
/* Save the target options into output bfd to avoid using to many global
variables. Do this after the output has been created, but before
inputs are read. */
static void
nds32_elf_create_output_section_statements (void)
{
if (strstr (bfd_get_target (link_info.output_bfd), "nds32") == NULL)
{
/* Check the output target is nds32. */
einfo (_("%F%P: error: cannot change output format whilst "
"linking %s binaries\n"), "NDS32");
return;
}
bfd_elf32_nds32_set_target_option (&link_info,
relax_fp_as_gp,
eliminate_gc_relocs,
sym_ld_script,
hyper_relax,
tls_desc_trampoline,
load_store_relax);
}
static void
nds32_elf_after_parse (void)
{
if (bfd_link_relocatable (&link_info)
|| bfd_link_pic (&link_info))
DISABLE_RELAXATION;
if (!RELAXATION_ENABLED)
relax_fp_as_gp = 0;
ldelf_after_parse ();
}
static void
nds32_elf_after_open (void)
{
unsigned int arch_ver = (unsigned int)-1;
unsigned int abi_ver = (unsigned int)-1;
bfd *abfd;
/* For now, make sure all object files are of the same architecture.
We may try to merge object files with different architecture together. */
for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
{
if (arch_ver == (unsigned int)-1 && E_N1_ARCH != (elf_elfheader (abfd)->e_flags & EF_NDS_ARCH))
arch_ver = elf_elfheader (abfd)->e_flags & EF_NDS_ARCH ;
if (abi_ver == (unsigned int)-1)
{
/* Initialize ABI version, if not ABI0.
(OS uses empty file to create empty ELF with ABI0). */
if ((elf_elfheader (abfd)->e_flags & EF_NDS_ABI) != 0)
abi_ver = elf_elfheader (abfd)->e_flags & EF_NDS_ABI ;
}
else if ((elf_elfheader (abfd)->e_flags & EF_NDS_ABI) != 0
&& abi_ver != (elf_elfheader (abfd)->e_flags & EF_NDS_ABI))
{
/* Incompatible objects. */
einfo (_("%F%P: %pB: ABI version of object files mismatched\n"),
abfd);
}
}
/* Check object files if the target is dynamic linked executable
or shared object. */
if (elf_hash_table (&link_info)->dynamic_sections_created
|| bfd_link_pic (&link_info)
|| bfd_link_pie (&link_info))
{
/* Dynamic linked executable with SDA and non-PIC.
Turn off load/store relaxtion. */
/* This may support in the future. */
load_store_relax = 0 ;
relax_fp_as_gp = 0;
}
/* Call the standard elf routine. */
gld${EMULATION_NAME}_after_open ();
}
static void
nds32_elf_after_allocation (void)
{
/* Call default after allocation callback.
1. This is where relaxation is done.
2. It calls ldelf_map_segments to build ELF segment table.
3. Any relaxation requires relax being done must be called after it. */
gld${EMULATION_NAME}_after_allocation ();
}
EOF
# Define some shell vars to insert bits of code into the standard elf
# parse_args and list_options functions.
#
PARSE_AND_LIST_PROLOGUE='
#define OPTION_BASELINE 301
#define OPTION_ELIM_GC_RELOCS (OPTION_BASELINE + 1)
#define OPTION_FP_AS_GP (OPTION_BASELINE + 2)
#define OPTION_NO_FP_AS_GP (OPTION_BASELINE + 3)
#define OPTION_REDUCE_FP_UPDATE (OPTION_BASELINE + 4)
#define OPTION_NO_REDUCE_FP_UPDATE (OPTION_BASELINE + 5)
#define OPTION_EXPORT_SYMBOLS (OPTION_BASELINE + 6)
#define OPTION_HYPER_RELAX (OPTION_BASELINE + 7)
#define OPTION_TLSDESC_TRAMPOLINE (OPTION_BASELINE + 8)
#define OPTION_NO_TLSDESC_TRAMPOLINE (OPTION_BASELINE + 9)
'
PARSE_AND_LIST_LONGOPTS='
{ "mfp-as-gp", no_argument, NULL, OPTION_FP_AS_GP},
{ "mno-fp-as-gp", no_argument, NULL, OPTION_NO_FP_AS_GP},
{ "mexport-symbols", required_argument, NULL, OPTION_EXPORT_SYMBOLS},
{ "mhyper-relax", required_argument, NULL, OPTION_HYPER_RELAX},
{ "mtlsdesc-trampoline", no_argument, NULL, OPTION_TLSDESC_TRAMPOLINE},
{ "mno-tlsdesc-trampoline", no_argument, NULL, OPTION_NO_TLSDESC_TRAMPOLINE},
/* These are deprecated options. Remove them in the future. */
{ "mrelax-reduce-fp-update", no_argument, NULL, OPTION_REDUCE_FP_UPDATE},
{ "mrelax-no-reduce-fp-update", no_argument, NULL, OPTION_NO_REDUCE_FP_UPDATE},
{ "mbaseline", required_argument, NULL, OPTION_BASELINE},
{ "meliminate-gc-relocs", no_argument, NULL, OPTION_ELIM_GC_RELOCS},
{ "mrelax-omit-fp", no_argument, NULL, OPTION_FP_AS_GP},
{ "mrelax-no-omit-fp", no_argument, NULL, OPTION_NO_FP_AS_GP},
{ "mgen-symbol-ld-script", required_argument, NULL, OPTION_EXPORT_SYMBOLS},
'
PARSE_AND_LIST_OPTIONS='
fprintf (file, _("\
--m[no-]fp-as-gp Disable/enable fp-as-gp relaxation\n"));
fprintf (file, _("\
--mexport-symbols=FILE Exporting symbols in linker script\n"));
fprintf (file, _("\
--mhyper-relax=level Adjust relax level (low|medium|high). default: medium\n"));
fprintf (file, _("\
--m[no-]tlsdesc-trampoline Disable/enable TLS DESC trampoline\n"));
'
PARSE_AND_LIST_ARGS_CASES='
case OPTION_BASELINE:
einfo (_("%P: --mbaseline is not used anymore\n"));
break;
case OPTION_ELIM_GC_RELOCS:
eliminate_gc_relocs = 1;
break;
case OPTION_FP_AS_GP:
case OPTION_NO_FP_AS_GP:
relax_fp_as_gp = (optc == OPTION_FP_AS_GP);
break;
case OPTION_REDUCE_FP_UPDATE:
case OPTION_NO_REDUCE_FP_UPDATE:
einfo (_("%P: --relax-[no-]reduce-fp-updat is not used anymore\n"));
break;
case OPTION_EXPORT_SYMBOLS:
if (!optarg)
einfo (_("%P: missing file for --mexport-symbols\n"), optarg);
if(strcmp (optarg, "-") == 0)
sym_ld_script = stdout;
else
{
sym_ld_script = fopen (optarg, FOPEN_WT);
if(sym_ld_script == NULL)
einfo (_("%F%P: cannot open map file %s: %E\n"), optarg);
}
break;
case OPTION_HYPER_RELAX:
if (!optarg)
einfo (_("%P: valid arguments to --mhyper-relax=(low|medium|high)\n"));
if (strcmp (optarg, "low") == 0)
hyper_relax = 0;
else if (strcmp (optarg, "medium") == 0)
hyper_relax = 1;
else if (strcmp (optarg, "high") == 0)
hyper_relax = 2;
else
einfo (_("%P: valid arguments to --mhyper-relax=(low|medium|high)\n"));
break;
case OPTION_TLSDESC_TRAMPOLINE:
tls_desc_trampoline = 1;
break;
case OPTION_NO_TLSDESC_TRAMPOLINE:
tls_desc_trampoline = 0;
break;
'
LDEMUL_AFTER_OPEN=nds32_elf_after_open
LDEMUL_AFTER_PARSE=nds32_elf_after_parse
LDEMUL_AFTER_ALLOCATION=nds32_elf_after_allocation
LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=nds32_elf_create_output_section_statements