xref: /netbsd-src/external/gpl3/binutils/dist/ld/emultempl/mmo.em (revision 4d5abbe83f525258eb479e5fca29f25cb943f379)
1# This shell script emits a C file. -*- C -*-
2#   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3#   Free Software Foundation, Inc.
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# This file is sourced from generic.em.
24
25fragment <<EOF
26/* Need to have this macro defined before mmix-elfnmmo, which uses the
27   name for the before_allocation function, defined in ldemul.c (for
28   the mmo "emulation") or in elf32.em (for the elf64mmix
29   "emulation").  */
30#define gldmmo_before_allocation before_allocation_default
31
32/* We include this header *not* because we expect to handle ELF here
33   but because we re-use the map_segments function in elf-generic.em,
34   a file which is rightly somewhat ELF-centric.  But this is only to
35   get a weird testcase right; ld-mmix/bpo-22, forcing ELF to be
36   output from the mmo emulation: -m mmo --oformat elf64-mmix!  */
37#include "elf-bfd.h"
38
39static void gld${EMULATION_NAME}_after_allocation (void);
40EOF
41
42source_em ${srcdir}/emultempl/elf-generic.em
43source_em ${srcdir}/emultempl/mmix-elfnmmo.em
44
45fragment <<EOF
46
47/* Place an orphan section.  We use this to put random SEC_CODE or
48   SEC_READONLY sections right after MMO_TEXT_SECTION_NAME.  Much borrowed
49   from elf32.em.  */
50
51static lang_output_section_statement_type *
52mmo_place_orphan (asection *s,
53		  const char *secname,
54		  int constraint ATTRIBUTE_UNUSED)
55{
56  static struct
57  {
58    flagword nonzero_flags;
59    struct orphan_save orphansave;
60  } holds[] =
61      {
62	{
63	  SEC_CODE | SEC_READONLY,
64	  {
65	    MMO_TEXT_SECTION_NAME,
66	    SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
67	    0, 0, 0, 0
68	  }
69	},
70	{
71	  SEC_LOAD | SEC_DATA,
72	  {
73	    MMO_DATA_SECTION_NAME,
74	    SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA,
75	    0, 0, 0, 0
76	  }
77	},
78	{
79	  SEC_ALLOC,
80	  {
81	    ".bss",
82	    SEC_ALLOC,
83	    0, 0, 0, 0
84	  }
85	}
86      };
87
88  struct orphan_save *place = NULL;
89  lang_output_section_statement_type *after;
90  lang_output_section_statement_type *os;
91  size_t i;
92
93  /* We have nothing to say for anything other than a final link or
94     for sections that are excluded.  */
95  if (link_info.relocatable
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, os);
106      return os;
107    }
108
109  /* Check for matching section type flags for sections we care about.
110     A section without contents can have SEC_LOAD == 0, but we still
111     want it attached to a sane section so the symbols appear as
112     expected.  */
113  if ((s->flags & (SEC_ALLOC | SEC_READONLY)) != SEC_READONLY)
114    for (i = 0; i < sizeof (holds) / sizeof (holds[0]); i++)
115      if ((s->flags & holds[i].nonzero_flags) != 0)
116	{
117	  place = &holds[i].orphansave;
118	  if (place->os == NULL)
119	    place->os = lang_output_section_find (place->name);
120	  break;
121	}
122
123  if (place == NULL)
124    {
125      /* For other combinations, we have to give up, except we make
126	 sure not to place the orphan section after the
127	 linker-generated register section; that'd make it continue
128	 the reg section and we never want that to happen for orphan
129	 sections.  */
130      lang_output_section_statement_type *before;
131      lang_output_section_statement_type *lookup;
132      static struct orphan_save hold_nonreg =
133	{
134	  NULL,
135	  SEC_READONLY,
136	  0, 0, 0, 0
137	};
138
139      if (hold_nonreg.os == NULL)
140	{
141	  before = lang_output_section_find (MMIX_REG_CONTENTS_SECTION_NAME);
142
143	  /* If we have no such section, all fine; we don't care where
144	     it's placed.  */
145	  if (before == NULL)
146	    return NULL;
147
148	  /* We have to find the oss before this one, so we can use that as
149	     "after".  */
150	  for (lookup = &lang_output_section_statement.head->output_section_statement;
151	       lookup != NULL && lookup->next != before;
152	       lookup = lookup->next)
153	    ;
154
155	  hold_nonreg.os = lookup;
156	}
157
158      place = &hold_nonreg;
159    }
160
161  after = place->os;
162  if (after == NULL)
163    return NULL;
164
165  /* If there's an output section by *this* name, we'll use it, regardless
166     of actual section flags, in contrast to what's done in elf32.em.  */
167  os = lang_insert_orphan (s, secname, 0, after, place, NULL, NULL);
168
169  return os;
170}
171
172/* Remove the spurious settings of SEC_RELOC that make it to the output at
173   link time.  We are as confused as elflink.h:elf_bfd_final_link, and
174   paper over the bug similarly.  */
175
176static void
177mmo_wipe_sec_reloc_flag (bfd *abfd, asection *sec, void *ptr ATTRIBUTE_UNUSED)
178{
179  bfd_set_section_flags (abfd, sec,
180			 bfd_get_section_flags (abfd, sec) & ~SEC_RELOC);
181}
182
183/* Iterate with bfd_map_over_sections over mmo_wipe_sec_reloc_flag... */
184
185static void
186gld${EMULATION_NAME}_after_allocation (void)
187{
188  bfd_map_over_sections (link_info.output_bfd, mmo_wipe_sec_reloc_flag, NULL);
189  gld${EMULATION_NAME}_map_segments (FALSE);
190}
191
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
198static void
199mmo_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}
218EOF
219
220LDEMUL_PLACE_ORPHAN=mmo_place_orphan
221LDEMUL_AFTER_OPEN=mmo_after_open
222