mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-12 01:24:12 +08:00
* ldgram.y: Add support for REGION_ALIAS operator.
* ldlang.c: Likewise. * ldlang.h: Likewise. * ldlex.l: Likewise. * NEWS: Mention the new feature. * ld.texinfo: Document the new feature. * ld-scripts/regions-alias-1.t: New file. * ld-scripts/regions-alias-2.t: New file. * ld-scripts/regions-alias-3.t: New file. * ld-scripts/regions-alias-4.t: New file. * ld-scripts/script.exp: Run region alias tests.
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
2009-03-02 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
|
* ldgram.y: Add support for REGION_ALIAS operator.
|
||||||
|
* ldlang.c: Likewise.
|
||||||
|
* ldlang.h: Likewise.
|
||||||
|
* ldlex.l: Likewise.
|
||||||
|
* NEWS: Mention the new feature.
|
||||||
|
* ld.texinfo: Document the new feature.
|
||||||
|
|
||||||
2009-03-02 Qinwei <qinwei@sunnorth.com.cn>
|
2009-03-02 Qinwei <qinwei@sunnorth.com.cn>
|
||||||
|
|
||||||
* Makefile.am: Replace score elf emulation with score3 and score7
|
* Makefile.am: Replace score elf emulation with score3 and score7
|
||||||
|
2
ld/NEWS
2
ld/NEWS
@ -1,5 +1,7 @@
|
|||||||
-*- text -*-
|
-*- text -*-
|
||||||
|
|
||||||
|
* New script function REGION_ALIAS to add alias names to memory regions.
|
||||||
|
|
||||||
* PE targets no longer make use of the long section names PE extension to
|
* PE targets no longer make use of the long section names PE extension to
|
||||||
the COFF format when generating executable images, by default. The old
|
the COFF format when generating executable images, by default. The old
|
||||||
(slightly non-conformant) behaviour can still be invoked by using the
|
(slightly non-conformant) behaviour can still be invoked by using the
|
||||||
|
161
ld/ld.texinfo
161
ld/ld.texinfo
@ -2785,6 +2785,7 @@ In this section we describe the simple linker script commands.
|
|||||||
* Format Commands:: Commands dealing with object file formats
|
* Format Commands:: Commands dealing with object file formats
|
||||||
@end ifclear
|
@end ifclear
|
||||||
|
|
||||||
|
* REGION_ALIAS:: Assign alias names to memory regions
|
||||||
* Miscellaneous Commands:: Other linker script commands
|
* Miscellaneous Commands:: Other linker script commands
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@ -2969,6 +2970,162 @@ command is also used to set the format for the output file. @xref{BFD}.
|
|||||||
@end table
|
@end table
|
||||||
@end ifclear
|
@end ifclear
|
||||||
|
|
||||||
|
@node REGION_ALIAS
|
||||||
|
@subsection Assign alias names to memory regions
|
||||||
|
@kindex REGION_ALIAS(@var{alias}, @var{region})
|
||||||
|
@cindex region alias
|
||||||
|
@cindex region names
|
||||||
|
|
||||||
|
Alias names can be added to existing memory regions created with the
|
||||||
|
@ref{MEMORY} command. Each name corresponds to at most one memory region.
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
REGION_ALIAS(@var{alias}, @var{region})
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
The @code{REGION_ALIAS} function creates an alias name @var{alias} for the
|
||||||
|
memory region @var{region}. This allows a flexible mapping of output sections
|
||||||
|
to memory regions. An example follows.
|
||||||
|
|
||||||
|
Suppose we have an application for embedded systems which come with various
|
||||||
|
memory storage devices. All have a general purpose, volatile memory @code{RAM}
|
||||||
|
that allows code execution or data storage. Some may have a read-only,
|
||||||
|
non-volatile memory @code{ROM} that allows code execution and read-only data
|
||||||
|
access. The last variant is a read-only, non-volatile memory @code{ROM2} with
|
||||||
|
read-only data access and no code execution capability. We have four output
|
||||||
|
sections:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
@code{.text} program code;
|
||||||
|
@item
|
||||||
|
@code{.rodata} read-only data;
|
||||||
|
@item
|
||||||
|
@code{.data} read-write initialized data;
|
||||||
|
@item
|
||||||
|
@code{.bss} read-write zero initialized data.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
The goal is to provide a linker command file that contains a system independent
|
||||||
|
part defining the output sections and a system dependent part mapping the
|
||||||
|
output sections to the memory regions available on the system. Our embedded
|
||||||
|
systems come with three different memory setups @code{A}, @code{B} and
|
||||||
|
@code{C}:
|
||||||
|
@multitable @columnfractions .25 .25 .25 .25
|
||||||
|
@item Section @tab Variant A @tab Variant B @tab Variant C
|
||||||
|
@item .text @tab RAM @tab ROM @tab ROM
|
||||||
|
@item .rodata @tab RAM @tab ROM @tab ROM2
|
||||||
|
@item .data @tab RAM @tab RAM/ROM @tab RAM/ROM2
|
||||||
|
@item .bss @tab RAM @tab RAM @tab RAM
|
||||||
|
@end multitable
|
||||||
|
The notation @code{RAM/ROM} or @code{RAM/ROM2} means that this section is
|
||||||
|
loaded into region @code{ROM} or @code{ROM2} respectively. Please note that
|
||||||
|
the load address of the @code{.data} section starts in all three variants at
|
||||||
|
the end of the @code{.rodata} section.
|
||||||
|
|
||||||
|
The base linker script that deals with the output sections follows. It
|
||||||
|
includes the system dependent @code{linkcmds.memory} file that describes the
|
||||||
|
memory layout:
|
||||||
|
@smallexample
|
||||||
|
INCLUDE linkcmds.memory
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
@{
|
||||||
|
.text :
|
||||||
|
@{
|
||||||
|
*(.text)
|
||||||
|
@} > REGION_TEXT
|
||||||
|
.rodata :
|
||||||
|
@{
|
||||||
|
*(.rodata)
|
||||||
|
rodata_end = .;
|
||||||
|
@} > REGION_RODATA
|
||||||
|
.data : AT (rodata_end)
|
||||||
|
@{
|
||||||
|
data_start = .;
|
||||||
|
*(.data)
|
||||||
|
@} > REGION_DATA
|
||||||
|
data_size = SIZEOF(.data);
|
||||||
|
data_load_start = LOADADDR(.data);
|
||||||
|
.bss :
|
||||||
|
@{
|
||||||
|
*(.bss)
|
||||||
|
@} > REGION_BSS
|
||||||
|
@}
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
Now we need three different @code{linkcmds.memory} files to define memory
|
||||||
|
regions and alias names. The content of @code{linkcmds.memory} for the three
|
||||||
|
variants @code{A}, @code{B} and @code{C}:
|
||||||
|
@table @code
|
||||||
|
@item A
|
||||||
|
Here everything goes into the @code{RAM}.
|
||||||
|
@smallexample
|
||||||
|
MEMORY
|
||||||
|
@{
|
||||||
|
RAM : ORIGIN = 0, LENGTH = 4M
|
||||||
|
@}
|
||||||
|
|
||||||
|
REGION_ALIAS("REGION_TEXT", RAM);
|
||||||
|
REGION_ALIAS("REGION_RODATA", RAM);
|
||||||
|
REGION_ALIAS("REGION_DATA", RAM);
|
||||||
|
REGION_ALIAS("REGION_BSS", RAM);
|
||||||
|
@end smallexample
|
||||||
|
@item B
|
||||||
|
Program code and read-only data go into the @code{ROM}. Read-write data goes
|
||||||
|
into the @code{RAM}. An image of the initialized data is loaded into the
|
||||||
|
@code{ROM} and will be copied during system start into the @code{RAM}.
|
||||||
|
@smallexample
|
||||||
|
MEMORY
|
||||||
|
@{
|
||||||
|
ROM : ORIGIN = 0, LENGTH = 3M
|
||||||
|
RAM : ORIGIN = 0x10000000, LENGTH = 1M
|
||||||
|
@}
|
||||||
|
|
||||||
|
REGION_ALIAS("REGION_TEXT", ROM);
|
||||||
|
REGION_ALIAS("REGION_RODATA", ROM);
|
||||||
|
REGION_ALIAS("REGION_DATA", RAM);
|
||||||
|
REGION_ALIAS("REGION_BSS", RAM);
|
||||||
|
@end smallexample
|
||||||
|
@item C
|
||||||
|
Program code goes into the @code{ROM}. Read-only data goes into the
|
||||||
|
@code{ROM2}. Read-write data goes into the @code{RAM}. An image of the
|
||||||
|
initialized data is loaded into the @code{ROM2} and will be copied during
|
||||||
|
system start into the @code{RAM}.
|
||||||
|
@smallexample
|
||||||
|
MEMORY
|
||||||
|
@{
|
||||||
|
ROM : ORIGIN = 0, LENGTH = 2M
|
||||||
|
ROM2 : ORIGIN = 0x10000000, LENGTH = 1M
|
||||||
|
RAM : ORIGIN = 0x20000000, LENGTH = 1M
|
||||||
|
@}
|
||||||
|
|
||||||
|
REGION_ALIAS("REGION_TEXT", ROM);
|
||||||
|
REGION_ALIAS("REGION_RODATA", ROM2);
|
||||||
|
REGION_ALIAS("REGION_DATA", RAM);
|
||||||
|
REGION_ALIAS("REGION_BSS", RAM);
|
||||||
|
@end smallexample
|
||||||
|
@end table
|
||||||
|
|
||||||
|
It is possible to write a common system initialization routine to copy the
|
||||||
|
@code{.data} section from @code{ROM} or @code{ROM2} into the @code{RAM} if
|
||||||
|
necessary:
|
||||||
|
@smallexample
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
extern char data_start [];
|
||||||
|
extern char data_size [];
|
||||||
|
extern char data_load_start [];
|
||||||
|
|
||||||
|
void copy_data(void)
|
||||||
|
@{
|
||||||
|
if (data_start != data_load_start)
|
||||||
|
@{
|
||||||
|
memcpy(data_start, data_load_start, (size_t) data_size);
|
||||||
|
@}
|
||||||
|
@}
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
@node Miscellaneous Commands
|
@node Miscellaneous Commands
|
||||||
@subsection Other Linker Script Commands
|
@subsection Other Linker Script Commands
|
||||||
There are a few other linker scripts commands.
|
There are a few other linker scripts commands.
|
||||||
@ -4310,7 +4467,9 @@ The @var{name} is a name used in the linker script to refer to the
|
|||||||
region. The region name has no meaning outside of the linker script.
|
region. The region name has no meaning outside of the linker script.
|
||||||
Region names are stored in a separate name space, and will not conflict
|
Region names are stored in a separate name space, and will not conflict
|
||||||
with symbol names, file names, or section names. Each memory region
|
with symbol names, file names, or section names. Each memory region
|
||||||
must have a distinct name.
|
must have a distinct name within the @code{MEMORY} command. However you can
|
||||||
|
add later alias names to existing memory regions with the @ref{REGION_ALIAS}
|
||||||
|
command.
|
||||||
|
|
||||||
@cindex memory region attributes
|
@cindex memory region attributes
|
||||||
The @var{attr} string is an optional list of attributes that specify
|
The @var{attr} string is an optional list of attributes that specify
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* A YACC grammar to parse a superset of the AT&T linker scripting language.
|
/* A YACC grammar to parse a superset of the AT&T linker scripting language.
|
||||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||||
2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
|
||||||
Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
|
Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
|
||||||
|
|
||||||
This file is part of the GNU Binutils.
|
This file is part of the GNU Binutils.
|
||||||
@ -131,6 +131,7 @@ static int error_index;
|
|||||||
%token SEGMENT_START
|
%token SEGMENT_START
|
||||||
%token INCLUDE
|
%token INCLUDE
|
||||||
%token MEMORY
|
%token MEMORY
|
||||||
|
%token REGION_ALIAS
|
||||||
%token NOLOAD DSECT COPY INFO OVERLAY
|
%token NOLOAD DSECT COPY INFO OVERLAY
|
||||||
%token DEFINED TARGET_K SEARCH_DIR MAP ENTRY
|
%token DEFINED TARGET_K SEARCH_DIR MAP ENTRY
|
||||||
%token <integer> NEXT
|
%token <integer> NEXT
|
||||||
@ -352,6 +353,8 @@ ifile_p1:
|
|||||||
{ lang_add_insert ($3, 0); }
|
{ lang_add_insert ($3, 0); }
|
||||||
| INSERT_K BEFORE NAME
|
| INSERT_K BEFORE NAME
|
||||||
{ lang_add_insert ($3, 1); }
|
{ lang_add_insert ($3, 1); }
|
||||||
|
| REGION_ALIAS '(' NAME ',' NAME ')'
|
||||||
|
{ lang_memory_region_alias ($3, $5); }
|
||||||
;
|
;
|
||||||
|
|
||||||
input_list:
|
input_list:
|
||||||
|
93
ld/ldlang.c
93
ld/ldlang.c
@ -1205,7 +1205,13 @@ lang_finish (void)
|
|||||||
In this case it is probably an error to create a region that has
|
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
|
already been created. If we are not inside a MEMORY block it is
|
||||||
dubious to use an undeclared region name (except DEFAULT_MEMORY_REGION)
|
dubious to use an undeclared region name (except DEFAULT_MEMORY_REGION)
|
||||||
and so we issue a warning. */
|
and so we issue a warning.
|
||||||
|
|
||||||
|
Each region has at least one name. The first name is either
|
||||||
|
DEFAULT_MEMORY_REGION or the name given in the MEMORY block. You can add
|
||||||
|
alias names to an existing region within a script with
|
||||||
|
REGION_ALIAS (alias, region_name). Each name corresponds to at most one
|
||||||
|
region. */
|
||||||
|
|
||||||
static lang_memory_region_type *lang_memory_region_list;
|
static lang_memory_region_type *lang_memory_region_list;
|
||||||
static lang_memory_region_type **lang_memory_region_list_tail
|
static lang_memory_region_type **lang_memory_region_list_tail
|
||||||
@ -1214,28 +1220,31 @@ static lang_memory_region_type **lang_memory_region_list_tail
|
|||||||
lang_memory_region_type *
|
lang_memory_region_type *
|
||||||
lang_memory_region_lookup (const char *const name, bfd_boolean create)
|
lang_memory_region_lookup (const char *const name, bfd_boolean create)
|
||||||
{
|
{
|
||||||
lang_memory_region_type *p;
|
lang_memory_region_name *n;
|
||||||
|
lang_memory_region_type *r;
|
||||||
lang_memory_region_type *new;
|
lang_memory_region_type *new;
|
||||||
|
|
||||||
/* NAME is NULL for LMA memspecs if no region was specified. */
|
/* NAME is NULL for LMA memspecs if no region was specified. */
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (p = lang_memory_region_list; p != NULL; p = p->next)
|
for (r = lang_memory_region_list; r != NULL; r = r->next)
|
||||||
if (strcmp (p->name, name) == 0)
|
for (n = &r->name_list; n != NULL; n = n->next)
|
||||||
|
if (strcmp (n->name, name) == 0)
|
||||||
{
|
{
|
||||||
if (create)
|
if (create)
|
||||||
einfo (_("%P:%S: warning: redeclaration of memory region '%s'\n"),
|
einfo (_("%P:%S: warning: redeclaration of memory region `%s'\n"),
|
||||||
name);
|
name);
|
||||||
return p;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!create && strcmp (name, DEFAULT_MEMORY_REGION))
|
if (!create && strcmp (name, DEFAULT_MEMORY_REGION))
|
||||||
einfo (_("%P:%S: warning: memory region %s not declared\n"), name);
|
einfo (_("%P:%S: warning: memory region `%s' not declared\n"), name);
|
||||||
|
|
||||||
new = stat_alloc (sizeof (lang_memory_region_type));
|
new = stat_alloc (sizeof (lang_memory_region_type));
|
||||||
|
|
||||||
new->name = xstrdup (name);
|
new->name_list.name = xstrdup (name);
|
||||||
|
new->name_list.next = NULL;
|
||||||
new->next = NULL;
|
new->next = NULL;
|
||||||
new->origin = 0;
|
new->origin = 0;
|
||||||
new->length = ~(bfd_size_type) 0;
|
new->length = ~(bfd_size_type) 0;
|
||||||
@ -1251,8 +1260,50 @@ lang_memory_region_lookup (const char *const name, bfd_boolean create)
|
|||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lang_memory_region_alias (const char * alias, const char * region_name)
|
||||||
|
{
|
||||||
|
lang_memory_region_name * n;
|
||||||
|
lang_memory_region_type * r;
|
||||||
|
lang_memory_region_type * region;
|
||||||
|
|
||||||
|
/* The default region must be unique. This ensures that it is not necessary
|
||||||
|
to iterate through the name list if someone wants the check if a region is
|
||||||
|
the default memory region. */
|
||||||
|
if (strcmp (region_name, DEFAULT_MEMORY_REGION) == 0
|
||||||
|
|| strcmp (alias, DEFAULT_MEMORY_REGION) == 0)
|
||||||
|
einfo (_("%F%P:%S: error: alias for default memory region\n"));
|
||||||
|
|
||||||
|
/* Look for the target region and check if the alias is not already
|
||||||
|
in use. */
|
||||||
|
region = NULL;
|
||||||
|
for (r = lang_memory_region_list; r != NULL; r = r->next)
|
||||||
|
for (n = &r->name_list; n != NULL; n = n->next)
|
||||||
|
{
|
||||||
|
if (region == NULL && strcmp (n->name, region_name) == 0)
|
||||||
|
region = r;
|
||||||
|
if (strcmp (n->name, alias) == 0)
|
||||||
|
einfo (_("%F%P:%S: error: redefinition of memory region "
|
||||||
|
"alias `%s'\n"),
|
||||||
|
alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the target region exists. */
|
||||||
|
if (region == NULL)
|
||||||
|
einfo (_("%F%P:%S: error: memory region `%s' "
|
||||||
|
"for alias `%s' does not exist\n"),
|
||||||
|
region_name,
|
||||||
|
alias);
|
||||||
|
|
||||||
|
/* Add alias to region name list. */
|
||||||
|
n = stat_alloc (sizeof (lang_memory_region_name));
|
||||||
|
n->name = xstrdup (alias);
|
||||||
|
n->next = region->name_list.next;
|
||||||
|
region->name_list.next = n;
|
||||||
|
}
|
||||||
|
|
||||||
static lang_memory_region_type *
|
static lang_memory_region_type *
|
||||||
lang_memory_default (asection *section)
|
lang_memory_default (asection * section)
|
||||||
{
|
{
|
||||||
lang_memory_region_type *p;
|
lang_memory_region_type *p;
|
||||||
|
|
||||||
@ -1847,7 +1898,7 @@ lang_map (void)
|
|||||||
char buf[100];
|
char buf[100];
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
fprintf (config.map_file, "%-16s ", m->name);
|
fprintf (config.map_file, "%-16s ", m->name_list.name);
|
||||||
|
|
||||||
sprintf_vma (buf, m->origin);
|
sprintf_vma (buf, m->origin);
|
||||||
minfo ("0x%s ", buf);
|
minfo ("0x%s ", buf);
|
||||||
@ -4462,8 +4513,8 @@ lang_check_section_addresses (void)
|
|||||||
a bfd_vma quantity in decimal. */
|
a bfd_vma quantity in decimal. */
|
||||||
for (m = lang_memory_region_list; m; m = m->next)
|
for (m = lang_memory_region_list; m; m = m->next)
|
||||||
if (m->had_full_message)
|
if (m->had_full_message)
|
||||||
einfo (_("%X%P: region %s overflowed by %ld bytes\n"),
|
einfo (_("%X%P: region `%s' overflowed by %ld bytes\n"),
|
||||||
m->name, (long)(m->current - (m->origin + m->length)));
|
m->name_list.name, (long)(m->current - (m->origin + m->length)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4485,21 +4536,21 @@ os_region_check (lang_output_section_statement_type *os,
|
|||||||
{
|
{
|
||||||
if (tree != NULL)
|
if (tree != NULL)
|
||||||
{
|
{
|
||||||
einfo (_("%X%P: address 0x%v of %B section %s"
|
einfo (_("%X%P: address 0x%v of %B section `%s'"
|
||||||
" is not within region %s\n"),
|
" is not within region `%s'\n"),
|
||||||
region->current,
|
region->current,
|
||||||
os->bfd_section->owner,
|
os->bfd_section->owner,
|
||||||
os->bfd_section->name,
|
os->bfd_section->name,
|
||||||
region->name);
|
region->name_list.name);
|
||||||
}
|
}
|
||||||
else if (!region->had_full_message)
|
else if (!region->had_full_message)
|
||||||
{
|
{
|
||||||
region->had_full_message = TRUE;
|
region->had_full_message = TRUE;
|
||||||
|
|
||||||
einfo (_("%X%P: %B section %s will not fit in region %s\n"),
|
einfo (_("%X%P: %B section `%s' will not fit in region `%s'\n"),
|
||||||
os->bfd_section->owner,
|
os->bfd_section->owner,
|
||||||
os->bfd_section->name,
|
os->bfd_section->name,
|
||||||
region->name);
|
region->name_list.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4588,8 +4639,8 @@ lang_size_sections_1
|
|||||||
from the region specification. */
|
from the region specification. */
|
||||||
if (os->region == NULL
|
if (os->region == NULL
|
||||||
|| ((os->bfd_section->flags & (SEC_ALLOC | SEC_LOAD))
|
|| ((os->bfd_section->flags & (SEC_ALLOC | SEC_LOAD))
|
||||||
&& os->region->name[0] == '*'
|
&& os->region->name_list.name[0] == '*'
|
||||||
&& strcmp (os->region->name,
|
&& strcmp (os->region->name_list.name,
|
||||||
DEFAULT_MEMORY_REGION) == 0))
|
DEFAULT_MEMORY_REGION) == 0))
|
||||||
{
|
{
|
||||||
os->region = lang_memory_default (os->bfd_section);
|
os->region = lang_memory_default (os->bfd_section);
|
||||||
@ -4602,10 +4653,10 @@ lang_size_sections_1
|
|||||||
&& !IGNORE_SECTION (os->bfd_section)
|
&& !IGNORE_SECTION (os->bfd_section)
|
||||||
&& ! link_info.relocatable
|
&& ! link_info.relocatable
|
||||||
&& check_regions
|
&& check_regions
|
||||||
&& strcmp (os->region->name,
|
&& strcmp (os->region->name_list.name,
|
||||||
DEFAULT_MEMORY_REGION) == 0
|
DEFAULT_MEMORY_REGION) == 0
|
||||||
&& lang_memory_region_list != NULL
|
&& lang_memory_region_list != NULL
|
||||||
&& (strcmp (lang_memory_region_list->name,
|
&& (strcmp (lang_memory_region_list->name_list.name,
|
||||||
DEFAULT_MEMORY_REGION) != 0
|
DEFAULT_MEMORY_REGION) != 0
|
||||||
|| lang_memory_region_list->next != NULL)
|
|| lang_memory_region_list->next != NULL)
|
||||||
&& expld.phase != lang_mark_phase_enum)
|
&& expld.phase != lang_mark_phase_enum)
|
||||||
|
23
ld/ldlang.h
23
ld/ldlang.h
@ -43,13 +43,19 @@ struct _fill_type
|
|||||||
|
|
||||||
typedef struct statement_list
|
typedef struct statement_list
|
||||||
{
|
{
|
||||||
union lang_statement_union *head;
|
union lang_statement_union * head;
|
||||||
union lang_statement_union **tail;
|
union lang_statement_union ** tail;
|
||||||
} lang_statement_list_type;
|
} lang_statement_list_type;
|
||||||
|
|
||||||
|
typedef struct memory_region_name_struct
|
||||||
|
{
|
||||||
|
const char * name;
|
||||||
|
struct memory_region_name_struct * next;
|
||||||
|
} lang_memory_region_name;
|
||||||
|
|
||||||
typedef struct memory_region_struct
|
typedef struct memory_region_struct
|
||||||
{
|
{
|
||||||
char *name;
|
lang_memory_region_name name_list;
|
||||||
struct memory_region_struct *next;
|
struct memory_region_struct *next;
|
||||||
bfd_vma origin;
|
bfd_vma origin;
|
||||||
bfd_size_type length;
|
bfd_size_type length;
|
||||||
@ -429,7 +435,8 @@ struct lang_definedness_hash_entry
|
|||||||
|
|
||||||
/* Used by place_orphan to keep track of orphan sections and statements. */
|
/* Used by place_orphan to keep track of orphan sections and statements. */
|
||||||
|
|
||||||
struct orphan_save {
|
struct orphan_save
|
||||||
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
flagword flags;
|
flagword flags;
|
||||||
lang_output_section_statement_type *os;
|
lang_output_section_statement_type *os;
|
||||||
@ -457,10 +464,10 @@ extern void lang_init
|
|||||||
(void);
|
(void);
|
||||||
extern void lang_finish
|
extern void lang_finish
|
||||||
(void);
|
(void);
|
||||||
extern lang_memory_region_type *lang_memory_region_lookup
|
extern lang_memory_region_type * lang_memory_region_lookup
|
||||||
(const char *const, bfd_boolean);
|
(const char * const, bfd_boolean);
|
||||||
extern lang_memory_region_type *lang_memory_region_default
|
extern void lang_memory_region_alias
|
||||||
(asection *);
|
(const char *, const char *);
|
||||||
extern void lang_map
|
extern void lang_map
|
||||||
(void);
|
(void);
|
||||||
extern void lang_set_flags
|
extern void lang_set_flags
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
%{
|
%{
|
||||||
|
|
||||||
/* Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
/* Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||||
2000, 2001, 2002, 2003, 2004, 2005, 2007
|
2000, 2001, 2002, 2003, 2004, 2005, 2007, 2009
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
Written by Steve Chamberlain of Cygnus Support.
|
Written by Steve Chamberlain of Cygnus Support.
|
||||||
|
|
||||||
@ -239,6 +239,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
|
|||||||
<BOTH,SCRIPT,EXPRESSION,MRI>":" { RTOKEN(':'); }
|
<BOTH,SCRIPT,EXPRESSION,MRI>":" { RTOKEN(':'); }
|
||||||
<BOTH,SCRIPT,EXPRESSION,MRI>";" { RTOKEN(';');}
|
<BOTH,SCRIPT,EXPRESSION,MRI>";" { RTOKEN(';');}
|
||||||
<BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);}
|
<BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);}
|
||||||
|
<BOTH,SCRIPT>"REGION_ALIAS" { RTOKEN(REGION_ALIAS);}
|
||||||
<BOTH,SCRIPT,EXPRESSION>"ORIGIN" { RTOKEN(ORIGIN);}
|
<BOTH,SCRIPT,EXPRESSION>"ORIGIN" { RTOKEN(ORIGIN);}
|
||||||
<BOTH,SCRIPT>"VERSION" { RTOKEN(VERSIONK);}
|
<BOTH,SCRIPT>"VERSION" { RTOKEN(VERSIONK);}
|
||||||
<EXPRESSION,BOTH,SCRIPT>"BLOCK" { RTOKEN(BLOCK);}
|
<EXPRESSION,BOTH,SCRIPT>"BLOCK" { RTOKEN(BLOCK);}
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
2009-03-02 Sebastian Huber <sebastian.huber@embedded-brains.de>
|
||||||
|
|
||||||
|
* ld-scripts/regions-alias-1.t: New file.
|
||||||
|
* ld-scripts/regions-alias-2.t: New file.
|
||||||
|
* ld-scripts/regions-alias-3.t: New file.
|
||||||
|
* ld-scripts/regions-alias-4.t: New file.
|
||||||
|
* ld-scripts/script.exp: Run region alias tests.
|
||||||
|
|
||||||
2009-02-27 Dave Korn <dave.korn.cygwin@gmail.com>
|
2009-02-27 Dave Korn <dave.korn.cygwin@gmail.com>
|
||||||
|
|
||||||
* ld-pe/pe.exp: Disable auto-import when linking on Cygwin.
|
* ld-pe/pe.exp: Disable auto-import when linking on Cygwin.
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#ld: -r --gc-sections --entry foo
|
#ld: -r --gc-sections --entry foo
|
||||||
#readelf: -g --wide
|
#readelf: -g --wide
|
||||||
#notarget: ia64-*-* mep-*-*
|
#notarget: ia64-*-* mep-*-*
|
||||||
|
#xfail: dlx-*-* openrisc-*-* or32-*-* alpha-*-* arc-*-* hppa64-*-*
|
||||||
|
|
||||||
COMDAT group section \[[ 0-9]+\] `.group' \[foo\] contains 1 sections:
|
COMDAT group section \[[ 0-9]+\] `.group' \[foo\] contains 1 sections:
|
||||||
\[Index\] Name
|
\[Index\] Name
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#ld: -r --gc-sections --entry bar
|
#ld: -r --gc-sections --entry bar
|
||||||
#readelf: -g --wide
|
#readelf: -g --wide
|
||||||
#notarget: ia64-*-* mep-*-*
|
#notarget: ia64-*-* mep-*-*
|
||||||
|
#xfail: dlx-*-* openrisc-*-* or32-*-* alpha-*-* arc-*-* hppa64-*-*
|
||||||
|
|
||||||
COMDAT group section \[[ 0-9]+\] `.group' \[bar\] contains 1 sections:
|
COMDAT group section \[[ 0-9]+\] `.group' \[bar\] contains 1 sections:
|
||||||
\[Index\] Name
|
\[Index\] Name
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#ld: -r --gc-sections --entry foo
|
#ld: -r --gc-sections --entry foo
|
||||||
#readelf: -g --wide
|
#readelf: -g --wide
|
||||||
#notarget: ia64-*-* mep-*-*
|
#notarget: ia64-*-* mep-*-*
|
||||||
|
#xfail: dlx-*-* openrisc-*-* or32-*-* alpha-*-* arc-*-*
|
||||||
|
|
||||||
COMDAT group section \[[ 0-9]+\] `.group' \[foo\] contains 2 sections:
|
COMDAT group section \[[ 0-9]+\] `.group' \[foo\] contains 2 sections:
|
||||||
\[Index\] Name
|
\[Index\] Name
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#ld: -r --gc-sections --entry bar
|
#ld: -r --gc-sections --entry bar
|
||||||
#readelf: -g --wide
|
#readelf: -g --wide
|
||||||
#notarget: ia64-*-* mep-*-*
|
#notarget: ia64-*-* mep-*-*
|
||||||
|
#xfail: dlx-*-* openrisc-*-* or32-*-* alpha-*-* hppa64-*-* arc-*-*
|
||||||
|
|
||||||
COMDAT group section \[[ 0-9]+\] `.group' \[foo\] contains 2 sections:
|
COMDAT group section \[[ 0-9]+\] `.group' \[foo\] contains 2 sections:
|
||||||
\[Index\] Name
|
\[Index\] Name
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
TEXTMEM (ARX) : ORIGIN = 0x100, LENGTH = 32K
|
R_TEXTMEM (ARX) : ORIGIN = 0x100, LENGTH = 32K
|
||||||
DATAMEM (AW) : org = 0x1000, l = (64 * 1024)
|
R_DATAMEM (AW) : org = 0x1000, l = (64 * 1024)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
REGION_ALIAS ("A_TEXTMEM", R_TEXTMEM);
|
||||||
|
REGION_ALIAS ("A_DATAMEM", R_DATAMEM);
|
||||||
|
|
||||||
|
REGION_ALIAS ("TEXTMEM", A_TEXTMEM);
|
||||||
|
REGION_ALIAS ("DATAMEM", A_DATAMEM);
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0;
|
. = 0;
|
||||||
|
7
ld/testsuite/ld-scripts/region-alias-1.t
Normal file
7
ld/testsuite/ld-scripts/region-alias-1.t
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
MY_REGION (ARX) : ORIGIN = 0, LENGTH = 32K
|
||||||
|
}
|
||||||
|
|
||||||
|
REGION_ALIAS ("MY_ALIAS", MY_REGION);
|
||||||
|
REGION_ALIAS ("MY_ALIAS", MY_REGION);
|
6
ld/testsuite/ld-scripts/region-alias-2.t
Normal file
6
ld/testsuite/ld-scripts/region-alias-2.t
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
MY_REGION (ARX) : ORIGIN = 0, LENGTH = 32K
|
||||||
|
}
|
||||||
|
|
||||||
|
REGION_ALIAS ("MY_ALIAS", "NIL");
|
6
ld/testsuite/ld-scripts/region-alias-3.t
Normal file
6
ld/testsuite/ld-scripts/region-alias-3.t
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
MY_REGION (ARX) : ORIGIN = 0, LENGTH = 32K
|
||||||
|
}
|
||||||
|
|
||||||
|
REGION_ALIAS ("MY_ALIAS", "*default*");
|
6
ld/testsuite/ld-scripts/region-alias-4.t
Normal file
6
ld/testsuite/ld-scripts/region-alias-4.t
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
MY_REGION (ARX) : ORIGIN = 0, LENGTH = 32K
|
||||||
|
}
|
||||||
|
|
||||||
|
REGION_ALIAS ("*default*", MY_REGION);
|
@ -1,7 +1,7 @@
|
|||||||
# name: rgn-over1
|
# name: rgn-over1
|
||||||
# source: rgn-over.s
|
# source: rgn-over.s
|
||||||
# ld: -T rgn-over1.t -Map tmpdir/rgn-over1.map
|
# ld: -T rgn-over1.t -Map tmpdir/rgn-over1.map
|
||||||
# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section \.text will not fit in region r1\n[^ \n]*?ld[^:\n]*?: region r1 overflowed by 16 bytes\Z
|
# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section \`.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 16 bytes\Z
|
||||||
|
|
||||||
Discarded input sections
|
Discarded input sections
|
||||||
#...
|
#...
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# name: rgn-over2
|
# name: rgn-over2
|
||||||
# source: rgn-over.s
|
# source: rgn-over.s
|
||||||
# ld: -T rgn-over2.t -Map tmpdir/rgn-over2.map
|
# ld: -T rgn-over2.t -Map tmpdir/rgn-over2.map
|
||||||
# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section \.data will not fit in region r1\n[^ \n]*?ld[^:\n]*?: region r1 overflowed by 4 bytes\Z
|
# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.data' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 4 bytes\Z
|
||||||
|
|
||||||
Discarded input sections
|
Discarded input sections
|
||||||
#...
|
#...
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# name: rgn-over3
|
# name: rgn-over3
|
||||||
# source: rgn-over.s
|
# source: rgn-over.s
|
||||||
# ld: -T rgn-over3.t -Map tmpdir/rgn-over3.map
|
# ld: -T rgn-over3.t -Map tmpdir/rgn-over3.map
|
||||||
# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section \.text will not fit in region r1\n[^ \n]*?ld[^:\n]*?: [^\n]*?section \.data will not fit in region r2\n[^ \n]*?ld[^:\n]*?: region r1 overflowed by 4 bytes\n[^ \n]*?ld[^:\n]*?: region r2 overflowed by 4 bytes\Z
|
# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.data' will not fit in region `r2'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 4 bytes\n[^ \n]*?ld[^:\n]*?: region `r2' overflowed by 4 bytes\Z
|
||||||
|
|
||||||
Discarded input sections
|
Discarded input sections
|
||||||
#...
|
#...
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# name: rgn-over4
|
# name: rgn-over4
|
||||||
# source: rgn-over.s
|
# source: rgn-over.s
|
||||||
# ld: -T rgn-over4.t -Map tmpdir/rgn-over4.map
|
# ld: -T rgn-over4.t -Map tmpdir/rgn-over4.map
|
||||||
# error: \A[^ \n]*?ld[^:\n]*?: [^:\n]*?section \.text will not fit in region r1\n[^ \n]*?ld[^:\n]*?: region r1 overflowed by 16 bytes\Z
|
# error: \A[^ \n]*?ld[^:\n]*?: [^:\n]*?section `\.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 16 bytes\Z
|
||||||
|
|
||||||
Discarded input sections
|
Discarded input sections
|
||||||
#...
|
#...
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# name: rgn-over5
|
# name: rgn-over5
|
||||||
# source: rgn-over.s
|
# source: rgn-over.s
|
||||||
# ld: -T rgn-over5.t -Map tmpdir/rgn-over5.map
|
# ld: -T rgn-over5.t -Map tmpdir/rgn-over5.map
|
||||||
# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section \.text will not fit in region v1\n[^ \n]*?ld[^:\n]*?: region v1 overflowed by 16 bytes\Z
|
# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `v1'\n[^ \n]*?ld[^:\n]*?: region `v1' overflowed by 16 bytes\Z
|
||||||
|
|
||||||
Discarded input sections
|
Discarded input sections
|
||||||
#...
|
#...
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# name: rgn-over6
|
# name: rgn-over6
|
||||||
# source: rgn-over.s
|
# source: rgn-over.s
|
||||||
# ld: -T rgn-over6.t -Map tmpdir/rgn-over6.map
|
# ld: -T rgn-over6.t -Map tmpdir/rgn-over6.map
|
||||||
# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section \.text will not fit in region r1\n[^ \n]*?ld[^:\n]*?: [^\n]*?section \.text will not fit in region v1\n[^ \n]*?ld[^:\n]*?: region r1 overflowed by 16 bytes\n[^ \n]*?ld[^:\n]*?: region v1 overflowed by 16 bytes\Z
|
# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `v1'\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 16 bytes\n[^ \n]*?ld[^:\n]*?: region `v1' overflowed by 16 bytes\Z
|
||||||
|
|
||||||
Discarded input sections
|
Discarded input sections
|
||||||
#...
|
#...
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# name: rgn-over7
|
# name: rgn-over7
|
||||||
# source: rgn-over.s
|
# source: rgn-over.s
|
||||||
# ld: -T rgn-over7.t -Map tmpdir/rgn-over7.map
|
# ld: -T rgn-over7.t -Map tmpdir/rgn-over7.map
|
||||||
# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section \.text will not fit in region r1\n[^ \n]*?ld[^:\n]*?: section \.data \[0+1008 -> 0+1013\] overlaps section \.text \[0+1000 -> 0+100b\]\n[^ \n]*?ld[^:\n]*?: region r1 overflowed by 4 bytes\Z
|
# error: \A[^ \n]*?ld[^:\n]*?: [^\n]*?section `\.text' will not fit in region `r1'\n[^ \n]*?ld[^:\n]*?: section \.data \[0+1008 -> 0+1013\] overlaps section \.text \[0+1000 -> 0+100b\]\n[^ \n]*?ld[^:\n]*?: region `r1' overflowed by 4 bytes\Z
|
||||||
|
|
||||||
Discarded input sections
|
Discarded input sections
|
||||||
#...
|
#...
|
||||||
|
@ -126,3 +126,13 @@ if ![ld_simple_link $ld tmpdir/script "$flags -T $srcdir/$subdir/memory.t tmpdir
|
|||||||
} else {
|
} else {
|
||||||
check_script
|
check_script
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set test_script_list [glob $srcdir/$subdir/region-alias-*.t]
|
||||||
|
|
||||||
|
foreach test_script $test_script_list {
|
||||||
|
if ![ld_simple_link $ld tmpdir/script "$flags -T $test_script tmpdir/script.o"] {
|
||||||
|
xfail "REGION_ALIAS: $test_script"
|
||||||
|
} else {
|
||||||
|
xpass "REGION_ALIAS: $test_script"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user