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