Add ORIGIN and LENGTH linker script operators.

This commit is contained in:
Nick Clifton 2004-11-19 09:31:55 +00:00
parent 288f74fae9
commit 3ec5763260
9 changed files with 287 additions and 152 deletions

View File

@ -1,3 +1,12 @@
2004-11-19 Jon Beniston <jon@beniston.com>
* ld/ldlex.l: Allow ORIGIN and LENGTH in EXPRESSION.
* ld/ldgram.y: Add ORIGIN and LENGTH expressions.
* ld/ldexp.c (fold_name): Implement LENGTH() and ORIGIN() functions
which return the length and origin of a memory.
* ld/ld.texinfo: Document LENGTH() and ORIGIN() functions.
* NEWS: Mention support for ORIGIN and LENGTH operators.
2004-11-17 Daniel Jacobowitz <dan@codesourcery.com>
* emultempl/armelf.em (arm_elf_set_bfd_for_interworking): Don't use

View File

@ -1,5 +1,8 @@
-*- text -*-
* New linker script functions: ORIGIN() and LENGTH() which return information
about a specified memory region.
* Port to MAXQ processor contributed by HCL Tech.
* Added SEGMENT_START to the linker script language to permit the user to

View File

@ -3886,6 +3886,16 @@ the next available address within the memory region. If the combined
output sections directed to a memory region are too large for the
region, the linker will issue an error message.
It is possible to access the origin and length of a memory in an
expression via the @code{ORIGIN(@var{memory})} and
@code{LENGTH(@var{memory})} functions:
@smallexample
@group
_fstack = ORIGIN(ram) + LENGTH(ram) - 4;
@end group
@end smallexample
@node PHDRS
@section PHDRS Command
@kindex PHDRS
@ -4661,6 +4671,10 @@ SECTIONS @{ @dots{}
@end group
@end smallexample
@item LENGTH(@var{memory})
@kindex LENGTH(@var{memory})
Return the length of the memory region named @var{memory}.
@item LOADADDR(@var{section})
@kindex LOADADDR(@var{section})
@cindex section load address in expression
@ -4685,6 +4699,10 @@ This function is closely related to @code{ALIGN(@var{exp})}; unless you
use the @code{MEMORY} command to define discontinuous memory for the
output file, the two functions are equivalent.
@item ORIGIN(@var{memory})
@kindex ORIGIN(@var{memory})
Return the origin of the memory region named @var{memory}.
@item SEGMENT_START(@var{segment}, @var{default})
@kindex SEGMENT_START(@var{segment}, @var{default})
Return the base address of the named @var{segment}. If an explicit

View File

@ -4,22 +4,22 @@
Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
This file is part of GLD, the Gnu Linker.
This file is part of GLD, the Gnu Linker.
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GLD is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GLD is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* This module is in charge of working out the contents of expressions.
@ -105,6 +105,8 @@ exp_print_token (token_code_type code, int infix_p)
{ DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" },
{ DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" },
{ DATA_SEGMENT_END, "DATA_SEGMENT_END" },
{ ORIGIN, "ORIGIN" },
{ LENGTH, "LENGTH" },
{ SEGMENT_START, "SEGMENT_START" }
};
unsigned int idx;
@ -645,6 +647,32 @@ fold_name (etree_type *tree,
}
break;
case LENGTH:
{
lang_memory_region_type *mem;
mem = lang_memory_region_lookup (tree->name.name, FALSE);
if (mem != NULL)
result = new_abs (mem->length);
else
einfo (_("%F%S: undefined MEMORY region `%s' referenced in expression\n"),
tree->name.name);
}
break;
case ORIGIN:
{
lang_memory_region_type *mem;
mem = lang_memory_region_lookup (tree->name.name, FALSE);
if (mem != NULL)
result = new_abs (mem->origin);
else
einfo (_("%F%S: undefined MEMORY region `%s' referenced in expression\n"),
tree->name.name);
}
break;
default:
FAIL ();
break;

View File

@ -1,23 +1,23 @@
/* 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,
2001, 2002, 2003 Free Software Foundation, Inc.
2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
This file is part of GNU ld.
This file is part of GNU ld.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
%{
/*
@ -762,88 +762,88 @@ nocrossref_list:
}
;
mustbe_exp: { ldlex_expression(); }
mustbe_exp: { ldlex_expression (); }
exp
{ ldlex_popstate(); $$=$2;}
{ ldlex_popstate (); $$=$2;}
;
exp :
'-' exp %prec UNARY
{ $$ = exp_unop('-', $2); }
{ $$ = exp_unop ('-', $2); }
| '(' exp ')'
{ $$ = $2; }
| NEXT '(' exp ')' %prec UNARY
{ $$ = exp_unop((int) $1,$3); }
{ $$ = exp_unop ((int) $1,$3); }
| '!' exp %prec UNARY
{ $$ = exp_unop('!', $2); }
{ $$ = exp_unop ('!', $2); }
| '+' exp %prec UNARY
{ $$ = $2; }
| '~' exp %prec UNARY
{ $$ = exp_unop('~', $2);}
{ $$ = exp_unop ('~', $2);}
| exp '*' exp
{ $$ = exp_binop('*', $1, $3); }
{ $$ = exp_binop ('*', $1, $3); }
| exp '/' exp
{ $$ = exp_binop('/', $1, $3); }
{ $$ = exp_binop ('/', $1, $3); }
| exp '%' exp
{ $$ = exp_binop('%', $1, $3); }
{ $$ = exp_binop ('%', $1, $3); }
| exp '+' exp
{ $$ = exp_binop('+', $1, $3); }
{ $$ = exp_binop ('+', $1, $3); }
| exp '-' exp
{ $$ = exp_binop('-' , $1, $3); }
{ $$ = exp_binop ('-' , $1, $3); }
| exp LSHIFT exp
{ $$ = exp_binop(LSHIFT , $1, $3); }
{ $$ = exp_binop (LSHIFT , $1, $3); }
| exp RSHIFT exp
{ $$ = exp_binop(RSHIFT , $1, $3); }
{ $$ = exp_binop (RSHIFT , $1, $3); }
| exp EQ exp
{ $$ = exp_binop(EQ , $1, $3); }
{ $$ = exp_binop (EQ , $1, $3); }
| exp NE exp
{ $$ = exp_binop(NE , $1, $3); }
{ $$ = exp_binop (NE , $1, $3); }
| exp LE exp
{ $$ = exp_binop(LE , $1, $3); }
{ $$ = exp_binop (LE , $1, $3); }
| exp GE exp
{ $$ = exp_binop(GE , $1, $3); }
{ $$ = exp_binop (GE , $1, $3); }
| exp '<' exp
{ $$ = exp_binop('<' , $1, $3); }
{ $$ = exp_binop ('<' , $1, $3); }
| exp '>' exp
{ $$ = exp_binop('>' , $1, $3); }
{ $$ = exp_binop ('>' , $1, $3); }
| exp '&' exp
{ $$ = exp_binop('&' , $1, $3); }
{ $$ = exp_binop ('&' , $1, $3); }
| exp '^' exp
{ $$ = exp_binop('^' , $1, $3); }
{ $$ = exp_binop ('^' , $1, $3); }
| exp '|' exp
{ $$ = exp_binop('|' , $1, $3); }
{ $$ = exp_binop ('|' , $1, $3); }
| exp '?' exp ':' exp
{ $$ = exp_trinop('?' , $1, $3, $5); }
{ $$ = exp_trinop ('?' , $1, $3, $5); }
| exp ANDAND exp
{ $$ = exp_binop(ANDAND , $1, $3); }
{ $$ = exp_binop (ANDAND , $1, $3); }
| exp OROR exp
{ $$ = exp_binop(OROR , $1, $3); }
{ $$ = exp_binop (OROR , $1, $3); }
| DEFINED '(' NAME ')'
{ $$ = exp_nameop(DEFINED, $3); }
{ $$ = exp_nameop (DEFINED, $3); }
| INT
{ $$ = exp_bigintop ($1.integer, $1.str); }
| SIZEOF_HEADERS
{ $$ = exp_nameop(SIZEOF_HEADERS,0); }
{ $$ = exp_nameop (SIZEOF_HEADERS,0); }
| SIZEOF '(' NAME ')'
{ $$ = exp_nameop(SIZEOF,$3); }
{ $$ = exp_nameop (SIZEOF,$3); }
| ADDR '(' NAME ')'
{ $$ = exp_nameop(ADDR,$3); }
{ $$ = exp_nameop (ADDR,$3); }
| LOADADDR '(' NAME ')'
{ $$ = exp_nameop(LOADADDR,$3); }
{ $$ = exp_nameop (LOADADDR,$3); }
| ABSOLUTE '(' exp ')'
{ $$ = exp_unop(ABSOLUTE, $3); }
{ $$ = exp_unop (ABSOLUTE, $3); }
| ALIGN_K '(' exp ')'
{ $$ = exp_unop(ALIGN_K,$3); }
{ $$ = exp_unop (ALIGN_K,$3); }
| ALIGN_K '(' exp ',' exp ')'
{ $$ = exp_binop(ALIGN_K,$3,$5); }
{ $$ = exp_binop (ALIGN_K,$3,$5); }
| DATA_SEGMENT_ALIGN '(' exp ',' exp ')'
{ $$ = exp_binop (DATA_SEGMENT_ALIGN, $3, $5); }
| DATA_SEGMENT_RELRO_END '(' exp ',' exp ')'
{ $$ = exp_binop (DATA_SEGMENT_RELRO_END, $5, $3); }
| DATA_SEGMENT_END '(' exp ')'
{ $$ = exp_unop(DATA_SEGMENT_END, $3); }
{ $$ = exp_unop (DATA_SEGMENT_END, $3); }
| SEGMENT_START '(' NAME ',' exp ')'
{ /* The operands to the expression node are
placed in the opposite order from the way
@ -854,15 +854,19 @@ exp :
$5,
exp_nameop (NAME, $3)); }
| BLOCK '(' exp ')'
{ $$ = exp_unop(ALIGN_K,$3); }
{ $$ = exp_unop (ALIGN_K,$3); }
| NAME
{ $$ = exp_nameop(NAME,$1); }
{ $$ = exp_nameop (NAME,$1); }
| MAX_K '(' exp ',' exp ')'
{ $$ = exp_binop (MAX_K, $3, $5 ); }
| MIN_K '(' exp ',' exp ')'
{ $$ = exp_binop (MIN_K, $3, $5 ); }
| ASSERT_K '(' exp ',' NAME ')'
{ $$ = exp_assert ($3, $5); }
| ORIGIN '(' NAME ')'
{ $$ = exp_nameop (ORIGIN, $3); }
| LENGTH '(' NAME ')'
{ $$ = exp_nameop (LENGTH, $3); }
;

View File

@ -1,24 +1,24 @@
%{
/* Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003 Free Software Foundation, Inc.
2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
This file is part of GLD, the Gnu Linker.
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GLD is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GLD is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/*
This was written by steve chamberlain
@ -234,60 +234,60 @@ 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,EXPRESSION,MRI>"}" { RTOKEN('}') ; }
<BOTH,SCRIPT,EXPRESSION,MRI>"{" { RTOKEN('{'); }
<BOTH,SCRIPT,EXPRESSION,MRI>")" { RTOKEN(')');}
<BOTH,SCRIPT,EXPRESSION,MRI>"(" { RTOKEN('(');}
<BOTH,SCRIPT,EXPRESSION,MRI>"=" { RTOKEN('=');}
<BOTH,SCRIPT,EXPRESSION,MRI>"}" { RTOKEN('}') ; }
<BOTH,SCRIPT,EXPRESSION,MRI>"{" { RTOKEN('{'); }
<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>"ORIGIN" { RTOKEN(ORIGIN);}
<BOTH,SCRIPT>"VERSION" { RTOKEN(VERSIONK);}
<BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);}
<BOTH,SCRIPT,EXPRESSION>"ORIGIN" { RTOKEN(ORIGIN);}
<BOTH,SCRIPT>"VERSION" { RTOKEN(VERSIONK);}
<EXPRESSION,BOTH,SCRIPT>"BLOCK" { RTOKEN(BLOCK);}
<EXPRESSION,BOTH,SCRIPT>"BIND" { RTOKEN(BIND);}
<BOTH,SCRIPT>"LENGTH" { RTOKEN(LENGTH);}
<EXPRESSION,BOTH,SCRIPT>"ALIGN" { RTOKEN(ALIGN_K);}
<BOTH,SCRIPT,EXPRESSION>"LENGTH" { RTOKEN(LENGTH);}
<EXPRESSION,BOTH,SCRIPT>"ALIGN" { RTOKEN(ALIGN_K);}
<EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_ALIGN" { RTOKEN(DATA_SEGMENT_ALIGN);}
<EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END);}
<EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_END" { RTOKEN(DATA_SEGMENT_END);}
<EXPRESSION,BOTH,SCRIPT>"ADDR" { RTOKEN(ADDR);}
<EXPRESSION,BOTH,SCRIPT>"LOADADDR" { RTOKEN(LOADADDR);}
<EXPRESSION,BOTH,SCRIPT>"ADDR" { RTOKEN(ADDR);}
<EXPRESSION,BOTH,SCRIPT>"LOADADDR" { RTOKEN(LOADADDR);}
<EXPRESSION,BOTH>"MAX" { RTOKEN(MAX_K); }
<EXPRESSION,BOTH>"MIN" { RTOKEN(MIN_K); }
<EXPRESSION,BOTH>"ASSERT" { RTOKEN(ASSERT_K); }
<BOTH,SCRIPT>"ENTRY" { RTOKEN(ENTRY);}
<BOTH,SCRIPT,MRI>"EXTERN" { RTOKEN(EXTERN);}
<EXPRESSION,BOTH,SCRIPT>"NEXT" { RTOKEN(NEXT);}
<EXPRESSION,BOTH,SCRIPT>"NEXT" { RTOKEN(NEXT);}
<EXPRESSION,BOTH,SCRIPT>"sizeof_headers" { RTOKEN(SIZEOF_HEADERS);}
<EXPRESSION,BOTH,SCRIPT>"SIZEOF_HEADERS" { RTOKEN(SIZEOF_HEADERS);}
<EXPRESSION,BOTH,SCRIPT>"SEGMENT_START" { RTOKEN(SEGMENT_START);}
<BOTH,SCRIPT>"MAP" { RTOKEN(MAP);}
<EXPRESSION,BOTH,SCRIPT>"SIZEOF" { RTOKEN(SIZEOF);}
<BOTH,SCRIPT>"TARGET" { RTOKEN(TARGET_K);}
<EXPRESSION,BOTH,SCRIPT>"SIZEOF" { RTOKEN(SIZEOF);}
<BOTH,SCRIPT>"TARGET" { RTOKEN(TARGET_K);}
<BOTH,SCRIPT>"SEARCH_DIR" { RTOKEN(SEARCH_DIR);}
<BOTH,SCRIPT>"OUTPUT" { RTOKEN(OUTPUT);}
<BOTH,SCRIPT>"OUTPUT" { RTOKEN(OUTPUT);}
<BOTH,SCRIPT>"INPUT" { RTOKEN(INPUT);}
<EXPRESSION,BOTH,SCRIPT>"GROUP" { RTOKEN(GROUP);}
<EXPRESSION,BOTH,SCRIPT>"DEFINED" { RTOKEN(DEFINED);}
<EXPRESSION,BOTH,SCRIPT>"DEFINED" { RTOKEN(DEFINED);}
<BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);}
<BOTH,SCRIPT>"CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);}
<BOTH,SCRIPT>"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION);}
<BOTH,SCRIPT>"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION);}
<BOTH,SCRIPT>"INHIBIT_COMMON_ALLOCATION" { RTOKEN(INHIBIT_COMMON_ALLOCATION);}
<BOTH,SCRIPT>"SECTIONS" { RTOKEN(SECTIONS);}
<BOTH,SCRIPT>"SECTIONS" { RTOKEN(SECTIONS);}
<BOTH,SCRIPT>"FILL" { RTOKEN(FILL);}
<BOTH,SCRIPT>"STARTUP" { RTOKEN(STARTUP);}
<BOTH,SCRIPT>"STARTUP" { RTOKEN(STARTUP);}
<BOTH,SCRIPT>"OUTPUT_FORMAT" { RTOKEN(OUTPUT_FORMAT);}
<BOTH,SCRIPT>"OUTPUT_ARCH" { RTOKEN( OUTPUT_ARCH);}
<BOTH,SCRIPT>"HLL" { RTOKEN(HLL);}
<BOTH,SCRIPT>"SYSLIB" { RTOKEN(SYSLIB);}
<BOTH,SCRIPT>"SYSLIB" { RTOKEN(SYSLIB);}
<BOTH,SCRIPT>"FLOAT" { RTOKEN(FLOAT);}
<BOTH,SCRIPT>"QUAD" { RTOKEN( QUAD);}
<BOTH,SCRIPT>"SQUAD" { RTOKEN( SQUAD);}
<BOTH,SCRIPT>"LONG" { RTOKEN( LONG);}
<BOTH,SCRIPT>"SHORT" { RTOKEN( SHORT);}
<BOTH,SCRIPT>"BYTE" { RTOKEN( BYTE);}
<BOTH,SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT);}
<BOTH,SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT);}
<EXPRESSION,BOTH,SCRIPT>"NOCROSSREFS" { RTOKEN(NOCROSSREFS);}
<BOTH,SCRIPT>"OVERLAY" { RTOKEN(OVERLAY); }
<BOTH,SCRIPT>"SORT_BY_NAME" { RTOKEN(SORT_BY_NAME); }
@ -306,22 +306,22 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
<BOTH,SCRIPT>"len" { RTOKEN( LENGTH);}
<BOTH,SCRIPT>"INCLUDE" { RTOKEN(INCLUDE);}
<BOTH,SCRIPT>"PHDRS" { RTOKEN (PHDRS); }
<EXPRESSION,BOTH,SCRIPT>"AT" { RTOKEN(AT);}
<EXPRESSION,BOTH,SCRIPT>"SUBALIGN" { RTOKEN(SUBALIGN);}
<EXPRESSION,BOTH,SCRIPT>"PROVIDE" { RTOKEN(PROVIDE); }
<EXPRESSION,BOTH,SCRIPT>"AT" { RTOKEN(AT);}
<EXPRESSION,BOTH,SCRIPT>"SUBALIGN" { RTOKEN(SUBALIGN);}
<EXPRESSION,BOTH,SCRIPT>"PROVIDE" { RTOKEN(PROVIDE); }
<EXPRESSION,BOTH,SCRIPT>"KEEP" { RTOKEN(KEEP); }
<EXPRESSION,BOTH,SCRIPT>"EXCLUDE_FILE" { RTOKEN(EXCLUDE_FILE); }
<EXPRESSION,BOTH,SCRIPT>"EXCLUDE_FILE" { RTOKEN(EXCLUDE_FILE); }
<MRI>"#".*\n? { ++ lineno; }
<MRI>"\n" { ++ lineno; RTOKEN(NEWLINE); }
<MRI>"*".* { /* Mri comment line */ }
<MRI>";".* { /* Mri comment line */ }
<MRI>"END" { RTOKEN(ENDWORD); }
<MRI>"ALIGNMOD" { RTOKEN(ALIGNMOD);}
<MRI>"ALIGN" { RTOKEN(ALIGN_K);}
<MRI>"ALIGNMOD" { RTOKEN(ALIGNMOD);}
<MRI>"ALIGN" { RTOKEN(ALIGN_K);}
<MRI>"CHIP" { RTOKEN(CHIP); }
<MRI>"BASE" { RTOKEN(BASE); }
<MRI>"ALIAS" { RTOKEN(ALIAS); }
<MRI>"TRUNCATE" { RTOKEN(TRUNCATE); }
<MRI>"ALIAS" { RTOKEN(ALIAS); }
<MRI>"TRUNCATE" { RTOKEN(TRUNCATE); }
<MRI>"LOAD" { RTOKEN(LOAD); }
<MRI>"PUBLIC" { RTOKEN(PUBLIC); }
<MRI>"ORDER" { RTOKEN(ORDER); }
@ -333,12 +333,12 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
<MRI>"SECT" { RTOKEN(SECT); }
<EXPRESSION,BOTH,SCRIPT,MRI>"ABSOLUTE" { RTOKEN(ABSOLUTE); }
<MRI>"end" { RTOKEN(ENDWORD); }
<MRI>"alignmod" { RTOKEN(ALIGNMOD);}
<MRI>"align" { RTOKEN(ALIGN_K);}
<MRI>"alignmod" { RTOKEN(ALIGNMOD);}
<MRI>"align" { RTOKEN(ALIGN_K);}
<MRI>"chip" { RTOKEN(CHIP); }
<MRI>"base" { RTOKEN(BASE); }
<MRI>"alias" { RTOKEN(ALIAS); }
<MRI>"truncate" { RTOKEN(TRUNCATE); }
<MRI>"alias" { RTOKEN(ALIAS); }
<MRI>"truncate" { RTOKEN(TRUNCATE); }
<MRI>"load" { RTOKEN(LOAD); }
<MRI>"public" { RTOKEN(PUBLIC); }
<MRI>"order" { RTOKEN(ORDER); }

View File

@ -1,3 +1,11 @@
2004-11-19 Nick Clifton <nickc@redhat.com>
* ld-scripts/script.exp: Add test of memory linker script.
Reorganise code to remove unnecessary indentation.
Fix target tests to avoid using --image-base with *-nto targets.
* ld-scripts/memory.t: New linker script to test the MEMORY
section and the ORIGIN and LENGTH operators.
2004-11-17 Daniel Jacobowitz <dan@codesourcery.com>
* ld-arm/mixed-app.d, ld-arm/mixed-app.r, ld-arm/mixed-app.s,

View File

@ -0,0 +1,39 @@
MEMORY
{
TEXTMEM (ARX) : ORIGIN = 0x100, LENGTH = 32K
DATAMEM (AW) : org = 0x1000, l = (64 * 1024)
}
SECTIONS
{
. = 0;
.text :
{
/* The value returned by the ORIGIN operator is a constant.
However it is being assigned to a symbol declared within
a section. Therefore the symbol is section-relative and
its value will include the offset of that section from
the start of memory. ie the declaration:
text_start = ORIGIN (TEXTMEM);
here will result in text_start having a value of 0x200.
Hence we need to subtract the absolute value of the
location counter at this point in order to give text_start
a value that is truely absolute, and which coincidentally
will allow the tests in script.exp to work. */
text_start = ORIGIN(TEXTMEM) - ABSOLUTE (.);
*(.text)
*(.pr)
text_end = .;
} > TEXTMEM
data_start = ORIGIN (DATAMEM);
.data :
{
*(.data)
*(.rw)
data_end = .;
} >DATAMEM
fred = ORIGIN(DATAMEM) + LENGTH(DATAMEM);
}

View File

@ -1,6 +1,6 @@
# Test basic linker script functionality
# By Ian Lance Taylor, Cygnus Support
# Copyright 2001
# Copyright 2001, 2004
# Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
@ -31,47 +31,63 @@ proc check_script { } {
if ![ld_nm $nm "" tmpdir/script] {
unresolved $testname
return
}
if {![info exists nm_output(text_start)] \
|| ![info exists nm_output(text_end)] \
|| ![info exists nm_output(data_start)] \
|| ![info exists nm_output(data_end)]} {
send_log "bad output from nm\n"
verbose "bad output from nm"
fail $testname
return
}
set passes 1
set text_end 0x104
set data_end 0x1004
if [istarget *c4x*-*-*] then {
set text_end 0x101
set data_end 0x1001
}
if [istarget *c54x*-*-*] then {
set text_end 0x102
set data_end 0x1002
}
if {$nm_output(text_start) != 0x100} {
send_log "text_start == $nm_output(text_start)\n"
verbose "text_start == $nm_output(text_start)"
set passes 0
}
if {$nm_output(text_end) < $text_end \
|| $nm_output(text_end) > 0x110} {
send_log "text_end == $nm_output(text_end)\n"
verbose "text_end == $nm_output(text_end)"
set passes 0
}
if {$nm_output(data_start) != 0x1000} {
send_log "data_start == $nm_output(data_start)\n"
verbose "data_start == $nm_output(data_start)"
set passes 0
}
if {$nm_output(data_end) < $data_end \
|| $nm_output(data_end) > 0x1010} {
send_log "data_end == $nm_output(data_end)\n"
verbose "data_end == $nm_output(data_end)"
set passes 0
}
if { $passes } {
pass $testname
} else {
if {![info exists nm_output(text_start)] \
|| ![info exists nm_output(text_end)] \
|| ![info exists nm_output(data_start)] \
|| ![info exists nm_output(data_end)]} {
send_log "bad output from nm\n"
verbose "bad output from nm"
fail $testname
} else {
set text_end 0x104
set data_end 0x1004
if [istarget *c4x*-*-*] then {
set text_end 0x101
set data_end 0x1001
}
if [istarget *c54x*-*-*] then {
set text_end 0x102
set data_end 0x1002
}
if {$nm_output(text_start) != 0x100} {
send_log "text_start == $nm_output(text_start)\n"
verbose "text_start == $nm_output(text_start)"
fail $testname
} else { if {$nm_output(text_end) < $text_end \
|| $nm_output(text_end) > 0x110} {
send_log "text_end == $nm_output(text_end)\n"
verbose "text_end == $nm_output(text_end)"
fail $testname
} else { if {$nm_output(data_start) != 0x1000} {
send_log "data_start == $nm_output(data_start)\n"
verbose "data_start == $nm_output(data_start)"
fail $testname
} else { if {$nm_output(data_end) < $data_end \
|| $nm_output(data_end) > 0x1010} {
send_log "data_end == $nm_output(data_end)\n"
verbose "data_end == $nm_output(data_end)"
fail $testname
} else {
pass $testname
} } } }
}
fail $testname
}
}
@ -81,7 +97,7 @@ if {[istarget "*-*-pe*"] \
|| [istarget "*-*-cygwin*"] \
|| [istarget "*-*-mingw32*"] \
|| [istarget "*-*-winnt*"] \
|| [istarget "*-*-nt*"] \
|| [istarget "*-*-nt"] \
|| [istarget "*-*-interix*"] } then {
set flags "--image-base 0"
}
@ -99,3 +115,13 @@ if ![ld_simple_link $ld tmpdir/script "$flags -c $srcdir/$subdir/scriptm.t"] {
} else {
check_script
}
set testname "MEMORY"
if ![ld_simple_link $ld tmpdir/script "$flags -T $srcdir/$subdir/memory.t tmpdir/script.o"] {
fail $testname
} else {
check_script
}