~angelsl/ubuntu/wily/binutils/mips-cross

« back to all changes in this revision

Viewing changes to ld/mri.c

  • Committer: angelsl
  • Date: 2015-11-03 15:54:40 UTC
  • Revision ID: angelsl-20151103155440-gbh6qo1olzlvaiqs
Import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* mri.c -- handle MRI style linker scripts
 
2
   Copyright (C) 1991-2014 Free Software Foundation, Inc.
 
3
   Contributed by Steve Chamberlain <sac@cygnus.com>.
 
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 bit does the tree decoration when MRI style link scripts
 
24
   are parsed.  */
 
25
 
 
26
#include "sysdep.h"
 
27
#include "bfd.h"
 
28
#include "ld.h"
 
29
#include "ldexp.h"
 
30
#include "ldlang.h"
 
31
#include "ldmisc.h"
 
32
#include "mri.h"
 
33
#include <ldgram.h>
 
34
#include "libiberty.h"
 
35
 
 
36
struct section_name_struct {
 
37
  struct section_name_struct *next;
 
38
  const char *name;
 
39
  const char *alias;
 
40
  etree_type *vma;
 
41
  etree_type *align;
 
42
  etree_type *subalign;
 
43
  int ok_to_load;
 
44
};
 
45
 
 
46
static unsigned int symbol_truncate = 10000;
 
47
static etree_type *base; /* Relocation base - or null */
 
48
 
 
49
static struct section_name_struct *order;
 
50
static struct section_name_struct *only_load;
 
51
static struct section_name_struct *address;
 
52
static struct section_name_struct *alias;
 
53
 
 
54
static struct section_name_struct *alignment;
 
55
static struct section_name_struct *subalignment;
 
56
 
 
57
static struct section_name_struct **
 
58
lookup (const char *name, struct section_name_struct **list)
 
59
{
 
60
  struct section_name_struct **ptr = list;
 
61
 
 
62
  while (*ptr)
 
63
    {
 
64
      if (strcmp (name, (*ptr)->name) == 0)
 
65
        /* If this is a match, delete it, we only keep the last instance
 
66
           of any name.  */
 
67
        *ptr = (*ptr)->next;
 
68
      else
 
69
        ptr = &((*ptr)->next);
 
70
    }
 
71
 
 
72
  *ptr = (struct section_name_struct *)
 
73
      xmalloc (sizeof (struct section_name_struct));
 
74
  return ptr;
 
75
}
 
76
 
 
77
static void
 
78
mri_add_to_list (struct section_name_struct **list,
 
79
                 const char *name,
 
80
                 etree_type *vma,
 
81
                 const char *zalias,
 
82
                 etree_type *align,
 
83
                 etree_type *subalign)
 
84
{
 
85
  struct section_name_struct **ptr = lookup (name, list);
 
86
 
 
87
  (*ptr)->name = name;
 
88
  (*ptr)->vma = vma;
 
89
  (*ptr)->next = NULL;
 
90
  (*ptr)->ok_to_load = 0;
 
91
  (*ptr)->alias = zalias;
 
92
  (*ptr)->align = align;
 
93
  (*ptr)->subalign = subalign;
 
94
}
 
95
 
 
96
void
 
97
mri_output_section (const char *name, etree_type *vma)
 
98
{
 
99
  mri_add_to_list (&address, name, vma, 0, 0, 0);
 
100
}
 
101
 
 
102
/* If any ABSOLUTE <name> are in the script, only load those files
 
103
   marked thus.  */
 
104
 
 
105
void
 
106
mri_only_load (const char *name)
 
107
{
 
108
  mri_add_to_list (&only_load, name, 0, 0, 0, 0);
 
109
}
 
110
 
 
111
void
 
112
mri_base (etree_type *exp)
 
113
{
 
114
  base = exp;
 
115
}
 
116
 
 
117
static int done_tree = 0;
 
118
 
 
119
void
 
120
mri_draw_tree (void)
 
121
{
 
122
  if (done_tree)
 
123
    return;
 
124
 
 
125
  /* Now build the statements for the ldlang machine.  */
 
126
 
 
127
  /* Attach the addresses of any which have addresses,
 
128
     and add the ones not mentioned.  */
 
129
  if (address != NULL)
 
130
    {
 
131
      struct section_name_struct *alist;
 
132
      struct section_name_struct *olist;
 
133
 
 
134
      if (order == NULL)
 
135
        order = address;
 
136
 
 
137
      for (alist = address;
 
138
           alist != NULL;
 
139
           alist = alist->next)
 
140
        {
 
141
          int done = 0;
 
142
 
 
143
          for (olist = order; done == 0 && olist != NULL; olist = olist->next)
 
144
            {
 
145
              if (strcmp (alist->name, olist->name) == 0)
 
146
                {
 
147
                  olist->vma = alist->vma;
 
148
                  done = 1;
 
149
                }
 
150
            }
 
151
 
 
152
          if (!done)
 
153
            {
 
154
              /* Add this onto end of order list.  */
 
155
              mri_add_to_list (&order, alist->name, alist->vma, 0, 0, 0);
 
156
            }
 
157
        }
 
158
    }
 
159
 
 
160
  /* If we're only supposed to load a subset of them in, then prune
 
161
     the list.  */
 
162
  if (only_load != NULL)
 
163
    {
 
164
      struct section_name_struct *ptr1;
 
165
      struct section_name_struct *ptr2;
 
166
 
 
167
      if (order == NULL)
 
168
        order = only_load;
 
169
 
 
170
      /* See if this name is in the list, if it is then we can load it.  */
 
171
      for (ptr1 = only_load; ptr1; ptr1 = ptr1->next)
 
172
        for (ptr2 = order; ptr2; ptr2 = ptr2->next)
 
173
          if (strcmp (ptr2->name, ptr1->name) == 0)
 
174
            ptr2->ok_to_load = 1;
 
175
    }
 
176
  else
 
177
    {
 
178
      /* No only load list, so everything is ok to load.  */
 
179
      struct section_name_struct *ptr;
 
180
 
 
181
      for (ptr = order; ptr; ptr = ptr->next)
 
182
        ptr->ok_to_load = 1;
 
183
    }
 
184
 
 
185
  /* Create the order of sections to load.  */
 
186
  if (order != NULL)
 
187
    {
 
188
      /* Been told to output the sections in a certain order.  */
 
189
      struct section_name_struct *p = order;
 
190
 
 
191
      while (p)
 
192
        {
 
193
          struct section_name_struct *aptr;
 
194
          etree_type *align = 0;
 
195
          etree_type *subalign = 0;
 
196
          struct wildcard_list *tmp;
 
197
 
 
198
          /* See if an alignment has been specified.  */
 
199
          for (aptr = alignment; aptr; aptr = aptr->next)
 
200
            if (strcmp (aptr->name, p->name) == 0)
 
201
              align = aptr->align;
 
202
 
 
203
          for (aptr = subalignment; aptr; aptr = aptr->next)
 
204
            if (strcmp (aptr->name, p->name) == 0)
 
205
              subalign = aptr->subalign;
 
206
 
 
207
          if (base == 0)
 
208
            base = p->vma ? p->vma : exp_nameop (NAME, ".");
 
209
 
 
210
          lang_enter_output_section_statement (p->name, base,
 
211
                                               p->ok_to_load ? normal_section : noload_section,
 
212
                                               align, subalign, NULL, 0, 0);
 
213
          base = 0;
 
214
          tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
 
215
          tmp->next = NULL;
 
216
          tmp->spec.name = p->name;
 
217
          tmp->spec.exclude_name_list = NULL;
 
218
          tmp->spec.sorted = none;
 
219
          tmp->spec.section_flag_list = NULL;
 
220
          lang_add_wild (NULL, tmp, FALSE);
 
221
 
 
222
          /* If there is an alias for this section, add it too.  */
 
223
          for (aptr = alias; aptr; aptr = aptr->next)
 
224
            if (strcmp (aptr->alias, p->name) == 0)
 
225
              {
 
226
                tmp = (struct wildcard_list *) xmalloc (sizeof *tmp);
 
227
                tmp->next = NULL;
 
228
                tmp->spec.name = aptr->name;
 
229
                tmp->spec.exclude_name_list = NULL;
 
230
                tmp->spec.sorted = none;
 
231
                tmp->spec.section_flag_list = NULL;
 
232
                lang_add_wild (NULL, tmp, FALSE);
 
233
              }
 
234
 
 
235
          lang_leave_output_section_statement (0, "*default*", NULL, NULL);
 
236
 
 
237
          p = p->next;
 
238
        }
 
239
    }
 
240
 
 
241
  done_tree = 1;
 
242
}
 
243
 
 
244
void
 
245
mri_load (const char *name)
 
246
{
 
247
  base = 0;
 
248
  lang_add_input_file (name, lang_input_file_is_file_enum, NULL);
 
249
}
 
250
 
 
251
void
 
252
mri_order (const char *name)
 
253
{
 
254
  mri_add_to_list (&order, name, 0, 0, 0, 0);
 
255
}
 
256
 
 
257
void
 
258
mri_alias (const char *want, const char *is, int isn)
 
259
{
 
260
  if (!is)
 
261
    {
 
262
      char buf[20];
 
263
 
 
264
      /* Some sections are digits.  */
 
265
      sprintf (buf, "%d", isn);
 
266
 
 
267
      is = xstrdup (buf);
 
268
 
 
269
      if (is == NULL)
 
270
        abort ();
 
271
    }
 
272
 
 
273
  mri_add_to_list (&alias, is, 0, want, 0, 0);
 
274
}
 
275
 
 
276
void
 
277
mri_name (const char *name)
 
278
{
 
279
  lang_add_output (name, 1);
 
280
}
 
281
 
 
282
void
 
283
mri_format (const char *name)
 
284
{
 
285
  if (strcmp (name, "S") == 0)
 
286
    lang_add_output_format ("srec", NULL, NULL, 1);
 
287
 
 
288
  else if (strcmp (name, "IEEE") == 0)
 
289
    lang_add_output_format ("ieee", NULL, NULL, 1);
 
290
 
 
291
  else if (strcmp (name, "COFF") == 0)
 
292
    lang_add_output_format ("coff-m68k", NULL, NULL, 1);
 
293
 
 
294
  else
 
295
    einfo (_("%P%F: unknown format type %s\n"), name);
 
296
}
 
297
 
 
298
void
 
299
mri_public (const char *name, etree_type *exp)
 
300
{
 
301
  lang_add_assignment (exp_assign (name, exp, FALSE));
 
302
}
 
303
 
 
304
void
 
305
mri_align (const char *name, etree_type *exp)
 
306
{
 
307
  mri_add_to_list (&alignment, name, 0, 0, exp, 0);
 
308
}
 
309
 
 
310
void
 
311
mri_alignmod (const char *name, etree_type *exp)
 
312
{
 
313
  mri_add_to_list (&subalignment, name, 0, 0, 0, exp);
 
314
}
 
315
 
 
316
void
 
317
mri_truncate (unsigned int exp)
 
318
{
 
319
  symbol_truncate = exp;
 
320
}