This is the mail archive of the binutils@sources.redhat.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]
Other format: [Raw text]

Re: ld doesn't warn about undefined memory region name


Hi Galit,

> If an output section is directed (via '>') into a memory region which
> wasn't defined in the MEMORY statement, e.g. the linker script has:
>
> MEMORY {
> 	rom : ORIGIN = oxfff0,	LENGTH = 0x1000
>         ram : ORIGIN = 0x1fff0, LENGTH = 0x1000
> }
>
> SECTIONS {
>
> 	.text : { *(.text) } > not_rom_nor_ram
> }
>
> Then ld issues no warning or error. Instead, the output section address
> is set to 0.
>
> Is this the intended behavior ?

No - it is a bug.  The patch below implements a warning message for
this situation.  (The linker accepts the undeclared region and treats
it as a region covering the entire memory map).  It also adds an
warning message if a memory region is redefined inside a MEMORY block.

Cheers
        Nick

2003-10-21  Nick Clifton  <nickc@redhat.com>

        * ldlang.c (lang_memory_region_lookup): Add second parameter -
        create - which is true if the region is being created.  Issue
        appropriate warning messages for finding and not finding
        already created regions.
        (lang_memory_default): Use DEFAULT_MEMORY_REGION.
        (lang_leave_overlay_section): Likewise.
        (lang_size_sections_1): Likewise.
        Pass second parameter to lang_memory_region_lookup.
        (lang_get_regions): Likewise.

        * ldlang.h (DEFAULT_MEMORY_REGION): Define.
        Update prototype for lang_memory_region_lookup.        
	* ldgram.y: Pass second parameter to lang_memory_region_lookup.
        Use DEFAULT_MEMORY_REGION instead of "*default".
        
Index: ld/ldgram.y
===================================================================
RCS file: /cvs/src/src/ld/ldgram.y,v
retrieving revision 1.27
diff -c -3 -p -r1.27 ldgram.y
*** ld/ldgram.y	27 Jul 2003 11:58:28 -0000	1.27
--- ld/ldgram.y	21 Oct 2003 15:25:18 -0000
*************** memory_spec_list:
*** 627,633 ****
  
  
  memory_spec: 	NAME
! 		{ region = lang_memory_region_lookup($1); }
  		attributes_opt ':'
  		origin_spec opt_comma length_spec
  		{}
--- 627,633 ----
  
  
  memory_spec: 	NAME
! 		{ region = lang_memory_region_lookup ($1, TRUE); }
  		attributes_opt ':'
  		origin_spec opt_comma length_spec
  		{}
*************** opt_nocrossrefs:
*** 924,930 ****
  memspec_opt:
  		'>' NAME
  		{ $$ = $2; }
! 	|	{ $$ = "*default*"; }
  	;
  
  phdr_opt:
--- 924,930 ----
  memspec_opt:
  		'>' NAME
  		{ $$ = $2; }
! 	|	{ $$ = DEFAULT_MEMORY_REGION; }
  	;
  
  phdr_opt:
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.120
diff -c -3 -p -r1.120 ldlang.c
*** ld/ldlang.c	17 Oct 2003 23:05:50 -0000	1.120
--- ld/ldlang.c	21 Oct 2003 15:25:23 -0000
*************** lang_init (void)
*** 504,516 ****
    We maintain a list of all the regions here.
  
    If no regions are specified in the script, then the default is used
!   which is created when looked up to be the entire data space.  */
  
  static lang_memory_region_type *lang_memory_region_list;
  static lang_memory_region_type **lang_memory_region_list_tail = &lang_memory_region_list;
  
  lang_memory_region_type *
! lang_memory_region_lookup (const char *const name)
  {
    lang_memory_region_type *p;
    lang_memory_region_type *new;
--- 504,522 ----
    We maintain a list of all the regions here.
  
    If no regions are specified in the script, then the default is used
!   which is created when looked up to be the entire data space.
! 
!   If create is true we are creating a region inside a MEMORY block.
!   In this case it is probably an error to create a region that has
!   already been created.  If we are not inside a MEMORY block it is
!   dubious to use an undeclared region name (except DEFAULT_MEMORY_REGION)
!   and so we issue a warning.  */
  
  static lang_memory_region_type *lang_memory_region_list;
  static lang_memory_region_type **lang_memory_region_list_tail = &lang_memory_region_list;
  
  lang_memory_region_type *
! lang_memory_region_lookup (const char *const name, bfd_boolean create)
  {
    lang_memory_region_type *p;
    lang_memory_region_type *new;
*************** lang_memory_region_lookup (const char *c
*** 520,529 ****
      return NULL;
  
    for (p = lang_memory_region_list; p != NULL; p = p->next)
!     {
!       if (strcmp (p->name, name) == 0)
  	return p;
!     }
  
  #if 0
    /* This code used to always use the first region in the list as the
--- 526,537 ----
      return NULL;
  
    for (p = lang_memory_region_list; p != NULL; p = p->next)
!     if (strcmp (p->name, name) == 0)
!       {
! 	if (create)
! 	  einfo (_("%P:%S: warning: redeclaration of memory region '%s'\n"), name);
  	return p;
!       }
  
  #if 0
    /* This code used to always use the first region in the list as the
*************** lang_memory_region_lookup (const char *c
*** 532,544 ****
       NOLOAD sections to work reasonably without requiring a region.
       People should specify what region they mean, if they really want
       a region.  */
!   if (strcmp (name, "*default*") == 0)
      {
        if (lang_memory_region_list != NULL)
  	return lang_memory_region_list;
      }
  #endif
  
    new = stat_alloc (sizeof (lang_memory_region_type));
  
    new->name = xstrdup (name);
--- 540,555 ----
       NOLOAD sections to work reasonably without requiring a region.
       People should specify what region they mean, if they really want
       a region.  */
!   if (strcmp (name, DEFAULT_MEMORY_REGION) == 0)
      {
        if (lang_memory_region_list != NULL)
  	return lang_memory_region_list;
      }
  #endif
  
+   if (!create && strcmp (name, DEFAULT_MEMORY_REGION))
+     einfo (_("%P:%S: warning: memory region %s not declared\n"), name);
+ 
    new = stat_alloc (sizeof (lang_memory_region_type));
  
    new->name = xstrdup (name);
*************** lang_memory_default (asection *section)
*** 575,581 ****
  	  return p;
  	}
      }
!   return lang_memory_region_lookup ("*default*");
  }
  
  lang_output_section_statement_type *
--- 586,592 ----
  	  return p;
  	}
      }
!   return lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE);
  }
  
  lang_output_section_statement_type *
*************** lang_size_sections_1
*** 2889,2895 ****
  			|| (((bfd_get_section_flags (output_bfd, os->bfd_section)
  			      & (SEC_ALLOC | SEC_LOAD)) != 0)
  			    && os->region->name[0] == '*'
! 			    && strcmp (os->region->name, "*default*") == 0))
  		      {
  			os->region = lang_memory_default (os->bfd_section);
  		      }
--- 2900,2906 ----
  			|| (((bfd_get_section_flags (output_bfd, os->bfd_section)
  			      & (SEC_ALLOC | SEC_LOAD)) != 0)
  			    && os->region->name[0] == '*'
! 			    && strcmp (os->region->name, DEFAULT_MEMORY_REGION) == 0))
  		      {
  			os->region = lang_memory_default (os->bfd_section);
  		      }
*************** lang_size_sections_1
*** 2902,2911 ****
  			    & SEC_NEVER_LOAD) == 0
  			&& ! link_info.relocatable
  			&& check_regions
! 			&& strcmp (os->region->name, "*default*") == 0
  			&& lang_memory_region_list != NULL
  			&& (strcmp (lang_memory_region_list->name,
! 				    "*default*") != 0
  			    || lang_memory_region_list->next != NULL))
  		      {
  			/* By default this is an error rather than just a
--- 2913,2922 ----
  			    & SEC_NEVER_LOAD) == 0
  			&& ! link_info.relocatable
  			&& check_regions
! 			&& strcmp (os->region->name, DEFAULT_MEMORY_REGION) == 0
  			&& lang_memory_region_list != NULL
  			&& (strcmp (lang_memory_region_list->name,
! 				    DEFAULT_MEMORY_REGION) != 0
  			    || lang_memory_region_list->next != NULL))
  		      {
  			/* By default this is an error rather than just a
*************** lang_size_sections_1
*** 3160,3166 ****
  		  {
  		    /* If we don't have an output section, then just adjust
  		       the default memory address.  */
! 		    lang_memory_region_lookup ("*default*")->current = newdot;
  		  }
  		else
  		  {
--- 3171,3177 ----
  		  {
  		    /* If we don't have an output section, then just adjust
  		       the default memory address.  */
! 		    lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE)->current = newdot;
  		  }
  		else
  		  {
*************** lang_float (bfd_boolean maybe)
*** 4464,4473 ****
  /* Work out the load- and run-time regions from a script statement, and
     store them in *LMA_REGION and *REGION respectively.
  
!    MEMSPEC is the name of the run-time region, or "*default*" if the
!    statement didn't specify one.  LMA_MEMSPEC is the name of the
!    load-time region, or null if the statement didn't specify one.
!    HAVE_LMA_P is TRUE if the statement had an explicit load address.
  
     It is an error to specify both a load region and a load address.  */
  
--- 4475,4485 ----
  /* Work out the load- and run-time regions from a script statement, and
     store them in *LMA_REGION and *REGION respectively.
  
!    MEMSPEC is the name of the run-time region, or the value of
!    DEFAULT_MEMORY_REGION if the statement didn't specify one.
!    LMA_MEMSPEC is the name of the load-time region, or null if the
!    statement didn't specify one.HAVE_LMA_P is TRUE if the statement
!    had an explicit load address.
  
     It is an error to specify both a load region and a load address.  */
  
*************** lang_get_regions (struct memory_region_s
*** 4478,4491 ****
  		  const char *lma_memspec,
  		  int have_lma_p)
  {
!   *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 (lma_memspec != 0 && strcmp (memspec, "*default*") == 0)
      *region = *lma_region;
    else
!     *region = lang_memory_region_lookup (memspec);
  
    if (have_lma_p && lma_memspec != 0)
      einfo (_("%X%P:%S: section has both a load address and a load region\n"));
--- 4490,4503 ----
  		  const char *lma_memspec,
  		  int have_lma_p)
  {
!   *lma_region = lang_memory_region_lookup (lma_memspec, FALSE);
  
    /* If no runtime region has been given, but the load region has
       been, use the load region.  */
!   if (lma_memspec != 0 && strcmp (memspec, DEFAULT_MEMORY_REGION) == 0)
      *region = *lma_region;
    else
!     *region = lang_memory_region_lookup (memspec, FALSE);
  
    if (have_lma_p && lma_memspec != 0)
      einfo (_("%X%P:%S: section has both a load address and a load region\n"));
*************** lang_leave_overlay_section (fill_type *f
*** 4849,4858 ****
  
    name = current_section->name;
  
!   /* For now, assume that "*default*" is the run-time memory region and
!      that no load-time region has been specified.  It doesn't really
!      matter what we say here, since lang_leave_overlay will override it.  */
!   lang_leave_output_section_statement (fill, "*default*", phdrs, 0);
  
    /* Define the magic symbols.  */
  
--- 4861,4871 ----
  
    name = current_section->name;
  
!   /* For now, assume that DEFAULT_MEMORY_REGION is the run-time memory
!      region and that no load-time region has been specified.  It doesn't
!      really matter what we say here, since lang_leave_overlay will
!      override it.  */
!   lang_leave_output_section_statement (fill, DEFAULT_MEMORY_REGION, phdrs, 0);
  
    /* Define the magic symbols.  */
  
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.30
diff -c -3 -p -r1.30 ldlang.h
*** ld/ldlang.h	11 Oct 2003 09:16:20 -0000	1.30
--- ld/ldlang.h	21 Oct 2003 15:25:24 -0000
***************
*** 23,28 ****
--- 23,30 ----
  #ifndef LDLANG_H
  #define LDLANG_H
  
+ #define DEFAULT_MEMORY_REGION   "*default*"
+ 
  typedef enum {
    lang_input_file_is_l_enum,
    lang_input_file_is_symbols_only_enum,
*************** extern int lang_statement_iteration;
*** 388,394 ****
  extern void lang_init
    (void);
  extern struct memory_region_struct *lang_memory_region_lookup
!   (const char *const);
  extern struct memory_region_struct *lang_memory_region_default
    (asection *);
  extern void lang_map
--- 390,396 ----
  extern void lang_init
    (void);
  extern struct memory_region_struct *lang_memory_region_lookup
!   (const char *const, bfd_boolean);
  extern struct memory_region_struct *lang_memory_region_default
    (asection *);
  extern void lang_map
                


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