Home | History | Annotate | Download | only in emultempl
      1 # This shell script emits a C file. -*- C -*-
      2 #   Copyright (C) 2001-2014 Free Software Foundation, Inc.
      3 #
      4 # This file is part of the 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 generic.em.
     23 
     24 fragment <<EOF
     25 /* Need to have this macro defined before mmix-elfnmmo, which uses the
     26    name for the before_allocation function, defined in ldemul.c (for
     27    the mmo "emulation") or in elf32.em (for the elf64mmix
     28    "emulation").  */
     29 #define gldmmo_before_allocation before_allocation_default
     30 
     31 /* We include this header *not* because we expect to handle ELF here
     32    but because we re-use the map_segments function in elf-generic.em,
     33    a file which is rightly somewhat ELF-centric.  But this is only to
     34    get a weird testcase right; ld-mmix/bpo-22, forcing ELF to be
     35    output from the mmo emulation: -m mmo --oformat elf64-mmix!  */
     36 #include "elf-bfd.h"
     37 
     38 static void gld${EMULATION_NAME}_after_allocation (void);
     39 EOF
     40 
     41 source_em ${srcdir}/emultempl/elf-generic.em
     42 source_em ${srcdir}/emultempl/mmix-elfnmmo.em
     43 
     44 fragment <<EOF
     45 
     46 /* Place an orphan section.  We use this to put random SEC_CODE or
     47    SEC_READONLY sections right after MMO_TEXT_SECTION_NAME.  Much borrowed
     48    from elf32.em.  */
     49 
     50 static lang_output_section_statement_type *
     51 mmo_place_orphan (asection *s,
     52 		  const char *secname,
     53 		  int constraint ATTRIBUTE_UNUSED)
     54 {
     55   static struct
     56   {
     57     flagword nonzero_flags;
     58     struct orphan_save orphansave;
     59   } holds[] =
     60       {
     61 	{
     62 	  SEC_CODE | SEC_READONLY,
     63 	  {
     64 	    MMO_TEXT_SECTION_NAME,
     65 	    SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
     66 	    0, 0, 0, 0
     67 	  }
     68 	},
     69 	{
     70 	  SEC_LOAD | SEC_DATA,
     71 	  {
     72 	    MMO_DATA_SECTION_NAME,
     73 	    SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA,
     74 	    0, 0, 0, 0
     75 	  }
     76 	},
     77 	{
     78 	  SEC_ALLOC,
     79 	  {
     80 	    ".bss",
     81 	    SEC_ALLOC,
     82 	    0, 0, 0, 0
     83 	  }
     84 	}
     85       };
     86 
     87   struct orphan_save *place = NULL;
     88   lang_output_section_statement_type *after;
     89   lang_output_section_statement_type *os;
     90   size_t i;
     91 
     92   /* We have nothing to say for anything other than a final link or
     93      for sections that are excluded.  */
     94   if (link_info.relocatable
     95       || (s->flags & SEC_EXCLUDE) != 0)
     96     return NULL;
     97 
     98   os = lang_output_section_find (secname);
     99 
    100   /* We have an output section by this name.  Place the section inside it
    101      (regardless of whether the linker script lists it as input).  */
    102   if (os != NULL)
    103     {
    104       lang_add_section (&os->children, s, NULL, os);
    105       return os;
    106     }
    107 
    108   /* Check for matching section type flags for sections we care about.
    109      A section without contents can have SEC_LOAD == 0, but we still
    110      want it attached to a sane section so the symbols appear as
    111      expected.  */
    112   if ((s->flags & (SEC_ALLOC | SEC_READONLY)) != SEC_READONLY)
    113     for (i = 0; i < sizeof (holds) / sizeof (holds[0]); i++)
    114       if ((s->flags & holds[i].nonzero_flags) != 0)
    115 	{
    116 	  place = &holds[i].orphansave;
    117 	  if (place->os == NULL)
    118 	    place->os = lang_output_section_find (place->name);
    119 	  break;
    120 	}
    121 
    122   if (place == NULL)
    123     {
    124       /* For other combinations, we have to give up, except we make
    125 	 sure not to place the orphan section after the
    126 	 linker-generated register section; that'd make it continue
    127 	 the reg section and we never want that to happen for orphan
    128 	 sections.  */
    129       lang_output_section_statement_type *before;
    130       lang_output_section_statement_type *lookup;
    131       static struct orphan_save hold_nonreg =
    132 	{
    133 	  NULL,
    134 	  SEC_READONLY,
    135 	  0, 0, 0, 0
    136 	};
    137 
    138       if (hold_nonreg.os == NULL)
    139 	{
    140 	  before = lang_output_section_find (MMIX_REG_CONTENTS_SECTION_NAME);
    141 
    142 	  /* If we have no such section, all fine; we don't care where
    143 	     it's placed.  */
    144 	  if (before == NULL)
    145 	    return NULL;
    146 
    147 	  /* We have to find the oss before this one, so we can use that as
    148 	     "after".  */
    149 	  for (lookup = &lang_output_section_statement.head->output_section_statement;
    150 	       lookup != NULL && lookup->next != before;
    151 	       lookup = lookup->next)
    152 	    ;
    153 
    154 	  hold_nonreg.os = lookup;
    155 	}
    156 
    157       place = &hold_nonreg;
    158     }
    159 
    160   after = place->os;
    161   if (after == NULL)
    162     return NULL;
    163 
    164   /* If there's an output section by *this* name, we'll use it, regardless
    165      of actual section flags, in contrast to what's done in elf32.em.  */
    166   os = lang_insert_orphan (s, secname, 0, after, place, NULL, NULL);
    167 
    168   return os;
    169 }
    170 
    171 /* Remove the spurious settings of SEC_RELOC that make it to the output at
    172    link time.  We are as confused as elflink.h:elf_bfd_final_link, and
    173    paper over the bug similarly.  */
    174 
    175 static void
    176 mmo_wipe_sec_reloc_flag (bfd *abfd, asection *sec, void *ptr ATTRIBUTE_UNUSED)
    177 {
    178   bfd_set_section_flags (abfd, sec,
    179 			 bfd_get_section_flags (abfd, sec) & ~SEC_RELOC);
    180 }
    181 
    182 /* Iterate with bfd_map_over_sections over mmo_wipe_sec_reloc_flag... */
    183 
    184 static void
    185 gld${EMULATION_NAME}_after_allocation (void)
    186 {
    187   bfd_map_over_sections (link_info.output_bfd, mmo_wipe_sec_reloc_flag, NULL);
    188   gld${EMULATION_NAME}_map_segments (FALSE);
    189 }
    190 
    192 /* To get on-demand global register allocation right, we need to parse the
    193    relocs, like what happens when linking to ELF.  It needs to be done
    194    before all input sections are supposed to be present.  When linking to
    195    ELF, it's done when reading symbols.  When linking to mmo, we do it
    196    when all input files are seen, which is equivalent.  */
    197 
    198 static void
    199 mmo_after_open (void)
    200 {
    201   /* When there's a mismatch between the output format and the emulation
    202      (using weird combinations like "-m mmo --oformat elf64-mmix" for
    203      example), we'd count relocs twice because they'd also be counted
    204      along the usual route for ELF-only linking, which would lead to an
    205      internal accounting error.  */
    206   if (bfd_get_flavour (link_info.output_bfd) != bfd_target_elf_flavour)
    207     {
    208       LANG_FOR_EACH_INPUT_STATEMENT (is)
    209 	{
    210 	  if (bfd_get_flavour (is->the_bfd) == bfd_target_elf_flavour
    211 	      && !_bfd_mmix_check_all_relocs (is->the_bfd, &link_info))
    212 	    einfo ("%X%P: Internal problems scanning %B after opening it",
    213 		   is->the_bfd);
    214 	}
    215     }
    216   after_open_default ();
    217 }
    218 EOF
    219 
    220 LDEMUL_PLACE_ORPHAN=mmo_place_orphan
    221 LDEMUL_AFTER_OPEN=mmo_after_open
    222