// x86_64.cc -- x86_64 target support for gold.
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
got_mod_index_offset_(-1U), tls_base_symbol_defined_(false)
{ }
+ // Scan the relocations to look for symbol adjustments.
+ void
+ gc_process_relocs(const General_options& options,
+ Symbol_table* symtab,
+ Layout* layout,
+ Sized_relobj<64, false>* object,
+ unsigned int data_shndx,
+ unsigned int sh_type,
+ const unsigned char* prelocs,
+ size_t reloc_count,
+ Output_section* output_section,
+ bool needs_special_offset_handling,
+ size_t local_symbol_count,
+ const unsigned char* plocal_symbols);
+
// Scan the relocations to look for symbol adjustments.
void
scan_relocs(const General_options& options,
// Return whether SYM is defined by the ABI.
bool
- do_is_defined_by_abi(Symbol* sym) const
+ do_is_defined_by_abi(const Symbol* sym) const
{ return strcmp(sym->name(), "__tls_get_addr") == 0; }
// Return the size of the GOT section.
// Do a relocation. Return false if the caller should not issue
// any warnings about this relocation.
inline bool
- relocate(const Relocate_info<64, false>*, Target_x86_64*, size_t relnum,
- const elfcpp::Rela<64, false>&,
+ relocate(const Relocate_info<64, false>*, Target_x86_64*, Output_section*,
+ size_t relnum, const elfcpp::Rela<64, false>&,
unsigned int r_type, const Sized_symbol<64>*,
const Symbol_value<64>*,
unsigned char*, elfcpp::Elf_types<64>::Elf_Addr,
void
make_plt_entry(Symbol_table*, Layout*, Symbol*);
- // Define the _TLS_MODULE_BASE_ symbol at the end of the TLS segment.
+ // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
void
define_tls_base_symbol(Symbol_table*, Layout*);
this->plt_->add_entry(gsym);
}
-// Define the _TLS_MODULE_BASE_ symbol at the end of the TLS segment.
+// Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
void
Target_x86_64::define_tls_base_symbol(Symbol_table* symtab, Layout* layout)
Output_segment* tls_segment = layout->tls_segment();
if (tls_segment != NULL)
{
+ bool is_exec = parameters->options().output_is_executable();
symtab->define_in_output_segment("_TLS_MODULE_BASE_", NULL,
tls_segment, 0, 0,
elfcpp::STT_TLS,
elfcpp::STB_LOCAL,
elfcpp::STV_HIDDEN, 0,
- Symbol::SEGMENT_END, true);
+ (is_exec
+ ? Symbol::SEGMENT_END
+ : Symbol::SEGMENT_START),
+ true);
}
this->tls_base_symbol_defined_ = true;
}
}
}
+void
+Target_x86_64::gc_process_relocs(const General_options& options,
+ Symbol_table* symtab,
+ Layout* layout,
+ Sized_relobj<64, false>* object,
+ unsigned int data_shndx,
+ unsigned int sh_type,
+ const unsigned char* prelocs,
+ size_t reloc_count,
+ Output_section* output_section,
+ bool needs_special_offset_handling,
+ size_t local_symbol_count,
+ const unsigned char* plocal_symbols)
+{
+
+ if (sh_type == elfcpp::SHT_REL)
+ {
+ return;
+ }
+
+ gold::gc_process_relocs<64, false, Target_x86_64, elfcpp::SHT_RELA,
+ Target_x86_64::Scan>(
+ options,
+ symtab,
+ layout,
+ this,
+ object,
+ data_shndx,
+ prelocs,
+ reloc_count,
+ output_section,
+ needs_special_offset_handling,
+ local_symbol_count,
+ plocal_symbols);
+
+}
// Scan relocations for a section.
void
inline bool
Target_x86_64::Relocate::relocate(const Relocate_info<64, false>* relinfo,
Target_x86_64* target,
+ Output_section*,
size_t relnum,
const elfcpp::Rela<64, false>& rela,
unsigned int r_type,
{
if (this->skip_call_tls_get_addr_)
{
- if (r_type != elfcpp::R_X86_64_PLT32
+ if ((r_type != elfcpp::R_X86_64_PLT32
+ && r_type != elfcpp::R_X86_64_PC32)
|| gsym == NULL
|| strcmp(gsym->name(), "__tls_get_addr") != 0)
{
if (this->saw_tls_block_reloc_)
value -= tls_segment->memsz();
}
- Relocate_functions<64, false>::rela32(view, value, 0);
+ Relocate_functions<64, false>::rela32(view, value, addend);
break;
case elfcpp::R_X86_64_DTPOFF64:
if (this->saw_tls_block_reloc_)
value -= tls_segment->memsz();
}
- Relocate_functions<64, false>::rela64(view, value, 0);
+ Relocate_functions<64, false>::rela64(view, value, addend);
break;
case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec
case elfcpp::R_X86_64_TPOFF32: // Local-exec
value -= tls_segment->memsz();
- Relocate_functions<64, false>::rela32(view, value, 0);
+ Relocate_functions<64, false>::rela32(view, value, addend);
break;
}
}