// 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.
#include "target-reloc.h"
#include "target-select.h"
#include "tls.h"
+#include "freebsd.h"
namespace
{
// http://people.redhat.com/drepper/tls.pdf
// http://www.lsd.ic.unicamp.br/~oliva/writeups/TLS/RFC-TLSDESC-x86.txt
-class Target_x86_64 : public Sized_target<64, false>
+class Target_x86_64 : public Target_freebsd<64, false>
{
public:
// In the x86_64 ABI (p 68), it says "The AMD64 ABI architectures
typedef Output_data_reloc<elfcpp::SHT_RELA, true, 64, false> Reloc_section;
Target_x86_64()
- : Sized_target<64, false>(&x86_64_info),
+ : Target_freebsd<64, false>(&x86_64_info),
got_(NULL), plt_(NULL), got_plt_(NULL), rela_dyn_(NULL),
copy_relocs_(elfcpp::R_X86_64_COPY), dynbss_(NULL),
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*);
void
Output_data_plt_x86_64::do_adjust_output_section(Output_section* os)
{
- // UnixWare sets the entsize of .plt to 4, and so does the old GNU
- // linker, and so do we.
- os->set_entsize(4);
+ os->set_entsize(plt_entry_size);
}
// Add an entry to the PLT.
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)
// error per object file.
if (this->issued_non_pic_error_)
return;
+ gold_assert(parameters->options().output_is_position_independent());
object->error(_("requires unsupported dynamic reloc; "
"recompile with -fPIC"));
this->issued_non_pic_error_ = 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)
{
// The selector for x86_64 object files.
-class Target_selector_x86_64 : public Target_selector
+class Target_selector_x86_64 : public Target_selector_freebsd
{
public:
Target_selector_x86_64()
- : Target_selector(elfcpp::EM_X86_64, 64, false, "elf64-x86-64")
+ : Target_selector_freebsd(elfcpp::EM_X86_64, 64, false, "elf64-x86-64",
+ "elf64-x86-64-freebsd")
{ }
Target*
do_instantiate_target()
{ return new Target_x86_64(); }
+
};
Target_selector_x86_64 target_selector_x86_64;