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