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%P: error: cannot change output format whilst " 55 "linking %s binaries\n"), "NDS32"); 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%P: %pB: ABI version of object files mismatched\n"), 125 abfd); 126 } 127 128#if defined NDS32_EX9_EXT 129 /* Append .ex9.itable section in the last input object file. */ 130 if (abfd->link_next == NULL && (target_optimize & NDS32_RELAX_EX9_ON)) 131 { 132 asection *itable; 133 struct bfd_link_hash_entry *h; 134 itable = bfd_make_section_with_flags (abfd, ".ex9.itable", 135 SEC_CODE | SEC_ALLOC | SEC_LOAD 136 | SEC_HAS_CONTENTS | SEC_READONLY 137 | SEC_IN_MEMORY | SEC_KEEP); 138 if (itable) 139 { 140 itable->gc_mark = 1; 141 itable->alignment_power = 2; 142 itable->size = 0x1000; 143 itable->contents = bfd_zalloc (abfd, itable->size); 144 145 /* Add a symbol in the head of ex9.itable to objdump clearly. */ 146 h = bfd_link_hash_lookup (link_info.hash, "_EX9_BASE_", 147 FALSE, FALSE, FALSE); 148 _bfd_generic_link_add_one_symbol 149 (&link_info, link_info.output_bfd, "_EX9_BASE_", 150 BSF_GLOBAL | BSF_WEAK, itable, 0, (const char *) NULL, FALSE, 151 get_elf_backend_data (link_info.output_bfd)->collect, &h); 152 } 153 } 154#endif 155 } 156 157 /* Check object files if the target is dynamic linked executable 158 or shared object. */ 159 if (elf_hash_table (&link_info)->dynamic_sections_created 160 || bfd_link_pic (&link_info)) 161 { 162 for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next) 163 { 164 if (!(elf_elfheader (abfd)->e_flags & E_NDS32_HAS_PIC)) 165 { 166 /* Non-PIC object file is used. */ 167 if (bfd_link_pic (&link_info)) 168 { 169 /* For PIE or shared object, all input must be PIC. */ 170 einfo (_("%P: %pB: must use -fpic to compile this file " 171 "for shared object or PIE\n"), abfd); 172 } 173 else 174 { 175 /* Dynamic linked executable with SDA and non-PIC. 176 Turn off load/store relaxtion. */ 177 /* TODO: This may support in the future. */ 178 load_store_relax = 0 ; 179 relax_fp_as_gp = 0; 180 } 181 } 182 } 183 /* Turn off relax when building shared object or PIE 184 until we can support their relaxation. */ 185 } 186 187 /* Call the standard elf routine. */ 188 gld${EMULATION_NAME}_after_open (); 189} 190 191static void 192nds32_elf_after_allocation (void) 193{ 194 /* Call default after allocation callback. 195 1. This is where relaxation is done. 196 2. It calls gld${EMULATION_NAME}_map_segments to build ELF segment table. 197 3. Any relaxation requires relax being done must be called after it. */ 198 gld${EMULATION_NAME}_after_allocation (); 199} 200 201EOF 202# Define some shell vars to insert bits of code into the standard elf 203# parse_args and list_options functions. 204# 205PARSE_AND_LIST_PROLOGUE=' 206#define OPTION_BASELINE 301 207#define OPTION_ELIM_GC_RELOCS (OPTION_BASELINE + 1) 208#define OPTION_FP_AS_GP (OPTION_BASELINE + 2) 209#define OPTION_NO_FP_AS_GP (OPTION_BASELINE + 3) 210#define OPTION_REDUCE_FP_UPDATE (OPTION_BASELINE + 4) 211#define OPTION_NO_REDUCE_FP_UPDATE (OPTION_BASELINE + 5) 212#define OPTION_EXPORT_SYMBOLS (OPTION_BASELINE + 6) 213 214/* These are only available to ex9. */ 215#if defined NDS32_EX9_EXT 216#define OPTION_EX9_BASELINE 320 217#define OPTION_EX9_TABLE (OPTION_EX9_BASELINE + 1) 218#define OPTION_NO_EX9_TABLE (OPTION_EX9_BASELINE + 2) 219#define OPTION_EXPORT_EX9 (OPTION_EX9_BASELINE + 3) 220#define OPTION_IMPORT_EX9 (OPTION_EX9_BASELINE + 4) 221#define OPTION_UPDATE_EX9 (OPTION_EX9_BASELINE + 5) 222#define OPTION_EX9_LIMIT (OPTION_EX9_BASELINE + 6) 223#define OPTION_EX9_LOOP (OPTION_EX9_BASELINE + 7) 224#endif 225 226/* These are only available to link-time ifc. */ 227#if defined NDS32_IFC_EXT 228#define OPTION_IFC_BASELINE 340 229#define OPTION_JUMP_IFC (OPTION_IFC_BASELINE + 1) 230#define OPTION_NO_JUMP_IFC (OPTION_IFC_BASELINE + 2) 231#define OPTION_IFC_LOOP (OPTION_IFC_BASELINE + 3) 232#endif 233' 234PARSE_AND_LIST_LONGOPTS=' 235 { "mfp-as-gp", no_argument, NULL, OPTION_FP_AS_GP}, 236 { "mno-fp-as-gp", no_argument, NULL, OPTION_NO_FP_AS_GP}, 237 { "mexport-symbols", required_argument, NULL, OPTION_EXPORT_SYMBOLS}, 238 /* These are deprecated options. Remove them in the future. */ 239 { "mrelax-reduce-fp-update", no_argument, NULL, OPTION_REDUCE_FP_UPDATE}, 240 { "mrelax-no-reduce-fp-update", no_argument, NULL, OPTION_NO_REDUCE_FP_UPDATE}, 241 { "mbaseline", required_argument, NULL, OPTION_BASELINE}, 242 { "meliminate-gc-relocs", no_argument, NULL, OPTION_ELIM_GC_RELOCS}, 243 { "mrelax-omit-fp", no_argument, NULL, OPTION_FP_AS_GP}, 244 { "mrelax-no-omit-fp", no_argument, NULL, OPTION_NO_FP_AS_GP}, 245 { "mgen-symbol-ld-script", required_argument, NULL, OPTION_EXPORT_SYMBOLS}, 246 /* These are specific optioins for ex9-ext support. */ 247#if defined NDS32_EX9_EXT 248 { "mex9", no_argument, NULL, OPTION_EX9_TABLE}, 249 { "mno-ex9", no_argument, NULL, OPTION_NO_EX9_TABLE}, 250 { "mexport-ex9", required_argument, NULL, OPTION_EXPORT_EX9}, 251 { "mimport-ex9", required_argument, NULL, OPTION_IMPORT_EX9}, 252 { "mupdate-ex9", no_argument, NULL, OPTION_UPDATE_EX9}, 253 { "mex9-limit", required_argument, NULL, OPTION_EX9_LIMIT}, 254 { "mex9-loop-aware", no_argument, NULL, OPTION_EX9_LOOP}, 255#endif 256 /* These are specific optioins for ifc-ext support. */ 257#if defined NDS32_IFC_EXT 258 { "mifc", no_argument, NULL, OPTION_JUMP_IFC}, 259 { "mno-ifc", no_argument, NULL, OPTION_NO_JUMP_IFC}, 260 { "mifc-loop-aware", no_argument, NULL, OPTION_IFC_LOOP}, 261#endif 262' 263PARSE_AND_LIST_OPTIONS=' 264 fprintf (file, _("\ 265 --m[no-]fp-as-gp Disable/enable fp-as-gp relaxation\n")); 266 fprintf (file, _("\ 267 --mexport-symbols=FILE Exporting symbols in linker script\n")); 268 269#if defined NDS32_EX9_EXT 270 fprintf (file, _("\ 271 --m[no-]ex9 Disable/enable link-time EX9 relaxation\n")); 272 fprintf (file, _("\ 273 --mexport-ex9=FILE Export EX9 table after linking\n")); 274 fprintf (file, _("\ 275 --mimport-ex9=FILE Import Ex9 table for EX9 relaxation\n")); 276 fprintf (file, _("\ 277 --mupdate-ex9 Update existing EX9 table\n")); 278 fprintf (file, _("\ 279 --mex9-limit=NUM Maximum number of entries in ex9 table\n")); 280 fprintf (file, _("\ 281 --mex9-loop-aware Avoid generate EX9 instruction inside loop\n")); 282#endif 283 284#if defined NDS32_IFC_EXT 285 fprintf (file, _("\ 286 --m[no-]ifc Disable/enable link-time IFC optimization\n")); 287 fprintf (file, _("\ 288 --mifc-loop-aware Avoid generate IFC instruction inside loop\n")); 289#endif 290' 291PARSE_AND_LIST_ARGS_CASES=' 292 case OPTION_BASELINE: 293 einfo (_("%P: --mbaseline is not used anymore\n")); 294 break; 295 case OPTION_ELIM_GC_RELOCS: 296 eliminate_gc_relocs = 1; 297 break; 298 case OPTION_FP_AS_GP: 299 case OPTION_NO_FP_AS_GP: 300 relax_fp_as_gp = (optc == OPTION_FP_AS_GP); 301 break; 302 case OPTION_REDUCE_FP_UPDATE: 303 case OPTION_NO_REDUCE_FP_UPDATE: 304 einfo (_("%P: --relax-[no-]reduce-fp-updat is not used anymore\n")); 305 break; 306 case OPTION_EXPORT_SYMBOLS: 307 if (!optarg) 308 einfo (_("%P: missing file for --mexport-symbols\n"), optarg); 309 310 if(strcmp (optarg, "-") == 0) 311 sym_ld_script = stdout; 312 else 313 { 314 sym_ld_script = fopen (optarg, FOPEN_WT); 315 if(sym_ld_script == NULL) 316 einfo (_("%F%P: cannot open map file %s: %E\n"), optarg); 317 } 318 break; 319#if defined NDS32_EX9_EXT 320 case OPTION_EX9_TABLE: 321 target_optimize = target_optimize | NDS32_RELAX_EX9_ON; 322 break; 323 case OPTION_NO_EX9_TABLE: 324 target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON); 325 break; 326 case OPTION_EXPORT_EX9: 327 if (!optarg) 328 einfo (_("%P: missing file for --mexport-ex9=<file>\n")); 329 330 if(strcmp (optarg, "-") == 0) 331 ex9_export_file = stdout; 332 else 333 { 334 ex9_export_file = fopen (optarg, "wb"); 335 if(ex9_export_file == NULL) 336 einfo (_("%F%P: cannot open ex9 export file %s\n"), optarg); 337 } 338 break; 339 case OPTION_IMPORT_EX9: 340 if (!optarg) 341 einfo (_("%P: missing file for --mimport-ex9=<file>\n")); 342 343 ex9_import_file = fopen (optarg, "rb+"); 344 if(ex9_import_file == NULL) 345 einfo (_("%F%P: cannot open ex9 import file %s\n"), optarg); 346 break; 347 case OPTION_UPDATE_EX9: 348 update_ex9_table = 1; 349 break; 350 case OPTION_EX9_LIMIT: 351 if (optarg) 352 { 353 ex9_limit = atoi (optarg); 354 if (ex9_limit > 511 || ex9_limit < 1) 355 einfo (_("%F%P: the range of ex9_limit must between 1 and 511\n")); 356 } 357 break; 358 case OPTION_EX9_LOOP: 359 target_optimize = target_optimize | NDS32_RELAX_EX9_ON; 360 ex9_loop_aware = 1; 361 break; 362#endif 363#if defined NDS32_IFC_EXT 364 case OPTION_JUMP_IFC: 365 target_optimize = target_optimize | NDS32_RELAX_JUMP_IFC_ON; 366 break; 367 case OPTION_NO_JUMP_IFC: 368 target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON); 369 break; 370 case OPTION_IFC_LOOP: 371 target_optimize = target_optimize | NDS32_RELAX_JUMP_IFC_ON; 372 ifc_loop_aware = 1; 373 break; 374#endif 375' 376LDEMUL_AFTER_OPEN=nds32_elf_after_open 377LDEMUL_AFTER_PARSE=nds32_elf_after_parse 378LDEMUL_AFTER_ALLOCATION=nds32_elf_after_allocation 379LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=nds32_elf_create_output_section_statements 380