source: branches/libc-0.6/src/binutils/ld/mri.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 8.5 KB
Line 
1/* mri.c -- handle MRI style linker scripts
2 Copyright 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2002
3 Free Software Foundation, Inc.
4
5This file is part of GLD, the Gnu Linker.
6
7GLD is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GLD is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GLD; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA.
21
22 This bit does the tree decoration when MRI style link scripts
23 are parsed.
24
25 Contributed by Steve Chamberlain <sac@cygnus.com>. */
26
27#include "bfd.h"
28#include "sysdep.h"
29#include "ld.h"
30#include "ldexp.h"
31#include "ldlang.h"
32#include "ldmisc.h"
33#include "mri.h"
34#include <ldgram.h>
35#include "libiberty.h"
36
37struct section_name_struct {
38 struct section_name_struct *next;
39 const char *name;
40 const char *alias;
41 etree_type *vma;
42 etree_type *align;
43 etree_type *subalign;
44 int ok_to_load;
45};
46
47unsigned int symbol_truncate = 10000;
48struct section_name_struct *order;
49struct section_name_struct *only_load;
50struct section_name_struct *address;
51struct section_name_struct *alias;
52
53struct section_name_struct *alignment;
54struct section_name_struct *subalignment;
55
56static struct section_name_struct **lookup
57 PARAMS ((const char *name, struct section_name_struct **list));
58static void mri_add_to_list PARAMS ((struct section_name_struct **list,
59 const char *name, etree_type *vma,
60 const char *zalias, etree_type *align,
61 etree_type *subalign));
62
63static struct section_name_struct **
64lookup (name, list)
65 const char *name;
66 struct section_name_struct **list;
67{
68 struct section_name_struct **ptr = list;
69
70 while (*ptr)
71 {
72 if (strcmp (name, (*ptr)->name) == 0)
73 /* If this is a match, delete it, we only keep the last instance
74 of any name. */
75 *ptr = (*ptr)->next;
76 else
77 ptr = &((*ptr)->next);
78 }
79
80 *ptr = (struct section_name_struct *) xmalloc (sizeof (struct section_name_struct));
81 return ptr;
82}
83
84static void
85mri_add_to_list (list, name, vma, zalias, align, subalign)
86 struct section_name_struct **list;
87 const char *name;
88 etree_type *vma;
89 const char *zalias;
90 etree_type *align;
91 etree_type *subalign;
92{
93 struct section_name_struct **ptr = lookup (name, list);
94
95 (*ptr)->name = name;
96 (*ptr)->vma = vma;
97 (*ptr)->next = (struct section_name_struct *) NULL;
98 (*ptr)->ok_to_load = 0;
99 (*ptr)->alias = zalias;
100 (*ptr)->align = align;
101 (*ptr)->subalign = subalign;
102}
103
104void
105mri_output_section (name, vma)
106 const char *name;
107 etree_type *vma;
108{
109 mri_add_to_list (&address, name, vma, 0, 0, 0);
110}
111
112/* If any ABSOLUTE <name> are in the script, only load those files
113 marked thus. */
114
115void
116mri_only_load (name)
117 const char *name;
118{
119 mri_add_to_list (&only_load, name, 0, 0, 0, 0);
120}
121
122void
123mri_base (exp)
124 etree_type *exp;
125{
126 base = exp;
127}
128
129static int done_tree = 0;
130
131void
132mri_draw_tree ()
133{
134 if (done_tree)
135 return;
136
137#if 0 /* We don't bother with memory regions. */
138 /* Create the regions. */
139 {
140 lang_memory_region_type *r;
141
142 r = lang_memory_region_lookup("long");
143 r->current = r->origin = exp_get_vma (base, (bfd_vma)0, "origin",
144 lang_first_phase_enum);
145 r->length = (bfd_size_type) exp_get_vma (0, (bfd_vma) ~((bfd_size_type)0),
146 "length", lang_first_phase_enum);
147 }
148#endif
149
150 /* Now build the statements for the ldlang machine. */
151
152 /* Attach the addresses of any which have addresses,
153 and add the ones not mentioned. */
154 if (address != (struct section_name_struct *) NULL)
155 {
156 struct section_name_struct *alist;
157 struct section_name_struct *olist;
158
159 if (order == (struct section_name_struct *) NULL)
160 order = address;
161
162 for (alist = address;
163 alist != (struct section_name_struct *) NULL;
164 alist = alist->next)
165 {
166 int done = 0;
167
168 for (olist = order;
169 done == 0 && olist != (struct section_name_struct *) NULL;
170 olist = olist->next)
171 {
172 if (strcmp (alist->name, olist->name) == 0)
173 {
174 olist->vma = alist->vma;
175 done = 1;
176 }
177 }
178
179 if (!done)
180 {
181 /* Add this onto end of order list. */
182 mri_add_to_list (&order, alist->name, alist->vma, 0, 0, 0);
183 }
184 }
185 }
186
187 /* If we're only supposed to load a subset of them in, then prune
188 the list. */
189 if (only_load != (struct section_name_struct *) NULL)
190 {
191 struct section_name_struct *ptr1;
192 struct section_name_struct *ptr2;
193
194 if (order == (struct section_name_struct *) NULL)
195 order = only_load;
196
197 /* See if this name is in the list, if it is then we can load it. */
198 for (ptr1 = only_load; ptr1; ptr1 = ptr1->next)
199 for (ptr2 = order; ptr2; ptr2 = ptr2->next)
200 if (strcmp (ptr2->name, ptr1->name) == 0)
201 ptr2->ok_to_load = 1;
202 }
203 else
204 {
205 /* No only load list, so everything is ok to load. */
206 struct section_name_struct *ptr;
207
208 for (ptr = order; ptr; ptr = ptr->next)
209 ptr->ok_to_load = 1;
210 }
211
212 /* Create the order of sections to load. */
213 if (order != (struct section_name_struct *) NULL)
214 {
215 /* Been told to output the sections in a certain order. */
216 struct section_name_struct *p = order;
217
218 while (p)
219 {
220 struct section_name_struct *aptr;
221 etree_type *align = 0;
222 etree_type *subalign = 0;
223 struct wildcard_list *tmp;
224
225 /* See if an alignment has been specified. */
226 for (aptr = alignment; aptr; aptr = aptr->next)
227 if (strcmp (aptr->name, p->name) == 0)
228 align = aptr->align;
229
230 for (aptr = subalignment; aptr; aptr = aptr->next)
231 if (strcmp (aptr->name, p->name) == 0)
232 subalign = aptr->subalign;
233
234 if (base == 0)
235 base = p->vma ? p->vma : exp_nameop (NAME, ".");
236
237 lang_enter_output_section_statement (p->name, base,
238 p->ok_to_load ? 0 : noload_section,
239 1, align, subalign,
240 (etree_type *) NULL);
241 base = 0;
242 tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
243 tmp->next = NULL;
244 tmp->spec.name = p->name;
245 tmp->spec.exclude_name_list = NULL;
246 tmp->spec.sorted = FALSE;
247 lang_add_wild (NULL, tmp, FALSE);
248
249 /* If there is an alias for this section, add it too. */
250 for (aptr = alias; aptr; aptr = aptr->next)
251 if (strcmp (aptr->alias, p->name) == 0)
252 {
253 tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
254 tmp->next = NULL;
255 tmp->spec.name = aptr->name;
256 tmp->spec.exclude_name_list = NULL;
257 tmp->spec.sorted = FALSE;
258 lang_add_wild (NULL, tmp, FALSE);
259 }
260
261 lang_leave_output_section_statement
262 (0, "*default*", (struct lang_output_section_phdr_list *) NULL,
263 NULL);
264
265 p = p->next;
266 }
267 }
268
269 done_tree = 1;
270}
271
272void
273mri_load (name)
274 const char *name;
275{
276 base = 0;
277 lang_add_input_file (name,
278 lang_input_file_is_file_enum, (char *) NULL);
279#if 0
280 lang_leave_output_section_statement (0, "*default*");
281#endif
282}
283
284void
285mri_order (name)
286 const char *name;
287{
288 mri_add_to_list (&order, name, 0, 0, 0, 0);
289}
290
291void
292mri_alias (want, is, isn)
293 const char *want;
294 const char *is;
295 int isn;
296{
297 if (!is)
298 {
299 char buf[20];
300
301 /* Some sections are digits. */
302 sprintf (buf, "%d", isn);
303
304 is = xstrdup (buf);
305
306 if (is == NULL)
307 abort ();
308 }
309
310 mri_add_to_list (&alias, is, 0, want, 0, 0);
311}
312
313void
314mri_name (name)
315 const char *name;
316{
317 lang_add_output (name, 1);
318}
319
320void
321mri_format (name)
322 const char *name;
323{
324 if (strcmp (name, "S") == 0)
325 lang_add_output_format ("srec", (char *) NULL, (char *) NULL, 1);
326
327 else if (strcmp (name, "IEEE") == 0)
328 lang_add_output_format ("ieee", (char *) NULL, (char *) NULL, 1);
329
330 else if (strcmp (name, "COFF") == 0)
331 lang_add_output_format ("coff-m68k", (char *) NULL, (char *) NULL, 1);
332
333 else
334 einfo (_("%P%F: unknown format type %s\n"), name);
335}
336
337void
338mri_public (name, exp)
339 const char *name;
340 etree_type *exp;
341{
342 lang_add_assignment (exp_assop ('=', name, exp));
343}
344
345void
346mri_align (name, exp)
347 const char *name;
348 etree_type *exp;
349{
350 mri_add_to_list (&alignment, name, 0, 0, exp, 0);
351}
352
353void
354mri_alignmod (name, exp)
355 const char *name;
356 etree_type *exp;
357{
358 mri_add_to_list (&subalignment, name, 0, 0, 0, exp);
359}
360
361void
362mri_truncate (exp)
363 unsigned int exp;
364{
365 symbol_truncate = exp;
366}
Note: See TracBrowser for help on using the repository browser.