From e291e7b9c9cd9e432fdcc63922f2529647f5b930 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 8 Jan 2010 19:33:18 +0000 Subject: PR 10287 PR 11063 * i386.cc (class Target_i386): Change return type of plt_section to be non-const. (class Output_data_plt_i386): Add tls_desc_rel_ field. (Output_data_plt_i386::Output_data_plt_i386): Initialize tls_desc_rel_ field. (Output_data_plt_i386::rel_tls_desc): New function. (Target_i386::rel_tls_desc_section): New function. (Target_i386::Scan::local): Rewrite R_386_TLS_GOTDESC handling. (Target_i386::Scan::global): For R_386_TLS_GOTDESC put R_386_TLS_DESC reloc in rel_tls_desc_section. * x86_64.cc (class Target_x86_64): Add tlsdesc_reloc_info_ field. Define struct Tlsdesc_info. (Target_x86_64::Target_x86_64): Initialize tlsdesc_reloc_info_. (Target_x86_64::do_reloc_symbol_index): New function. (Target_x86_64::add_tlsdesc_info): New function. (class Output_data_plt_x86_64): Add tlsdesc_rel_ field. (Output_data_plt_x86_64::Output_data_plt_x86_64): Initialize tlsdesc_rel_ field. (Output_data_plt_x86_64::rela_plt): Rename from rel_plt. Change all callers. (Output_data_plt_x86_64::rela_tlsdesc): New function. (Target_x86_64::rela_tlsdesc_section): New function. (Target_x86_64::Scan::local): Rewrite R_X86_64_GOTPC32_TLSDESC handling. (Target_x86_64::Scan::global): For R_X86_64_GOTPC32_TLSDESC put (Target_x86_64::do_reloc_addend): New function. R_X86_64_TLSDESC reloc in rela_tlsdesc_section. * output.h (class Output_reloc) [SHT_REL]: Add new constructor declarations. Define TARGET_CODE. Add arg field to u1_ union. (Output_reloc::type): New function. (Output_reloc::is_local_section_symbol): Check for TARGET_CODE. (Output_reloc::is_target_specific): New function. (Output_reloc::target_arg): New function. (class Output_reloc) [SHT_RELA]: Add four new constructors for absolute relocs and target specific relocs. (class Output_data_reloc) [SHT_REL]: Add add_absolute and add_target_specific. (class Output_data_reloc) [SHT_RELA]: Likewise. * output.cc (Output_reloc::Output_reloc): Add four new versions for absolute relocs and target specific relocs. (Output_reloc::set_needs_dynsym_index): Add TARGET_CODE case. (Output_reloc::get_symbol_index): Likewise. (Output_reloc::local_section_offset): Check that local_sym_index_ is not TARGET_CODE or 0. (Output_reloc::symbol_value): Likewise. (Output_reloc::write) [SHT_RELA]: Call target for target specific reloc. * target.h (class Target): Add reloc_symbol_index and reloc_addend functions. Add do_reloc_symbol_index and do_reloc_addend virtual functions. * layout.cc (add_target_dynamic_tags): Use output section for DT_PLTRELSZ and DT_JMPREL. --- gold/output.cc | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) (limited to 'gold/output.cc') diff --git a/gold/output.cc b/gold/output.cc index b9ded6e..bb61d86 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -756,6 +756,72 @@ Output_reloc::Output_reloc( os->set_needs_symtab_index(); } +// An absolute relocation. + +template +Output_reloc::Output_reloc( + unsigned int type, + Output_data* od, + Address address) + : address_(address), local_sym_index_(0), type_(type), + is_relative_(false), is_section_symbol_(false), shndx_(INVALID_CODE) +{ + // this->type_ is a bitfield; make sure TYPE fits. + gold_assert(this->type_ == type); + this->u1_.relobj = NULL; + this->u2_.od = od; +} + +template +Output_reloc::Output_reloc( + unsigned int type, + Sized_relobj* relobj, + unsigned int shndx, + Address address) + : address_(address), local_sym_index_(0), type_(type), + is_relative_(false), is_section_symbol_(false), shndx_(shndx) +{ + gold_assert(shndx != INVALID_CODE); + // this->type_ is a bitfield; make sure TYPE fits. + gold_assert(this->type_ == type); + this->u1_.relobj = NULL; + this->u2_.relobj = relobj; +} + +// A target specific relocation. + +template +Output_reloc::Output_reloc( + unsigned int type, + void* arg, + Output_data* od, + Address address) + : address_(address), local_sym_index_(TARGET_CODE), type_(type), + is_relative_(false), is_section_symbol_(false), shndx_(INVALID_CODE) +{ + // this->type_ is a bitfield; make sure TYPE fits. + gold_assert(this->type_ == type); + this->u1_.arg = arg; + this->u2_.od = od; +} + +template +Output_reloc::Output_reloc( + unsigned int type, + void* arg, + Sized_relobj* relobj, + unsigned int shndx, + Address address) + : address_(address), local_sym_index_(TARGET_CODE), type_(type), + is_relative_(false), is_section_symbol_(false), shndx_(shndx) +{ + gold_assert(shndx != INVALID_CODE); + // this->type_ is a bitfield; make sure TYPE fits. + gold_assert(this->type_ == type); + this->u1_.arg = arg; + this->u2_.relobj = relobj; +} + // Record that we need a dynamic symbol index for this relocation. template @@ -778,6 +844,10 @@ set_needs_dynsym_index() this->u1_.os->set_needs_dynsym_index(); break; + case TARGET_CODE: + // The target must take care of this if necessary. + break; + case 0: break; @@ -822,6 +892,11 @@ Output_reloc::get_symbol_index() index = this->u1_.os->symtab_index(); break; + case TARGET_CODE: + index = parameters->target().reloc_symbol_index(this->u1_.arg, + this->type_); + break; + case 0: // Relocations without symbols use a symbol index of 0. index = 0; @@ -863,7 +938,9 @@ Output_reloc:: { gold_assert(this->local_sym_index_ != GSYM_CODE && this->local_sym_index_ != SECTION_CODE + && this->local_sym_index_ != TARGET_CODE && this->local_sym_index_ != INVALID_CODE + && this->local_sym_index_ != 0 && this->is_section_symbol_); const unsigned int lsi = this->local_sym_index_; Output_section* os = this->u1_.relobj->output_section(lsi); @@ -942,7 +1019,9 @@ Output_reloc::symbol_value( return sym->value() + addend; } gold_assert(this->local_sym_index_ != SECTION_CODE + && this->local_sym_index_ != TARGET_CODE && this->local_sym_index_ != INVALID_CODE + && this->local_sym_index_ != 0 && !this->is_section_symbol_); const unsigned int lsi = this->local_sym_index_; const Symbol_value* symval = this->u1_.relobj->local_symbol(lsi); @@ -1010,7 +1089,10 @@ Output_reloc::write( elfcpp::Rela_write orel(pov); this->rel_.write_rel(&orel); Addend addend = this->addend_; - if (this->rel_.is_relative()) + if (this->rel_.is_target_specific()) + addend = parameters->target().reloc_addend(this->rel_.target_arg(), + this->rel_.type(), addend); + else 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); -- cgit v1.1