mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 12:03:41 +08:00
* target-reloc.h (class Default_comdat_behavior): New, package up..
(get_comdat_behaviour): ..this. (relocate_section): Add Relocate_comdat_behavior template arg, adjust code to suit. * arm.cc (Target_arm::relocate_section): Adjust to suit. (Target_arm::scan_reloc_section): Likewise. * i386.cc (Target_i386::relocate_section): Likewise. * sparc.cc (Target_sparc::relocate_section): Likewise. * tilegx.cc (Target_tilegx::relocate_section): Likewise. * x86_64.cc (Target_x86_64::relocate_section): Likewise. * powerpc.cc (class Relocate_comdat_behavior): New. (Target_powerpc::relocate_section): Don't zap opd relocs. Supply gold::relocate_section with new template arg.
This commit is contained in:
parent
522307fe68
commit
168a472611
@ -1,3 +1,19 @@
|
||||
2012-10-18 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* target-reloc.h (class Default_comdat_behavior): New, package up..
|
||||
(get_comdat_behaviour): ..this.
|
||||
(relocate_section): Add Relocate_comdat_behavior template arg,
|
||||
adjust code to suit.
|
||||
* arm.cc (Target_arm::relocate_section): Adjust to suit.
|
||||
(Target_arm::scan_reloc_section): Likewise.
|
||||
* i386.cc (Target_i386::relocate_section): Likewise.
|
||||
* sparc.cc (Target_sparc::relocate_section): Likewise.
|
||||
* tilegx.cc (Target_tilegx::relocate_section): Likewise.
|
||||
* x86_64.cc (Target_x86_64::relocate_section): Likewise.
|
||||
* powerpc.cc (class Relocate_comdat_behavior): New.
|
||||
(Target_powerpc::relocate_section): Don't zap opd relocs. Supply
|
||||
gold::relocate_section with new template arg.
|
||||
|
||||
2012-10-18 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* powerpc.cc (Target_powerpc::Scan::local, global): Always emit
|
||||
|
@ -9518,7 +9518,7 @@ Target_arm<big_endian>::relocate_section(
|
||||
}
|
||||
|
||||
gold::relocate_section<32, big_endian, Target_arm, elfcpp::SHT_REL,
|
||||
Arm_relocate>(
|
||||
Arm_relocate, gold::Default_comdat_behavior>(
|
||||
relinfo,
|
||||
this,
|
||||
prelocs,
|
||||
@ -11150,6 +11150,7 @@ Target_arm<big_endian>::scan_reloc_section_for_stubs(
|
||||
Arm_relobj<big_endian>::as_arm_relobj(relinfo->object);
|
||||
unsigned int local_count = arm_object->local_symbol_count();
|
||||
|
||||
gold::Default_comdat_behavior default_comdat_behavior;
|
||||
Comdat_behavior comdat_behavior = CB_UNDETERMINED;
|
||||
|
||||
for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
|
||||
@ -11323,7 +11324,7 @@ Target_arm<big_endian>::scan_reloc_section_for_stubs(
|
||||
if (comdat_behavior == CB_UNDETERMINED)
|
||||
{
|
||||
std::string name = arm_object->section_name(relinfo->data_shndx);
|
||||
comdat_behavior = get_comdat_behavior(name.c_str());
|
||||
comdat_behavior = default_comdat_behavior.get(name.c_str());
|
||||
}
|
||||
if (comdat_behavior == CB_PRETEND)
|
||||
{
|
||||
|
@ -3487,7 +3487,7 @@ Target_i386::relocate_section(const Relocate_info<32, false>* relinfo,
|
||||
gold_assert(sh_type == elfcpp::SHT_REL);
|
||||
|
||||
gold::relocate_section<32, false, Target_i386, elfcpp::SHT_REL,
|
||||
Target_i386::Relocate>(
|
||||
Target_i386::Relocate, gold::Default_comdat_behavior>(
|
||||
relinfo,
|
||||
this,
|
||||
prelocs,
|
||||
|
@ -619,6 +619,32 @@ class Target_powerpc : public Sized_target<size, big_endian>
|
||||
enum skip_tls call_tls_get_addr_;
|
||||
};
|
||||
|
||||
class Relocate_comdat_behavior
|
||||
{
|
||||
public:
|
||||
// Decide what the linker should do for relocations that refer to
|
||||
// discarded comdat sections.
|
||||
inline Comdat_behavior
|
||||
get(const char* name)
|
||||
{
|
||||
gold::Default_comdat_behavior default_behavior;
|
||||
Comdat_behavior ret = default_behavior.get(name);
|
||||
if (ret == CB_WARNING)
|
||||
{
|
||||
if (size == 32
|
||||
&& (strcmp(name, ".fixup") == 0
|
||||
|| strcmp(name, ".got2") == 0))
|
||||
ret = CB_IGNORE;
|
||||
if (size == 64
|
||||
&& (strcmp(name, ".opd") == 0
|
||||
|| strcmp(name, ".toc") == 0
|
||||
|| strcmp(name, ".toc1") == 0))
|
||||
ret = CB_IGNORE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
// A class which returns the size required for a relocation type,
|
||||
// used while scanning relocs during a relocatable link.
|
||||
class Relocatable_size_for_reloc
|
||||
@ -5051,48 +5077,13 @@ Target_powerpc<size, big_endian>::relocate_section(
|
||||
{
|
||||
typedef Target_powerpc<size, big_endian> Powerpc;
|
||||
typedef typename Target_powerpc<size, big_endian>::Relocate Powerpc_relocate;
|
||||
typedef typename Target_powerpc<size, big_endian>::Relocate_comdat_behavior
|
||||
Powerpc_comdat_behavior;
|
||||
|
||||
gold_assert(sh_type == elfcpp::SHT_RELA);
|
||||
|
||||
unsigned char *opd_rel = NULL;
|
||||
Powerpc_relobj<size, big_endian>* const object
|
||||
= static_cast<Powerpc_relobj<size, big_endian>*>(relinfo->object);
|
||||
if (size == 64
|
||||
&& relinfo->data_shndx == object->opd_shndx())
|
||||
{
|
||||
// Rewrite opd relocs, omitting those for discarded sections
|
||||
// to silence gold::relocate_section errors.
|
||||
const int reloc_size
|
||||
= Reloc_types<elfcpp::SHT_RELA, size, big_endian>::reloc_size;
|
||||
opd_rel = new unsigned char[reloc_count * reloc_size];
|
||||
const unsigned char* rrel = prelocs;
|
||||
unsigned char* wrel = opd_rel;
|
||||
|
||||
for (size_t i = 0;
|
||||
i < reloc_count;
|
||||
++i, rrel += reloc_size, wrel += reloc_size)
|
||||
{
|
||||
typename Reloc_types<elfcpp::SHT_RELA, size, big_endian>::Reloc
|
||||
reloc(rrel);
|
||||
typename elfcpp::Elf_types<size>::Elf_WXword r_info
|
||||
= reloc.get_r_info();
|
||||
unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
|
||||
Address r_off = reloc.get_r_offset();
|
||||
if (r_type == elfcpp::R_PPC64_TOC)
|
||||
r_off -= 8;
|
||||
bool is_discarded = object->get_opd_discard(r_off);
|
||||
|
||||
// Reloc number is reported in some errors, so keep all relocs.
|
||||
if (is_discarded)
|
||||
memset(wrel, 0, reloc_size);
|
||||
else
|
||||
memcpy(wrel, rrel, reloc_size);
|
||||
}
|
||||
prelocs = opd_rel;
|
||||
}
|
||||
|
||||
gold::relocate_section<size, big_endian, Powerpc, elfcpp::SHT_RELA,
|
||||
Powerpc_relocate>(
|
||||
Powerpc_relocate, Powerpc_comdat_behavior>(
|
||||
relinfo,
|
||||
this,
|
||||
prelocs,
|
||||
@ -5103,9 +5094,6 @@ Target_powerpc<size, big_endian>::relocate_section(
|
||||
address,
|
||||
view_size,
|
||||
reloc_symbol_changes);
|
||||
|
||||
if (opd_rel != NULL)
|
||||
delete[] opd_rel;
|
||||
}
|
||||
|
||||
class Powerpc_scan_relocatable_reloc
|
||||
|
@ -4138,7 +4138,7 @@ Target_sparc<size, big_endian>::relocate_section(
|
||||
gold_assert(sh_type == elfcpp::SHT_RELA);
|
||||
|
||||
gold::relocate_section<size, big_endian, Sparc, elfcpp::SHT_RELA,
|
||||
Sparc_relocate>(
|
||||
Sparc_relocate, gold::Default_comdat_behavior>(
|
||||
relinfo,
|
||||
this,
|
||||
prelocs,
|
||||
|
@ -124,20 +124,24 @@ enum Comdat_behavior
|
||||
CB_WARNING // Print a warning.
|
||||
};
|
||||
|
||||
// Decide what the linker should do for relocations that refer to discarded
|
||||
// comdat sections. This decision is based on the name of the section being
|
||||
// relocated.
|
||||
|
||||
inline Comdat_behavior
|
||||
get_comdat_behavior(const char* name)
|
||||
class Default_comdat_behavior
|
||||
{
|
||||
if (Layout::is_debug_info_section(name))
|
||||
return CB_PRETEND;
|
||||
if (strcmp(name, ".eh_frame") == 0
|
||||
|| strcmp(name, ".gcc_except_table") == 0)
|
||||
return CB_IGNORE;
|
||||
return CB_WARNING;
|
||||
}
|
||||
public:
|
||||
// Decide what the linker should do for relocations that refer to
|
||||
// discarded comdat sections. This decision is based on the name of
|
||||
// the section being relocated.
|
||||
|
||||
inline Comdat_behavior
|
||||
get(const char* name)
|
||||
{
|
||||
if (Layout::is_debug_info_section(name))
|
||||
return CB_PRETEND;
|
||||
if (strcmp(name, ".eh_frame") == 0
|
||||
|| strcmp(name, ".gcc_except_table") == 0)
|
||||
return CB_IGNORE;
|
||||
return CB_WARNING;
|
||||
}
|
||||
};
|
||||
|
||||
// Give an error for a symbol with non-default visibility which is not
|
||||
// defined locally.
|
||||
@ -220,6 +224,11 @@ issue_undefined_symbol_error(const Symbol* sym)
|
||||
// a single function, relocate(), which implements the machine
|
||||
// specific part of a relocation.
|
||||
|
||||
// The template parameter Relocate_comdat_behavior is a class type
|
||||
// which provides a single function, get(), which determines what the
|
||||
// linker should do for relocations that refer to discarded comdat
|
||||
// sections.
|
||||
|
||||
// SIZE is the ELF size: 32 or 64. BIG_ENDIAN is the endianness of
|
||||
// the data. SH_TYPE is the section type: SHT_REL or SHT_RELA.
|
||||
// RELOCATE implements operator() to do a relocation.
|
||||
@ -241,7 +250,8 @@ issue_undefined_symbol_error(const Symbol* sym)
|
||||
// relocation.
|
||||
|
||||
template<int size, bool big_endian, typename Target_type, int sh_type,
|
||||
typename Relocate>
|
||||
typename Relocate,
|
||||
typename Relocate_comdat_behavior>
|
||||
inline void
|
||||
relocate_section(
|
||||
const Relocate_info<size, big_endian>* relinfo,
|
||||
@ -258,6 +268,7 @@ relocate_section(
|
||||
typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
|
||||
const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
|
||||
Relocate relocate;
|
||||
Relocate_comdat_behavior relocate_comdat_behavior;
|
||||
|
||||
Sized_relobj_file<size, big_endian>* object = relinfo->object;
|
||||
unsigned int local_count = object->local_symbol_count();
|
||||
@ -348,7 +359,7 @@ relocate_section(
|
||||
if (comdat_behavior == CB_UNDETERMINED)
|
||||
{
|
||||
std::string name = object->section_name(relinfo->data_shndx);
|
||||
comdat_behavior = get_comdat_behavior(name.c_str());
|
||||
comdat_behavior = relocate_comdat_behavior.get(name.c_str());
|
||||
}
|
||||
if (comdat_behavior == CB_PRETEND)
|
||||
{
|
||||
|
@ -4733,8 +4733,8 @@ Target_tilegx<size, big_endian>::relocate_section(
|
||||
|
||||
gold_assert(sh_type == elfcpp::SHT_RELA);
|
||||
|
||||
gold::relocate_section<size, big_endian, Tilegx,
|
||||
elfcpp::SHT_RELA, Tilegx_relocate>(
|
||||
gold::relocate_section<size, big_endian, Tilegx, elfcpp::SHT_RELA,
|
||||
Tilegx_relocate, gold::Default_comdat_behavior>(
|
||||
relinfo,
|
||||
this,
|
||||
prelocs,
|
||||
|
@ -4060,7 +4060,8 @@ Target_x86_64<size>::relocate_section(
|
||||
gold_assert(sh_type == elfcpp::SHT_RELA);
|
||||
|
||||
gold::relocate_section<size, false, Target_x86_64<size>, elfcpp::SHT_RELA,
|
||||
typename Target_x86_64<size>::Relocate>(
|
||||
typename Target_x86_64<size>::Relocate,
|
||||
gold::Default_comdat_behavior>(
|
||||
relinfo,
|
||||
this,
|
||||
prelocs,
|
||||
|
Loading…
Reference in New Issue
Block a user