8949aed13fa22a88c6feacd95d063998db7ff677
[external/binutils.git] / ld / emultempl / mmo.em
1 # This shell script emits a C file. -*- C -*-
2 #   Copyright (C) 2001-2015 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   flagword flags;
92   asection *nexts;
93
94   /* We have nothing to say for anything other than a final link or
95      for sections that are excluded.  */
96   if (bfd_link_relocatable (&link_info)
97       || (s->flags & SEC_EXCLUDE) != 0)
98     return NULL;
99
100   os = lang_output_section_find (secname);
101
102   /* We have an output section by this name.  Place the section inside it
103      (regardless of whether the linker script lists it as input).  */
104   if (os != NULL)
105     {
106       lang_add_section (&os->children, s, NULL, os);
107       return os;
108     }
109
110   /* Check for matching section type flags for sections we care about.
111      A section without contents can have SEC_LOAD == 0, but we still
112      want it attached to a sane section so the symbols appear as
113      expected.  */
114   flags = s->flags;
115   nexts = s;
116   while ((nexts = bfd_get_next_section_by_name (nexts->owner, nexts)) != NULL)
117     if (nexts->output_section == NULL
118         && (nexts->flags & SEC_EXCLUDE) == 0
119         && ((nexts->flags ^ flags) & (SEC_LOAD | SEC_ALLOC)) == 0
120         && (nexts->owner->flags & DYNAMIC) == 0
121         && nexts->owner->usrdata != NULL
122         && !(((lang_input_statement_type *) nexts->owner->usrdata)
123              ->flags.just_syms))
124       flags = (((flags ^ SEC_READONLY) | (nexts->flags ^ SEC_READONLY))
125                ^ SEC_READONLY);
126   if ((flags & (SEC_ALLOC | SEC_READONLY)) != SEC_READONLY)
127     for (i = 0; i < sizeof (holds) / sizeof (holds[0]); i++)
128       if ((flags & holds[i].nonzero_flags) != 0)
129         {
130           place = &holds[i].orphansave;
131           if (place->os == NULL)
132             place->os = lang_output_section_find (place->name);
133           break;
134         }
135
136   if (place == NULL)
137     {
138       /* For other combinations, we have to give up, except we make
139          sure not to place the orphan section after the
140          linker-generated register section; that'd make it continue
141          the reg section and we never want that to happen for orphan
142          sections.  */
143       lang_output_section_statement_type *before;
144       lang_output_section_statement_type *lookup;
145       static struct orphan_save hold_nonreg =
146         {
147           NULL,
148           SEC_READONLY,
149           0, 0, 0, 0
150         };
151
152       if (hold_nonreg.os == NULL)
153         {
154           before = lang_output_section_find (MMIX_REG_CONTENTS_SECTION_NAME);
155
156           /* If we have no such section, all fine; we don't care where
157              it's placed.  */
158           if (before == NULL)
159             return NULL;
160
161           /* We have to find the oss before this one, so we can use that as
162              "after".  */
163           for (lookup = &lang_output_section_statement.head->output_section_statement;
164                lookup != NULL && lookup->next != before;
165                lookup = lookup->next)
166             ;
167
168           hold_nonreg.os = lookup;
169         }
170
171       place = &hold_nonreg;
172     }
173
174   after = place->os;
175   if (after == NULL)
176     return NULL;
177
178   /* If there's an output section by *this* name, we'll use it, regardless
179      of actual section flags, in contrast to what's done in elf32.em.  */
180   os = lang_insert_orphan (s, secname, 0, after, place, NULL, NULL);
181
182   return os;
183 }
184
185 /* Remove the spurious settings of SEC_RELOC that make it to the output at
186    link time.  We are as confused as elflink.h:elf_bfd_final_link, and
187    paper over the bug similarly.  */
188
189 static void
190 mmo_wipe_sec_reloc_flag (bfd *abfd, asection *sec, void *ptr ATTRIBUTE_UNUSED)
191 {
192   bfd_set_section_flags (abfd, sec,
193                          bfd_get_section_flags (abfd, sec) & ~SEC_RELOC);
194 }
195
196 /* Iterate with bfd_map_over_sections over mmo_wipe_sec_reloc_flag... */
197
198 static void
199 gld${EMULATION_NAME}_after_allocation (void)
200 {
201   bfd_map_over_sections (link_info.output_bfd, mmo_wipe_sec_reloc_flag, NULL);
202   gld${EMULATION_NAME}_map_segments (FALSE);
203 }
204 \f
205 /* To get on-demand global register allocation right, we need to parse the
206    relocs, like what happens when linking to ELF.  It needs to be done
207    before all input sections are supposed to be present.  When linking to
208    ELF, it's done when reading symbols.  When linking to mmo, we do it
209    when all input files are seen, which is equivalent.  */
210
211 static void
212 mmo_after_open (void)
213 {
214   /* When there's a mismatch between the output format and the emulation
215      (using weird combinations like "-m mmo --oformat elf64-mmix" for
216      example), we'd count relocs twice because they'd also be counted
217      along the usual route for ELF-only linking, which would lead to an
218      internal accounting error.  */
219   if (bfd_get_flavour (link_info.output_bfd) != bfd_target_elf_flavour)
220     {
221       LANG_FOR_EACH_INPUT_STATEMENT (is)
222         {
223           if (bfd_get_flavour (is->the_bfd) == bfd_target_elf_flavour
224               && !_bfd_mmix_check_all_relocs (is->the_bfd, &link_info))
225             einfo ("%X%P: Internal problems scanning %B after opening it",
226                    is->the_bfd);
227         }
228     }
229   after_open_default ();
230 }
231 EOF
232
233 LDEMUL_PLACE_ORPHAN=mmo_place_orphan
234 LDEMUL_AFTER_OPEN=mmo_after_open