Back to index

cell-binutils  2.17cvs20070401
mri.c
Go to the documentation of this file.
00001 /* mri.c -- handle MRI style linker scripts
00002    Copyright 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2001,
00003    2002, 2003, 2004, 2005 Free Software Foundation, Inc.
00004 
00005 This file is part of GLD, the Gnu Linker.
00006 
00007 GLD is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2, or (at your option)
00010 any later version.
00011 
00012 GLD is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with GLD; see the file COPYING.  If not, write to the Free
00019 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00020 02110-1301, USA.
00021 
00022    This bit does the tree decoration when MRI style link scripts
00023    are parsed.
00024 
00025    Contributed by Steve Chamberlain <sac@cygnus.com>.  */
00026 
00027 #include "bfd.h"
00028 #include "sysdep.h"
00029 #include "ld.h"
00030 #include "ldexp.h"
00031 #include "ldlang.h"
00032 #include "ldmisc.h"
00033 #include "mri.h"
00034 #include <ldgram.h>
00035 #include "libiberty.h"
00036 
00037 struct section_name_struct {
00038   struct section_name_struct *next;
00039   const char *name;
00040   const char *alias;
00041   etree_type *vma;
00042   etree_type *align;
00043   etree_type *subalign;
00044   int ok_to_load;
00045 };
00046 
00047 static unsigned int symbol_truncate = 10000;
00048 static struct section_name_struct *order;
00049 static struct section_name_struct *only_load;
00050 static struct section_name_struct *address;
00051 static struct section_name_struct *alias;
00052 
00053 static struct section_name_struct *alignment;
00054 static struct section_name_struct *subalignment;
00055 
00056 static struct section_name_struct **
00057 lookup (const char *name, struct section_name_struct **list)
00058 {
00059   struct section_name_struct **ptr = list;
00060 
00061   while (*ptr)
00062     {
00063       if (strcmp (name, (*ptr)->name) == 0)
00064        /* If this is a match, delete it, we only keep the last instance
00065           of any name.  */
00066        *ptr = (*ptr)->next;
00067       else
00068        ptr = &((*ptr)->next);
00069     }
00070 
00071   *ptr = xmalloc (sizeof (struct section_name_struct));
00072   return ptr;
00073 }
00074 
00075 static void
00076 mri_add_to_list (struct section_name_struct **list,
00077                const char *name,
00078                etree_type *vma,
00079                const char *zalias,
00080                etree_type *align,
00081                etree_type *subalign)
00082 {
00083   struct section_name_struct **ptr = lookup (name, list);
00084 
00085   (*ptr)->name = name;
00086   (*ptr)->vma = vma;
00087   (*ptr)->next = NULL;
00088   (*ptr)->ok_to_load = 0;
00089   (*ptr)->alias = zalias;
00090   (*ptr)->align = align;
00091   (*ptr)->subalign = subalign;
00092 }
00093 
00094 void
00095 mri_output_section (const char *name, etree_type *vma)
00096 {
00097   mri_add_to_list (&address, name, vma, 0, 0, 0);
00098 }
00099 
00100 /* If any ABSOLUTE <name> are in the script, only load those files
00101    marked thus.  */
00102 
00103 void
00104 mri_only_load (const char *name)
00105 {
00106   mri_add_to_list (&only_load, name, 0, 0, 0, 0);
00107 }
00108 
00109 void
00110 mri_base (etree_type *exp)
00111 {
00112   base = exp;
00113 }
00114 
00115 static int done_tree = 0;
00116 
00117 void
00118 mri_draw_tree (void)
00119 {
00120   if (done_tree)
00121     return;
00122 
00123   /* Now build the statements for the ldlang machine.  */
00124 
00125   /* Attach the addresses of any which have addresses,
00126      and add the ones not mentioned.  */
00127   if (address != NULL)
00128     {
00129       struct section_name_struct *alist;
00130       struct section_name_struct *olist;
00131 
00132       if (order == NULL)
00133        order = address;
00134 
00135       for (alist = address;
00136           alist != NULL;
00137           alist = alist->next)
00138        {
00139          int done = 0;
00140 
00141          for (olist = order; done == 0 && olist != NULL; olist = olist->next)
00142            {
00143              if (strcmp (alist->name, olist->name) == 0)
00144               {
00145                 olist->vma = alist->vma;
00146                 done = 1;
00147               }
00148            }
00149 
00150          if (!done)
00151            {
00152              /* Add this onto end of order list.  */
00153              mri_add_to_list (&order, alist->name, alist->vma, 0, 0, 0);
00154            }
00155        }
00156     }
00157 
00158   /* If we're only supposed to load a subset of them in, then prune
00159      the list.  */
00160   if (only_load != NULL)
00161     {
00162       struct section_name_struct *ptr1;
00163       struct section_name_struct *ptr2;
00164 
00165       if (order == NULL)
00166        order = only_load;
00167 
00168       /* See if this name is in the list, if it is then we can load it.  */
00169       for (ptr1 = only_load; ptr1; ptr1 = ptr1->next)
00170        for (ptr2 = order; ptr2; ptr2 = ptr2->next)
00171          if (strcmp (ptr2->name, ptr1->name) == 0)
00172            ptr2->ok_to_load = 1;
00173     }
00174   else
00175     {
00176       /* No only load list, so everything is ok to load.  */
00177       struct section_name_struct *ptr;
00178 
00179       for (ptr = order; ptr; ptr = ptr->next)
00180        ptr->ok_to_load = 1;
00181     }
00182 
00183   /* Create the order of sections to load.  */
00184   if (order != NULL)
00185     {
00186       /* Been told to output the sections in a certain order.  */
00187       struct section_name_struct *p = order;
00188 
00189       while (p)
00190        {
00191          struct section_name_struct *aptr;
00192          etree_type *align = 0;
00193          etree_type *subalign = 0;
00194          struct wildcard_list *tmp;
00195 
00196          /* See if an alignment has been specified.  */
00197          for (aptr = alignment; aptr; aptr = aptr->next)
00198            if (strcmp (aptr->name, p->name) == 0)
00199              align = aptr->align;
00200 
00201          for (aptr = subalignment; aptr; aptr = aptr->next)
00202            if (strcmp (aptr->name, p->name) == 0)
00203              subalign = aptr->subalign;
00204 
00205          if (base == 0)
00206            base = p->vma ? p->vma : exp_nameop (NAME, ".");
00207 
00208          lang_enter_output_section_statement (p->name, base,
00209                                           p->ok_to_load ? 0 : noload_section,
00210                                           align, subalign, NULL, 0);
00211          base = 0;
00212          tmp = xmalloc (sizeof *tmp);
00213          tmp->next = NULL;
00214          tmp->spec.name = p->name;
00215          tmp->spec.exclude_name_list = NULL;
00216          tmp->spec.sorted = none;
00217          lang_add_wild (NULL, tmp, FALSE);
00218 
00219          /* If there is an alias for this section, add it too.  */
00220          for (aptr = alias; aptr; aptr = aptr->next)
00221            if (strcmp (aptr->alias, p->name) == 0)
00222              {
00223               tmp = xmalloc (sizeof *tmp);
00224               tmp->next = NULL;
00225               tmp->spec.name = aptr->name;
00226               tmp->spec.exclude_name_list = NULL;
00227               tmp->spec.sorted = none;
00228               lang_add_wild (NULL, tmp, FALSE);
00229              }
00230 
00231          lang_leave_output_section_statement (0, "*default*", NULL, NULL);
00232 
00233          p = p->next;
00234        }
00235     }
00236 
00237   done_tree = 1;
00238 }
00239 
00240 void
00241 mri_load (const char *name)
00242 {
00243   base = 0;
00244   lang_add_input_file (name, lang_input_file_is_file_enum, NULL);
00245 }
00246 
00247 void
00248 mri_order (const char *name)
00249 {
00250   mri_add_to_list (&order, name, 0, 0, 0, 0);
00251 }
00252 
00253 void
00254 mri_alias (const char *want, const char *is, int isn)
00255 {
00256   if (!is)
00257     {
00258       char buf[20];
00259 
00260       /* Some sections are digits.  */
00261       sprintf (buf, "%d", isn);
00262 
00263       is = xstrdup (buf);
00264 
00265       if (is == NULL)
00266        abort ();
00267     }
00268 
00269   mri_add_to_list (&alias, is, 0, want, 0, 0);
00270 }
00271 
00272 void
00273 mri_name (const char *name)
00274 {
00275   lang_add_output (name, 1);
00276 }
00277 
00278 void
00279 mri_format (const char *name)
00280 {
00281   if (strcmp (name, "S") == 0)
00282     lang_add_output_format ("srec", NULL, NULL, 1);
00283 
00284   else if (strcmp (name, "IEEE") == 0)
00285     lang_add_output_format ("ieee", NULL, NULL, 1);
00286 
00287   else if (strcmp (name, "COFF") == 0)
00288     lang_add_output_format ("coff-m68k", NULL, NULL, 1);
00289 
00290   else
00291     einfo (_("%P%F: unknown format type %s\n"), name);
00292 }
00293 
00294 void
00295 mri_public (const char *name, etree_type *exp)
00296 {
00297   lang_add_assignment (exp_assop ('=', name, exp));
00298 }
00299 
00300 void
00301 mri_align (const char *name, etree_type *exp)
00302 {
00303   mri_add_to_list (&alignment, name, 0, 0, exp, 0);
00304 }
00305 
00306 void
00307 mri_alignmod (const char *name, etree_type *exp)
00308 {
00309   mri_add_to_list (&subalignment, name, 0, 0, 0, exp);
00310 }
00311 
00312 void
00313 mri_truncate (unsigned int exp)
00314 {
00315   symbol_truncate = exp;
00316 }