Home | History | Annotate | Download | only in emultempl
      1 # This shell script emits a C file. -*- C -*-
      2 #   Copyright (C) 2013-2014 Free Software Foundation, Inc.
      3 #
      4 # This file is part of GNU Binutils.
      5 #
      6 # This program is free software; you can redistribute it and/or modify
      7 # it under the terms of the GNU General Public License as published by
      8 # the Free Software Foundation; either version 3 of the License, or
      9 # (at your option) any later version.
     10 #
     11 # This program is distributed in the hope that it will be useful,
     12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 # GNU General Public License for more details.
     15 #
     16 # You should have received a copy of the GNU General Public License
     17 # along with this program; if not, write to the Free Software
     18 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19 # MA 02110-1301, USA.
     20 #
     21 
     22 # This file is sourced from elf32.em, and defines extra Nios II ELF
     23 # specific routines. Taken from metagelf.em.
     24 #
     25 fragment <<EOF
     26 
     27 #include "ldctor.h"
     28 #include "elf32-nios2.h"
     29 
     30 
     31 /* Fake input file for stubs.  */
     32 static lang_input_statement_type *stub_file;
     33 
     34 /* Whether we need to call nios2_layout_sections_again.  */
     35 static int need_laying_out = 0;
     36 
     37 
     38 /* This is called before the input files are opened.  We create a new
     39    fake input file to hold the stub sections.  */
     40 
     41 static void
     42 nios2elf_create_output_section_statements (void)
     43 {
     44   extern const bfd_target nios2_elf32_le_vec, nios2_elf32_be_vec;
     45 
     46   if (link_info.output_bfd->xvec != &nios2_elf32_le_vec
     47       && link_info.output_bfd->xvec != &nios2_elf32_be_vec)
     48     return;
     49 
     50   /* If --no-relax was not explicitly specified by the user, enable
     51      relaxation.  If it's not enabled (either explicitly or by default),
     52      we're done, as we won't need to create any stubs.  */
     53   if (!link_info.relocatable && RELAXATION_DISABLED_BY_DEFAULT)
     54     ENABLE_RELAXATION;
     55   if (!RELAXATION_ENABLED)
     56     return;
     57 
     58   stub_file = lang_add_input_file ("linker stubs",
     59 				   lang_input_file_is_fake_enum,
     60 				   NULL);
     61   stub_file->the_bfd = bfd_create ("linker stubs", link_info.output_bfd);
     62   if (stub_file->the_bfd == NULL
     63       || ! bfd_set_arch_mach (stub_file->the_bfd,
     64 			      bfd_get_arch (link_info.output_bfd),
     65 			      bfd_get_mach (link_info.output_bfd)))
     66     {
     67       einfo ("%X%P: can not create BFD %E\n");
     68       return;
     69     }
     70 
     71   stub_file->the_bfd->flags |= BFD_LINKER_CREATED;
     72   ldlang_add_file (stub_file);
     73 }
     74 
     75 
     76 struct hook_stub_info
     77 {
     78   lang_statement_list_type add;
     79   asection *input_section;
     80 };
     81 
     82 /* Traverse the linker tree to find the spot where the stub goes.  */
     83 
     84 static bfd_boolean
     85 hook_in_stub (struct hook_stub_info *info, lang_statement_union_type **lp,
     86 	      bfd_boolean afterp)
     87 {
     88   lang_statement_union_type *l;
     89   bfd_boolean ret;
     90 
     91   for (; (l = *lp) != NULL; lp = &l->header.next)
     92     {
     93       switch (l->header.type)
     94 	{
     95 	case lang_constructors_statement_enum:
     96 	  ret = hook_in_stub (info, &constructor_list.head, afterp);
     97 	  if (ret)
     98 	    return ret;
     99 	  break;
    100 
    101 	case lang_output_section_statement_enum:
    102 	  ret = hook_in_stub (info,
    103 			      &l->output_section_statement.children.head,
    104 			      afterp);
    105 	  if (ret)
    106 	    return ret;
    107 	  break;
    108 
    109 	case lang_wild_statement_enum:
    110 	  ret = hook_in_stub (info, &l->wild_statement.children.head, afterp);
    111 	  if (ret)
    112 	    return ret;
    113 	  break;
    114 
    115 	case lang_group_statement_enum:
    116 	  ret = hook_in_stub (info, &l->group_statement.children.head, afterp);
    117 	  if (ret)
    118 	    return ret;
    119 	  break;
    120 
    121 	case lang_input_section_enum:
    122 	  if (l->input_section.section == info->input_section)
    123 	    {
    124 	      /* We've found our section.  Insert the stub immediately
    125 		 before or after its associated input section.  */
    126 	      if (afterp)
    127 		{
    128 		  *(info->add.tail) = l->header.next;
    129 		  l->header.next = info->add.head;
    130 		}
    131 	      else
    132 		{
    133 		  *lp = info->add.head;
    134 		  *(info->add.tail) = l;
    135 		}
    136 	      return TRUE;
    137 	    }
    138 	  break;
    139 
    140 	case lang_data_statement_enum:
    141 	case lang_reloc_statement_enum:
    142 	case lang_object_symbols_statement_enum:
    143 	case lang_output_statement_enum:
    144 	case lang_target_statement_enum:
    145 	case lang_input_statement_enum:
    146 	case lang_assignment_statement_enum:
    147 	case lang_padding_statement_enum:
    148 	case lang_address_statement_enum:
    149 	case lang_fill_statement_enum:
    150 	  break;
    151 
    152 	default:
    153 	  FAIL ();
    154 	  break;
    155 	}
    156     }
    157   return FALSE;
    158 }
    159 
    160 /* Call-back for elf32_nios2_size_stubs.  */
    161 
    162 /* Create a new stub section, and arrange for it to be linked
    163    immediately before or after INPUT_SECTION, according to AFTERP.  */
    164 
    165 static asection *
    166 nios2elf_add_stub_section (const char *stub_sec_name, asection *input_section,
    167 			   bfd_boolean afterp)
    168 {
    169   asection *stub_sec;
    170   flagword flags;
    171   asection *output_section;
    172   const char *secname;
    173   lang_output_section_statement_type *os;
    174   struct hook_stub_info info;
    175 
    176   flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
    177 	   | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
    178   stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd,
    179 						 stub_sec_name, flags);
    180   if (stub_sec == NULL)
    181     goto err_ret;
    182 
    183   output_section = input_section->output_section;
    184   secname = bfd_get_section_name (output_section->owner, output_section);
    185   os = lang_output_section_find (secname);
    186 
    187   info.input_section = input_section;
    188   lang_list_init (&info.add);
    189   lang_add_section (&info.add, stub_sec, NULL, os);
    190 
    191   if (info.add.head == NULL)
    192     goto err_ret;
    193 
    194   if (hook_in_stub (&info, &os->children.head, afterp))
    195     return stub_sec;
    196 
    197  err_ret:
    198   einfo ("%X%P: can not make stub section: %E\n");
    199   return NULL;
    200 }
    201 
    202 
    203 /* Another call-back for elf32_nios2_size_stubs.  */
    204 
    205 static void
    206 nios2elf_layout_sections_again (void)
    207 {
    208   /* If we have changed sizes of the stub sections, then we need
    209      to recalculate all the section offsets.  This may mean we need to
    210      add even more stubs.  */
    211   gld${EMULATION_NAME}_map_segments (TRUE);
    212   need_laying_out = -1;
    213 }
    214 
    215 
    216 static void
    217 build_section_lists (lang_statement_union_type *statement)
    218 {
    219   if (statement->header.type == lang_input_section_enum)
    220     {
    221       asection *i = statement->input_section.section;
    222 
    223       if (i->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
    224 	  && (i->flags & SEC_EXCLUDE) == 0
    225 	  && i->output_section != NULL
    226 	  && i->output_section->owner == link_info.output_bfd)
    227 	{
    228 	  nios2_elf32_next_input_section (&link_info, i);
    229 	}
    230     }
    231 }
    232 
    233 
    234 /* For Nios II we use this opportunity to build linker stubs.  */
    235 
    236 static void
    237 gld${EMULATION_NAME}_after_allocation (void)
    238 {
    239   int ret;
    240 
    241   /* bfd_elf_discard_info just plays with data and debugging sections,
    242      ie. doesn't affect code size, so we can delay resizing the
    243      sections.  It's likely we'll resize everything in the process of
    244      adding stubs.  */
    245   ret = bfd_elf_discard_info (link_info.output_bfd, &link_info);
    246   if (ret < 0)
    247     {
    248       einfo ("%X%P: .eh_frame/.stab edit: %E\n");
    249       return;
    250     }
    251   else if (ret > 0)
    252     need_laying_out = 1;
    253 
    254   /* If generating a relocatable output file, then we don't
    255      have to examine the relocs.  */
    256   if (stub_file != NULL && !link_info.relocatable && RELAXATION_ENABLED)
    257     {
    258       ret = nios2_elf32_setup_section_lists (link_info.output_bfd, &link_info);
    259       if (ret != 0)
    260 	{
    261 	  if (ret < 0)
    262 	    {
    263 	      einfo ("%X%P: can not size stub section: %E\n");
    264 	      return;
    265 	    }
    266 
    267 	  lang_for_each_statement (build_section_lists);
    268 
    269 	  /* Call into the BFD backend to do the real work.  */
    270 	  if (! nios2_elf32_size_stubs (link_info.output_bfd,
    271 					stub_file->the_bfd,
    272 					&link_info,
    273 					&nios2elf_add_stub_section,
    274 					&nios2elf_layout_sections_again))
    275 	    {
    276 	      einfo ("%X%P: can not size stub section: %E\n");
    277 	      return;
    278 	    }
    279 	}
    280     }
    281 
    282   if (need_laying_out != -1)
    283     gld${EMULATION_NAME}_map_segments (need_laying_out);
    284 
    285   if (!link_info.relocatable && RELAXATION_ENABLED)
    286     {
    287       /* Now build the linker stubs.  */
    288       if (stub_file != NULL && stub_file->the_bfd->sections != NULL)
    289 	{
    290 	  if (! nios2_elf32_build_stubs (&link_info))
    291 	    einfo ("%X%P: can not build stubs: %E\n");
    292 	}
    293     }
    294 }
    295 
    296 
    297 /* Avoid processing the fake stub_file in vercheck, stat_needed and
    298    check_needed routines.  */
    299 
    300 static void (*real_func) (lang_input_statement_type *);
    301 
    302 static void nios2_for_each_input_file_wrapper (lang_input_statement_type *l)
    303 {
    304   if (l != stub_file)
    305     (*real_func) (l);
    306 }
    307 
    308 static void
    309 nios2_lang_for_each_input_file (void (*func) (lang_input_statement_type *))
    310 {
    311   real_func = func;
    312   lang_for_each_input_file (&nios2_for_each_input_file_wrapper);
    313 }
    314 
    315 #define lang_for_each_input_file nios2_lang_for_each_input_file
    316 
    317 EOF
    318 
    319 
    320 # Put these extra nios2elf routines in ld_${EMULATION_NAME}_emulation
    321 #
    322 LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
    323 LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=nios2elf_create_output_section_statements
    324