xref: /netbsd/external/gpl3/gdb/dist/ld/mri.c (revision 1424dfb3)
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