Subversion Repositories Kolibri OS

Rev

Rev 5199 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /* mri.c -- handle MRI style linker scripts
  2.    Copyright (C) 1991-2015 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. }
  321.