* 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.
This commit is contained in:
Ian Lance Taylor 2008-04-07 22:46:17 +00:00
parent 6835af537e
commit 624f881062
7 changed files with 76 additions and 9 deletions

View File

@ -1,5 +1,18 @@
2008-04-07 Ian Lance Taylor <iant@google.com> 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. * configure.ac: Don't test for objdump, c++filt, or readelf.
* testsuite/Makefile.am: Remove READELF and OBJDUMP_AND_CPPFILT * testsuite/Makefile.am: Remove READELF and OBJDUMP_AND_CPPFILT
conditionals. conditionals.

View File

@ -790,18 +790,27 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_symbol_index()
return index; return index;
} }
// For a local section symbol, get the section offset of the input // For a local section symbol, get the address of the offset ADDEND
// section within the output section. // within the input section.
template<bool dynamic, int size, bool big_endian> template<bool dynamic, int size, bool big_endian>
section_offset_type section_offset_type
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>:: 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_; const unsigned int lsi = this->local_sym_index_;
section_offset_type offset; section_offset_type offset;
Output_section* os = this->u1_.relobj->output_section(lsi, &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; return offset;
} }
@ -853,7 +862,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::write(
template<bool dynamic, int size, bool big_endian> template<bool dynamic, int size, bool big_endian>
typename elfcpp::Elf_types<size>::Elf_Addr typename elfcpp::Elf_types<size>::Elf_Addr
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::symbol_value( Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::symbol_value(
Address addend) const Addend addend) const
{ {
if (this->local_sym_index_ == GSYM_CODE) 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()) if (this->rel_.is_relative())
addend = this->rel_.symbol_value(addend); addend = this->rel_.symbol_value(addend);
else if (this->rel_.is_local_section_symbol()) 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); orel.put_r_addend(addend);
} }

View File

@ -779,6 +779,7 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
{ {
public: public:
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address; 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 // An uninitialized entry. We need this because we want to put
// instances of this class into an STL container. // 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 // 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 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 // Get the value of the symbol referred to by a Rel relocation when
// we are adding the given ADDEND. // we are adding the given ADDEND.
Address Address
symbol_value(Address addend) const; symbol_value(Addend addend) const;
// Write the reloc entry to an output view. // Write the reloc entry to an output view.
void void

View File

@ -73,3 +73,6 @@ extern bool t16a();
extern bool t17(); extern bool t17();
extern const char* t17data[]; extern const char* t17data[];
#define T17_COUNT 5 #define T17_COUNT 5
extern bool t18();
extern const char* f18(int);

View File

@ -48,6 +48,7 @@
// 15 Compare wide string constants in file 1 and file 2. // 15 Compare wide string constants in file 1 and file 2.
// 16 Call a function directly after its address has been taken. // 16 Call a function directly after its address has been taken.
// 17 File 1 checks array of string constants defined in file 2. // 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" #include "two_file_test.h"
@ -219,3 +220,19 @@ t17()
} }
return true; 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;
}

View File

@ -121,3 +121,25 @@ const char* t17data[T17_COUNT] =
{ {
"a", "b", "c", "d", "e" "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;
}
}

View File

@ -52,5 +52,6 @@ main()
assert(t16()); assert(t16());
assert(t16a()); assert(t16a());
assert(t17()); assert(t17());
assert(t18());
return 0; return 0;
} }