Add ORIGIN and LENGTH linker script operators.
authorNick Clifton <nickc@redhat.com>
Fri, 19 Nov 2004 09:31:55 +0000 (09:31 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 19 Nov 2004 09:31:55 +0000 (09:31 +0000)
ld/ChangeLog
ld/NEWS
ld/ld.texinfo
ld/ldexp.c
ld/ldgram.y
ld/ldlex.l
ld/testsuite/ChangeLog
ld/testsuite/ld-scripts/memory.t [new file with mode: 0644]
ld/testsuite/ld-scripts/script.exp

index 68292f5..85ed0cf 100644 (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
diff --git a/ld/NEWS b/ld/NEWS
index 8196f44..42a0e09 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -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
index e2a971b..ab78ece 100644 (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
index 103b615..ebf988e 100644 (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;
index 13e4ca6..49f274d 100644 (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); }
        ;
 
 
index 0ace6ec..d49c085 100644 (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); }
index ee6081d..c54dd11 100644 (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,
diff --git a/ld/testsuite/ld-scripts/memory.t b/ld/testsuite/ld-scripts/memory.t
new file mode 100644 (file)
index 0000000..8a73c58
--- /dev/null
@@ -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);  
+}
index 96cf04b..866d128 100644 (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
+}
+
+