1# This shell script emits a C file. -*- C -*-
2# It does some substitutions.
3cat >e${EMULATION_NAME}.c <<EOF
4/* This file is is generated by a shell script.  DO NOT EDIT! */
5
6/* Handle embedded relocs for MIPS.
7   Copyright 1994, 95, 97, 1999 Free Software Foundation, Inc.
8   Written by Ian Lance Taylor <ian@cygnus.com> based on generic.em.
9
10This file is part of GLD, the Gnu Linker.
11
12This program is free software; you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation; either version 2 of the License, or
15(at your option) any later version.
16
17This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with this program; if not, write to the Free Software
24Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
25
26#define TARGET_IS_${EMULATION_NAME}
27
28#include "bfd.h"
29#include "sysdep.h"
30#include "bfdlink.h"
31
32#include "ld.h"
33#include "ldmain.h"
34#include "ldemul.h"
35#include "ldfile.h"
36#include "ldmisc.h"
37
38static void gld${EMULATION_NAME}_before_parse PARAMS ((void));
39static void gld${EMULATION_NAME}_after_open PARAMS ((void));
40static void check_sections PARAMS ((bfd *, asection *, PTR));
41static void gld${EMULATION_NAME}_after_allocation PARAMS ((void));
42static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
43
44static void
45gld${EMULATION_NAME}_before_parse()
46{
47#ifndef TARGET_			/* I.e., if not generic.  */
48  ldfile_output_architecture = bfd_arch_${ARCH};
49#endif /* not TARGET_ */
50}
51
52/* This function is run after all the input files have been opened.
53   We create a .rel.sdata section for each input file with a non zero
54   .sdata section.  The BFD backend will fill in these sections with
55   magic numbers which can be used to relocate the data section at run
56   time.  This will only do the right thing if all the input files
57   have been compiled using -membedded-pic.  */
58
59static void
60gld${EMULATION_NAME}_after_open ()
61{
62  bfd *abfd;
63
64  if (! command_line.embedded_relocs
65      || link_info.relocateable)
66    return;
67
68  for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next)
69    {
70      asection *datasec;
71
72      /* As first-order business, make sure that each input BFD is ECOFF. It
73         better be, as we are directly calling an ECOFF backend function.  */
74      if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour)
75	einfo ("%F%B: all input objects must be ECOFF for --embedded-relocs\n");
76
77      datasec = bfd_get_section_by_name (abfd, ".sdata");
78
79      /* Note that we assume that the reloc_count field has already
80         been set up.  We could call bfd_get_reloc_upper_bound, but
81         that returns the size of a memory buffer rather than a reloc
82         count.  We do not want to call bfd_canonicalize_reloc,
83         because although it would always work it would force us to
84         read in the relocs into BFD canonical form, which would waste
85         a significant amount of time and memory.  */
86      if (datasec != NULL && datasec->reloc_count > 0)
87	{
88	  asection *relsec;
89
90	  relsec = bfd_make_section (abfd, ".rel.sdata");
91	  if (relsec == NULL
92	      || ! bfd_set_section_flags (abfd, relsec,
93					  (SEC_ALLOC
94					   | SEC_LOAD
95					   | SEC_HAS_CONTENTS
96					   | SEC_IN_MEMORY))
97	      || ! bfd_set_section_alignment (abfd, relsec, 2)
98	      || ! bfd_set_section_size (abfd, relsec,
99					 datasec->reloc_count * 4))
100	    einfo ("%F%B: can not create .rel.sdata section: %E\n");
101	}
102
103      /* Double check that all other data sections are empty, as is
104         required for embedded PIC code.  */
105      bfd_map_over_sections (abfd, check_sections, (PTR) datasec);
106    }
107}
108
109/* Check that of the data sections, only the .sdata section has
110   relocs.  This is called via bfd_map_over_sections.  */
111
112static void
113check_sections (abfd, sec, sdatasec)
114     bfd *abfd;
115     asection *sec;
116     PTR sdatasec;
117{
118  if ((bfd_get_section_flags (abfd, sec) & SEC_CODE) == 0
119      && sec != (asection *) sdatasec
120      && sec->reloc_count != 0)
121    einfo ("%B%X: section %s has relocs; can not use --embedded-relocs\n",
122	   abfd, bfd_get_section_name (abfd, sec));
123}
124
125/* This function is called after the section sizes and offsets have
126   been set.  If we are generating embedded relocs, it calls a special
127   BFD backend routine to do the work.  */
128
129static void
130gld${EMULATION_NAME}_after_allocation ()
131{
132  bfd *abfd;
133
134  if (! command_line.embedded_relocs
135      || link_info.relocateable)
136    return;
137
138  for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link_next)
139    {
140      asection *datasec, *relsec;
141      char *errmsg;
142
143      datasec = bfd_get_section_by_name (abfd, ".sdata");
144
145      if (datasec == NULL || datasec->reloc_count == 0)
146	continue;
147
148      relsec = bfd_get_section_by_name (abfd, ".rel.sdata");
149      ASSERT (relsec != NULL);
150
151      if (! bfd_mips_ecoff_create_embedded_relocs (abfd, &link_info,
152						   datasec, relsec,
153						   &errmsg))
154	{
155	  if (errmsg == NULL)
156	    einfo ("%B%X: can not create runtime reloc information: %E\n",
157		   abfd);
158	  else
159	    einfo ("%X%B: can not create runtime reloc information: %s\n",
160		   abfd, errmsg);
161	}
162    }
163}
164
165static char *
166gld${EMULATION_NAME}_get_script(isfile)
167     int *isfile;
168EOF
169
170if test -n "$COMPILE_IN"
171then
172# Scripts compiled in.
173
174# sed commands to quote an ld script as a C string.
175sc="-f stringify.sed"
176
177cat >>e${EMULATION_NAME}.c <<EOF
178{
179  *isfile = 0;
180
181  if (link_info.relocateable == true && config.build_constructors == true)
182    return
183EOF
184sed $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
185echo '  ; else if (link_info.relocateable == true) return' >> e${EMULATION_NAME}.c
186sed $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
187echo '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
188sed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
189echo '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
190sed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
191echo '  ; else return'                                     >> e${EMULATION_NAME}.c
192sed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
193echo '; }'                                                 >> e${EMULATION_NAME}.c
194
195else
196# Scripts read from the filesystem.
197
198cat >>e${EMULATION_NAME}.c <<EOF
199{
200  *isfile = 1;
201
202  if (link_info.relocateable == true && config.build_constructors == true)
203    return "ldscripts/${EMULATION_NAME}.xu";
204  else if (link_info.relocateable == true)
205    return "ldscripts/${EMULATION_NAME}.xr";
206  else if (!config.text_read_only)
207    return "ldscripts/${EMULATION_NAME}.xbn";
208  else if (!config.magic_demand_paged)
209    return "ldscripts/${EMULATION_NAME}.xn";
210  else
211    return "ldscripts/${EMULATION_NAME}.x";
212}
213EOF
214
215fi
216
217cat >>e${EMULATION_NAME}.c <<EOF
218
219struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
220{
221  gld${EMULATION_NAME}_before_parse,
222  syslib_default,
223  hll_default,
224  after_parse_default,
225  gld${EMULATION_NAME}_after_open,
226  gld${EMULATION_NAME}_after_allocation,
227  set_output_arch_default,
228  ldemul_default_target,
229  before_allocation_default,
230  gld${EMULATION_NAME}_get_script,
231  "${EMULATION_NAME}",
232  "${OUTPUT_FORMAT}",
233  NULL,	/* finish */
234  NULL,	/* create output section statements */
235  NULL,	/* open dynamic archive */
236  NULL,	/* place orphan */
237  NULL,	/* set symbols */
238  NULL,	/* parse args */
239  NULL,	/* unrecognized file */
240  NULL,	/* list options */
241  NULL,	/* recognized file */
242  NULL 	/* find_potential_libraries */
243};
244EOF
245