This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] LMA memory regions


This patch adds functionality for assigning sections to load-time memory
regions analagous to the existing function for assigning to run-time
memory regions.

(This is a stripped-down version of a previous patch)

T.


Index: ChangeLog
===================================================================
RCS file: /cvs/src/src/ld/ChangeLog,v
retrieving revision 1.134
diff -d -c -p -r1.134 ChangeLog
*** ChangeLog	2000/02/09 14:42:47	1.134
--- ChangeLog	2000/02/16 18:22:07
***************
*** 1,3 ****
--- 1,24 ----
+ 2000-02-16  Timothy Wall  <twall@cygnus.com>
+ 
+ 	* mri.c (mri_draw_tree): Add default LMA region argument to call
+ 	to lang_leave_output_section_statement.
+ 	* ldlang.h: Update prototypes with LMA region arguments.
+ 	* ldlang.c (lang_size_sections): Encapsulate region bounds
+ 	checking in os_check_region call.
+ 	(os_check_region): New function.
+ 	(lang_output_section_statement_lookup): Initialize lma_region.
+ 	(lang_leave_output_section_statement): Add LMA region argument.
+ 	(lang_leave_overlay): Ditto.
+ 	* ldgram.y: Handle LMA region syntax.
+ 	* ld.texinfo (Output Section Description): Describe LMA region usage.
+ 	* emultempl/armelf.em (gld$place_orphan): Add default value for
+ 	lma region in call to lang_leave_output_statement.
+ 	* emultempl/elf32.em (gld$place_orphan): Add default value for
+ 	lma region in call to lang_leave_output_statement.
+ 	* emultempl/pe.em (gld$place_orphan): Add default value for
+ 	lma region in call to lang_leave_output_statement.
+ 	
+ 	
  2000-02-04  Timothy Wall  <twall@redhat.com>
  
  	* ldlang.c (lang_check_section_addresses): Use bytes instead of
Index: ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.10
diff -d -c -p -r1.10 ld.texinfo
*** ld.texinfo	2000/01/07 19:46:04	1.10
--- ld.texinfo	2000/02/16 18:22:08
*************** The full description of an output sectio
*** 2127,2133 ****
      @var{output-section-command}
      @var{output-section-command}
      @dots{}
!   @} [>@var{region}] [:@var{phdr} :@var{phdr} @dots{}] [=@var{fillexp}]
  @end group
  @end smallexample
  
--- 2127,2133 ----
      @var{output-section-command}
      @var{output-section-command}
      @dots{}
!   @} [>@var{region}] [AT>@var{lma_region}] [:@var{phdr} :@var{phdr} @dots{}] [=@var{fillexp}]
  @end group
  @end smallexample
  
*************** like this:
*** 2632,2638 ****
      @var{output-section-command}
      @var{output-section-command}
      @dots{}
!   @} [>@var{region}] [:@var{phdr} :@var{phdr} @dots{}] [=@var{fillexp}]
  @end group
  @end smallexample
  We've already described @var{section}, @var{address}, and
--- 2632,2638 ----
      @var{output-section-command}
      @var{output-section-command}
      @dots{}
!   @} [>@var{region}] [AT>@var{lma_region}] [:@var{phdr} :@var{phdr} @dots{}] [=@var{fillexp}]
  @end group
  @end smallexample
  We've already described @var{section}, @var{address}, and
*************** SECTIONS @{
*** 2686,2691 ****
--- 2686,2692 ----
  
  @node Output Section LMA
  @subsubsection Output section LMA
+ @kindex AT>@var{lma_region}
  @kindex AT(@var{lma})
  @cindex load address
  @cindex section load address
*************** Address}).
*** 2696,2702 ****
  
  The linker will normally set the LMA equal to the VMA.  You can change
  that by using the @code{AT} keyword.  The expression @var{lma} that
! follows the @code{AT} keyword specifies the load address of the section.
  
  @cindex ROM initialized data
  @cindex initialized data in ROM
--- 2697,2705 ----
  
  The linker will normally set the LMA equal to the VMA.  You can change
  that by using the @code{AT} keyword.  The expression @var{lma} that
! follows the @code{AT} keyword specifies the load address of the
! section.  Alternatively, with @samp{AT>@var{lma_region}} expression,
! you may specify a memory region for the section's load address. @xref{MEMORY}.
  
  @cindex ROM initialized data
  @cindex initialized data in ROM
Index: ldgram.y
===================================================================
RCS file: /cvs/src/src/ld/ldgram.y,v
retrieving revision 1.3
diff -d -c -p -r1.3 ldgram.y
*** ldgram.y	2000/01/05 14:12:23	1.3
--- ldgram.y	2000/02/16 18:22:08
*************** static int error_index;
*** 92,97 ****
--- 92,98 ----
  %type <integer> fill_opt
  %type <name_list> exclude_name_list
  %type <name> memspec_opt casesymlist
+ %type <name> memspec_at_opt
  %type <cname> wildcard_name
  %type <wildcard> wildcard_spec
  %token <integer> INT  
*************** memory_spec_list:
*** 611,624 ****
  	|	memory_spec_list ',' memory_spec
  	|
  	;
- 
  
! memory_spec: 		NAME
! 			{ region = lang_memory_region_lookup($1); }
! 		attributes_opt ':'
! 		origin_spec opt_comma length_spec
  
! 	; origin_spec:
  	ORIGIN '=' mustbe_exp
  		{ region->current =
  		 region->origin =
--- 612,636 ----
  	|	memory_spec_list ',' memory_spec
  	|
  	;
  
! memory_spec:
!                 NAME {
!                   region = lang_memory_region_lookup($1);
!                   region->page = current_mempage;
!                 }
!                 attributes_opt ':' origin_spec opt_comma length_spec 
!         |       PAGE INT ':' NAME
!                 {
!                   current_mempage = $2;
!                   if (($2 & 0xFF) != $2)
!                     einfo (_("%P%F:%S: page number %d out of range\n"), $2);
!                   region = lang_memory_region_lookup($4);
!                   region->page = current_mempage;
!                 }
!                 attributes_opt ':' origin_spec opt_comma length_spec 
! 	;
  
! origin_spec:
  	ORIGIN '=' mustbe_exp
  		{ region->current =
  		 region->origin =
*************** exp	:
*** 799,804 ****
--- 811,821 ----
  	;
  
  
+ memspec_at_opt:
+                 AT '>' NAME { $$ = $3; }
+         |       { $$ = "*default*"; }
+         ;
+ 
  opt_at:
  		AT '(' exp ')' { $$ = $3; }
  	|	{ $$ = 0; }
*************** section:	NAME 		{ ldlex_expression(); }
*** 815,824 ****
  			}
  		statement_list_opt 	
   		'}' { ldlex_popstate (); ldlex_expression (); }
! 		memspec_opt phdr_opt fill_opt
  		{
  		  ldlex_popstate ();
! 		  lang_leave_output_section_statement ($13, $11, $12);
  		}
  		opt_comma
  	|	OVERLAY
--- 832,841 ----
  			}
  		statement_list_opt 	
   		'}' { ldlex_popstate (); ldlex_expression (); }
! 		memspec_opt memspec_at_opt phdr_opt fill_opt
  		{
  		  ldlex_popstate ();
! 		  lang_leave_output_section_statement ($14, $11, $13, $12);
  		}
  		opt_comma
  	|	OVERLAY
*************** section:	NAME 		{ ldlex_expression(); }
*** 832,841 ****
  		overlay_section
  		'}'
  			{ ldlex_popstate (); ldlex_expression (); }
! 		memspec_opt phdr_opt fill_opt
  			{
  			  ldlex_popstate ();
! 			  lang_leave_overlay ($14, $12, $13);
  			}
  		opt_comma
  	|	/* The GROUP case is just enough to support the gcc
--- 849,858 ----
  		overlay_section
  		'}'
  			{ ldlex_popstate (); ldlex_expression (); }
! 		memspec_opt memspec_at_opt phdr_opt fill_opt
  			{
  			  ldlex_popstate ();
! 			  lang_leave_overlay ($15, $12, $14, $13);
  			}
  		opt_comma
  	|	/* The GROUP case is just enough to support the gcc
Index: ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.22
diff -d -c -p -r1.22 ldlang.c
*** ldlang.c	2000/02/09 14:42:48	1.22
--- ldlang.c	2000/02/16 18:22:08
*************** lang_output_section_statement_lookup (na
*** 682,687 ****
--- 682,688 ----
        lookup = (lang_output_section_statement_type *)
  	new_stat (lang_output_section_statement, stat_ptr);
        lookup->region = (lang_memory_region_type *) NULL;
+       lookup->lma_region = (lang_memory_region_type *) NULL;
        lookup->fill = 0;
        lookup->block_value = 1;
        lookup->name = name;
*************** _("%X%P: section %s [%V -> %V] overlaps 
*** 2695,2700 ****
--- 2696,2738 ----
  
  static boolean relax_again;
  
+ /* Make sure the new address is within the region.  We explicitly permit the
+    current address to be at the exact end of the region when the address is
+    non-zero, in case the region is at the end of addressable memory and the
+    calculation wraps around.  */ 
+ 
+ static void
+ os_region_check (os, region, tree, base)
+   lang_output_section_statement_type *os;
+   struct memory_region_struct *region;
+   etree_type *tree;
+   bfd_vma base;
+ {
+   if ((region->current < region->origin
+        || (region->current - region->origin > region->length))
+       && ((region->current != region->origin + region->length)
+            || base == 0))
+     {
+       if (tree != (etree_type *) NULL)
+         {
+           einfo (_("%X%P: address 0x%v of %B section %s is not within region %s\n"),
+                  region->current,
+                  os->bfd_section->owner,
+                  os->bfd_section->name,
+                  region->name);
+         }
+       else
+         {
+           einfo (_("%X%P: region %s is full (%B section %s)\n"),
+                  region->name,
+                  os->bfd_section->owner,
+                  os->bfd_section->name);
+         }
+       /* Reset the region pointer.  */
+       region->current = region->origin;
+     }
+ }
+ 
  /* Set the sizes for all the output sections.  */
  
  bfd_vma
*************** lang_size_sections (s, output_section_st
*** 2853,2889 ****
  	      {
  		os->region->current = dot;
  		
! 		/* Make sure the new address is within the region.  We
!                    explicitly permit the current address to be at the
!                    exact end of the region when the VMA is non-zero,
!                    in case the region is at the end of addressable
!                    memory and the calculation wraps around.  */
! 		if ((os->region->current < os->region->origin
! 		     || (os->region->current - os->region->origin
! 			 > os->region->length))
! 		    && ((os->region->current
! 			 != os->region->origin + os->region->length)
! 			|| os->bfd_section->vma == 0))
  
! 		  {
! 		    if (os->addr_tree != (etree_type *) NULL)
! 		      {
! 			einfo (_("%X%P: address 0x%v of %B section %s is not within region %s\n"),
! 			       os->region->current,
! 			       os->bfd_section->owner,
! 			       os->bfd_section->name,
! 			       os->region->name);
! 		      }
! 		    else
! 		      {
! 			einfo (_("%X%P: region %s is full (%B section %s)\n"),
! 			       os->region->name,
! 			       os->bfd_section->owner,
! 			       os->bfd_section->name);
! 		      }
! 		    /* Reset the region pointer.  */
! 		    os->region->current = os->region->origin;
! 		  }
  	      }
  	  }
  	  break;
--- 2891,2925 ----
  	      {
  		os->region->current = dot;
  		
! 		/* Make sure the new address is within the region.  */
!                 os_region_check (os, os->region, os->addr_tree, 
!                                  os->bfd_section->vma);
  
!                 /* if there's no load address specified, use the run region as
!                    the load region */
!                 if (os->lma_region == NULL && os->load_base == NULL)
!                     os->lma_region = os->region;
! 
!                 if (os->lma_region != NULL)
!                   {
!                     if (os->load_base != NULL)
!                       {
!                         einfo (_("%X%P: use an absolute load address or a load memory region, not both\n"));
!                       }
!                     else
!                       {
!                         /* don't allocate twice */
!                         if (os->lma_region != os->region)
!                           {
!                             /* set load_base, which will be handled later */
!                             os->load_base = exp_intop (os->lma_region->current);
!                             os->lma_region->current += 
!                               os->bfd_section->_raw_size / opb;
!                             os_region_check (os, os->lma_region, NULL,
!                                              os->bfd_section->lma);
!                           }
!                       }
!                   }
  	      }
  	  }
  	  break;
*************** lang_float (maybe)
*** 4259,4271 ****
  }
  
  void
! lang_leave_output_section_statement (fill, memspec, phdrs)
       bfd_vma fill;
       const char *memspec;
       struct lang_output_section_phdr_list *phdrs;
  {
    current_section->fill = fill;
    current_section->region = lang_memory_region_lookup (memspec);
    current_section->phdrs = phdrs;
    stat_ptr = &statement_list;
  }
--- 4295,4316 ----
  }
  
  void
! lang_leave_output_section_statement (fill, memspec, phdrs, lma_memspec)
       bfd_vma fill;
       const char *memspec;
       struct lang_output_section_phdr_list *phdrs;
+      const char *lma_memspec;
  {
    current_section->fill = fill;
    current_section->region = lang_memory_region_lookup (memspec);
+   if (strcmp (lma_memspec, "*default*") != 0)
+     {
+       current_section->lma_region = lang_memory_region_lookup (lma_memspec);
+       /* if no runtime region has been given, but the load region has been,
+          use the load region */
+       if (strcmp (memspec, "*default*") == 0)
+         current_section->region = lang_memory_region_lookup (lma_memspec);
+     }
    current_section->phdrs = phdrs;
    stat_ptr = &statement_list;
  }
*************** lang_leave_overlay_section (fill, phdrs)
*** 4644,4650 ****
  
    name = current_section->name;
  
!   lang_leave_output_section_statement (fill, "*default*", phdrs);
  
    /* Define the magic symbols.  */
  
--- 4689,4696 ----
  
    name = current_section->name;
  
!   lang_leave_output_section_statement (fill, "*default*", 
!                                        phdrs, "*default*");
  
    /* Define the magic symbols.  */
  
*************** lang_leave_overlay_section (fill, phdrs)
*** 4674,4685 ****
     looks through all the sections in the overlay and sets them.  */
  
  void
! lang_leave_overlay (fill, memspec, phdrs)
       bfd_vma fill;
       const char *memspec;
       struct lang_output_section_phdr_list *phdrs;
  {
    lang_memory_region_type *region;
    struct overlay_list *l;
    struct lang_nocrossref *nocrossref;
  
--- 4720,4733 ----
     looks through all the sections in the overlay and sets them.  */
  
  void
! lang_leave_overlay (fill, memspec, phdrs, lma_memspec)
       bfd_vma fill;
       const char *memspec;
       struct lang_output_section_phdr_list *phdrs;
+      const char *lma_memspec;
  {
    lang_memory_region_type *region;
+   lang_memory_region_type *lma_region;
    struct overlay_list *l;
    struct lang_nocrossref *nocrossref;
  
*************** lang_leave_overlay (fill, memspec, phdrs
*** 4688,4693 ****
--- 4736,4746 ----
    else
      region = lang_memory_region_lookup (memspec);
  
+   if (lma_memspec == NULL)
+     lma_region = NULL;
+   else
+     lma_region = lang_memory_region_lookup (lma_memspec);
+ 
    nocrossref = NULL;
  
    l = overlay_list;
*************** lang_leave_overlay (fill, memspec, phdrs
*** 4699,4704 ****
--- 4752,4759 ----
  	l->os->fill = fill;
        if (region != NULL && l->os->region == NULL)
  	l->os->region = region;
+       if (lma_region != NULL && l->os->lma_region == NULL)
+         l->os->lma_region = lma_region;
        if (phdrs != NULL && l->os->phdrs == NULL)
  	l->os->phdrs = phdrs;
  
Index: ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.3
diff -d -c -p -r1.3 ldlang.h
*** ldlang.h	2000/01/05 14:12:23	1.3
--- ldlang.h	2000/02/16 18:22:08
*************** typedef struct lang_output_section_state
*** 136,141 ****
--- 136,142 ----
    flagword flags;		/* Or together of all input sections */
    enum section_type sectype;
    struct memory_region_struct *region;
+   struct memory_region_struct *lma_region;
    size_t block_value;
    fill_type fill;
  
*************** extern void lang_add_attribute PARAMS ((
*** 409,415 ****
  extern void lang_startup PARAMS ((const char *));
  extern void lang_float PARAMS ((enum bfd_boolean));
  extern void lang_leave_output_section_statement
!   PARAMS ((bfd_vma, const char *, struct lang_output_section_phdr_list *));
  extern void lang_abs_symbol_at_end_of PARAMS ((const char *, const char *));
  extern void lang_abs_symbol_at_beginning_of PARAMS ((const char *,
  						     const char *));
--- 410,417 ----
  extern void lang_startup PARAMS ((const char *));
  extern void lang_float PARAMS ((enum bfd_boolean));
  extern void lang_leave_output_section_statement
!   PARAMS ((bfd_vma, const char *, struct lang_output_section_phdr_list *,
!            const char *));
  extern void lang_abs_symbol_at_end_of PARAMS ((const char *, const char *));
  extern void lang_abs_symbol_at_beginning_of PARAMS ((const char *,
  						     const char *));
*************** extern void lang_enter_overlay_section P
*** 475,481 ****
  extern void lang_leave_overlay_section
    PARAMS ((bfd_vma, struct lang_output_section_phdr_list *));
  extern void lang_leave_overlay
!   PARAMS ((bfd_vma, const char *, struct lang_output_section_phdr_list *));
  
  extern struct bfd_elf_version_tree *lang_elf_version_info;
  
--- 477,484 ----
  extern void lang_leave_overlay_section
    PARAMS ((bfd_vma, struct lang_output_section_phdr_list *));
  extern void lang_leave_overlay
!   PARAMS ((bfd_vma, const char *, struct lang_output_section_phdr_list *,
!            const char *));
  
  extern struct bfd_elf_version_tree *lang_elf_version_info;
  
Index: mri.c
===================================================================
RCS file: /cvs/src/src/ld/mri.c,v
retrieving revision 1.1.1.1
diff -d -c -p -r1.1.1.1 mri.c
*** mri.c	1999/05/03 07:29:07	1.1.1.1
--- mri.c	2000/02/16 18:22:09
*************** mri_draw_tree ()
*** 266,272 ****
        }
  
        lang_leave_output_section_statement
! 	(0, "*default*", (struct lang_output_section_phdr_list *) NULL);
  
        p = p->next;
      }
--- 266,273 ----
        }
  
        lang_leave_output_section_statement
! 	(0, "*default*", (struct lang_output_section_phdr_list *) NULL, 
!          "*default*");
  
        p = p->next;
      }
Index: emultempl/armelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/armelf.em,v
retrieving revision 1.12
diff -d -c -p -r1.12 armelf.em
*** armelf.em	2000/01/22 23:22:17	1.12
--- armelf.em	2000/02/16 18:22:09
*************** gld${EMULATION_NAME}_place_orphan (file,
*** 942,948 ****
    wild_doit (&os->children, s, os, file);
  
    lang_leave_output_section_statement
!     ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL);
    stat_ptr = &add;
  
    if (*ps == '\0' && config.build_constructors)
--- 942,949 ----
    wild_doit (&os->children, s, os, file);
  
    lang_leave_output_section_statement
!     ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL,
!      "*default*");
    stat_ptr = &add;
  
    if (*ps == '\0' && config.build_constructors)
Index: emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.10
diff -d -c -p -r1.10 elf32.em
*** elf32.em	1999/11/04 06:45:07	1.10
--- elf32.em	2000/02/16 18:22:09
*************** gld${EMULATION_NAME}_place_orphan (file,
*** 1024,1030 ****
    wild_doit (&os->children, s, os, file);
  
    lang_leave_output_section_statement
!     ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL);
    stat_ptr = &add;
  
    if (*ps == '\0' && config.build_constructors)
--- 1024,1031 ----
    wild_doit (&os->children, s, os, file);
  
    lang_leave_output_section_statement
!     ((bfd_vma) 0, "*default*", (struct lang_output_section_phdr_list *) NULL,
!      "*default*");
    stat_ptr = &add;
  
    if (*ps == '\0' && config.build_constructors)
Index: emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.17
diff -d -c -p -r1.17 pe.em
*** pe.em	2000/01/04 23:48:31	1.17
--- pe.em	2000/02/16 18:22:09
*************** gld_${EMULATION_NAME}_place_orphan (file
*** 1146,1152 ****
  
        lang_leave_output_section_statement
  	((bfd_vma) 0, "*default*",
! 	 (struct lang_output_section_phdr_list *) NULL);
  
        /* Now stick the new statement list right after PLACE.  */
        if (place != NULL)
--- 1146,1153 ----
  
        lang_leave_output_section_statement
  	((bfd_vma) 0, "*default*",
! 	 (struct lang_output_section_phdr_list *) NULL,
! 	"*default*");
  
        /* Now stick the new statement list right after PLACE.  */
        if (place != NULL)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]