1# This shell script emits a C file. -*- C -*- 2# Copyright (C) 2012-2018 Free Software Foundation, Inc. 3# Contributed by Andes Technology Corporation. 4# 5# This file is part of the GNU Binutils. 6# 7# This program is free software; you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation; either version 3 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program; if not, write to the Free Software 19# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20# MA 02110-1301, USA. 21# 22 23fragment <<EOF 24 25#include "elf-bfd.h" 26#include "elf/nds32.h" 27#include "bfd_stdint.h" 28#include "elf32-nds32.h" 29 30static int relax_fp_as_gp = 1; /* --mrelax-omit-fp */ 31static int eliminate_gc_relocs = 0; /* --meliminate-gc-relocs */ 32static FILE *sym_ld_script = NULL; /* --mgen-symbol-ld-script=<file> */ 33/* Disable if linking a dynamically linked executable. */ 34static int load_store_relax = 1; 35static int target_optimize = 0; /* Switch optimization. */ 36static int relax_status = 0; /* Finished optimization. */ 37static int relax_round = 0; /* Going optimization. */ 38static FILE *ex9_export_file = NULL; /* --mexport-ex9=<file> */ 39static FILE *ex9_import_file = NULL; /* --mimport-ex9=<file> */ 40static int update_ex9_table = 0; /* --mupdate-ex9. */ 41static int ex9_limit = 511; 42static bfd_boolean ex9_loop_aware = FALSE; /* Ignore ex9 if inside a loop. */ 43static bfd_boolean ifc_loop_aware = FALSE; /* Ignore ifc if inside a loop. */ 44 45/* Save the target options into output bfd to avoid using to many global 46 variables. Do this after the output has been created, but before 47 inputs are read. */ 48static void 49nds32_elf_create_output_section_statements (void) 50{ 51 if (strstr (bfd_get_target (link_info.output_bfd), "nds32") == NULL) 52 { 53 /* Check the output target is nds32. */ 54 einfo (_("%F%X%P: error: Cannot change output format whilst " 55 "linking NDS32 binaries.\n")); 56 return; 57 } 58 59 bfd_elf32_nds32_set_target_option (&link_info, relax_fp_as_gp, 60 eliminate_gc_relocs, 61 sym_ld_script, 62 load_store_relax, 63 target_optimize, relax_status, relax_round, 64 ex9_export_file, ex9_import_file, 65 update_ex9_table, ex9_limit, 66 ex9_loop_aware, ifc_loop_aware); 67} 68 69static void 70nds32_elf_after_parse (void) 71{ 72 if (bfd_link_relocatable (&link_info)) 73 DISABLE_RELAXATION; 74 75 if (!RELAXATION_ENABLED) 76 { 77 target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON); 78 target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON); 79 relax_fp_as_gp = 0; 80 } 81 82 if (ex9_import_file != NULL) 83 { 84 ex9_export_file = NULL; 85 target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON); 86 } 87 else 88 update_ex9_table = 0; 89 90 if (bfd_link_pic (&link_info)) 91 { 92 target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON); 93 target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON); 94 } 95 96 gld${EMULATION_NAME}_after_parse (); 97} 98 99static void 100nds32_elf_after_open (void) 101{ 102 unsigned int arch_ver = (unsigned int)-1; 103 unsigned int abi_ver = (unsigned int)-1; 104 bfd *abfd; 105 106 /* For now, make sure all object files are of the same architecture. 107 We may try to merge object files with different architecture together. */ 108 for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next) 109 { 110 if (arch_ver == (unsigned int)-1 && E_N1_ARCH != (elf_elfheader (abfd)->e_flags & EF_NDS_ARCH)) 111 arch_ver = elf_elfheader (abfd)->e_flags & EF_NDS_ARCH ; 112 113 if (abi_ver == (unsigned int)-1) 114 { 115 /* Initialize ABI version, if not ABI0. 116 (OS uses empty file to create empty ELF with ABI0). */ 117 if ((elf_elfheader (abfd)->e_flags & EF_NDS_ABI) != 0) 118 abi_ver = elf_elfheader (abfd)->e_flags & EF_NDS_ABI ; 119 } 120 else if ((elf_elfheader (abfd)->e_flags & EF_NDS_ABI) != 0 121 && abi_ver != (elf_elfheader (abfd)->e_flags & EF_NDS_ABI)) 122 { 123 /* Incompatible objects. */ 124 einfo (_("%F%B: ABI version of object files mismatched\n"), abfd); 125 } 126 127#if defined NDS32_EX9_EXT 128 /* Append .ex9.itable section in the last input object file. */ 129 if (abfd->link_next == NULL && (target_optimize & NDS32_RELAX_EX9_ON)) 130 { 131 asection *itable; 132 struct bfd_link_hash_entry *h; 133 itable = bfd_make_section_with_flags (abfd, ".ex9.itable", 134 SEC_CODE | SEC_ALLOC | SEC_LOAD 135 | SEC_HAS_CONTENTS | SEC_READONLY 136 | SEC_IN_MEMORY | SEC_KEEP); 137 if (itable) 138 { 139 itable->gc_mark = 1; 140 itable->alignment_power = 2; 141 itable->size = 0x1000; 142 itable->contents = bfd_zalloc (abfd, itable->size); 143 144 /* Add a symbol in the head of ex9.itable to objdump clearly. */ 145 h = bfd_link_hash_lookup (link_info.hash, "_EX9_BASE_", 146 FALSE, FALSE, FALSE); 147 _bfd_generic_link_add_one_symbol 148 (&link_info, link_info.output_bfd, "_EX9_BASE_", 149 BSF_GLOBAL | BSF_WEAK, itable, 0, (const char *) NULL, FALSE, 150 get_elf_backend_data (link_info.output_bfd)->collect, &h); 151 } 152 } 153#endif 154 } 155 156 /* Check object files if the target is dynamic linked executable 157 or shared object. */ 158 if (elf_hash_table (&link_info)->dynamic_sections_created 159 || bfd_link_pic (&link_info)) 160 { 161 for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next) 162 { 163 if (!(elf_elfheader (abfd)->e_flags & E_NDS32_HAS_PIC)) 164 { 165 /* Non-PIC object file is used. */ 166 if (bfd_link_pic (&link_info)) 167 { 168 /* For PIE or shared object, all input must be PIC. */ 169 einfo (_("%B: must use -fpic to compile this file " 170 "for shared object or PIE\n"), abfd); 171 } 172 else 173 { 174 /* Dynamic linked executable with SDA and non-PIC. 175 Turn off load/store relaxtion. */ 176 /* TODO: This may support in the future. */ 177 load_store_relax = 0 ; 178 relax_fp_as_gp = 0; 179 } 180 } 181 } 182 /* Turn off relax when building shared object or PIE 183 until we can support their relaxation. */ 184 } 185 186 /* Call the standard elf routine. */ 187 gld${EMULATION_NAME}_after_open (); 188} 189 190static void 191nds32_elf_after_allocation (void) 192{ 193 if (target_optimize & NDS32_RELAX_EX9_ON 194 || (ex9_import_file != NULL && update_ex9_table == 1)) 195 { 196 /* Initialize ex9 hash table. */ 197 if (!nds32_elf_ex9_init ()) 198 return; 199 } 200 201 /* Call default after allocation callback. 202 1. This is where relaxation is done. 203 2. It calls gld${EMULATION_NAME}_map_segments to build ELF segment table. 204 3. Any relaxation requires relax being done must be called after it. */ 205 gld${EMULATION_NAME}_after_allocation (); 206} 207 208EOF 209# Define some shell vars to insert bits of code into the standard elf 210# parse_args and list_options functions. 211# 212PARSE_AND_LIST_PROLOGUE=' 213#define OPTION_BASELINE 301 214#define OPTION_ELIM_GC_RELOCS (OPTION_BASELINE + 1) 215#define OPTION_FP_AS_GP (OPTION_BASELINE + 2) 216#define OPTION_NO_FP_AS_GP (OPTION_BASELINE + 3) 217#define OPTION_REDUCE_FP_UPDATE (OPTION_BASELINE + 4) 218#define OPTION_NO_REDUCE_FP_UPDATE (OPTION_BASELINE + 5) 219#define OPTION_EXPORT_SYMBOLS (OPTION_BASELINE + 6) 220 221/* These are only available to ex9. */ 222#if defined NDS32_EX9_EXT 223#define OPTION_EX9_BASELINE 320 224#define OPTION_EX9_TABLE (OPTION_EX9_BASELINE + 1) 225#define OPTION_NO_EX9_TABLE (OPTION_EX9_BASELINE + 2) 226#define OPTION_EXPORT_EX9 (OPTION_EX9_BASELINE + 3) 227#define OPTION_IMPORT_EX9 (OPTION_EX9_BASELINE + 4) 228#define OPTION_UPDATE_EX9 (OPTION_EX9_BASELINE + 5) 229#define OPTION_EX9_LIMIT (OPTION_EX9_BASELINE + 6) 230#define OPTION_EX9_LOOP (OPTION_EX9_BASELINE + 7) 231#endif 232 233/* These are only available to link-time ifc. */ 234#if defined NDS32_IFC_EXT 235#define OPTION_IFC_BASELINE 340 236#define OPTION_JUMP_IFC (OPTION_IFC_BASELINE + 1) 237#define OPTION_NO_JUMP_IFC (OPTION_IFC_BASELINE + 2) 238#define OPTION_IFC_LOOP (OPTION_IFC_BASELINE + 3) 239#endif 240' 241PARSE_AND_LIST_LONGOPTS=' 242 { "mfp-as-gp", no_argument, NULL, OPTION_FP_AS_GP}, 243 { "mno-fp-as-gp", no_argument, NULL, OPTION_NO_FP_AS_GP}, 244 { "mexport-symbols", required_argument, NULL, OPTION_EXPORT_SYMBOLS}, 245 /* These are deprecated options. Remove them in the future. */ 246 { "mrelax-reduce-fp-update", no_argument, NULL, OPTION_REDUCE_FP_UPDATE}, 247 { "mrelax-no-reduce-fp-update", no_argument, NULL, OPTION_NO_REDUCE_FP_UPDATE}, 248 { "mbaseline", required_argument, NULL, OPTION_BASELINE}, 249 { "meliminate-gc-relocs", no_argument, NULL, OPTION_ELIM_GC_RELOCS}, 250 { "mrelax-omit-fp", no_argument, NULL, OPTION_FP_AS_GP}, 251 { "mrelax-no-omit-fp", no_argument, NULL, OPTION_NO_FP_AS_GP}, 252 { "mgen-symbol-ld-script", required_argument, NULL, OPTION_EXPORT_SYMBOLS}, 253 /* These are specific optioins for ex9-ext support. */ 254#if defined NDS32_EX9_EXT 255 { "mex9", no_argument, NULL, OPTION_EX9_TABLE}, 256 { "mno-ex9", no_argument, NULL, OPTION_NO_EX9_TABLE}, 257 { "mexport-ex9", required_argument, NULL, OPTION_EXPORT_EX9}, 258 { "mimport-ex9", required_argument, NULL, OPTION_IMPORT_EX9}, 259 { "mupdate-ex9", no_argument, NULL, OPTION_UPDATE_EX9}, 260 { "mex9-limit", required_argument, NULL, OPTION_EX9_LIMIT}, 261 { "mex9-loop-aware", no_argument, NULL, OPTION_EX9_LOOP}, 262#endif 263 /* These are specific optioins for ifc-ext support. */ 264#if defined NDS32_IFC_EXT 265 { "mifc", no_argument, NULL, OPTION_JUMP_IFC}, 266 { "mno-ifc", no_argument, NULL, OPTION_NO_JUMP_IFC}, 267 { "mifc-loop-aware", no_argument, NULL, OPTION_IFC_LOOP}, 268#endif 269' 270PARSE_AND_LIST_OPTIONS=' 271 fprintf (file, _("\ 272 --m[no-]fp-as-gp Disable/enable fp-as-gp relaxation\n\ 273 --mexport-symbols=FILE Exporting symbols in linker script\n\ 274")); 275 276#if defined NDS32_EX9_EXT 277 fprintf (file, _("\ 278 --m[no-]ex9 Disable/enable link-time EX9 relaxation\n\ 279 --mexport-ex9=FILE Export EX9 table after linking\n\ 280 --mimport-ex9=FILE Import Ex9 table for EX9 relaxation\n\ 281 --mupdate-ex9 Update existing EX9 table\n\ 282 --mex9-limit=NUM Maximum number of entries in ex9 table\n\ 283 --mex9-loop-aware Avoid generate EX9 instruction inside loop\n\ 284")); 285#endif 286 287#if defined NDS32_IFC_EXT 288 fprintf (file, _("\ 289 --m[no-]ifc Disable/enable link-time IFC optimization\n\ 290 --mifc-loop-aware Avoid generate IFC instruction inside loop\n\ 291")); 292#endif 293' 294PARSE_AND_LIST_ARGS_CASES=' 295 case OPTION_BASELINE: 296 einfo (_("%P: --mbaseline is not used anymore.\n")); 297 break; 298 case OPTION_ELIM_GC_RELOCS: 299 eliminate_gc_relocs = 1; 300 break; 301 case OPTION_FP_AS_GP: 302 case OPTION_NO_FP_AS_GP: 303 relax_fp_as_gp = (optc == OPTION_FP_AS_GP); 304 break; 305 case OPTION_REDUCE_FP_UPDATE: 306 case OPTION_NO_REDUCE_FP_UPDATE: 307 einfo (_("%P: --relax-[no-]reduce-fp-updat is not used anymore.\n")); 308 break; 309 case OPTION_EXPORT_SYMBOLS: 310 if (!optarg) 311 einfo (_("Missing file for --mexport-symbols.\n"), optarg); 312 313 if(strcmp (optarg, "-") == 0) 314 sym_ld_script = stdout; 315 else 316 { 317 sym_ld_script = fopen (optarg, FOPEN_WT); 318 if(sym_ld_script == NULL) 319 einfo (_("%P%F: cannot open map file %s: %E.\n"), optarg); 320 } 321 break; 322#if defined NDS32_EX9_EXT 323 case OPTION_EX9_TABLE: 324 target_optimize = target_optimize | NDS32_RELAX_EX9_ON; 325 break; 326 case OPTION_NO_EX9_TABLE: 327 target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON); 328 break; 329 case OPTION_EXPORT_EX9: 330 if (!optarg) 331 einfo (_("Missing file for --mexport-ex9=<file>.\n")); 332 333 if(strcmp (optarg, "-") == 0) 334 ex9_export_file = stdout; 335 else 336 { 337 ex9_export_file = fopen (optarg, "wb"); 338 if(ex9_export_file == NULL) 339 einfo (_("ERROR %P%F: cannot open ex9 export file %s.\n"), optarg); 340 } 341 break; 342 case OPTION_IMPORT_EX9: 343 if (!optarg) 344 einfo (_("Missing file for --mimport-ex9=<file>.\n")); 345 346 ex9_import_file = fopen (optarg, "rb+"); 347 if(ex9_import_file == NULL) 348 einfo (_("ERROR %P%F: cannot open ex9 import file %s.\n"), optarg); 349 break; 350 case OPTION_UPDATE_EX9: 351 update_ex9_table = 1; 352 break; 353 case OPTION_EX9_LIMIT: 354 if (optarg) 355 { 356 ex9_limit = atoi (optarg); 357 if (ex9_limit > 511 || ex9_limit < 1) 358 { 359 einfo (_("ERROR: the range of ex9_limit must between 1 and 511\n")); 360 exit (1); 361 } 362 } 363 break; 364 case OPTION_EX9_LOOP: 365 target_optimize = target_optimize | NDS32_RELAX_EX9_ON; 366 ex9_loop_aware = 1; 367 break; 368#endif 369#if defined NDS32_IFC_EXT 370 case OPTION_JUMP_IFC: 371 target_optimize = target_optimize | NDS32_RELAX_JUMP_IFC_ON; 372 break; 373 case OPTION_NO_JUMP_IFC: 374 target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON); 375 break; 376 case OPTION_IFC_LOOP: 377 target_optimize = target_optimize | NDS32_RELAX_JUMP_IFC_ON; 378 ifc_loop_aware = 1; 379 break; 380#endif 381' 382LDEMUL_AFTER_OPEN=nds32_elf_after_open 383LDEMUL_AFTER_PARSE=nds32_elf_after_parse 384LDEMUL_AFTER_ALLOCATION=nds32_elf_after_allocation 385LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=nds32_elf_create_output_section_statements 386