From 3ec5763260bc86f8b87d3ad985336665120edf0b Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 19 Nov 2004 09:31:55 +0000 Subject: [PATCH] Add ORIGIN and LENGTH linker script operators. --- ld/ChangeLog | 9 +++ ld/NEWS | 3 + ld/ld.texinfo | 18 ++++++ ld/ldexp.c | 54 +++++++++++++----- ld/ldgram.y | 102 +++++++++++++++++----------------- ld/ldlex.l | 96 ++++++++++++++++---------------- ld/testsuite/ChangeLog | 8 +++ ld/testsuite/ld-scripts/memory.t | 39 +++++++++++++ ld/testsuite/ld-scripts/script.exp | 110 +++++++++++++++++++++++-------------- 9 files changed, 287 insertions(+), 152 deletions(-) create mode 100644 ld/testsuite/ld-scripts/memory.t 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 + + * 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 * emultempl/armelf.em (arm_elf_set_bfd_for_interworking): Don't use diff --git a/ld/NEWS b/ld/NEWS index 8196f44..42a0e09 100644 --- 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 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 diff --git a/ld/ldexp.c b/ld/ldexp.c index 103b615..ebf988e 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -4,22 +4,22 @@ Free Software Foundation, Inc. Written by Steve Chamberlain of Cygnus Support . -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); } ; diff --git a/ld/ldlex.l b/ld/ldlex.l index 0ace6ec..d49c085 100644 --- a/ld/ldlex.l +++ b/ld/ldlex.l @@ -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\[\]\-\!\^\\]|::)* "/" { RTOKEN('/');} "%" { RTOKEN('%');} "<" { RTOKEN('<');} -"=" { RTOKEN('=');} -"}" { RTOKEN('}') ; } -"{" { RTOKEN('{'); } -")" { RTOKEN(')');} -"(" { RTOKEN('(');} +"=" { RTOKEN('=');} +"}" { RTOKEN('}') ; } +"{" { RTOKEN('{'); } +")" { RTOKEN(')');} +"(" { RTOKEN('(');} ":" { RTOKEN(':'); } ";" { RTOKEN(';');} -"MEMORY" { RTOKEN(MEMORY);} -"ORIGIN" { RTOKEN(ORIGIN);} -"VERSION" { RTOKEN(VERSIONK);} +"MEMORY" { RTOKEN(MEMORY);} +"ORIGIN" { RTOKEN(ORIGIN);} +"VERSION" { RTOKEN(VERSIONK);} "BLOCK" { RTOKEN(BLOCK);} "BIND" { RTOKEN(BIND);} -"LENGTH" { RTOKEN(LENGTH);} -"ALIGN" { RTOKEN(ALIGN_K);} +"LENGTH" { RTOKEN(LENGTH);} +"ALIGN" { RTOKEN(ALIGN_K);} "DATA_SEGMENT_ALIGN" { RTOKEN(DATA_SEGMENT_ALIGN);} "DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END);} "DATA_SEGMENT_END" { RTOKEN(DATA_SEGMENT_END);} -"ADDR" { RTOKEN(ADDR);} -"LOADADDR" { RTOKEN(LOADADDR);} +"ADDR" { RTOKEN(ADDR);} +"LOADADDR" { RTOKEN(LOADADDR);} "MAX" { RTOKEN(MAX_K); } "MIN" { RTOKEN(MIN_K); } "ASSERT" { RTOKEN(ASSERT_K); } "ENTRY" { RTOKEN(ENTRY);} "EXTERN" { RTOKEN(EXTERN);} -"NEXT" { RTOKEN(NEXT);} +"NEXT" { RTOKEN(NEXT);} "sizeof_headers" { RTOKEN(SIZEOF_HEADERS);} "SIZEOF_HEADERS" { RTOKEN(SIZEOF_HEADERS);} "SEGMENT_START" { RTOKEN(SEGMENT_START);} "MAP" { RTOKEN(MAP);} -"SIZEOF" { RTOKEN(SIZEOF);} -"TARGET" { RTOKEN(TARGET_K);} +"SIZEOF" { RTOKEN(SIZEOF);} +"TARGET" { RTOKEN(TARGET_K);} "SEARCH_DIR" { RTOKEN(SEARCH_DIR);} -"OUTPUT" { RTOKEN(OUTPUT);} +"OUTPUT" { RTOKEN(OUTPUT);} "INPUT" { RTOKEN(INPUT);} "GROUP" { RTOKEN(GROUP);} -"DEFINED" { RTOKEN(DEFINED);} +"DEFINED" { RTOKEN(DEFINED);} "CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);} "CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);} -"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION);} +"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION);} "INHIBIT_COMMON_ALLOCATION" { RTOKEN(INHIBIT_COMMON_ALLOCATION);} -"SECTIONS" { RTOKEN(SECTIONS);} +"SECTIONS" { RTOKEN(SECTIONS);} "FILL" { RTOKEN(FILL);} -"STARTUP" { RTOKEN(STARTUP);} +"STARTUP" { RTOKEN(STARTUP);} "OUTPUT_FORMAT" { RTOKEN(OUTPUT_FORMAT);} "OUTPUT_ARCH" { RTOKEN( OUTPUT_ARCH);} "HLL" { RTOKEN(HLL);} -"SYSLIB" { RTOKEN(SYSLIB);} +"SYSLIB" { RTOKEN(SYSLIB);} "FLOAT" { RTOKEN(FLOAT);} "QUAD" { RTOKEN( QUAD);} "SQUAD" { RTOKEN( SQUAD);} "LONG" { RTOKEN( LONG);} "SHORT" { RTOKEN( SHORT);} "BYTE" { RTOKEN( BYTE);} -"NOFLOAT" { RTOKEN(NOFLOAT);} +"NOFLOAT" { RTOKEN(NOFLOAT);} "NOCROSSREFS" { RTOKEN(NOCROSSREFS);} "OVERLAY" { RTOKEN(OVERLAY); } "SORT_BY_NAME" { RTOKEN(SORT_BY_NAME); } @@ -306,22 +306,22 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* "len" { RTOKEN( LENGTH);} "INCLUDE" { RTOKEN(INCLUDE);} "PHDRS" { RTOKEN (PHDRS); } -"AT" { RTOKEN(AT);} -"SUBALIGN" { RTOKEN(SUBALIGN);} -"PROVIDE" { RTOKEN(PROVIDE); } +"AT" { RTOKEN(AT);} +"SUBALIGN" { RTOKEN(SUBALIGN);} +"PROVIDE" { RTOKEN(PROVIDE); } "KEEP" { RTOKEN(KEEP); } -"EXCLUDE_FILE" { RTOKEN(EXCLUDE_FILE); } +"EXCLUDE_FILE" { RTOKEN(EXCLUDE_FILE); } "#".*\n? { ++ lineno; } "\n" { ++ lineno; RTOKEN(NEWLINE); } "*".* { /* Mri comment line */ } ";".* { /* Mri comment line */ } "END" { RTOKEN(ENDWORD); } -"ALIGNMOD" { RTOKEN(ALIGNMOD);} -"ALIGN" { RTOKEN(ALIGN_K);} +"ALIGNMOD" { RTOKEN(ALIGNMOD);} +"ALIGN" { RTOKEN(ALIGN_K);} "CHIP" { RTOKEN(CHIP); } "BASE" { RTOKEN(BASE); } -"ALIAS" { RTOKEN(ALIAS); } -"TRUNCATE" { RTOKEN(TRUNCATE); } +"ALIAS" { RTOKEN(ALIAS); } +"TRUNCATE" { RTOKEN(TRUNCATE); } "LOAD" { RTOKEN(LOAD); } "PUBLIC" { RTOKEN(PUBLIC); } "ORDER" { RTOKEN(ORDER); } @@ -333,12 +333,12 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* "SECT" { RTOKEN(SECT); } "ABSOLUTE" { RTOKEN(ABSOLUTE); } "end" { RTOKEN(ENDWORD); } -"alignmod" { RTOKEN(ALIGNMOD);} -"align" { RTOKEN(ALIGN_K);} +"alignmod" { RTOKEN(ALIGNMOD);} +"align" { RTOKEN(ALIGN_K);} "chip" { RTOKEN(CHIP); } "base" { RTOKEN(BASE); } -"alias" { RTOKEN(ALIAS); } -"truncate" { RTOKEN(TRUNCATE); } +"alias" { RTOKEN(ALIAS); } +"truncate" { RTOKEN(TRUNCATE); } "load" { RTOKEN(LOAD); } "public" { RTOKEN(PUBLIC); } "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 + + * 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 * 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 +} + + -- 2.7.4