2009-10-16 Doug Kwan <dougkwan@google.com>
authorDoug Kwan <dougkwan@google.com>
Fri, 16 Oct 2009 18:56:07 +0000 (18:56 +0000)
committerDoug Kwan <dougkwan@google.com>
Fri, 16 Oct 2009 18:56:07 +0000 (18:56 +0000)
* 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.

14 files changed:
gold/ChangeLog
gold/expression.cc
gold/script-c.h
gold/script-sections.cc
gold/script-sections.h
gold/script.cc
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/script_test_6.sh [new file with mode: 0755]
gold/testsuite/script_test_6.t [new file with mode: 0644]
gold/testsuite/script_test_7.sh [new file with mode: 0755]
gold/testsuite/script_test_7.t [new file with mode: 0644]
gold/testsuite/script_test_8.sh [new file with mode: 0755]
gold/yyscript.y

index a18cf54ddfffc492c1b367b28e8a26dea6ce8139..635819195a9f1d41f674fa3f43b7025a62287a46 100644 (file)
@@ -1,3 +1,37 @@
+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
index 25f3ac33936a30a604d6af5a3b68ebecc733a933..853a698d187b1fc99a5a28ba5a49ba43eeafac8f 100644 (file)
@@ -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
index 37016b09cc12da2e3463c4cf9e875d9a20232f1e..a646bdadf873dcc656291657bf0354d6e160020d 100644 (file)
@@ -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
index a541e9aa13ed3756ed11860990f70d80c9d965bd..8fb9a7359712cfa394fc3e61e285bff697b27d04 100644 (file)
@@ -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)
     {
index b326eae4bd9e1865893480b74cb1f1e996c04167..c0d1d081c24e21c63574c4a3c9db693a78f6d7a8 100644 (file)
@@ -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.
index d0ffe41a6158a479c6dbdb6d5cc835d4e95d487a..8839213bc2558f740cd00a960fdbb6679a261aff 100644 (file)
@@ -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);
+}
index 09d7325cb3df1aa302ba16f0798e71a491c64aa4..6fa1e18cd185a2c4ed1ee4e571ca7ada3e9b6c50 100644 (file)
@@ -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
 
index 3f5459f707a4dd327fd5e8dd6583ec882ea2a66c..193888aa4dec6883c06e0bc10cc687393f30ac8c 100644 (file)
@@ -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 (executable)
index 0000000..bbc96d8
--- /dev/null
@@ -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 (file)
index 0000000..9676371
--- /dev/null
@@ -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 (executable)
index 0000000..982a1c1
--- /dev/null
@@ -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 (file)
index 0000000..a4c4973
--- /dev/null
@@ -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 (executable)
index 0000000..83e8e72
--- /dev/null
@@ -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...."
index 0d52882d4b33745e716e1092f04ce02163949ac1..81c136ae01cf184f3b735225e84cc1e34bf9ccc3 100644 (file)
@@ -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); }