mri.c revision 60484
133965Sjdp/* mri.c -- handle MRI style linker scripts
260484Sobrien   Copyright (C) 1991, 92, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
333965Sjdp
433965SjdpThis file is part of GLD, the Gnu Linker.
533965Sjdp
633965SjdpGLD is free software; you can redistribute it and/or modify
733965Sjdpit under the terms of the GNU General Public License as published by
860484Sobrienthe Free Software Foundation; either version 2, or (at your option)
933965Sjdpany later version.
1033965Sjdp
1133965SjdpGLD is distributed in the hope that it will be useful,
1233965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of
1333965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1433965SjdpGNU General Public License for more details.
1533965Sjdp
1633965SjdpYou should have received a copy of the GNU General Public License
1733965Sjdpalong with GLD; see the file COPYING.  If not, write to the Free
1833965SjdpSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
1933965Sjdp02111-1307, USA.  */
2033965Sjdp
2133965Sjdp
2233965Sjdp/* This bit does the tree decoration when MRI style link scripts are parsed */
2333965Sjdp
2433965Sjdp/*
2533965Sjdp  contributed by Steve Chamberlain
2633965Sjdp  		 sac@cygnus.com
2733965Sjdp
2833965Sjdp*/
2933965Sjdp
3033965Sjdp#include "bfd.h"
3133965Sjdp#include "sysdep.h"
3233965Sjdp#include "ld.h"
3333965Sjdp#include "ldexp.h"
3433965Sjdp#include "ldlang.h"
3533965Sjdp#include "ldmisc.h"
3633965Sjdp#include "mri.h"
3733965Sjdp#include "ldgram.h"
3833965Sjdp#include "libiberty.h"
3933965Sjdp
4033965Sjdpstruct section_name_struct {
4133965Sjdp  struct section_name_struct *next;
4233965Sjdp  CONST char *name;
4333965Sjdp  CONST char *alias;
4433965Sjdp  etree_type *vma;
4533965Sjdp  etree_type *align;
4633965Sjdp  etree_type *subalign;
4733965Sjdp  int ok_to_load;
4833965Sjdp} ;
4933965Sjdp
5033965Sjdpunsigned int symbol_truncate = 10000;
5133965Sjdpstruct section_name_struct *order;
5233965Sjdpstruct section_name_struct *only_load;
5333965Sjdpstruct section_name_struct *address;
5433965Sjdpstruct section_name_struct *alias;
5533965Sjdp
5633965Sjdpstruct section_name_struct *alignment;
5733965Sjdpstruct section_name_struct *subalignment;
5833965Sjdp
5933965Sjdpstatic struct section_name_struct **lookup
6033965Sjdp  PARAMS ((const char *name, struct section_name_struct **list));
6133965Sjdpstatic void mri_add_to_list PARAMS ((struct section_name_struct **list,
6233965Sjdp				     const char *name, etree_type *vma,
6333965Sjdp				     const char *zalias, etree_type *align,
6433965Sjdp				     etree_type *subalign));
6533965Sjdp
6633965Sjdpstatic struct section_name_struct **
6733965Sjdplookup (name, list)
6833965Sjdp     CONST char *name;
6933965Sjdp     struct section_name_struct **list;
7033965Sjdp{
7133965Sjdp
7233965Sjdp  struct section_name_struct **ptr = list;
7333965Sjdp  while (*ptr)
7433965Sjdp  {
7533965Sjdp    if (strcmp(name, (*ptr)->name) == 0) {
7633965Sjdp      /* If this is a match, delete it, we only keep the last instance
7733965Sjdp	 of any name */
7833965Sjdp      *ptr = (*ptr)->next;
7933965Sjdp    }
8033965Sjdp    else {
8133965Sjdp      ptr = &((*ptr)->next);
8233965Sjdp    }
8333965Sjdp  }
8433965Sjdp
8533965Sjdp  *ptr = (struct section_name_struct *)xmalloc(sizeof(struct section_name_struct));
8633965Sjdp  return ptr;
8733965Sjdp}
8833965Sjdp
8933965Sjdpstatic void
9033965Sjdpmri_add_to_list (list, name, vma, zalias, align, subalign)
9133965Sjdp     struct section_name_struct **list;
9233965Sjdp     CONST char *name;
9333965Sjdp     etree_type *vma;
9433965Sjdp     CONST char *zalias;
9533965Sjdp     etree_type *align;
9633965Sjdp     etree_type *subalign;
9733965Sjdp{
9833965Sjdp  struct section_name_struct **ptr = lookup(name,list);
9933965Sjdp  (*ptr)->name = name;
10033965Sjdp  (*ptr)->vma = vma;
10133965Sjdp  (*ptr)->next = (struct section_name_struct *)NULL;
10233965Sjdp  (*ptr)->ok_to_load = 0;
10333965Sjdp  (*ptr)->alias = zalias;
10433965Sjdp  (*ptr)->align = align;
10533965Sjdp  (*ptr)->subalign = subalign;
10633965Sjdp}
10733965Sjdp
10833965Sjdp
10933965Sjdpvoid
11033965Sjdpmri_output_section (name, vma)
11133965Sjdp     CONST char *name;
11233965Sjdp     etree_type *vma;
11333965Sjdp{
11433965Sjdp  mri_add_to_list(&address, name, vma, 0,0,0);
11533965Sjdp}
11633965Sjdp
11733965Sjdp/* if any ABSOLUTE <name> are in the script, only load those files
11833965Sjdpmarked thus */
11933965Sjdp
12033965Sjdpvoid
12133965Sjdpmri_only_load (name)
12233965Sjdp     CONST char *name;
12333965Sjdp{
12433965Sjdp  mri_add_to_list(&only_load, name, 0, 0,0,0);
12533965Sjdp}
12633965Sjdp
12733965Sjdp
12833965Sjdpvoid
12933965Sjdpmri_base (exp)
13033965Sjdp     etree_type *exp;
13133965Sjdp{
13233965Sjdp  base = exp;
13333965Sjdp}
13433965Sjdp
13533965Sjdpstatic int done_tree = 0;
13633965Sjdp
13733965Sjdpvoid
13833965Sjdpmri_draw_tree ()
13933965Sjdp{
14033965Sjdp  if (done_tree) return;
14133965Sjdp
14233965Sjdp  /* We don't bother with memory regions.  */
14333965Sjdp#if 0
14433965Sjdp  /* Create the regions */
14533965Sjdp {
14633965Sjdp   lang_memory_region_type *r;
14733965Sjdp   r = lang_memory_region_lookup("long");
14833965Sjdp   r->current = r->origin = exp_get_vma(base, (bfd_vma)0, "origin",
14933965Sjdp					lang_first_phase_enum);
15033965Sjdp   r->length = (bfd_size_type) exp_get_vma(0, (bfd_vma) ~((bfd_size_type)0),
15133965Sjdp					   "length", lang_first_phase_enum);
15233965Sjdp }
15333965Sjdp#endif
15433965Sjdp
15533965Sjdp  /* Now build the statements for the ldlang machine */
15633965Sjdp
15733965Sjdp
15833965Sjdp  /* Attatch the addresses of any which have addresses, and add the
15933965Sjdp     ones not mentioned */
16033965Sjdp  if (address != (struct section_name_struct *)NULL) {
16133965Sjdp    struct section_name_struct *alist;
16233965Sjdp    struct section_name_struct *olist;
16333965Sjdp    if (order == (struct section_name_struct *)NULL) {
16433965Sjdp      order = address;
16533965Sjdp    }
16633965Sjdp
16733965Sjdp    for (alist = address;
16833965Sjdp	 alist != (struct section_name_struct*)NULL;
16933965Sjdp	 alist = alist->next)
17033965Sjdp    {
17133965Sjdp      int done = 0;
17233965Sjdp      for (olist = order;
17333965Sjdp	   done == 0 &&
17433965Sjdp	   olist != (struct section_name_struct *)NULL;
17533965Sjdp	   olist = olist->next)
17633965Sjdp      {
17733965Sjdp	if (strcmp(alist->name, olist->name) == 0)
17833965Sjdp	{
17933965Sjdp	  olist->vma = alist->vma;
18033965Sjdp	  done = 1;
18133965Sjdp	}
18233965Sjdp      }
18333965Sjdp      if (!done) {
18433965Sjdp	/* add this onto end of order list */
18533965Sjdp	mri_add_to_list(&order, alist->name, alist->vma, 0,0,0);
18633965Sjdp      }
18733965Sjdp
18833965Sjdp    }
18933965Sjdp
19033965Sjdp  }
19133965Sjdp
19233965Sjdp  /* If we're only supposed to load a subset of them in, then prune
19333965Sjdp     the list.  */
19433965Sjdp
19533965Sjdp  if (only_load != (struct section_name_struct *)NULL)
19633965Sjdp  {
19733965Sjdp    struct section_name_struct *ptr1;
19833965Sjdp    struct section_name_struct *ptr2;
19933965Sjdp    if (order == (struct section_name_struct*)NULL)
20033965Sjdp     order = only_load;
20133965Sjdp
20233965Sjdp    /* See if this name is in the list, if it is then we can load it
20333965Sjdp     */
20433965Sjdp    for (ptr1 = only_load; ptr1; ptr1 = ptr1->next)
20533965Sjdp    {
20633965Sjdp      for (ptr2= order; ptr2; ptr2=ptr2->next)
20733965Sjdp      {
20833965Sjdp	if (strcmp(ptr2->name, ptr1->name)==0) {
20933965Sjdp	  ptr2->ok_to_load = 1;
21033965Sjdp	}
21133965Sjdp      }
21233965Sjdp    }
21333965Sjdp  }
21433965Sjdp  else
21533965Sjdp  {
21633965Sjdp    /* No only load list, so everything is ok to load */
21733965Sjdp    struct section_name_struct *ptr;
21833965Sjdp    for (ptr = order; ptr; ptr=ptr->next) {
21933965Sjdp      ptr->ok_to_load = 1;
22033965Sjdp    }
22133965Sjdp  }
22233965Sjdp
22333965Sjdp
22433965Sjdp
22533965Sjdp  /* Create the order of sections to load */
22633965Sjdp  if (order != (struct section_name_struct *)NULL)
22733965Sjdp  {
22833965Sjdp    /* Been told to output the sections in a certain order */
22933965Sjdp    struct section_name_struct *p = order;
23033965Sjdp    while (p)
23133965Sjdp    {
23233965Sjdp      struct section_name_struct *aptr;
23333965Sjdp      etree_type *align = 0;
23433965Sjdp      etree_type *subalign = 0;
23533965Sjdp      /* See if an alignment has been specified */
23633965Sjdp
23733965Sjdp      for (aptr = alignment; aptr; aptr= aptr->next)
23833965Sjdp      {
23933965Sjdp	if (strcmp(aptr->name, p->name)==0) {
24033965Sjdp	  align =  aptr->align;
24133965Sjdp	}
24233965Sjdp      }
24333965Sjdp
24433965Sjdp      for (aptr = subalignment; aptr; aptr= aptr->next)
24533965Sjdp      {
24633965Sjdp	if (strcmp(aptr->name, p->name)==0) {
24733965Sjdp	  subalign =  aptr->subalign;
24833965Sjdp	}
24933965Sjdp      }
25033965Sjdp
25133965Sjdp      if (base == 0) {
25233965Sjdp	base = p->vma ? p->vma :exp_nameop(NAME, ".");
25333965Sjdp      }
25433965Sjdp      lang_enter_output_section_statement (p->name, base,
25533965Sjdp					   p->ok_to_load ? 0 : noload_section,
25633965Sjdp					   1, align, subalign,
25733965Sjdp					   (etree_type *) NULL);
25833965Sjdp      base = 0;
25960484Sobrien      lang_add_wild (p->name, false, (char *)NULL, false, false, NULL);
26033965Sjdp      /* If there is an alias for this section, add it too */
26133965Sjdp      for (aptr = alias; aptr; aptr = aptr->next) {
26233965Sjdp
26333965Sjdp	if (strcmp(aptr->alias, p->name)== 0) {
26460484Sobrien	  lang_add_wild (aptr->name, false, (char *)NULL, false, false, NULL);
26533965Sjdp	}
26633965Sjdp      }
26733965Sjdp
26833965Sjdp      lang_leave_output_section_statement
26960484Sobrien	(0, "*default*", (struct lang_output_section_phdr_list *) NULL,
27060484Sobrien         "*default*");
27133965Sjdp
27233965Sjdp      p = p->next;
27333965Sjdp    }
27433965Sjdp  }
27533965Sjdp
27633965Sjdp
27733965Sjdp  done_tree = 1;
27833965Sjdp
27933965Sjdp}
28033965Sjdpvoid
28133965Sjdpmri_load (name)
28233965Sjdp     CONST char *name;
28333965Sjdp{
28433965Sjdp  base = 0;
28533965Sjdp  lang_add_input_file(name,
28633965Sjdp		      lang_input_file_is_file_enum, (char *)NULL);
28733965Sjdp  /*  lang_leave_output_section_statement(0,"*default*");*/
28833965Sjdp}
28933965Sjdp
29033965Sjdp
29133965Sjdpvoid
29233965Sjdpmri_order (name)
29333965Sjdp     CONST char *name;
29433965Sjdp{
29533965Sjdp  mri_add_to_list(&order, name, 0, 0,0,0);
29633965Sjdp}
29733965Sjdp
29833965Sjdpvoid
29933965Sjdpmri_alias (want, is, isn)
30033965Sjdp     CONST char *want;
30133965Sjdp     CONST char *is;
30233965Sjdp     int isn;
30333965Sjdp{
30433965Sjdp  if (!is) {
30533965Sjdp    /* Some sections are digits - */
30633965Sjdp    char buf[20];
30733965Sjdp    sprintf(buf, "%d", isn);
30833965Sjdp    is = xstrdup (buf);
30933965Sjdp    if (is == NULL)
31033965Sjdp      abort ();
31133965Sjdp  }
31233965Sjdp  mri_add_to_list(&alias, is, 0, want,0,0);
31333965Sjdp
31433965Sjdp}
31533965Sjdp
31633965Sjdp
31733965Sjdpvoid
31833965Sjdpmri_name (name)
31933965Sjdp     CONST char *name;
32033965Sjdp{
32133965Sjdp  lang_add_output(name, 1);
32233965Sjdp
32333965Sjdp}
32433965Sjdp
32533965Sjdp
32633965Sjdpvoid
32733965Sjdpmri_format (name)
32833965Sjdp     CONST char *name;
32933965Sjdp{
33033965Sjdp  if (strcmp(name, "S") == 0)
33133965Sjdp  {
33233965Sjdp    lang_add_output_format("srec", (char *) NULL, (char *) NULL, 1);
33333965Sjdp  }
33433965Sjdp  else if (strcmp(name, "IEEE") == 0)
33533965Sjdp  {
33633965Sjdp    lang_add_output_format("ieee", (char *) NULL, (char *) NULL, 1);
33733965Sjdp  }
33833965Sjdp  else if (strcmp(name, "COFF") == 0)
33933965Sjdp  {
34033965Sjdp    lang_add_output_format("coff-m68k", (char *) NULL, (char *) NULL, 1);
34133965Sjdp  }
34233965Sjdp  else {
34360484Sobrien    einfo(_("%P%F: unknown format type %s\n"), name);
34433965Sjdp  }
34533965Sjdp}
34633965Sjdp
34733965Sjdp
34833965Sjdpvoid
34933965Sjdpmri_public (name, exp)
35033965Sjdp     CONST char *name;
35133965Sjdp     etree_type *exp;
35233965Sjdp{
35333965Sjdp  lang_add_assignment(exp_assop('=', name, exp));
35433965Sjdp}
35533965Sjdp
35633965Sjdpvoid
35733965Sjdpmri_align (name, exp)
35833965Sjdp     CONST char *name;
35933965Sjdp     etree_type *exp;
36033965Sjdp{
36133965Sjdp  mri_add_to_list(&alignment, name,0,0,exp,0);
36233965Sjdp}
36333965Sjdp
36433965Sjdpvoid
36533965Sjdpmri_alignmod (name, exp)
36633965Sjdp     CONST char *name;
36733965Sjdp     etree_type *exp;
36833965Sjdp{
36933965Sjdp  mri_add_to_list(&subalignment, name,0,0,0,exp);
37033965Sjdp}
37133965Sjdp
37233965Sjdp
37333965Sjdpvoid
37433965Sjdpmri_truncate (exp)
37533965Sjdp     unsigned int exp;
37633965Sjdp{
37733965Sjdp  symbol_truncate = exp;
37833965Sjdp}
379