Index: ld/ChangeLog =================================================================== RCS file: /cvs/src/src/ld/ChangeLog,v retrieving revision 1.2076 diff -u -p -r1.2076 ChangeLog --- ld/ChangeLog 6 Nov 2009 16:50:59 -0000 1.2076 +++ ld/ChangeLog 10 Nov 2009 13:34:43 -0000 @@ -1,3 +1,11 @@ +2009-11-10 David Stubbs + + * ldlex.l: New ALIGNTOATLEAST linker script directive. + * ldexp.c (fold_binary, aligntoatleast_n): Likewise. + * ldgram.y: Likewise. + * ld.texinfo (Builtin Functions): Documented new ALIGNTOATLEAST + linker script directive. + 2009-11-06 H.J. Lu PR ld/10912 Index: ld/ld.texinfo =================================================================== RCS file: /cvs/src/src/ld/ld.texinfo,v retrieving revision 1.253 diff -u -p -r1.253 ld.texinfo --- ld/ld.texinfo 5 Nov 2009 15:35:50 -0000 1.253 +++ ld/ld.texinfo 10 Nov 2009 13:34:43 -0000 @@ -5499,6 +5499,28 @@ SECTIONS @{ @dots{} @end group @end smallexample +@item ALIGNTOATLEAST(@var{address},@var{align}) +@kindex ALIGNTOATLEAST(@var{address},@var{align}) +If the absolute location counter (@var{.}) is less than @var{address}, then +returns @var{address} aligned to the next @var{align} boundary. + +If the absolute location counter (@var{.}) is greater than @var{address}, +then returns the absolute location counter (@var{.}) aligned to the next +@var{align} boundary. + +Here is an example which aligns the start of the output @code{.dmem} +section to at least the address @code{0x40000000 + 256k}, aligned to the +next @code{4} byte boundary. + +@smallexample +SECTIONS @{ @dots{} + .dmem 0x40000000: @{ + *(.dmem) + . = ALIGNTOATLEAST(0x40000000 + 256K, 4); + @} +@dots{} @} +@end smallexample + @item ALIGN(@var{align}) @itemx ALIGN(@var{exp},@var{align}) @kindex ALIGN(@var{align}) Index: ld/ldexp.c =================================================================== RCS file: /cvs/src/src/ld/ldexp.c,v retrieving revision 1.80 diff -u -p -r1.80 ldexp.c --- ld/ldexp.c 11 Sep 2009 15:27:35 -0000 1.80 +++ ld/ldexp.c 10 Nov 2009 13:34:43 -0000 @@ -46,6 +46,7 @@ static void exp_fold_tree_1 (etree_type *); static void exp_fold_tree_no_dot (etree_type *); static bfd_vma align_n (bfd_vma, bfd_vma); +static bfd_vma aligntoatleast_n (bfd_vma, bfd_vma, bfd_vma); segment_type *segments; @@ -396,6 +397,13 @@ fold_binary (etree_type *tree) expld.result.value = align_n (lhs.value, expld.result.value); break; + case ALIGNTOATLEAST_K: + if (expld.phase != lang_first_phase_enum) + new_rel_from_abs (aligntoatleast_n (expld.dot, lhs.value, expld.result.value)); + else + expld.result.valid_p = FALSE; + break; + case DATA_SEGMENT_ALIGN: expld.dataseg.relro = exp_dataseg_relro_start; if (expld.phase != lang_first_phase_enum @@ -1161,3 +1169,12 @@ align_n (bfd_vma value, bfd_vma align) value = (value + align - 1) / align; return value * align; } + +static bfd_vma +aligntoatleast_n (bfd_vma value, bfd_vma min, bfd_vma align) +{ + if (min > value) + value = min; + + return align_n (value, align); +} Index: ld/ldgram.y =================================================================== RCS file: /cvs/src/src/ld/ldgram.y,v retrieving revision 1.61 diff -u -p -r1.61 ldgram.y --- ld/ldgram.y 5 Nov 2009 15:35:50 -0000 1.61 +++ ld/ldgram.y 10 Nov 2009 13:34:43 -0000 @@ -122,7 +122,7 @@ static int error_index; %right UNARY %token END %left '(' -%token ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE +%token ALIGN_K ALIGNTOATLEAST_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE %token SECTIONS PHDRS INSERT_K AFTER BEFORE %token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END %token SORT_BY_NAME SORT_BY_ALIGNMENT @@ -870,6 +870,8 @@ exp : { $$ = exp_unop (ALIGN_K,$3); } | ALIGN_K '(' exp ',' exp ')' { $$ = exp_binop (ALIGN_K,$3,$5); } + | ALIGNTOATLEAST_K '(' exp ',' exp ')' + { $$ = exp_binop (ALIGNTOATLEAST_K,$3,$5); } | DATA_SEGMENT_ALIGN '(' exp ',' exp ')' { $$ = exp_binop (DATA_SEGMENT_ALIGN, $3, $5); } | DATA_SEGMENT_RELRO_END '(' exp ',' exp ')' Index: ld/ldlex.l =================================================================== RCS file: /cvs/src/src/ld/ldlex.l,v retrieving revision 1.44 diff -u -p -r1.44 ldlex.l --- ld/ldlex.l 14 Oct 2009 10:54:27 -0000 1.44 +++ ld/ldlex.l 10 Nov 2009 13:34:44 -0000 @@ -246,6 +246,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([ "BIND" { RTOKEN(BIND);} "LENGTH" { RTOKEN(LENGTH);} "ALIGN" { RTOKEN(ALIGN_K);} +"ALIGNTOATLEAST" { RTOKEN(ALIGNTOATLEAST_K);} "DATA_SEGMENT_ALIGN" { RTOKEN(DATA_SEGMENT_ALIGN);} "DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END);} "DATA_SEGMENT_END" { RTOKEN(DATA_SEGMENT_END);} Index: ld/testsuite/ChangeLog =================================================================== RCS file: /cvs/src/src/ld/testsuite/ChangeLog,v retrieving revision 1.1191 diff -u -p -r1.1191 ChangeLog --- ld/testsuite/ChangeLog 9 Nov 2009 14:37:16 -0000 1.1191 +++ ld/testsuite/ChangeLog 10 Nov 2009 13:34:44 -0000 @@ -1,3 +1,9 @@ +2009-11-10 David Stubbs + + * ld-scripts/aligntoatleast.exp: New test. + * ld-scripts/aligntoatleast.t: Likewise. + * ld-scripts/aligntoatleast.s: Likewise + 2009-11-09 H.J. Lu PR ld/10911 Index: ld/testsuite/ld-scripts/aligntoatleast.exp =================================================================== RCS file: ld/testsuite/ld-scripts/aligntoatleast.exp diff -N ld/testsuite/ld-scripts/aligntoatleast.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-scripts/aligntoatleast.exp 10 Nov 2009 13:34:45 -0000 @@ -0,0 +1,41 @@ +# Test ALIGNTOATLEAST directive +# By David Stubbs, Icera Semiconductor Inc. +# Copyright 2009 +# Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# 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 3 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. +# +# 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., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA + +set testname "ALIGNTOATLEAST" + +# This test only works for ELF targets. +if {! [is_elf_format] } { + unsupported $testname + return +} + +if ![ld_assemble $as $srcdir/$subdir/aligntoatleast.s tmpdir/aligntoatleast.o] { + unresolved $testname + return +} + +if ![ld_simple_link $ld tmpdir/aligntoatleast "$LDFLAGS -T $srcdir/$subdir/aligntoatleast.t tmpdir/aligntoatleast.o"] { + fail $testname +} else { + pass $testname +} + Index: ld/testsuite/ld-scripts/aligntoatleast.s =================================================================== RCS file: ld/testsuite/ld-scripts/aligntoatleast.s diff -N ld/testsuite/ld-scripts/aligntoatleast.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-scripts/aligntoatleast.s 10 Nov 2009 13:34:45 -0000 @@ -0,0 +1,2 @@ + .text + .long 0 Index: ld/testsuite/ld-scripts/aligntoatleast.t =================================================================== RCS file: ld/testsuite/ld-scripts/aligntoatleast.t diff -N ld/testsuite/ld-scripts/aligntoatleast.t --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ld/testsuite/ld-scripts/aligntoatleast.t 10 Nov 2009 13:34:45 -0000 @@ -0,0 +1,21 @@ +SECTIONS +{ + .text 0x10000000: + { + aligntoatleast_start = .; + . = ALIGNTOATLEAST(0x10000000 + 256k, 4); + aligntoatleast_moved_on = .; + + BYTE(0x0); + . = ALIGNTOATLEAST(0x10000000 + 256k, 4); + aligntoatleast_not_moved_on = .; + } + + ASSERT ((aligntoatleast_start == 0x10000000), "ALIGNTOATLEAST test error") + ASSERT (aligntoatleast_moved_on == 0x10040000, "ALIGNTOATLEAST force minimum address error") + ASSERT (aligntoatleast_not_moved_on == 0x10040004, "ALIGNTOATLEAST minumum address ok error") + +} + + +