# This shell script emits a C file. -*- C -*- # Copyright (C) 2012-2023 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 <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