This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH COMMITTED: Output local section symbol relocs to merge sections
- From: Ian Lance Taylor <iant at google dot com>
- To: binutils at sourceware dot org
- Date: Mon, 07 Apr 2008 15:49:18 -0700
- Subject: PATCH COMMITTED: Output local section symbol relocs to merge sections
This patch adds support for outputting relocs against local section
symbols defined in merge sections. I originally thought this case
could not happen because I couldn't figure out any way to generate
code for it. But then I did figure out how to generate it, if we
permit x86-64 non-PIC object files to go into shared libraries. Which
we don't, but that's OK, the case will arise for other processors.
I committed this patch to make it work, including a test case which
would trigger it if we could.
Ian
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.
Index: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.68
diff -u -p -u -r1.68 output.cc
--- output.cc 29 Mar 2008 08:09:55 -0000 1.68
+++ output.cc 7 Apr 2008 22:45:11 -0000
@@ -790,18 +790,27 @@ Output_reloc<elfcpp::SHT_REL, dynamic, s
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, s
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,
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: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.59
diff -u -p -u -r1.59 output.h
--- output.h 28 Mar 2008 22:42:34 -0000 1.59
+++ output.h 7 Apr 2008 22:45:11 -0000
@@ -779,6 +779,7 @@ class Output_reloc<elfcpp::SHT_REL, dyna
{
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, dyna
}
// 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: testsuite/two_file_test.h
===================================================================
RCS file: /cvs/src/src/gold/testsuite/two_file_test.h,v
retrieving revision 1.7
diff -u -p -u -r1.7 two_file_test.h
--- testsuite/two_file_test.h 16 Mar 2008 23:51:19 -0000 1.7
+++ testsuite/two_file_test.h 7 Apr 2008 22:45:11 -0000
@@ -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: testsuite/two_file_test_1.cc
===================================================================
RCS file: /cvs/src/src/gold/testsuite/two_file_test_1.cc,v
retrieving revision 1.6
diff -u -p -u -r1.6 two_file_test_1.cc
--- testsuite/two_file_test_1.cc 16 Mar 2008 23:51:19 -0000 1.6
+++ testsuite/two_file_test_1.cc 7 Apr 2008 22:45:11 -0000
@@ -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: testsuite/two_file_test_2.cc
===================================================================
RCS file: /cvs/src/src/gold/testsuite/two_file_test_2.cc,v
retrieving revision 1.6
diff -u -p -u -r1.6 two_file_test_2.cc
--- testsuite/two_file_test_2.cc 16 Mar 2008 23:51:19 -0000 1.6
+++ testsuite/two_file_test_2.cc 7 Apr 2008 22:45:11 -0000
@@ -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: testsuite/two_file_test_main.cc
===================================================================
RCS file: /cvs/src/src/gold/testsuite/two_file_test_main.cc,v
retrieving revision 1.5
diff -u -p -u -r1.5 two_file_test_main.cc
--- testsuite/two_file_test_main.cc 16 Mar 2008 23:51:19 -0000 1.5
+++ testsuite/two_file_test_main.cc 7 Apr 2008 22:45:11 -0000
@@ -52,5 +52,6 @@ main()
assert(t16());
assert(t16a());
assert(t17());
+ assert(t18());
return 0;
}