mri.c revision 107492
133965Sjdp/* mri.c -- handle MRI style linker scripts 2104834Sobrien Copyright 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, 2002 377298Sobrien Free Software Foundation, Inc. 433965Sjdp 533965SjdpThis file is part of GLD, the Gnu Linker. 633965Sjdp 733965SjdpGLD is free software; you can redistribute it and/or modify 833965Sjdpit under the terms of the GNU General Public License as published by 960484Sobrienthe Free Software Foundation; either version 2, or (at your option) 1033965Sjdpany later version. 1133965Sjdp 1233965SjdpGLD is distributed in the hope that it will be useful, 1333965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1433965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1533965SjdpGNU General Public License for more details. 1633965Sjdp 1733965SjdpYou should have received a copy of the GNU General Public License 1833965Sjdpalong with GLD; see the file COPYING. If not, write to the Free 1933965SjdpSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2077298Sobrien02111-1307, USA. 2133965Sjdp 2277298Sobrien This bit does the tree decoration when MRI style link scripts 2377298Sobrien are parsed. 2433965Sjdp 2577298Sobrien Contributed by Steve Chamberlain <sac@cygnus.com>. */ 2633965Sjdp 2733965Sjdp#include "bfd.h" 2877298Sobrien#include "sysdep.h" 2933965Sjdp#include "ld.h" 3033965Sjdp#include "ldexp.h" 3133965Sjdp#include "ldlang.h" 3233965Sjdp#include "ldmisc.h" 3333965Sjdp#include "mri.h" 34107492Sobrien#include <ldgram.h> 3533965Sjdp#include "libiberty.h" 3633965Sjdp 3733965Sjdpstruct section_name_struct { 3833965Sjdp struct section_name_struct *next; 39104834Sobrien const char *name; 40104834Sobrien const char *alias; 4133965Sjdp etree_type *vma; 4233965Sjdp etree_type *align; 4333965Sjdp etree_type *subalign; 4433965Sjdp int ok_to_load; 4577298Sobrien}; 4633965Sjdp 4733965Sjdpunsigned int symbol_truncate = 10000; 4833965Sjdpstruct section_name_struct *order; 4933965Sjdpstruct section_name_struct *only_load; 5033965Sjdpstruct section_name_struct *address; 5133965Sjdpstruct section_name_struct *alias; 5233965Sjdp 5333965Sjdpstruct section_name_struct *alignment; 5433965Sjdpstruct section_name_struct *subalignment; 5533965Sjdp 5633965Sjdpstatic struct section_name_struct **lookup 5733965Sjdp PARAMS ((const char *name, struct section_name_struct **list)); 5833965Sjdpstatic void mri_add_to_list PARAMS ((struct section_name_struct **list, 5933965Sjdp const char *name, etree_type *vma, 6033965Sjdp const char *zalias, etree_type *align, 6133965Sjdp etree_type *subalign)); 6233965Sjdp 6333965Sjdpstatic struct section_name_struct ** 6433965Sjdplookup (name, list) 65104834Sobrien const char *name; 6633965Sjdp struct section_name_struct **list; 6733965Sjdp{ 6877298Sobrien struct section_name_struct **ptr = list; 6933965Sjdp 7077298Sobrien while (*ptr) 7177298Sobrien { 7277298Sobrien if (strcmp (name, (*ptr)->name) == 0) 7377298Sobrien /* If this is a match, delete it, we only keep the last instance 7477298Sobrien of any name. */ 7577298Sobrien *ptr = (*ptr)->next; 7677298Sobrien else 7777298Sobrien ptr = &((*ptr)->next); 7833965Sjdp } 7933965Sjdp 8077298Sobrien *ptr = (struct section_name_struct *) xmalloc (sizeof (struct section_name_struct)); 8133965Sjdp return ptr; 8233965Sjdp} 8333965Sjdp 8433965Sjdpstatic void 8533965Sjdpmri_add_to_list (list, name, vma, zalias, align, subalign) 8633965Sjdp struct section_name_struct **list; 87104834Sobrien const char *name; 8833965Sjdp etree_type *vma; 89104834Sobrien const char *zalias; 9033965Sjdp etree_type *align; 9133965Sjdp etree_type *subalign; 9233965Sjdp{ 9377298Sobrien struct section_name_struct **ptr = lookup (name, list); 9477298Sobrien 9533965Sjdp (*ptr)->name = name; 9633965Sjdp (*ptr)->vma = vma; 9777298Sobrien (*ptr)->next = (struct section_name_struct *) NULL; 9833965Sjdp (*ptr)->ok_to_load = 0; 9933965Sjdp (*ptr)->alias = zalias; 10033965Sjdp (*ptr)->align = align; 10133965Sjdp (*ptr)->subalign = subalign; 10233965Sjdp} 10333965Sjdp 10433965Sjdpvoid 10533965Sjdpmri_output_section (name, vma) 106104834Sobrien const char *name; 10733965Sjdp etree_type *vma; 10833965Sjdp{ 10977298Sobrien mri_add_to_list (&address, name, vma, 0, 0, 0); 11033965Sjdp} 11133965Sjdp 11277298Sobrien/* If any ABSOLUTE <name> are in the script, only load those files 11377298Sobrien marked thus. */ 11433965Sjdp 11533965Sjdpvoid 11633965Sjdpmri_only_load (name) 117104834Sobrien const char *name; 11833965Sjdp{ 11977298Sobrien mri_add_to_list (&only_load, name, 0, 0, 0, 0); 12033965Sjdp} 12133965Sjdp 12233965Sjdpvoid 12333965Sjdpmri_base (exp) 12433965Sjdp etree_type *exp; 12533965Sjdp{ 12633965Sjdp base = exp; 12733965Sjdp} 12833965Sjdp 12933965Sjdpstatic int done_tree = 0; 13033965Sjdp 13133965Sjdpvoid 13233965Sjdpmri_draw_tree () 13333965Sjdp{ 13477298Sobrien if (done_tree) 13577298Sobrien return; 13633965Sjdp 13777298Sobrien#if 0 /* We don't bother with memory regions. */ 13877298Sobrien /* Create the regions. */ 13977298Sobrien { 14077298Sobrien lang_memory_region_type *r; 14177298Sobrien 14277298Sobrien r = lang_memory_region_lookup("long"); 14377298Sobrien r->current = r->origin = exp_get_vma (base, (bfd_vma)0, "origin", 14477298Sobrien lang_first_phase_enum); 14577298Sobrien r->length = (bfd_size_type) exp_get_vma (0, (bfd_vma) ~((bfd_size_type)0), 14677298Sobrien "length", lang_first_phase_enum); 14777298Sobrien } 14833965Sjdp#endif 14933965Sjdp 15077298Sobrien /* Now build the statements for the ldlang machine. */ 15133965Sjdp 15277298Sobrien /* Attatch the addresses of any which have addresses, 15377298Sobrien and add the ones not mentioned. */ 15477298Sobrien if (address != (struct section_name_struct *) NULL) 15577298Sobrien { 15677298Sobrien struct section_name_struct *alist; 15777298Sobrien struct section_name_struct *olist; 15833965Sjdp 15977298Sobrien if (order == (struct section_name_struct *) NULL) 16077298Sobrien order = address; 16177298Sobrien 16277298Sobrien for (alist = address; 16377298Sobrien alist != (struct section_name_struct *) NULL; 16477298Sobrien alist = alist->next) 16533965Sjdp { 16677298Sobrien int done = 0; 16777298Sobrien 16877298Sobrien for (olist = order; 16977298Sobrien done == 0 && olist != (struct section_name_struct *) NULL; 17077298Sobrien olist = olist->next) 17177298Sobrien { 17277298Sobrien if (strcmp (alist->name, olist->name) == 0) 17377298Sobrien { 17477298Sobrien olist->vma = alist->vma; 17577298Sobrien done = 1; 17677298Sobrien } 17777298Sobrien } 17877298Sobrien 17977298Sobrien if (!done) 18077298Sobrien { 18177298Sobrien /* Add this onto end of order list. */ 18277298Sobrien mri_add_to_list (&order, alist->name, alist->vma, 0, 0, 0); 18377298Sobrien } 18433965Sjdp } 18533965Sjdp } 18633965Sjdp 18733965Sjdp /* If we're only supposed to load a subset of them in, then prune 18833965Sjdp the list. */ 18977298Sobrien if (only_load != (struct section_name_struct *) NULL) 19077298Sobrien { 19177298Sobrien struct section_name_struct *ptr1; 19277298Sobrien struct section_name_struct *ptr2; 19333965Sjdp 19477298Sobrien if (order == (struct section_name_struct *) NULL) 19577298Sobrien order = only_load; 19677298Sobrien 19777298Sobrien /* See if this name is in the list, if it is then we can load it. */ 19877298Sobrien for (ptr1 = only_load; ptr1; ptr1 = ptr1->next) 19977298Sobrien for (ptr2 = order; ptr2; ptr2 = ptr2->next) 20077298Sobrien if (strcmp (ptr2->name, ptr1->name) == 0) 20177298Sobrien ptr2->ok_to_load = 1; 20277298Sobrien } 20377298Sobrien else 20433965Sjdp { 20577298Sobrien /* No only load list, so everything is ok to load. */ 20677298Sobrien struct section_name_struct *ptr; 20777298Sobrien 20877298Sobrien for (ptr = order; ptr; ptr = ptr->next) 20977298Sobrien ptr->ok_to_load = 1; 21033965Sjdp } 21133965Sjdp 21277298Sobrien /* Create the order of sections to load. */ 21377298Sobrien if (order != (struct section_name_struct *) NULL) 21477298Sobrien { 21577298Sobrien /* Been told to output the sections in a certain order. */ 21677298Sobrien struct section_name_struct *p = order; 21733965Sjdp 21877298Sobrien while (p) 21977298Sobrien { 22077298Sobrien struct section_name_struct *aptr; 22177298Sobrien etree_type *align = 0; 22277298Sobrien etree_type *subalign = 0; 22389857Sobrien struct wildcard_list *tmp; 22433965Sjdp 22577298Sobrien /* See if an alignment has been specified. */ 22677298Sobrien for (aptr = alignment; aptr; aptr = aptr->next) 22777298Sobrien if (strcmp (aptr->name, p->name) == 0) 22877298Sobrien align = aptr->align; 22933965Sjdp 23077298Sobrien for (aptr = subalignment; aptr; aptr = aptr->next) 23177298Sobrien if (strcmp (aptr->name, p->name) == 0) 23277298Sobrien subalign = aptr->subalign; 23333965Sjdp 23477298Sobrien if (base == 0) 23577298Sobrien base = p->vma ? p->vma : exp_nameop (NAME, "."); 23633965Sjdp 23777298Sobrien lang_enter_output_section_statement (p->name, base, 23877298Sobrien p->ok_to_load ? 0 : noload_section, 23977298Sobrien 1, align, subalign, 24077298Sobrien (etree_type *) NULL); 24177298Sobrien base = 0; 24289857Sobrien tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); 24389857Sobrien tmp->next = NULL; 24489857Sobrien tmp->spec.name = p->name; 24589857Sobrien tmp->spec.exclude_name_list = NULL; 24689857Sobrien tmp->spec.sorted = false; 24789857Sobrien lang_add_wild (NULL, tmp, false); 24833965Sjdp 24977298Sobrien /* If there is an alias for this section, add it too. */ 25077298Sobrien for (aptr = alias; aptr; aptr = aptr->next) 25177298Sobrien if (strcmp (aptr->alias, p->name) == 0) 25289857Sobrien { 25389857Sobrien tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); 25489857Sobrien tmp->next = NULL; 25589857Sobrien tmp->spec.name = aptr->name; 25689857Sobrien tmp->spec.exclude_name_list = NULL; 25789857Sobrien tmp->spec.sorted = false; 25889857Sobrien lang_add_wild (NULL, tmp, false); 25989857Sobrien } 26033965Sjdp 26177298Sobrien lang_leave_output_section_statement 26277298Sobrien (0, "*default*", (struct lang_output_section_phdr_list *) NULL, 263104834Sobrien NULL); 26433965Sjdp 26577298Sobrien p = p->next; 26677298Sobrien } 26733965Sjdp } 26833965Sjdp 26933965Sjdp done_tree = 1; 27077298Sobrien} 27133965Sjdp 27233965Sjdpvoid 27333965Sjdpmri_load (name) 274104834Sobrien const char *name; 27533965Sjdp{ 27633965Sjdp base = 0; 27777298Sobrien lang_add_input_file (name, 27877298Sobrien lang_input_file_is_file_enum, (char *) NULL); 27977298Sobrien#if 0 28077298Sobrien lang_leave_output_section_statement (0, "*default*"); 28177298Sobrien#endif 28233965Sjdp} 28333965Sjdp 28433965Sjdpvoid 28533965Sjdpmri_order (name) 286104834Sobrien const char *name; 28733965Sjdp{ 28877298Sobrien mri_add_to_list (&order, name, 0, 0, 0, 0); 28933965Sjdp} 29033965Sjdp 29177298Sobrienvoid 29233965Sjdpmri_alias (want, is, isn) 293104834Sobrien const char *want; 294104834Sobrien const char *is; 29533965Sjdp int isn; 29633965Sjdp{ 29777298Sobrien if (!is) 29877298Sobrien { 29977298Sobrien char buf[20]; 30033965Sjdp 30177298Sobrien /* Some sections are digits. */ 30277298Sobrien sprintf (buf, "%d", isn); 30377298Sobrien 30477298Sobrien is = xstrdup (buf); 30577298Sobrien 30677298Sobrien if (is == NULL) 30777298Sobrien abort (); 30877298Sobrien } 30977298Sobrien 31077298Sobrien mri_add_to_list (&alias, is, 0, want, 0, 0); 31133965Sjdp} 31233965Sjdp 31377298Sobrienvoid 31433965Sjdpmri_name (name) 315104834Sobrien const char *name; 31633965Sjdp{ 31777298Sobrien lang_add_output (name, 1); 31833965Sjdp} 31933965Sjdp 32033965Sjdpvoid 32133965Sjdpmri_format (name) 322104834Sobrien const char *name; 32333965Sjdp{ 32477298Sobrien if (strcmp (name, "S") == 0) 32577298Sobrien lang_add_output_format ("srec", (char *) NULL, (char *) NULL, 1); 32677298Sobrien 32777298Sobrien else if (strcmp (name, "IEEE") == 0) 32877298Sobrien lang_add_output_format ("ieee", (char *) NULL, (char *) NULL, 1); 32977298Sobrien 33077298Sobrien else if (strcmp (name, "COFF") == 0) 33177298Sobrien lang_add_output_format ("coff-m68k", (char *) NULL, (char *) NULL, 1); 33277298Sobrien 33377298Sobrien else 33477298Sobrien einfo (_("%P%F: unknown format type %s\n"), name); 33533965Sjdp} 33633965Sjdp 33733965Sjdpvoid 33833965Sjdpmri_public (name, exp) 339104834Sobrien const char *name; 34033965Sjdp etree_type *exp; 34133965Sjdp{ 34277298Sobrien lang_add_assignment (exp_assop ('=', name, exp)); 34333965Sjdp} 34433965Sjdp 34577298Sobrienvoid 34633965Sjdpmri_align (name, exp) 347104834Sobrien const char *name; 34833965Sjdp etree_type *exp; 34933965Sjdp{ 35077298Sobrien mri_add_to_list (&alignment, name, 0, 0, exp, 0); 35133965Sjdp} 35233965Sjdp 35377298Sobrienvoid 35433965Sjdpmri_alignmod (name, exp) 355104834Sobrien const char *name; 35633965Sjdp etree_type *exp; 35733965Sjdp{ 35877298Sobrien mri_add_to_list (&subalignment, name, 0, 0, 0, exp); 35933965Sjdp} 36033965Sjdp 36177298Sobrienvoid 36233965Sjdpmri_truncate (exp) 36333965Sjdp unsigned int exp; 36433965Sjdp{ 36533965Sjdp symbol_truncate = exp; 36633965Sjdp} 367