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