diff options
Diffstat (limited to 'gold')
-rw-r--r-- | gold/ChangeLog | 34 | ||||
-rw-r--r-- | gold/expression.cc | 61 | ||||
-rw-r--r-- | gold/script-c.h | 5 | ||||
-rw-r--r-- | gold/script-sections.cc | 47 | ||||
-rw-r--r-- | gold/script-sections.h | 13 | ||||
-rw-r--r-- | gold/script.cc | 8 | ||||
-rw-r--r-- | gold/testsuite/Makefile.am | 26 | ||||
-rw-r--r-- | gold/testsuite/Makefile.in | 29 | ||||
-rwxr-xr-x | gold/testsuite/script_test_6.sh | 43 | ||||
-rw-r--r-- | gold/testsuite/script_test_6.t | 41 | ||||
-rwxr-xr-x | gold/testsuite/script_test_7.sh | 43 | ||||
-rw-r--r-- | gold/testsuite/script_test_7.t | 41 | ||||
-rwxr-xr-x | gold/testsuite/script_test_8.sh | 44 | ||||
-rw-r--r-- | gold/yyscript.y | 4 |
14 files changed, 425 insertions, 14 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index a18cf54..6358191 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,39 @@ 2009-10-16 Doug Kwan <dougkwan@google.com> + * expression.cc (class Segment_start_expression): New class definition. + (Segment_start_expression::value): New method definition. + (script_exp_function_segment_start): Return a new + Segment_start_expression. + * gold/script-c.h (script_saw_segment_start_expression): New function + prototype. + * script-sections.cc (Script_sections::Script_sections): Initialize + SAW_SEGMENT_START_EXPRESSION_ to false. + (Script_sections::set_section_addresses): Use -Ttext, -Tdata + and -Tbbs options to specify section addresses if given in + command line and no SEGMENT_START expression is seen in a script. + * script-sections.h (Script_sections::saw_segment_start_expression, + Script_sections::set_saw_segment_start_expression): New method + definition. + (Script_sections::saw_segment_start_expression_): New data member + declaration. + * script.cc (script_saw_segment_start_expression): New function. + * yyscript.y (SEGMENT_START): Call script_saw_segment_start_expression. + * testsuite/Makefile.am (check_SCRIPTS): Add script_test_6.sh, + script_test_7.sh and script_test_8.sh. + (check_DATA): Add script_test_6.stdout, script_test_7.stdout and + script_test_8.stdout. + (MOSTLYCLEANFILES): Add script_test_6, script_test_7 and script_test_8. + (script_test_6, script_test_6.stdout, script_test_7, + script_test_7.stdout, script_test_8, script_test_8.stdout): New rules. + * Makefile.in: Regenerate. + * testsuite/script_test_6.sh: New file. + * testsuite/script_test_6.t: Same. + * testsuite/script_test_7.sh: Same. + * testsuite/script_test_7.t: Same. + * testsuite/script_test_8.sh: Same. + +2009-10-16 Doug Kwan <dougkwan@google.com> + * output.cc (Output_segment::set_section_list_address): Cast expressions to unsigned long long type to avoid format warnings. diff --git a/gold/expression.cc b/gold/expression.cc index 25f3ac3..853a698 100644 --- a/gold/expression.cc +++ b/gold/expression.cc @@ -1113,17 +1113,62 @@ script_exp_function_sizeof_headers() return new Sizeof_headers_expression(); } -// In the GNU linker SEGMENT_START basically returns the value for -// -Ttext, -Tdata, or -Tbss. We could implement this by copying the -// values from General_options to Parameters. But I doubt that -// anybody actually uses it. The point of it for the GNU linker was -// because -Ttext set the address of the .text section rather than the -// text segment. In gold -Ttext sets the text segment address anyhow. +// SEGMENT_START. + +class Segment_start_expression : public Unary_expression +{ + public: + Segment_start_expression(const char* segment_name, size_t segment_name_len, + Expression* default_value) + : Unary_expression(default_value), + segment_name_(segment_name, segment_name_len) + { } + + uint64_t + value(const Expression_eval_info*); + + void + print(FILE* f) const + { + fprintf(f, "SEGMENT_START(\"%s\", ", this->segment_name_.c_str()); + this->arg_print(f); + fprintf(f, ")"); + } + + private: + std::string segment_name_; +}; + +uint64_t +Segment_start_expression::value(const Expression_eval_info* eei) +{ + // Check for command line overrides. + if (parameters->options().user_set_Ttext() + && this->segment_name_ == ".text") + return parameters->options().Ttext(); + else if (parameters->options().user_set_Tdata() + && this->segment_name_ == ".data") + return parameters->options().Tdata(); + else if (parameters->options().user_set_Tbss() + && this->segment_name_ == ".bss") + return parameters->options().Tbss(); + else + { + Output_section* dummy; + uint64_t ret = this->arg_value(eei, &dummy); + // Force the value to be absolute. + *eei->result_section_pointer = NULL; + return ret; + } +} extern "C" Expression* -script_exp_function_segment_start(const char*, size_t, Expression*) +script_exp_function_segment_start(const char* segment_name, + size_t segment_name_len, + Expression* default_value) { - gold_fatal(_("SEGMENT_START not implemented")); + return new Segment_start_expression(segment_name, segment_name_len, + default_value); } // Functions for memory regions. These can not be implemented unless diff --git a/gold/script-c.h b/gold/script-c.h index 37016b0..a646bda 100644 --- a/gold/script-c.h +++ b/gold/script-c.h @@ -389,6 +389,11 @@ script_data_segment_align(void* closure); extern void script_data_segment_relro_end(void* closure); +/* Record the fact that a SEGMENT_START expression is seen. */ + +extern void +script_saw_segment_start_expression(void* closure); + /* Called by the bison parser for expressions. */ extern Expression_ptr diff --git a/gold/script-sections.cc b/gold/script-sections.cc index a541e9a..8fb9a73 100644 --- a/gold/script-sections.cc +++ b/gold/script-sections.cc @@ -2487,7 +2487,8 @@ Script_sections::Script_sections() orphan_section_placement_(NULL), data_segment_align_start_(), saw_data_segment_align_(false), - saw_relro_end_(false) + saw_relro_end_(false), + saw_segment_start_expression_(false) { } @@ -2850,10 +2851,52 @@ Script_sections::set_section_addresses(Symbol_table* symtab, Layout* layout) // For a relocatable link, we implicitly set dot to zero. uint64_t dot_value = 0; uint64_t load_address = 0; + + // Check to see if we want to use any of -Ttext, -Tdata and -Tbss options + // to set section addresses. If the script has any SEGMENT_START + // expression, we do not set the section addresses. + bool use_tsection_options = + (!this->saw_segment_start_expression_ + && (parameters->options().user_set_Ttext() + || parameters->options().user_set_Tdata() + || parameters->options().user_set_Tbss())); + for (Sections_elements::iterator p = this->sections_elements_->begin(); p != this->sections_elements_->end(); ++p) - (*p)->set_section_addresses(symtab, layout, &dot_value, &load_address); + { + Output_section* os = (*p)->get_output_section(); + + // Handle -Ttext, -Tdata and -Tbss options. We do this by looking for + // the special sections by names and doing dot assignments. + if (use_tsection_options + && os != NULL + && (os->flags() & elfcpp::SHF_ALLOC) != 0) + { + uint64_t new_dot_value = dot_value; + + if (parameters->options().user_set_Ttext() + && strcmp(os->name(), ".text") == 0) + new_dot_value = parameters->options().Ttext(); + else if (parameters->options().user_set_Tdata() + && strcmp(os->name(), ".data") == 0) + new_dot_value = parameters->options().Tdata(); + else if (parameters->options().user_set_Tbss() + && strcmp(os->name(), ".bss") == 0) + new_dot_value = parameters->options().Tbss(); + + // Update dot and load address if necessary. + if (new_dot_value < dot_value) + gold_error(_("dot may not move backward")); + else if (new_dot_value != dot_value) + { + dot_value = new_dot_value; + load_address = new_dot_value; + } + } + + (*p)->set_section_addresses(symtab, layout, &dot_value, &load_address); + } if (this->phdrs_elements_ != NULL) { diff --git a/gold/script-sections.h b/gold/script-sections.h index b326eae..c0d1d08 100644 --- a/gold/script-sections.h +++ b/gold/script-sections.h @@ -191,6 +191,17 @@ class Script_sections void release_segments(); + // Whether we ever saw a SEGMENT_START expression, the presence of which + // changes the behaviour of -Ttext, -Tdata and -Tbss options. + bool + saw_segment_start_expression() const + { return this->saw_segment_start_expression_; } + + // Set the flag which indicates whether we saw a SEGMENT_START expression. + void + set_saw_segment_start_expression(bool value) + { this->saw_segment_start_expression_ = value; } + // Print the contents to the FILE. This is for debugging. void print(FILE*) const; @@ -253,6 +264,8 @@ class Script_sections bool saw_data_segment_align_; // Whether we have seen DATA_SEGMENT_RELRO_END. bool saw_relro_end_; + // Whether we have seen SEGMENT_START. + bool saw_segment_start_expression_; }; } // End namespace gold. diff --git a/gold/script.cc b/gold/script.cc index d0ffe41..8839213 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -2739,3 +2739,11 @@ script_phdr_string_to_type(void* closurev, const char* name, size_t namelen) yyerror(closurev, _("unknown PHDR type (try integer)")); return elfcpp::PT_NULL; } + +extern "C" void +script_saw_segment_start_expression(void* closurev) +{ + Parser_closure* closure = static_cast<Parser_closure*>(closurev); + Script_sections* ss = closure->script_options()->script_sections(); + ss->set_saw_segment_start_expression(true); +} diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 09d7325..6fa1e18 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -1009,6 +1009,32 @@ script_test_5: script_test_5.o gcctestdir/ld $(srcdir)/script_test_5.t script_test_5.stdout: script_test_5 $(TEST_READELF) -SW script_test_5 > script_test_5.stdout +check_SCRIPTS += script_test_6.sh +check_DATA += script_test_6.stdout +MOSTLYCLEANFILES += script_test_6 +script_test_6: basic_test.o gcctestdir/ld $(srcdir)/script_test_6.t + $(CXXLINK) -Bgcctestdir/ basic_test.o -T $(srcdir)/script_test_6.t \ + -Wl,-Ttext=0x10001000 -Wl,-Tdata=0x10200000 -Wl,-Tbss=0x10400000 +script_test_6.stdout: script_test_6 + $(TEST_READELF) -SlW script_test_6 > script_test_6.stdout + +check_SCRIPTS += script_test_7.sh +check_DATA += script_test_7.stdout +MOSTLYCLEANFILES += script_test_7 +script_test_7: basic_test.o gcctestdir/ld $(srcdir)/script_test_7.t + $(CXXLINK) -Bgcctestdir/ basic_test.o -T $(srcdir)/script_test_7.t +script_test_7.stdout: script_test_7 + $(TEST_READELF) -SlW script_test_7 > script_test_7.stdout + +check_SCRIPTS += script_test_8.sh +check_DATA += script_test_8.stdout +MOSTLYCLEANFILES += script_test_8 +script_test_8: basic_test.o gcctestdir/ld $(srcdir)/script_test_7.t + $(CXXLINK) -Bgcctestdir/ basic_test.o -T $(srcdir)/script_test_7.t \ + -Wl,-Ttext=0x20001000 -Wl,-Tdata=0x20200000 -Wl,-Tbss=0x20400000 +script_test_8.stdout: script_test_8 + $(TEST_READELF) -SlW script_test_8 > script_test_8.stdout + # Test --dynamic-list, --dynamic-list-data, --dynamic-list-cpp-new, # and --dynamic-list-cpp-typeinfo diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 3f5459f..193888a 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -67,7 +67,10 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_matching_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_3.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_4.sh \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_5.sh dynamic_list.sh +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_5.sh \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_6.sh \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_7.sh \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_8.sh dynamic_list.sh # Create the data files that debug_msg.sh analyzes. @@ -92,6 +95,9 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_3.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_4.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_5.stdout \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_6.stdout \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_7.stdout \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_8.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list.stdout @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_3 = gc_comdat_test \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_tls_test icf_test \ @@ -242,9 +248,10 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_matching_test.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_3.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_4 script_test_5 \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list dynamic_list.stdout \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ libthin1.a libthin3.a \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ libthinall.a \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_6 script_test_7 \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_8 dynamic_list \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list.stdout libthin1.a \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ libthin3.a libthinall.a \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/thin_archive_test_2.o \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/thin_archive_test_4.o \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/libthin2.a alt/libthin4.a @@ -2972,6 +2979,20 @@ uninstall-am: @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ script_test_5.o -T $(srcdir)/script_test_5.t @GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_5.stdout: script_test_5 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -SW script_test_5 > script_test_5.stdout +@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_6: basic_test.o gcctestdir/ld $(srcdir)/script_test_6.t +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ basic_test.o -T $(srcdir)/script_test_6.t \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ -Wl,-Ttext=0x10001000 -Wl,-Tdata=0x10200000 -Wl,-Tbss=0x10400000 +@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_6.stdout: script_test_6 +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -SlW script_test_6 > script_test_6.stdout +@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_7: basic_test.o gcctestdir/ld $(srcdir)/script_test_7.t +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ basic_test.o -T $(srcdir)/script_test_7.t +@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_7.stdout: script_test_7 +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -SlW script_test_7 > script_test_7.stdout +@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_8: basic_test.o gcctestdir/ld $(srcdir)/script_test_7.t +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ basic_test.o -T $(srcdir)/script_test_7.t \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ -Wl,-Ttext=0x20001000 -Wl,-Tdata=0x20200000 -Wl,-Tbss=0x20400000 +@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_8.stdout: script_test_8 +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -SlW script_test_8 > script_test_8.stdout @GCC_TRUE@@NATIVE_LINKER_TRUE@dynamic_list: basic_test.o gcctestdir/ld $(srcdir)/dynamic_list.t @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ basic_test.o \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ -Wl,--dynamic-list $(srcdir)/dynamic_list.t \ diff --git a/gold/testsuite/script_test_6.sh b/gold/testsuite/script_test_6.sh new file mode 100755 index 0000000..bbc96d8 --- /dev/null +++ b/gold/testsuite/script_test_6.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +# script_test_6.sh -- test for -Ttext, -Tdata and -Tbss with a script. + +# Copyright 2009 Free Software Foundation, Inc. +# Written by Doug Kwan <dougkwan@google.com>. + +# This file is part of gold. + +# 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. + +# This file goes with script_test_4.t, which is a linker script which +# starts the program at an unaligned address. + +check() +{ + if ! grep -q "$2" "$1" + then + echo "Did not find expected section in $1:" + echo " $2" + echo "" + echo "Actual output below:" + cat "$1" + exit 1 + fi +} + +check script_test_6.stdout "\\.text[ ]*PROGBITS[ ]*0*10001000" +check script_test_6.stdout "\\.data[ ]*PROGBITS[ ]*0*10200000" +check script_test_6.stdout "\\.bss[ ]*NOBITS[ ]*0*10400000" diff --git a/gold/testsuite/script_test_6.t b/gold/testsuite/script_test_6.t new file mode 100644 index 0000000..9676371 --- /dev/null +++ b/gold/testsuite/script_test_6.t @@ -0,0 +1,41 @@ +/* script_test_5.t -- linker script test 5 for gold + + Copyright 2009 Free Software Foundation, Inc. + Written by Cary Coutant <ccoutant@google.com>. + + This file is part of gold. + + 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. */ + +/* We won't try to run this program, just ensure that it links + as expected. */ + +SECTIONS +{ + . = 0x10000000; + + /* With luck this will be enough to get the program working. */ + .interp : { *(.interp) } + .text : { *(.text .text.*) } + .rodata : { *(.rodata .rodata.*) } + . += 0x100000; + . = ALIGN(0x100); + .dynamic : { *(.dynamic) } + .data : { *(.data) } + . += 0x100000; + . = ALIGN(0x100); + .bss : { *(.bss) } +} diff --git a/gold/testsuite/script_test_7.sh b/gold/testsuite/script_test_7.sh new file mode 100755 index 0000000..982a1c1 --- /dev/null +++ b/gold/testsuite/script_test_7.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +# script_test_7.sh -- test for SEGMENT_START expressions. + +# Copyright 2009 Free Software Foundation, Inc. +# Written by Doug Kwan <dougkwan@google.com>. + +# This file is part of gold. + +# 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. + +# This file goes with script_test_4.t, which is a linker script which +# starts the program at an unaligned address. + +check() +{ + if ! grep -q "$2" "$1" + then + echo "Did not find expected section in $1:" + echo " $2" + echo "" + echo "Actual output below:" + cat "$1" + exit 1 + fi +} + +check script_test_7.stdout "\\.interp[ ]*PROGBITS[ ]*0*10000100" +check script_test_7.stdout "\\.data[ ]*PROGBITS[ ]*0*10200000" +check script_test_7.stdout "\\.bss[ ]*NOBITS[ ]*0*10400..." diff --git a/gold/testsuite/script_test_7.t b/gold/testsuite/script_test_7.t new file mode 100644 index 0000000..a4c4973 --- /dev/null +++ b/gold/testsuite/script_test_7.t @@ -0,0 +1,41 @@ +/* script_test_5.t -- linker script test 5 for gold + + Copyright 2009 Free Software Foundation, Inc. + Written by Cary Coutant <ccoutant@google.com>. + + This file is part of gold. + + 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. */ + +/* We won't try to run this program, just ensure that it links + as expected. */ + +SECTIONS +{ + . = SEGMENT_START(".text", 0x10000100); + + /* With luck this will be enough to get the program working. */ + .interp : { *(.interp) } + .text : { *(.text .text.*) } + .rodata : { *(.rodata .rodata.*) } + .dynamic : { *(.dynamic) } + + . = SEGMENT_START(".data", 0x10200000); + .data : { *(.data) } + + . = SEGMENT_START(".bss", 0x10400000); + .bss : { *(.bss) } +} diff --git a/gold/testsuite/script_test_8.sh b/gold/testsuite/script_test_8.sh new file mode 100755 index 0000000..83e8e72 --- /dev/null +++ b/gold/testsuite/script_test_8.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# script_test_8.sh -- test for SEGMENT_START expressions with +# -Ttext, -Tdata and -Tbss in a script. + +# Copyright 2009 Free Software Foundation, Inc. +# Written by Doug Kwan <dougkwan@google.com>. + +# This file is part of gold. + +# 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. + +# This file goes with script_test_4.t, which is a linker script which +# starts the program at an unaligned address. + +check() +{ + if ! grep -q "$2" "$1" + then + echo "Did not find expected section in $1:" + echo " $2" + echo "" + echo "Actual output below:" + cat "$1" + exit 1 + fi +} + +check script_test_8.stdout "\\.interp[ ]*PROGBITS[ ]*0*20001000" +check script_test_8.stdout "\\.data[ ]*PROGBITS[ ]*0*20200000" +check script_test_8.stdout "\\.bss[ ]*NOBITS[ ]*0*2040...." diff --git a/gold/yyscript.y b/gold/yyscript.y index 0d52882..81c136a 100644 --- a/gold/yyscript.y +++ b/gold/yyscript.y @@ -861,6 +861,10 @@ exp: | SEGMENT_START '(' string ',' exp ')' { $$ = script_exp_function_segment_start($3.value, $3.length, $5); + /* We need to take note of any SEGMENT_START expressions + because they change the behaviour of -Ttext, -Tdata and + -Tbss options. */ + script_saw_segment_start_expression(closure); } | ASSERT_K '(' exp ',' string ')' { $$ = script_exp_function_assert($3, $5.value, $5.length); } |