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