This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: ld doesn't warn about undefined memory region name
- From: Nick Clifton <nickc at redhat dot com>
- To: "Galit Heller" <Galit dot Heller at nsc dot com>
- Cc: binutils at sources dot redhat dot com
- Date: Tue, 21 Oct 2003 16:25:57 +0100
- Subject: Re: ld doesn't warn about undefined memory region name
- References: <3F95059D.1D389FAD@nsc.com>
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