* output.cc (Output_reloc<SHT_REL>::local_section_offset): Add
authorIan Lance Taylor <ian@airs.com>
Mon, 7 Apr 2008 22:46:17 +0000 (22:46 +0000)
committerIan Lance Taylor <ian@airs.com>
Mon, 7 Apr 2008 22:46:17 +0000 (22:46 +0000)
addend parameter.  Change caller.  Handle merge sections.
(Output_reloc<SHT_REL>::symbol_value): Change parameter type from
Address to Addend.  Don't add in the result of
local_section_offset, pass down the addend and use the returned
value.
* output.h (class Output_reloc<SHT_REL>): Add Addend typedef.
Update declarations of local_section_offset and symbol_value.
* testsuite/two_file_test_1.cc (t18): New function.
* testsuite/two_file_test_2.cc (f18): New function.
* testsuite/two_file_test_main.cc (main): Call t18.
* testsuite/two_file_test.h (t18, f18): Declare.

gold/ChangeLog
gold/output.cc
gold/output.h
gold/testsuite/two_file_test.h
gold/testsuite/two_file_test_1.cc
gold/testsuite/two_file_test_2.cc
gold/testsuite/two_file_test_main.cc

index 38f8c3dfc363a3425f8703df5a45a75ff1440787..6df30ff8db6f8243c10c735ece1316b83f378c2f 100644 (file)
@@ -1,5 +1,18 @@
 2008-04-07  Ian Lance Taylor  <iant@google.com>
 
+       * output.cc (Output_reloc<SHT_REL>::local_section_offset): Add
+       addend parameter.  Change caller.  Handle merge sections.
+       (Output_reloc<SHT_REL>::symbol_value): Change parameter type from
+       Address to Addend.  Don't add in the result of
+       local_section_offset, pass down the addend and use the returned
+       value.
+       * output.h (class Output_reloc<SHT_REL>): Add Addend typedef.
+       Update declarations of local_section_offset and symbol_value.
+       * testsuite/two_file_test_1.cc (t18): New function.
+       * testsuite/two_file_test_2.cc (f18): New function.
+       * testsuite/two_file_test_main.cc (main): Call t18.
+       * testsuite/two_file_test.h (t18, f18): Declare.
+
        * configure.ac: Don't test for objdump, c++filt, or readelf.
        * testsuite/Makefile.am: Remove READELF and OBJDUMP_AND_CPPFILT
        conditionals.
index f3ae6784074ad8e15ba10062aabdba07693ee618..7a76f79377c129743980d547b6fb8d6cf68f1a93 100644 (file)
@@ -790,18 +790,27 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_symbol_index()
   return index;
 }
 
-// For a local section symbol, get the section offset of the input
-// section within the output section.
+// For a local section symbol, get the address of the offset ADDEND
+// within the input section.
 
 template<bool dynamic, int size, bool big_endian>
 section_offset_type
 Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::
-  local_section_offset() const
+  local_section_offset(Addend addend) const
 {
+  gold_assert(this->local_sym_index_ != GSYM_CODE
+              && this->local_sym_index_ != SECTION_CODE
+              && this->local_sym_index_ != INVALID_CODE
+              && this->is_section_symbol_);
   const unsigned int lsi = this->local_sym_index_;
   section_offset_type offset;
   Output_section* os = this->u1_.relobj->output_section(lsi, &offset);
-  gold_assert(os != NULL && offset != -1);
+  gold_assert(os != NULL);
+  if (offset != -1)
+    return offset + addend;
+  // This is a merge section.
+  offset = os->output_address(this->u1_.relobj, lsi, addend);
+  gold_assert(offset != -1);
   return offset;
 }
 
@@ -853,7 +862,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::write(
 template<bool dynamic, int size, bool big_endian>
 typename elfcpp::Elf_types<size>::Elf_Addr
 Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::symbol_value(
-    Address addend) const
+    Addend addend) const
 {
   if (this->local_sym_index_ == GSYM_CODE)
     {
@@ -882,7 +891,7 @@ Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>::write(
   if (this->rel_.is_relative())
     addend = this->rel_.symbol_value(addend);
   else if (this->rel_.is_local_section_symbol())
-    addend += this->rel_.local_section_offset();
+    addend = this->rel_.local_section_offset(addend);
   orel.put_r_addend(addend);
 }
 
index 5a95748762a6bf0bb21623d2f9fae1ae1f28babc..e69777554930691f8e227b569bf03a5a1f75cf8e 100644 (file)
@@ -779,6 +779,7 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
 {
  public:
   typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
+  typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;
 
   // An uninitialized entry.  We need this because we want to put
   // instances of this class into an STL container.
@@ -835,14 +836,15 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
   }
 
   // For a local section symbol, return the offset of the input
-  // section within the output section.
+  // section within the output section.  ADDEND is the addend being
+  // applied to the input section.
   section_offset_type
-  local_section_offset() const;
+  local_section_offset(Addend addend) const;
 
   // Get the value of the symbol referred to by a Rel relocation when
   // we are adding the given ADDEND.
   Address
-  symbol_value(Address addend) const;
+  symbol_value(Addend addend) const;
 
   // Write the reloc entry to an output view.
   void
index 32a247f1929abbedca18aecf85671c19fc1735c5..d89f050cd7b72a0ba1b72fb6d17ee284f26e0f50 100644 (file)
@@ -73,3 +73,6 @@ extern bool t16a();
 extern bool t17();
 extern const char* t17data[];
 #define T17_COUNT 5
+
+extern bool t18();
+extern const char* f18(int);
index 7646838cdb753df95069fe30872ac6b6ab83ca99..8b4c8ad4aaf525735c5c4f3517da142983137f35 100644 (file)
@@ -48,6 +48,7 @@
 // 15 Compare wide string constants in file 1 and file 2.
 // 16 Call a function directly after its address has been taken.
 // 17 File 1 checks array of string constants defined in file 2.
+// 18 File 1 checks string constants referenced in code in file 2.
 
 #include "two_file_test.h"
 
@@ -219,3 +220,19 @@ t17()
     }
   return true;
 }
+
+// 18 File 1 checks string constants referenced in code in file 2.
+
+bool
+t18()
+{
+  char c = 'a';
+  for (int i = 0; i < T17_COUNT; ++i)
+    {
+      const char* s = f18(i);
+      if (s[0] != c || s[1] != '\0')
+        return false;
+      ++c;
+    }
+  return true;
+}
index 3888befb732cdb1754f898c53eb488038ffdf6a1..e1aeaf4883ceb7859dba9a5a6c447504094b9ad9 100644 (file)
@@ -121,3 +121,25 @@ const char* t17data[T17_COUNT] =
 {
   "a", "b", "c", "d", "e"
 };
+
+// 18 File 1 checks string constants referenced directly in file 2.
+
+const char*
+f18(int i)
+{
+  switch (i)
+    {
+    case 0:
+      return "a";
+    case 1:
+      return "b";
+    case 2:
+      return "c";
+    case 3:
+      return "d";
+    case 4:
+      return "e";
+    default:
+      return 0;
+    }
+}
index c69d6e0970e78ab8d3bf362ceb5d0227cda8612b..b7e38385da5581834225814aae26f68093bfb8bd 100644 (file)
@@ -52,5 +52,6 @@ main()
   assert(t16());
   assert(t16a());
   assert(t17());
+  assert(t18());
   return 0;
 }