Home | History | Annotate | Download | only in emultempl
      1 # This shell script emits a C file. -*- C -*-
      2 # Copyright (C) 2012-2014 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 
     23 fragment <<EOF
     24 
     25 #include "libbfd.h"
     26 #include "elf-bfd.h"
     27 #include "elf/nds32.h"
     28 #include "bfd_stdint.h"
     29 #include "elf32-nds32.h"
     30 
     31 static int relax_fp_as_gp = 1;		/* --mrelax-omit-fp  */
     32 static int eliminate_gc_relocs = 0;	/* --meliminate-gc-relocs  */
     33 static FILE *sym_ld_script = NULL;	/* --mgen-symbol-ld-script=<file>  */
     34 /* Disable if linking a dynamically linked executable.  */
     35 static int load_store_relax = 1;
     36 static int target_optimize = 0;	/* Switch optimization.  */
     37 static int relax_status = 0;	/* Finished optimization.  */
     38 static int relax_round = 0;		/* Going optimization.  */
     39 static FILE *ex9_export_file = NULL;	/* --mexport-ex9=<file>  */
     40 static FILE *ex9_import_file = NULL;	/* --mimport-ex9=<file>  */
     41 static int update_ex9_table = 0;	/* --mupdate-ex9.  */
     42 static int ex9_limit = 511;
     43 static bfd_boolean ex9_loop_aware = FALSE;	/* Ignore ex9 if inside a loop.  */
     44 static bfd_boolean ifc_loop_aware = FALSE;	/* Ignore ifc if inside a loop.  */
     45 
     46 /* Save the target options into output bfd to avoid using to many global
     47    variables. Do this after the output has been created, but before
     48    inputs are read.  */
     49 static void
     50 nds32_elf_create_output_section_statements (void)
     51 {
     52   if (strstr (bfd_get_target (link_info.output_bfd), "nds32") == NULL)
     53     {
     54       /* Check the output target is nds32.  */
     55       einfo ("%F%X%P: error: Cannot change output format whilst "
     56 	     "linking NDS32 binaries.\n");
     57       return;
     58     }
     59 
     60   bfd_elf32_nds32_set_target_option (&link_info, relax_fp_as_gp,
     61 				     eliminate_gc_relocs,
     62 				     sym_ld_script,
     63 				     load_store_relax,
     64 				     target_optimize, relax_status, relax_round,
     65 				     ex9_export_file, ex9_import_file,
     66 				     update_ex9_table, ex9_limit,
     67 				     ex9_loop_aware, ifc_loop_aware);
     68 }
     69 
     70 static void
     71 nds32_elf_after_parse (void)
     72 {
     73   if (link_info.relocatable)
     74     DISABLE_RELAXATION;
     75 
     76   if (!RELAXATION_ENABLED)
     77     {
     78       target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON);
     79       target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON);
     80       relax_fp_as_gp = 0;
     81     }
     82 
     83   if (ex9_import_file != NULL)
     84     {
     85       ex9_export_file = NULL;
     86       target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON);
     87     }
     88   else
     89     update_ex9_table = 0;
     90 
     91   if (link_info.shared)
     92     {
     93       target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON);
     94       target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON);
     95     }
     96 
     97   after_parse_default ();
     98 }
     99 
    100 static void
    101 nds32_elf_after_open (void)
    102 {
    103   unsigned int arch_ver = (unsigned int)-1;
    104   unsigned int abi_ver = (unsigned int)-1;
    105   bfd *abfd;
    106 
    107   /* For now, make sure all object files are of the same architecture.
    108      We may try to merge object files with different architecture together.  */
    109   for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
    110     {
    111       if (arch_ver == (unsigned int)-1 && E_N1_ARCH != (elf_elfheader (abfd)->e_flags & EF_NDS_ARCH))
    112 	arch_ver = elf_elfheader (abfd)->e_flags & EF_NDS_ARCH ;
    113 
    114       if (abi_ver == (unsigned int)-1)
    115 	{
    116 	  /* Initialize ABI version, if not ABI0.
    117 	     (OS uses empty file to create empty ELF with ABI0).  */
    118 	  if ((elf_elfheader (abfd)->e_flags & EF_NDS_ABI) != 0)
    119 	    abi_ver = elf_elfheader (abfd)->e_flags & EF_NDS_ABI ;
    120 	}
    121       else if ((elf_elfheader (abfd)->e_flags & EF_NDS_ABI) != 0
    122 	       && abi_ver != (elf_elfheader (abfd)->e_flags & EF_NDS_ABI))
    123 	{
    124 	  /* Incompatible objects.  */
    125 	  einfo (_("%F%B: ABI version of object files mismatched\n"), 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       || link_info.shared || link_info.pie)
    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 (link_info.shared || link_info.pie)
    168 		{
    169 		  /* For PIE or shared object, all input must be PIC.  */
    170 		  einfo (_("%B: 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 
    191 static void
    192 nds32_elf_after_allocation (void)
    193 {
    194   if (target_optimize & NDS32_RELAX_EX9_ON
    195       || (ex9_import_file != NULL && update_ex9_table == 1))
    196     {
    197       /* Initialize ex9 hash table.  */
    198       if (!nds32_elf_ex9_init ())
    199         return;
    200     }
    201 
    202   /* Call default after allocation callback.
    203      1. This is where relaxation is done.
    204      2. It calls gld${EMULATION_NAME}_map_segments to build ELF segment table.
    205      3. Any relaxation requires relax being done must be called after it.  */
    206   gld${EMULATION_NAME}_after_allocation ();
    207 }
    208 
    209 EOF
    210 # Define some shell vars to insert bits of code into the standard elf
    211 # parse_args and list_options functions.
    212 #
    213 PARSE_AND_LIST_PROLOGUE='
    214 #define OPTION_BASELINE			301
    215 #define OPTION_ELIM_GC_RELOCS		(OPTION_BASELINE + 1)
    216 #define OPTION_FP_AS_GP			(OPTION_BASELINE + 2)
    217 #define OPTION_NO_FP_AS_GP		(OPTION_BASELINE + 3)
    218 #define OPTION_REDUCE_FP_UPDATE		(OPTION_BASELINE + 4)
    219 #define OPTION_NO_REDUCE_FP_UPDATE	(OPTION_BASELINE + 5)
    220 #define OPTION_EXPORT_SYMBOLS		(OPTION_BASELINE + 6)
    221 
    222 /* These are only available to ex9.  */
    223 #if defined NDS32_EX9_EXT
    224 #define OPTION_EX9_BASELINE		320
    225 #define OPTION_EX9_TABLE		(OPTION_EX9_BASELINE + 1)
    226 #define OPTION_NO_EX9_TABLE		(OPTION_EX9_BASELINE + 2)
    227 #define OPTION_EXPORT_EX9		(OPTION_EX9_BASELINE + 3)
    228 #define OPTION_IMPORT_EX9		(OPTION_EX9_BASELINE + 4)
    229 #define OPTION_UPDATE_EX9		(OPTION_EX9_BASELINE + 5)
    230 #define OPTION_EX9_LIMIT		(OPTION_EX9_BASELINE + 6)
    231 #define OPTION_EX9_LOOP			(OPTION_EX9_BASELINE + 7)
    232 #endif
    233 
    234 /* These are only available to link-time ifc.  */
    235 #if defined NDS32_IFC_EXT
    236 #define OPTION_IFC_BASELINE		340
    237 #define OPTION_JUMP_IFC			(OPTION_IFC_BASELINE + 1)
    238 #define OPTION_NO_JUMP_IFC		(OPTION_IFC_BASELINE + 2)
    239 #define OPTION_IFC_LOOP			(OPTION_IFC_BASELINE + 3)
    240 #endif
    241 '
    242 PARSE_AND_LIST_LONGOPTS='
    243   { "mfp-as-gp", no_argument, NULL, OPTION_FP_AS_GP},
    244   { "mno-fp-as-gp", no_argument, NULL, OPTION_NO_FP_AS_GP},
    245   { "mexport-symbols", required_argument, NULL, OPTION_EXPORT_SYMBOLS},
    246   /* These are deprecated options.  Remove them in the future.  */
    247   { "mrelax-reduce-fp-update", no_argument, NULL, OPTION_REDUCE_FP_UPDATE},
    248   { "mrelax-no-reduce-fp-update", no_argument, NULL, OPTION_NO_REDUCE_FP_UPDATE},
    249   { "mbaseline", required_argument, NULL, OPTION_BASELINE},
    250   { "meliminate-gc-relocs", no_argument, NULL, OPTION_ELIM_GC_RELOCS},
    251   { "mrelax-omit-fp", no_argument, NULL, OPTION_FP_AS_GP},
    252   { "mrelax-no-omit-fp", no_argument, NULL, OPTION_NO_FP_AS_GP},
    253   { "mgen-symbol-ld-script", required_argument, NULL, OPTION_EXPORT_SYMBOLS},
    254   /* These are specific optioins for ex9-ext support.  */
    255 #if defined NDS32_EX9_EXT
    256   { "mex9", no_argument, NULL, OPTION_EX9_TABLE},
    257   { "mno-ex9", no_argument, NULL, OPTION_NO_EX9_TABLE},
    258   { "mexport-ex9", required_argument, NULL, OPTION_EXPORT_EX9},
    259   { "mimport-ex9", required_argument, NULL, OPTION_IMPORT_EX9},
    260   { "mupdate-ex9", no_argument, NULL, OPTION_UPDATE_EX9},
    261   { "mex9-limit", required_argument, NULL, OPTION_EX9_LIMIT},
    262   { "mex9-loop-aware", no_argument, NULL, OPTION_EX9_LOOP},
    263 #endif
    264   /* These are specific optioins for ifc-ext support.  */
    265 #if defined NDS32_IFC_EXT
    266   { "mifc", no_argument, NULL, OPTION_JUMP_IFC},
    267   { "mno-ifc", no_argument, NULL, OPTION_NO_JUMP_IFC},
    268   { "mifc-loop-aware", no_argument, NULL, OPTION_IFC_LOOP},
    269 #endif
    270 '
    271 PARSE_AND_LIST_OPTIONS='
    272   fprintf (file, _("\
    273   --m[no-]fp-as-gp            Disable/enable fp-as-gp relaxation\n\
    274   --mexport-symbols=FILE      Exporting symbols in linker script\n\
    275 "));
    276 
    277 #if defined NDS32_EX9_EXT
    278   fprintf (file, _("\
    279   --m[no-]ex9                 Disable/enable link-time EX9 relaxation\n\
    280   --mexport-ex9=FILE          Export EX9 table after linking\n\
    281   --mimport-ex9=FILE          Import Ex9 table for EX9 relaxation\n\
    282   --mupdate-ex9               Update existing EX9 table\n\
    283   --mex9-limit=NUM            Maximum number of entries in ex9 table\n\
    284   --mex9-loop-aware           Avoid generate EX9 instruction inside loop\n\
    285 "));
    286 #endif
    287 
    288 #if defined NDS32_IFC_EXT
    289   fprintf (file, _("\
    290   --m[no-]ifc                 Disable/enable link-time IFC optimization\n\
    291   --mifc-loop-aware           Avoid generate IFC instruction inside loop\n\
    292 "));
    293 #endif
    294 '
    295 PARSE_AND_LIST_ARGS_CASES='
    296   case OPTION_BASELINE:
    297     einfo ("%P: --mbaseline is not used anymore.\n");
    298     break;
    299   case OPTION_ELIM_GC_RELOCS:
    300     eliminate_gc_relocs = 1;
    301     break;
    302   case OPTION_FP_AS_GP:
    303   case OPTION_NO_FP_AS_GP:
    304     relax_fp_as_gp = (optc == OPTION_FP_AS_GP);
    305     break;
    306   case OPTION_REDUCE_FP_UPDATE:
    307   case OPTION_NO_REDUCE_FP_UPDATE:
    308     einfo ("%P: --relax-[no-]reduce-fp-updat is not used anymore.\n");
    309     break;
    310   case OPTION_EXPORT_SYMBOLS:
    311     if (!optarg)
    312       einfo (_("Missing file for --mexport-symbols.\n"), optarg);
    313 
    314     if(strcmp (optarg, "-") == 0)
    315       sym_ld_script = stdout;
    316     else
    317       {
    318 	sym_ld_script = fopen (optarg, FOPEN_WT);
    319 	if(sym_ld_script == NULL)
    320 	  einfo (_("%P%F: cannot open map file %s: %E.\n"), optarg);
    321       }
    322     break;
    323 #if defined NDS32_EX9_EXT
    324   case OPTION_EX9_TABLE:
    325     target_optimize = target_optimize | NDS32_RELAX_EX9_ON;
    326     break;
    327   case OPTION_NO_EX9_TABLE:
    328     target_optimize = target_optimize & (!NDS32_RELAX_EX9_ON);
    329     break;
    330   case OPTION_EXPORT_EX9:
    331     if (!optarg)
    332       einfo (_("Missing file for --mexport-ex9=<file>.\n"));
    333 
    334     if(strcmp (optarg, "-") == 0)
    335       ex9_export_file = stdout;
    336     else
    337       {
    338 	ex9_export_file = fopen (optarg, "wb");
    339 	if(ex9_export_file == NULL)
    340 	  einfo (_("ERROR %P%F: cannot open ex9 export file %s.\n"), optarg);
    341       }
    342     break;
    343   case OPTION_IMPORT_EX9:
    344     if (!optarg)
    345       einfo (_("Missing file for --mimport-ex9=<file>.\n"));
    346 
    347     ex9_import_file = fopen (optarg, "rb+");
    348     if(ex9_import_file == NULL)
    349       einfo (_("ERROR %P%F: cannot open ex9 import file %s.\n"), optarg);
    350     break;
    351   case OPTION_UPDATE_EX9:
    352     update_ex9_table = 1;
    353     break;
    354   case OPTION_EX9_LIMIT:
    355     if (optarg)
    356       {
    357 	ex9_limit = atoi (optarg);
    358 	if (ex9_limit > 511 || ex9_limit < 1)
    359 	  {
    360 	    einfo (_("ERROR: the range of ex9_limit must between 1 and 511\n"));
    361 	    exit (1);
    362 	  }
    363       }
    364     break;
    365   case OPTION_EX9_LOOP:
    366     target_optimize = target_optimize | NDS32_RELAX_EX9_ON;
    367     ex9_loop_aware = 1;
    368     break;
    369 #endif
    370 #if defined NDS32_IFC_EXT
    371   case OPTION_JUMP_IFC:
    372     target_optimize = target_optimize | NDS32_RELAX_JUMP_IFC_ON;
    373     break;
    374   case OPTION_NO_JUMP_IFC:
    375     target_optimize = target_optimize & (!NDS32_RELAX_JUMP_IFC_ON);
    376     break;
    377   case OPTION_IFC_LOOP:
    378     target_optimize = target_optimize | NDS32_RELAX_JUMP_IFC_ON;
    379     ifc_loop_aware = 1;
    380     break;
    381 #endif
    382 '
    383 LDEMUL_AFTER_OPEN=nds32_elf_after_open
    384 LDEMUL_AFTER_PARSE=nds32_elf_after_parse
    385 LDEMUL_AFTER_ALLOCATION=nds32_elf_after_allocation
    386 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=nds32_elf_create_output_section_statements
    387