From: Nick Clifton Date: Fri, 19 Jul 2013 10:39:51 +0000 (+0000) Subject: * ldgram.y: Add ALIGN_WITH_INPUT output section attribute. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1eec346e1275ed5aa982486f5a0d4ea4c21afe15;p=binutils-gdb.git * ldgram.y: Add ALIGN_WITH_INPUT output section attribute. * ldlang.c: Likewise. * ldlang.h: Likewise. * ldlex.l: Likewise. * mri.c: Likewise. * ld.texinfo: Document new feature. * NEWS: Mention new feature. * ld-scripts/script.exp: Run align with input test. * ld-scripts/align-with-input.t: New file. * ld-scripts/rgn-at8.d: Likewise. * ld-scripts/rgn-at8.t: Likewise. --- diff --git a/ld/ChangeLog b/ld/ChangeLog index f5671b4e99e..4af9fca38d2 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,13 @@ +2013-07-19 Sebastian Huber + + * ldgram.y: Add ALIGN_WITH_INPUT output section attribute. + * ldlang.c: Likewise. + * ldlang.h: Likewise. + * ldlex.l: Likewise. + * mri.c: Likewise. + * ld.texinfo: Document new feature. + * NEWS: Mention new feature. + 2013-07-18 Roland McGrath * emultempl/armelf.em (elf32_arm_add_stub_section): Take third diff --git a/ld/NEWS b/ld/NEWS index 34b494afb6f..d79c78fae6c 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -12,6 +12,9 @@ * Remove linker support for MIPS ECOFF targets. +* Add ALIGN_WITH_INPUT to the linker script language to force the alignment of + an output section to use the maximum alignment of all its input sections. + Changes in 2.23: * Enable compressed debug section feature for x86/x86_64 pe-coff. diff --git a/ld/ld.texinfo b/ld/ld.texinfo index d783ca99592..986194bbc1f 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -3762,7 +3762,7 @@ The full description of an output section looks like this: @group @var{section} [@var{address}] [(@var{type})] : [AT(@var{lma})] - [ALIGN(@var{section_align})] + [ALIGN(@var{section_align}) | ALIGN_WITH_INPUT] [SUBALIGN(@var{subsection_align})] [@var{constraint}] @{ @@ -4585,7 +4585,11 @@ for (dst = &_bstart; dst< &_bend; dst++) @kindex ALIGN(@var{section_align}) @cindex forcing output section alignment @cindex output section alignment -You can increase an output section's alignment by using ALIGN. +You can increase an output section's alignment by using ALIGN. As an +alternative you can force the output section alignment to the maximum alignment +of all its input sections with ALIGN_WITH_INPUT. The alignment forced by +ALIGN_WITH_INPUT is used even in case the load and virtual memory regions are +different. @node Forced Input Alignment @subsubsection Forced Input Alignment diff --git a/ld/ldgram.y b/ld/ldgram.y index ee8819660c2..26cb6772995 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -1,7 +1,5 @@ /* 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, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 - Free Software Foundation, Inc. + Copyright 1991-2013 Free Software Foundation, Inc. Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com). This file is part of the GNU Binutils. @@ -147,14 +145,14 @@ static int error_index; %token ORIGIN FILL %token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS %token ALIGNMOD AT SUBALIGN HIDDEN PROVIDE PROVIDE_HIDDEN AS_NEEDED -%type assign_op atype attributes_opt sect_constraint +%type assign_op atype attributes_opt sect_constraint opt_align_with_input %type filename %token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K %token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START %token VERS_TAG VERS_IDENTIFIER %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT -%token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL INPUT_SECTION_FLAGS +%token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL INPUT_SECTION_FLAGS ALIGN_WITH_INPUT %token EXCLUDE_FILE %token CONSTANT %type vers_defns @@ -1030,6 +1028,11 @@ opt_align: | { $$ = 0; } ; +opt_align_with_input: + ALIGN_WITH_INPUT { $$ = ALIGN_WITH_INPUT; } + | { $$ = 0; } + ; + opt_subalign: SUBALIGN '(' exp ')' { $$ = $3; } | { $$ = 0; } @@ -1046,20 +1049,21 @@ section: NAME { ldlex_expression(); } opt_exp_with_type opt_at opt_align + opt_align_with_input opt_subalign { ldlex_popstate (); ldlex_script (); } sect_constraint '{' { lang_enter_output_section_statement($1, $3, sectype, - $5, $6, $4, $8); + $5, $7, $4, $9, $6); } statement_list_opt '}' { ldlex_popstate (); ldlex_expression (); } memspec_opt memspec_at_opt phdr_opt fill_opt { ldlex_popstate (); - lang_leave_output_section_statement ($17, $14, $16, $15); + lang_leave_output_section_statement ($18, $15, $17, $16); } opt_comma {} diff --git a/ld/ldlang.c b/ld/ldlang.c index 645c26c1511..ba7f493bee1 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1,7 +1,5 @@ /* Linker command language support. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 - Free Software Foundation, Inc. + Copyright 1991-2013 Free Software Foundation, Inc. This file is part of the GNU Binutils. @@ -1779,7 +1777,7 @@ lang_insert_orphan (asection *s, os_tail = ((lang_output_section_statement_type **) lang_output_section_statement.tail); os = lang_enter_output_section_statement (secname, address, normal_section, - NULL, NULL, NULL, constraint); + NULL, NULL, NULL, constraint, 0); ps = NULL; if (config.build_constructors && *os_tail == os) @@ -4967,8 +4965,8 @@ lang_size_sections_1 as we did for the VMA, possibly including alignment from the bfd section. If a different region, then only align according to the value in the output - statement. */ - if (os->lma_region != os->region) + statement unless specified otherwise. */ + if (os->lma_region != os->region && !os->align_lma_with_input) section_alignment = os->section_alignment; if (section_alignment > 0) lma = align_power (lma, section_alignment); @@ -6235,7 +6233,8 @@ lang_enter_output_section_statement (const char *output_section_statement_name, etree_type *align, etree_type *subalign, etree_type *ebase, - int constraint) + int constraint, + int align_with_input) { lang_output_section_statement_type *os; @@ -6257,6 +6256,10 @@ lang_enter_output_section_statement (const char *output_section_statement_name, /* Make next things chain into subchain of this. */ push_stat_ptr (&os->children); + os->align_lma_with_input = align_with_input == ALIGN_WITH_INPUT; + if (os->align_lma_with_input && align != NULL) + einfo (_("%F%P:%S: error: align with input and explicit align specified\n"), NULL); + os->subsection_alignment = topower (exp_get_value_int (subalign, -1, "subsection alignment")); os->section_alignment = @@ -7307,7 +7310,7 @@ lang_enter_overlay_section (const char *name) etree_type *size; lang_enter_output_section_statement (name, overlay_vma, overlay_section, - 0, overlay_subalign, 0, 0); + 0, overlay_subalign, 0, 0, 0); /* If this is the first section, then base the VMA of future sections on this one. This will work correctly even if `.' is diff --git a/ld/ldlang.h b/ld/ldlang.h index 00e37578d5b..2dbec5a413b 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -1,7 +1,5 @@ /* ldlang.h - linker command language support - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 - Free Software Foundation, Inc. + Copyright 1991-2013 Free Software Foundation, Inc. This file is part of the GNU Binutils. @@ -167,6 +165,8 @@ typedef struct lang_output_section_statement_struct unsigned int update_dot : 1; /* If this section is after assignment to _end. */ unsigned int after_end : 1; + /* If this section uses the alignment of its input sections. */ + unsigned int align_lma_with_input : 1; } lang_output_section_statement_type; typedef struct @@ -502,12 +502,8 @@ extern void lang_set_flags extern void lang_add_output (const char *, int from_script); extern lang_output_section_statement_type *lang_enter_output_section_statement - (const char *output_section_statement_name, - etree_type *address_exp, - enum section_type sectype, - etree_type *align, - etree_type *subalign, - etree_type *, int); + (const char *, etree_type *, enum section_type, etree_type *, etree_type *, + etree_type *, int, int); extern void lang_final (void); extern void lang_relax_sections diff --git a/ld/ldlex.l b/ld/ldlex.l index abe31c01f50..75be86d7de1 100644 --- a/ld/ldlex.l +++ b/ld/ldlex.l @@ -2,9 +2,7 @@ %{ -/* Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 - Free Software Foundation, Inc. +/* Copyright 1991-2013 Free Software Foundation, Inc. Written by Steve Chamberlain of Cygnus Support. This file is part of the GNU Binutils. @@ -319,6 +317,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* "INCLUDE" { RTOKEN(INCLUDE);} "PHDRS" { RTOKEN (PHDRS); } "AT" { RTOKEN(AT);} +"ALIGN_WITH_INPUT" { RTOKEN(ALIGN_WITH_INPUT);} "SUBALIGN" { RTOKEN(SUBALIGN);} "HIDDEN" { RTOKEN(HIDDEN); } "PROVIDE" { RTOKEN(PROVIDE); } diff --git a/ld/mri.c b/ld/mri.c index fc7076af8ec..450cdf73ab4 100644 --- a/ld/mri.c +++ b/ld/mri.c @@ -208,7 +208,7 @@ mri_draw_tree (void) lang_enter_output_section_statement (p->name, base, p->ok_to_load ? normal_section : noload_section, - align, subalign, NULL, 0); + align, subalign, NULL, 0, 0); base = 0; tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); tmp->next = NULL; diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 9eeb006c8cc..ddb5bc37246 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2013-07-19 Sebastian Huber + + * ld-scripts/script.exp: Run align with input test. + * ld-scripts/align-with-input.t: New file. + * ld-scripts/rgn-at8.d: Likewise. + * ld-scripts/rgn-at8.t: Likewise. + 2013-07-18 Terry Guo * ld-arm/thumb-b-lks-sym.d: Updated to be more flexible. diff --git a/ld/testsuite/ld-scripts/align-with-input.t b/ld/testsuite/ld-scripts/align-with-input.t new file mode 100644 index 00000000000..616061c81ce --- /dev/null +++ b/ld/testsuite/ld-scripts/align-with-input.t @@ -0,0 +1,5 @@ +SECTIONS { + .abc : ALIGN(1) ALIGN_WITH_INPUT { + *(.abc) + } +} diff --git a/ld/testsuite/ld-scripts/rgn-at8.d b/ld/testsuite/ld-scripts/rgn-at8.d new file mode 100644 index 00000000000..c9d63506049 --- /dev/null +++ b/ld/testsuite/ld-scripts/rgn-at8.d @@ -0,0 +1,9 @@ +#source: rgn-at6.s +#ld: -T rgn-at8.t +#objdump: -h --wide +#xfail: rx-*-* +# Test that lma is aligned when lma_region!=region and requested by script. + +#... +.* 0+10000 +0+20000 .* +.* 0+10100 +0+20100 .* diff --git a/ld/testsuite/ld-scripts/script.exp b/ld/testsuite/ld-scripts/script.exp index 267c0be7278..cc099a9d87f 100644 --- a/ld/testsuite/ld-scripts/script.exp +++ b/ld/testsuite/ld-scripts/script.exp @@ -1,7 +1,6 @@ # Test basic linker script functionality # By Ian Lance Taylor, Cygnus Support -# Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2009, 2010 -# Free Software Foundation, Inc. +# Copyright 1999-2013 Free Software Foundation, Inc. # # This file is part of the GNU Binutils. # @@ -137,3 +136,11 @@ foreach test_script $test_script_list { xpass "REGION_ALIAS: $testname" } } + +set testname "ALIGN_WITH_INPUT" + +if ![ld_simple_link $ld tmpdir/script "$flags -T $srcdir/$subdir/align-with-input.t tmpdir/script.o"] { + xfail $testname +} else { + xpass $testname +}