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