Add ORIGIN and LENGTH linker script operators.
This commit is contained in:
parent
288f74fae9
commit
3ec5763260
|
@ -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
|
||||
|
|
3
ld/NEWS
3
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
|
||||
|
|
|
@ -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
|
||||
|
|
54
ld/ldexp.c
54
ld/ldexp.c
|
@ -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;
|
||||
|
|
102
ld/ldgram.y
102
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); }
|
||||
;
|
||||
|
||||
|
||||
|
|
96
ld/ldlex.l
96
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\[\]\-\!\^\\]|::)*
|
|||
<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); }
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue