diff options
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 9 | ||||
-rw-r--r-- | ld/NEWS | 3 | ||||
-rw-r--r-- | ld/ld.texinfo | 18 | ||||
-rw-r--r-- | ld/ldexp.c | 54 | ||||
-rw-r--r-- | ld/ldgram.y | 102 | ||||
-rw-r--r-- | ld/ldlex.l | 96 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/memory.t | 39 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/script.exp | 110 |
9 files changed, 287 insertions, 152 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 68292f5..85ed0cf 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -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 @@ -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 diff --git a/ld/ld.texinfo b/ld/ld.texinfo index e2a971b..ab78ece 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -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 @@ -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; diff --git a/ld/ldgram.y b/ld/ldgram.y index 13e4ca6..49f274d 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -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); } ; @@ -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); } diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index ee6081d..c54dd11 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -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 index 0000000..8a73c58 --- /dev/null +++ b/ld/testsuite/ld-scripts/memory.t @@ -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); +} diff --git a/ld/testsuite/ld-scripts/script.exp b/ld/testsuite/ld-scripts/script.exp index 96cf04b..866d128 100644 --- a/ld/testsuite/ld-scripts/script.exp +++ b/ld/testsuite/ld-scripts/script.exp @@ -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 +} + + |