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