* object.h (Relobj::local_symbol_value): New function.
(Relobj::local_plt_offset): New function. (Relobj::local_has_got_offset): New function. (Relobj::local_got_offset): New function. (Relobj::set_local_got_offset): New function. (Relobj::do_local_symbol_value): New pure virtual function. (Relobj::do_local_plt_offset): Likewise. (Relobj::do_local_has_got_offset): Likewise. (Relobj::do_local_got_offset): Likewise. (Relobj::do_set_local_got_offset): Likewise. (Sized_relobj::do_local_has_got_offset): Rename from local_has_got_offset. (Sized_relobj::do_local_got_offset): Rename from local_got_offset. (Sized_relobj::do_set_local_got_offset): Rename from set_local_got_offset. (Sized_relobj_file::do_local_plt_offset): Rename from local_plt_offset. (Sized_relobj_file::do_local_symbol_value): New function. * object.cc (Sized_relobj_file::do_local_plt_offset): Rename from local_plt_offset. * output.cc (Output_data_got::Got_entry::write): Change object to Relobj. Use local_symbol_value. (Output_data_got::add_global_with_rel): Change rel_dyn to Output_data_reloc_generic*. Use add_global_generic. (Output_data_got::add_global_with_rela): Remove. Change all callers to use add_global_with_rel. (Output_data_got::add_global_pair_with_rel): Change rel_dyn to Output_data_reloc_generic*. Use add_global_generic. (Output_data_got::add_global_pair_with_rela): Remove. Change all callers to use add_global_pair_with_rel. (Output_data_got::add_local): Change object to Relobj*. (Output_data_got::add_local_plt): Likewise. (Output_data_got::add_local_with_rel): Change object to Relobj*, change rel_dyn to Output_data_reloc_generic*. Use add_local_generic. (Output_data_got::add_local_with_rela): Remove. Change all callers to use all_local_with_rel. (Output_data_got::add_local_pair_with_rel): Change object to Relobj*, change rel_dyn to Output_data_reloc_generic*. Use add_output_section_generic. (Output_data_got::add_local_pair_with_rela): Remove. Change all callers to use add_local_pair_with_rel. (Output_data_got::reserve_local): Change object to Relobj*. * output.h: (class Output_data_reloc_generic): Add pure virtual declarations for add_global_generic, add_local_generic, add_output_section_generic. (class Output_data_reloc) [SHT_REL, SHT_RELA]: Implement new functions for Output_data_reloc_generic. Update declarations for changes listed in output.cc. (class Output_data_got): Change template parameter to got_size. Don't define Rel_dyn or Rela_dyn. Update declarations per above. * incremental.h (Sized_relobj_incr::do_local_symbol_value): New function. (Sized_relobj_incr::do_local_plt_offset): New function. * copy-relocs.cc (Copy_relocs::Copy_reloc_entry::emit): Call add_global_generic.
This commit is contained in:
parent
984ac46443
commit
83896202bf
@ -1,3 +1,62 @@
|
||||
2011-12-18 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* object.h (Relobj::local_symbol_value): New function.
|
||||
(Relobj::local_plt_offset): New function.
|
||||
(Relobj::local_has_got_offset): New function.
|
||||
(Relobj::local_got_offset): New function.
|
||||
(Relobj::set_local_got_offset): New function.
|
||||
(Relobj::do_local_symbol_value): New pure virtual function.
|
||||
(Relobj::do_local_plt_offset): Likewise.
|
||||
(Relobj::do_local_has_got_offset): Likewise.
|
||||
(Relobj::do_local_got_offset): Likewise.
|
||||
(Relobj::do_set_local_got_offset): Likewise.
|
||||
(Sized_relobj::do_local_has_got_offset): Rename from
|
||||
local_has_got_offset.
|
||||
(Sized_relobj::do_local_got_offset): Rename from local_got_offset.
|
||||
(Sized_relobj::do_set_local_got_offset): Rename from
|
||||
set_local_got_offset.
|
||||
(Sized_relobj_file::do_local_plt_offset): Rename from
|
||||
local_plt_offset.
|
||||
(Sized_relobj_file::do_local_symbol_value): New function.
|
||||
* object.cc (Sized_relobj_file::do_local_plt_offset): Rename from
|
||||
local_plt_offset.
|
||||
* output.cc (Output_data_got::Got_entry::write): Change object to
|
||||
Relobj. Use local_symbol_value.
|
||||
(Output_data_got::add_global_with_rel): Change rel_dyn to
|
||||
Output_data_reloc_generic*. Use add_global_generic.
|
||||
(Output_data_got::add_global_with_rela): Remove. Change all
|
||||
callers to use add_global_with_rel.
|
||||
(Output_data_got::add_global_pair_with_rel): Change rel_dyn to
|
||||
Output_data_reloc_generic*. Use add_global_generic.
|
||||
(Output_data_got::add_global_pair_with_rela): Remove. Change all
|
||||
callers to use add_global_pair_with_rel.
|
||||
(Output_data_got::add_local): Change object to Relobj*.
|
||||
(Output_data_got::add_local_plt): Likewise.
|
||||
(Output_data_got::add_local_with_rel): Change object to Relobj*,
|
||||
change rel_dyn to Output_data_reloc_generic*. Use
|
||||
add_local_generic.
|
||||
(Output_data_got::add_local_with_rela): Remove. Change all
|
||||
callers to use all_local_with_rel.
|
||||
(Output_data_got::add_local_pair_with_rel): Change object to
|
||||
Relobj*, change rel_dyn to Output_data_reloc_generic*. Use
|
||||
add_output_section_generic.
|
||||
(Output_data_got::add_local_pair_with_rela): Remove. Change all
|
||||
callers to use add_local_pair_with_rel.
|
||||
(Output_data_got::reserve_local): Change object to Relobj*.
|
||||
* output.h: (class Output_data_reloc_generic): Add pure virtual
|
||||
declarations for add_global_generic, add_local_generic,
|
||||
add_output_section_generic.
|
||||
(class Output_data_reloc) [SHT_REL, SHT_RELA]: Implement new
|
||||
functions for Output_data_reloc_generic. Update declarations for
|
||||
changes listed in output.cc.
|
||||
(class Output_data_got): Change template parameter to got_size.
|
||||
Don't define Rel_dyn or Rela_dyn. Update declarations per above.
|
||||
* incremental.h (Sized_relobj_incr::do_local_symbol_value): New
|
||||
function.
|
||||
(Sized_relobj_incr::do_local_plt_offset): New function.
|
||||
* copy-relocs.cc (Copy_relocs::Copy_reloc_entry::emit): Call
|
||||
add_global_generic.
|
||||
|
||||
2011-12-17 Cary Coutant <ccoutant@google.com>
|
||||
|
||||
* dwarf_reader.cc (Sized_dwarf_line_info::read_lines): Add casts.
|
||||
|
@ -1,6 +1,6 @@
|
||||
// copy-relocs.cc -- handle COPY relocations for gold.
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -41,10 +41,10 @@ Copy_relocs<sh_type, size, big_endian>::Copy_reloc_entry::emit(
|
||||
// emitted a COPY relocation, and we do not want to emit this
|
||||
// dynamic relocation.
|
||||
if (this->sym_->is_from_dynobj())
|
||||
reloc_section->add_global(this->sym_, this->reloc_type_,
|
||||
this->output_section_, this->relobj_,
|
||||
this->shndx_, this->address_,
|
||||
this->addend_);
|
||||
reloc_section->add_global_generic(this->sym_, this->reloc_type_,
|
||||
this->output_section_, this->relobj_,
|
||||
this->shndx_, this->address_,
|
||||
this->addend_);
|
||||
}
|
||||
|
||||
// Copy_relocs methods.
|
||||
@ -115,7 +115,8 @@ Copy_relocs<sh_type, size, big_endian>::emit_copy_reloc(
|
||||
symtab->define_with_copy_reloc(sym, posd, offset);
|
||||
|
||||
// Add the COPY relocation to the dynamic reloc section.
|
||||
reloc_section->add_global(sym, this->copy_reloc_type_, posd, offset, 0);
|
||||
reloc_section->add_global_generic(sym, this->copy_reloc_type_, posd,
|
||||
offset, 0);
|
||||
}
|
||||
|
||||
// Make a COPY relocation for SYM and emit it.
|
||||
|
@ -1,6 +1,6 @@
|
||||
// expression.cc -- expressions in linker scripts for gold
|
||||
|
||||
// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
|
@ -1,6 +1,6 @@
|
||||
// inremental.h -- incremental linking support for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2009, 2010 Free Software Foundation, Inc.
|
||||
// Copyright 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
// Written by Mikolaj Zalewski <mikolajz@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -1924,6 +1924,15 @@ class Sized_relobj_incr : public Sized_relobj<size, big_endian>
|
||||
do_get_global_symbols() const
|
||||
{ return &this->symbols_; }
|
||||
|
||||
// Return the value of a local symbol.
|
||||
uint64_t
|
||||
do_local_symbol_value(unsigned int, uint64_t) const
|
||||
{ gold_unreachable(); }
|
||||
|
||||
unsigned int
|
||||
do_local_plt_offset(unsigned int) const
|
||||
{ gold_unreachable(); }
|
||||
|
||||
// Return the number of local symbols.
|
||||
unsigned int
|
||||
do_local_symbol_count() const
|
||||
|
@ -1819,7 +1819,8 @@ Sized_relobj_file<size, big_endian>::local_has_plt_offset(
|
||||
|
||||
template<int size, bool big_endian>
|
||||
unsigned int
|
||||
Sized_relobj_file<size, big_endian>::local_plt_offset(unsigned int symndx) const
|
||||
Sized_relobj_file<size, big_endian>::do_local_plt_offset(
|
||||
unsigned int symndx) const
|
||||
{
|
||||
typename Local_plt_offsets::const_iterator p =
|
||||
this->local_plt_offsets_.find(symndx);
|
||||
|
157
gold/object.h
157
gold/object.h
@ -1009,6 +1009,39 @@ class Relobj : public Object
|
||||
scan_relocs(Symbol_table* symtab, Layout* layout, Read_relocs_data* rd)
|
||||
{ return this->do_scan_relocs(symtab, layout, rd); }
|
||||
|
||||
// Return the value of the local symbol whose index is SYMNDX, plus
|
||||
// ADDEND. ADDEND is passed in so that we can correctly handle the
|
||||
// section symbol for a merge section.
|
||||
uint64_t
|
||||
local_symbol_value(unsigned int symndx, uint64_t addend) const
|
||||
{ return this->do_local_symbol_value(symndx, addend); }
|
||||
|
||||
// Return the PLT offset for a local symbol. It is an error to call
|
||||
// this if it doesn't have one.
|
||||
unsigned int
|
||||
local_plt_offset(unsigned int symndx) const
|
||||
{ return this->do_local_plt_offset(symndx); }
|
||||
|
||||
// Return whether the local symbol SYMNDX has a GOT offset of type
|
||||
// GOT_TYPE.
|
||||
bool
|
||||
local_has_got_offset(unsigned int symndx, unsigned int got_type) const
|
||||
{ return this->do_local_has_got_offset(symndx, got_type); }
|
||||
|
||||
// Return the GOT offset of type GOT_TYPE of the local symbol
|
||||
// SYMNDX. It is an error to call this if the symbol does not have
|
||||
// a GOT offset of the specified type.
|
||||
unsigned int
|
||||
local_got_offset(unsigned int symndx, unsigned int got_type) const
|
||||
{ return this->do_local_got_offset(symndx, got_type); }
|
||||
|
||||
// Set the GOT offset with type GOT_TYPE of the local symbol SYMNDX
|
||||
// to GOT_OFFSET.
|
||||
void
|
||||
set_local_got_offset(unsigned int symndx, unsigned int got_type,
|
||||
unsigned int got_offset)
|
||||
{ this->do_set_local_got_offset(symndx, got_type, got_offset); }
|
||||
|
||||
// The number of local symbols in the input symbol table.
|
||||
virtual unsigned int
|
||||
local_symbol_count() const
|
||||
@ -1167,6 +1200,28 @@ class Relobj : public Object
|
||||
virtual void
|
||||
do_scan_relocs(Symbol_table*, Layout*, Read_relocs_data*) = 0;
|
||||
|
||||
// Return the value of a local symbol.
|
||||
virtual uint64_t
|
||||
do_local_symbol_value(unsigned int symndx, uint64_t addend) const = 0;
|
||||
|
||||
// Return the PLT offset of a local symbol.
|
||||
virtual unsigned int
|
||||
do_local_plt_offset(unsigned int symndx) const = 0;
|
||||
|
||||
// Return whether a local symbol has a GOT offset of a given type.
|
||||
virtual bool
|
||||
do_local_has_got_offset(unsigned int symndx,
|
||||
unsigned int got_type) const = 0;
|
||||
|
||||
// Return the GOT offset of a given type of a local symbol.
|
||||
virtual unsigned int
|
||||
do_local_got_offset(unsigned int symndx, unsigned int got_type) const = 0;
|
||||
|
||||
// Set the GOT offset with a given type for a local symbol.
|
||||
virtual void
|
||||
do_set_local_got_offset(unsigned int symndx, unsigned int got_type,
|
||||
unsigned int got_offset) = 0;
|
||||
|
||||
// Return the number of local symbols--implemented by child class.
|
||||
virtual unsigned int
|
||||
do_local_symbol_count() const = 0;
|
||||
@ -1775,47 +1830,6 @@ class Sized_relobj : public Relobj
|
||||
return this->section_offsets_[shndx];
|
||||
}
|
||||
|
||||
// Return whether the local symbol SYMNDX has a GOT offset.
|
||||
// For TLS symbols, the GOT entry will hold its tp-relative offset.
|
||||
bool
|
||||
local_has_got_offset(unsigned int symndx, unsigned int got_type) const
|
||||
{
|
||||
Local_got_offsets::const_iterator p =
|
||||
this->local_got_offsets_.find(symndx);
|
||||
return (p != this->local_got_offsets_.end()
|
||||
&& p->second->get_offset(got_type) != -1U);
|
||||
}
|
||||
|
||||
// Return the GOT offset of the local symbol SYMNDX.
|
||||
unsigned int
|
||||
local_got_offset(unsigned int symndx, unsigned int got_type) const
|
||||
{
|
||||
Local_got_offsets::const_iterator p =
|
||||
this->local_got_offsets_.find(symndx);
|
||||
gold_assert(p != this->local_got_offsets_.end());
|
||||
unsigned int off = p->second->get_offset(got_type);
|
||||
gold_assert(off != -1U);
|
||||
return off;
|
||||
}
|
||||
|
||||
// Set the GOT offset of the local symbol SYMNDX to GOT_OFFSET.
|
||||
void
|
||||
set_local_got_offset(unsigned int symndx, unsigned int got_type,
|
||||
unsigned int got_offset)
|
||||
{
|
||||
Local_got_offsets::const_iterator p =
|
||||
this->local_got_offsets_.find(symndx);
|
||||
if (p != this->local_got_offsets_.end())
|
||||
p->second->set_offset(got_type, got_offset);
|
||||
else
|
||||
{
|
||||
Got_offset_list* g = new Got_offset_list(got_type, got_offset);
|
||||
std::pair<Local_got_offsets::iterator, bool> ins =
|
||||
this->local_got_offsets_.insert(std::make_pair(symndx, g));
|
||||
gold_assert(ins.second);
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over local symbols, calling a visitor class V for each GOT offset
|
||||
// associated with a local symbol.
|
||||
void
|
||||
@ -1855,6 +1869,49 @@ class Sized_relobj : public Relobj
|
||||
: convert_types<Address, uint64_t>(off));
|
||||
}
|
||||
|
||||
// Return whether the local symbol SYMNDX has a GOT offset of type
|
||||
// GOT_TYPE.
|
||||
bool
|
||||
do_local_has_got_offset(unsigned int symndx, unsigned int got_type) const
|
||||
{
|
||||
Local_got_offsets::const_iterator p =
|
||||
this->local_got_offsets_.find(symndx);
|
||||
return (p != this->local_got_offsets_.end()
|
||||
&& p->second->get_offset(got_type) != -1U);
|
||||
}
|
||||
|
||||
// Return the GOT offset of type GOT_TYPE of the local symbol
|
||||
// SYMNDX.
|
||||
unsigned int
|
||||
do_local_got_offset(unsigned int symndx, unsigned int got_type) const
|
||||
{
|
||||
Local_got_offsets::const_iterator p =
|
||||
this->local_got_offsets_.find(symndx);
|
||||
gold_assert(p != this->local_got_offsets_.end());
|
||||
unsigned int off = p->second->get_offset(got_type);
|
||||
gold_assert(off != -1U);
|
||||
return off;
|
||||
}
|
||||
|
||||
// Set the GOT offset with type GOT_TYPE of the local symbol SYMNDX
|
||||
// to GOT_OFFSET.
|
||||
void
|
||||
do_set_local_got_offset(unsigned int symndx, unsigned int got_type,
|
||||
unsigned int got_offset)
|
||||
{
|
||||
Local_got_offsets::const_iterator p =
|
||||
this->local_got_offsets_.find(symndx);
|
||||
if (p != this->local_got_offsets_.end())
|
||||
p->second->set_offset(got_type, got_offset);
|
||||
else
|
||||
{
|
||||
Got_offset_list* g = new Got_offset_list(got_type, got_offset);
|
||||
std::pair<Local_got_offsets::iterator, bool> ins =
|
||||
this->local_got_offsets_.insert(std::make_pair(symndx, g));
|
||||
gold_assert(ins.second);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// The GOT offsets of local symbols. This map also stores GOT offsets
|
||||
// for tp-relative offsets for TLS symbols.
|
||||
@ -2000,11 +2057,6 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
|
||||
bool
|
||||
local_has_plt_offset(unsigned int symndx) const;
|
||||
|
||||
// Return the PLT offset for a local symbol. It is an error to call
|
||||
// this if it doesn't have one.
|
||||
unsigned int
|
||||
local_plt_offset(unsigned int symndx) const;
|
||||
|
||||
// Set the PLT offset of the local symbol SYMNDX.
|
||||
void
|
||||
set_local_plt_offset(unsigned int symndx, unsigned int plt_offset);
|
||||
@ -2050,6 +2102,19 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
|
||||
void
|
||||
do_read_symbols(Read_symbols_data*);
|
||||
|
||||
// Return the value of a local symbol.
|
||||
uint64_t
|
||||
do_local_symbol_value(unsigned int symndx, uint64_t addend) const
|
||||
{
|
||||
const Symbol_value<size>* symval = this->local_symbol(symndx);
|
||||
return symval->value(this, addend);
|
||||
}
|
||||
|
||||
// Return the PLT offset for a local symbol. It is an error to call
|
||||
// this if it doesn't have one.
|
||||
unsigned int
|
||||
do_local_plt_offset(unsigned int symndx) const;
|
||||
|
||||
// Return the number of local symbols.
|
||||
unsigned int
|
||||
do_local_symbol_count() const
|
||||
|
118
gold/output.cc
118
gold/output.cc
@ -1387,11 +1387,13 @@ Output_data_got<size, big_endian>::Got_entry::write(unsigned char* pov) const
|
||||
|
||||
default:
|
||||
{
|
||||
const Sized_relobj_file<size, big_endian>* object = this->u_.object;
|
||||
const Relobj* object = this->u_.object;
|
||||
const unsigned int lsi = this->local_sym_index_;
|
||||
const Symbol_value<size>* symval = object->local_symbol(lsi);
|
||||
if (!this->use_plt_offset_)
|
||||
val = symval->value(this->u_.object, 0);
|
||||
{
|
||||
uint64_t lval = object->local_symbol_value(lsi, 0);
|
||||
val = convert_types<Valtype, uint64_t>(lval);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t plt_address =
|
||||
@ -1448,7 +1450,7 @@ void
|
||||
Output_data_got<size, big_endian>::add_global_with_rel(
|
||||
Symbol* gsym,
|
||||
unsigned int got_type,
|
||||
Rel_dyn* rel_dyn,
|
||||
Output_data_reloc_generic* rel_dyn,
|
||||
unsigned int r_type)
|
||||
{
|
||||
if (gsym->has_got_offset(got_type))
|
||||
@ -1456,23 +1458,7 @@ Output_data_got<size, big_endian>::add_global_with_rel(
|
||||
|
||||
unsigned int got_offset = this->add_got_entry(Got_entry());
|
||||
gsym->set_got_offset(got_type, got_offset);
|
||||
rel_dyn->add_global(gsym, r_type, this, got_offset);
|
||||
}
|
||||
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Output_data_got<size, big_endian>::add_global_with_rela(
|
||||
Symbol* gsym,
|
||||
unsigned int got_type,
|
||||
Rela_dyn* rela_dyn,
|
||||
unsigned int r_type)
|
||||
{
|
||||
if (gsym->has_got_offset(got_type))
|
||||
return;
|
||||
|
||||
unsigned int got_offset = this->add_got_entry(Got_entry());
|
||||
gsym->set_got_offset(got_type, got_offset);
|
||||
rela_dyn->add_global(gsym, r_type, this, got_offset, 0);
|
||||
rel_dyn->add_global_generic(gsym, r_type, this, got_offset, 0);
|
||||
}
|
||||
|
||||
// Add a pair of entries for a global symbol to the GOT, and add
|
||||
@ -1483,7 +1469,7 @@ void
|
||||
Output_data_got<size, big_endian>::add_global_pair_with_rel(
|
||||
Symbol* gsym,
|
||||
unsigned int got_type,
|
||||
Rel_dyn* rel_dyn,
|
||||
Output_data_reloc_generic* rel_dyn,
|
||||
unsigned int r_type_1,
|
||||
unsigned int r_type_2)
|
||||
{
|
||||
@ -1492,30 +1478,11 @@ Output_data_got<size, big_endian>::add_global_pair_with_rel(
|
||||
|
||||
unsigned int got_offset = this->add_got_entry_pair(Got_entry(), Got_entry());
|
||||
gsym->set_got_offset(got_type, got_offset);
|
||||
rel_dyn->add_global(gsym, r_type_1, this, got_offset);
|
||||
rel_dyn->add_global_generic(gsym, r_type_1, this, got_offset, 0);
|
||||
|
||||
if (r_type_2 != 0)
|
||||
rel_dyn->add_global(gsym, r_type_2, this, got_offset + size / 8);
|
||||
}
|
||||
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Output_data_got<size, big_endian>::add_global_pair_with_rela(
|
||||
Symbol* gsym,
|
||||
unsigned int got_type,
|
||||
Rela_dyn* rela_dyn,
|
||||
unsigned int r_type_1,
|
||||
unsigned int r_type_2)
|
||||
{
|
||||
if (gsym->has_got_offset(got_type))
|
||||
return;
|
||||
|
||||
unsigned int got_offset = this->add_got_entry_pair(Got_entry(), Got_entry());
|
||||
gsym->set_got_offset(got_type, got_offset);
|
||||
rela_dyn->add_global(gsym, r_type_1, this, got_offset, 0);
|
||||
|
||||
if (r_type_2 != 0)
|
||||
rela_dyn->add_global(gsym, r_type_2, this, got_offset + size / 8, 0);
|
||||
rel_dyn->add_global_generic(gsym, r_type_2, this,
|
||||
got_offset + size / 8, 0);
|
||||
}
|
||||
|
||||
// Add an entry for a local symbol to the GOT. This returns true if
|
||||
@ -1525,7 +1492,7 @@ Output_data_got<size, big_endian>::add_global_pair_with_rela(
|
||||
template<int size, bool big_endian>
|
||||
bool
|
||||
Output_data_got<size, big_endian>::add_local(
|
||||
Sized_relobj_file<size, big_endian>* object,
|
||||
Relobj* object,
|
||||
unsigned int symndx,
|
||||
unsigned int got_type)
|
||||
{
|
||||
@ -1543,7 +1510,7 @@ Output_data_got<size, big_endian>::add_local(
|
||||
template<int size, bool big_endian>
|
||||
bool
|
||||
Output_data_got<size, big_endian>::add_local_plt(
|
||||
Sized_relobj_file<size, big_endian>* object,
|
||||
Relobj* object,
|
||||
unsigned int symndx,
|
||||
unsigned int got_type)
|
||||
{
|
||||
@ -1562,10 +1529,10 @@ Output_data_got<size, big_endian>::add_local_plt(
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Output_data_got<size, big_endian>::add_local_with_rel(
|
||||
Sized_relobj_file<size, big_endian>* object,
|
||||
Relobj* object,
|
||||
unsigned int symndx,
|
||||
unsigned int got_type,
|
||||
Rel_dyn* rel_dyn,
|
||||
Output_data_reloc_generic* rel_dyn,
|
||||
unsigned int r_type)
|
||||
{
|
||||
if (object->local_has_got_offset(symndx, got_type))
|
||||
@ -1573,24 +1540,7 @@ Output_data_got<size, big_endian>::add_local_with_rel(
|
||||
|
||||
unsigned int got_offset = this->add_got_entry(Got_entry());
|
||||
object->set_local_got_offset(symndx, got_type, got_offset);
|
||||
rel_dyn->add_local(object, symndx, r_type, this, got_offset);
|
||||
}
|
||||
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Output_data_got<size, big_endian>::add_local_with_rela(
|
||||
Sized_relobj_file<size, big_endian>* object,
|
||||
unsigned int symndx,
|
||||
unsigned int got_type,
|
||||
Rela_dyn* rela_dyn,
|
||||
unsigned int r_type)
|
||||
{
|
||||
if (object->local_has_got_offset(symndx, got_type))
|
||||
return;
|
||||
|
||||
unsigned int got_offset = this->add_got_entry(Got_entry());
|
||||
object->set_local_got_offset(symndx, got_type, got_offset);
|
||||
rela_dyn->add_local(object, symndx, r_type, this, got_offset, 0);
|
||||
rel_dyn->add_local_generic(object, symndx, r_type, this, got_offset, 0);
|
||||
}
|
||||
|
||||
// Add a pair of entries for a local symbol to the GOT, and add
|
||||
@ -1599,11 +1549,11 @@ Output_data_got<size, big_endian>::add_local_with_rela(
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Output_data_got<size, big_endian>::add_local_pair_with_rel(
|
||||
Sized_relobj_file<size, big_endian>* object,
|
||||
Relobj* object,
|
||||
unsigned int symndx,
|
||||
unsigned int shndx,
|
||||
unsigned int got_type,
|
||||
Rel_dyn* rel_dyn,
|
||||
Output_data_reloc_generic* rel_dyn,
|
||||
unsigned int r_type_1,
|
||||
unsigned int r_type_2)
|
||||
{
|
||||
@ -1615,35 +1565,11 @@ Output_data_got<size, big_endian>::add_local_pair_with_rel(
|
||||
Got_entry(object, symndx, false));
|
||||
object->set_local_got_offset(symndx, got_type, got_offset);
|
||||
Output_section* os = object->output_section(shndx);
|
||||
rel_dyn->add_output_section(os, r_type_1, this, got_offset);
|
||||
rel_dyn->add_output_section_generic(os, r_type_1, this, got_offset, 0);
|
||||
|
||||
if (r_type_2 != 0)
|
||||
rel_dyn->add_output_section(os, r_type_2, this, got_offset + size / 8);
|
||||
}
|
||||
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Output_data_got<size, big_endian>::add_local_pair_with_rela(
|
||||
Sized_relobj_file<size, big_endian>* object,
|
||||
unsigned int symndx,
|
||||
unsigned int shndx,
|
||||
unsigned int got_type,
|
||||
Rela_dyn* rela_dyn,
|
||||
unsigned int r_type_1,
|
||||
unsigned int r_type_2)
|
||||
{
|
||||
if (object->local_has_got_offset(symndx, got_type))
|
||||
return;
|
||||
|
||||
unsigned int got_offset =
|
||||
this->add_got_entry_pair(Got_entry(),
|
||||
Got_entry(object, symndx, false));
|
||||
object->set_local_got_offset(symndx, got_type, got_offset);
|
||||
Output_section* os = object->output_section(shndx);
|
||||
rela_dyn->add_output_section(os, r_type_1, this, got_offset, 0);
|
||||
|
||||
if (r_type_2 != 0)
|
||||
rela_dyn->add_output_section(os, r_type_2, this, got_offset + size / 8, 0);
|
||||
rel_dyn->add_output_section_generic(os, r_type_2, this,
|
||||
got_offset + size / 8, 0);
|
||||
}
|
||||
|
||||
// Reserve a slot in the GOT for a local symbol or the second slot of a pair.
|
||||
@ -1652,7 +1578,7 @@ template<int size, bool big_endian>
|
||||
void
|
||||
Output_data_got<size, big_endian>::reserve_local(
|
||||
unsigned int i,
|
||||
Sized_relobj<size, big_endian>* object,
|
||||
Relobj* object,
|
||||
unsigned int sym_index,
|
||||
unsigned int got_type)
|
||||
{
|
||||
|
266
gold/output.h
266
gold/output.h
@ -1397,6 +1397,55 @@ class Output_data_reloc_generic : public Output_section_data_build
|
||||
sort_relocs() const
|
||||
{ return this->sort_relocs_; }
|
||||
|
||||
// Add a reloc of type TYPE against the global symbol GSYM. The
|
||||
// relocation applies to the data at offset ADDRESS within OD.
|
||||
virtual void
|
||||
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
uint64_t address, uint64_t addend) = 0;
|
||||
|
||||
// Add a reloc of type TYPE against the global symbol GSYM. The
|
||||
// relocation applies to data at offset ADDRESS within section SHNDX
|
||||
// of object file RELOBJ. OD is the associated output section.
|
||||
virtual void
|
||||
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
Relobj* relobj, unsigned int shndx, uint64_t address,
|
||||
uint64_t addend) = 0;
|
||||
|
||||
// Add a reloc of type TYPE against the local symbol LOCAL_SYM_INDEX
|
||||
// in RELOBJ. The relocation applies to the data at offset ADDRESS
|
||||
// within OD.
|
||||
virtual void
|
||||
add_local_generic(Relobj* relobj, unsigned int local_sym_index,
|
||||
unsigned int type, Output_data* od, uint64_t address,
|
||||
uint64_t addend) = 0;
|
||||
|
||||
// Add a reloc of type TYPE against the local symbol LOCAL_SYM_INDEX
|
||||
// in RELOBJ. The relocation applies to the data at offset ADDRESS
|
||||
// within section SHNDX of RELOBJ. OD is the associated output
|
||||
// section.
|
||||
virtual void
|
||||
add_local_generic(Relobj* relobj, unsigned int local_sym_index,
|
||||
unsigned int type, Output_data* od, unsigned int shndx,
|
||||
uint64_t address, uint64_t addend) = 0;
|
||||
|
||||
// Add a reloc of type TYPE against the STT_SECTION symbol of the
|
||||
// output section OS. The relocation applies to the data at offset
|
||||
// ADDRESS within OD.
|
||||
virtual void
|
||||
add_output_section_generic(Output_section *os, unsigned int type,
|
||||
Output_data* od, uint64_t address,
|
||||
uint64_t addend) = 0;
|
||||
|
||||
// Add a reloc of type TYPE against the STT_SECTION symbol of the
|
||||
// output section OS. The relocation applies to the data at offset
|
||||
// ADDRESS within section SHNDX of RELOBJ. OD is the associated
|
||||
// output section.
|
||||
virtual void
|
||||
add_output_section_generic(Output_section* os, unsigned int type,
|
||||
Output_data* od, Relobj* relobj,
|
||||
unsigned int shndx, uint64_t address,
|
||||
uint64_t addend) = 0;
|
||||
|
||||
protected:
|
||||
// Note that we've added another relative reloc.
|
||||
void
|
||||
@ -1518,23 +1567,27 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
||||
false, false)); }
|
||||
|
||||
// These are to simplify the Copy_relocs class.
|
||||
|
||||
void
|
||||
add_global(Symbol* gsym, unsigned int type, Output_data* od, Address address,
|
||||
Address addend)
|
||||
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
uint64_t address, uint64_t addend)
|
||||
{
|
||||
gold_assert(addend == 0);
|
||||
this->add_global(gsym, type, od, address);
|
||||
this->add(od, Output_reloc_type(gsym, type, od,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
false, false));
|
||||
}
|
||||
|
||||
void
|
||||
add_global(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
Sized_relobj<size, big_endian>* relobj,
|
||||
unsigned int shndx, Address address, Address addend)
|
||||
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
Relobj* relobj, unsigned int shndx, uint64_t address,
|
||||
uint64_t addend)
|
||||
{
|
||||
gold_assert(addend == 0);
|
||||
this->add_global(gsym, type, od, relobj, shndx, address);
|
||||
Sized_relobj<size, big_endian>* sized_relobj =
|
||||
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
||||
this->add(od, Output_reloc_type(gsym, type, sized_relobj, shndx,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
false, false));
|
||||
}
|
||||
|
||||
// Add a RELATIVE reloc against a global symbol. The final relocation
|
||||
@ -1592,6 +1645,32 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
address, false, false, false, false));
|
||||
}
|
||||
|
||||
void
|
||||
add_local_generic(Relobj* relobj, unsigned int local_sym_index,
|
||||
unsigned int type, Output_data* od, uint64_t address,
|
||||
uint64_t addend)
|
||||
{
|
||||
gold_assert(addend == 0);
|
||||
Sized_relobj<size, big_endian>* sized_relobj =
|
||||
static_cast<Sized_relobj<size, big_endian> *>(relobj);
|
||||
this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, od,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
false, false, false, false));
|
||||
}
|
||||
|
||||
void
|
||||
add_local_generic(Relobj* relobj, unsigned int local_sym_index,
|
||||
unsigned int type, Output_data* od, unsigned int shndx,
|
||||
uint64_t address, uint64_t addend)
|
||||
{
|
||||
gold_assert(addend == 0);
|
||||
Sized_relobj<size, big_endian>* sized_relobj =
|
||||
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
||||
this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, shndx,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
false, false, false, false));
|
||||
}
|
||||
|
||||
// Add a RELATIVE reloc against a local symbol.
|
||||
|
||||
void
|
||||
@ -1671,6 +1750,29 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
unsigned int shndx, Address address)
|
||||
{ this->add(od, Output_reloc_type(os, type, relobj, shndx, address)); }
|
||||
|
||||
void
|
||||
add_output_section_generic(Output_section* os, unsigned int type,
|
||||
Output_data* od, uint64_t address,
|
||||
uint64_t addend)
|
||||
{
|
||||
gold_assert(addend == 0);
|
||||
this->add(od, Output_reloc_type(os, type, od,
|
||||
convert_types<Address, uint64_t>(address)));
|
||||
}
|
||||
|
||||
void
|
||||
add_output_section_generic(Output_section* os, unsigned int type,
|
||||
Output_data* od, Relobj* relobj,
|
||||
unsigned int shndx, uint64_t address,
|
||||
uint64_t addend)
|
||||
{
|
||||
gold_assert(addend == 0);
|
||||
Sized_relobj<size, big_endian>* sized_relobj =
|
||||
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
||||
this->add(od, Output_reloc_type(os, type, sized_relobj, shndx,
|
||||
convert_types<Address, uint64_t>(address)));
|
||||
}
|
||||
|
||||
// Add an absolute relocation.
|
||||
|
||||
void
|
||||
@ -1733,6 +1835,29 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
||||
addend, false, false)); }
|
||||
|
||||
void
|
||||
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
uint64_t address, uint64_t addend)
|
||||
{
|
||||
this->add(od, Output_reloc_type(gsym, type, od,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
convert_types<Addend, uint64_t>(addend),
|
||||
false, false));
|
||||
}
|
||||
|
||||
void
|
||||
add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
|
||||
Relobj* relobj, unsigned int shndx, uint64_t address,
|
||||
uint64_t addend)
|
||||
{
|
||||
Sized_relobj<size, big_endian>* sized_relobj =
|
||||
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
||||
this->add(od, Output_reloc_type(gsym, type, sized_relobj, shndx,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
convert_types<Addend, uint64_t>(addend),
|
||||
false, false));
|
||||
}
|
||||
|
||||
// Add a RELATIVE reloc against a global symbol. The final output
|
||||
// relocation will not reference the symbol, but we must keep the symbol
|
||||
// information long enough to set the addend of the relocation correctly
|
||||
@ -1790,6 +1915,32 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
false));
|
||||
}
|
||||
|
||||
void
|
||||
add_local_generic(Relobj* relobj, unsigned int local_sym_index,
|
||||
unsigned int type, Output_data* od, uint64_t address,
|
||||
uint64_t addend)
|
||||
{
|
||||
Sized_relobj<size, big_endian>* sized_relobj =
|
||||
static_cast<Sized_relobj<size, big_endian> *>(relobj);
|
||||
this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, od,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
convert_types<Addend, uint64_t>(addend),
|
||||
false, false, false, false));
|
||||
}
|
||||
|
||||
void
|
||||
add_local_generic(Relobj* relobj, unsigned int local_sym_index,
|
||||
unsigned int type, Output_data* od, unsigned int shndx,
|
||||
uint64_t address, uint64_t addend)
|
||||
{
|
||||
Sized_relobj<size, big_endian>* sized_relobj =
|
||||
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
||||
this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, shndx,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
convert_types<Addend, uint64_t>(addend),
|
||||
false, false, false, false));
|
||||
}
|
||||
|
||||
// Add a RELATIVE reloc against a local symbol.
|
||||
|
||||
void
|
||||
@ -1875,6 +2026,29 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
{ this->add(od, Output_reloc_type(os, type, relobj, shndx, address,
|
||||
addend)); }
|
||||
|
||||
void
|
||||
add_output_section_generic(Output_section* os, unsigned int type,
|
||||
Output_data* od, uint64_t address,
|
||||
uint64_t addend)
|
||||
{
|
||||
this->add(od, Output_reloc_type(os, type, od,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
convert_types<Addend, uint64_t>(addend)));
|
||||
}
|
||||
|
||||
void
|
||||
add_output_section_generic(Output_section* os, unsigned int type,
|
||||
Output_data* od, Relobj* relobj,
|
||||
unsigned int shndx, uint64_t address,
|
||||
uint64_t addend)
|
||||
{
|
||||
Sized_relobj<size, big_endian>* sized_relobj =
|
||||
static_cast<Sized_relobj<size, big_endian>*>(relobj);
|
||||
this->add(od, Output_reloc_type(os, type, sized_relobj, shndx,
|
||||
convert_types<Address, uint64_t>(address),
|
||||
convert_types<Addend, uint64_t>(addend)));
|
||||
}
|
||||
|
||||
// Add an absolute relocation.
|
||||
|
||||
void
|
||||
@ -1974,29 +2148,28 @@ class Output_data_group : public Output_section_data
|
||||
// Output_data_got is used to manage a GOT. Each entry in the GOT is
|
||||
// for one symbol--either a global symbol or a local symbol in an
|
||||
// object. The target specific code adds entries to the GOT as
|
||||
// needed.
|
||||
// needed. The GOT_SIZE template parameter is the size in bits of a
|
||||
// GOT entry, typically 32 or 64.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
template<int got_size, bool big_endian>
|
||||
class Output_data_got : public Output_section_data_build
|
||||
{
|
||||
public:
|
||||
typedef typename elfcpp::Elf_types<size>::Elf_Addr Valtype;
|
||||
typedef Output_data_reloc<elfcpp::SHT_REL, true, size, big_endian> Rel_dyn;
|
||||
typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian> Rela_dyn;
|
||||
typedef typename elfcpp::Elf_types<got_size>::Elf_Addr Valtype;
|
||||
|
||||
Output_data_got()
|
||||
: Output_section_data_build(Output_data::default_alignment_for_size(size)),
|
||||
: Output_section_data_build(Output_data::default_alignment_for_size(got_size)),
|
||||
entries_(), free_list_()
|
||||
{ }
|
||||
|
||||
Output_data_got(off_t data_size)
|
||||
: Output_section_data_build(data_size,
|
||||
Output_data::default_alignment_for_size(size)),
|
||||
Output_data::default_alignment_for_size(got_size)),
|
||||
entries_(), free_list_()
|
||||
{
|
||||
// For an incremental update, we have an existing GOT section.
|
||||
// Initialize the list of entries and the free list.
|
||||
this->entries_.resize(data_size / (size / 8));
|
||||
this->entries_.resize(data_size / (got_size / 8));
|
||||
this->free_list_.init(data_size, false);
|
||||
}
|
||||
|
||||
@ -2014,62 +2187,39 @@ class Output_data_got : public Output_section_data_build
|
||||
// relocation of type R_TYPE for the GOT entry.
|
||||
void
|
||||
add_global_with_rel(Symbol* gsym, unsigned int got_type,
|
||||
Rel_dyn* rel_dyn, unsigned int r_type);
|
||||
|
||||
void
|
||||
add_global_with_rela(Symbol* gsym, unsigned int got_type,
|
||||
Rela_dyn* rela_dyn, unsigned int r_type);
|
||||
Output_data_reloc_generic* rel_dyn, unsigned int r_type);
|
||||
|
||||
// Add a pair of entries for a global symbol to the GOT, and add
|
||||
// dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively.
|
||||
void
|
||||
add_global_pair_with_rel(Symbol* gsym, unsigned int got_type,
|
||||
Rel_dyn* rel_dyn, unsigned int r_type_1,
|
||||
unsigned int r_type_2);
|
||||
|
||||
void
|
||||
add_global_pair_with_rela(Symbol* gsym, unsigned int got_type,
|
||||
Rela_dyn* rela_dyn, unsigned int r_type_1,
|
||||
unsigned int r_type_2);
|
||||
Output_data_reloc_generic* rel_dyn,
|
||||
unsigned int r_type_1, unsigned int r_type_2);
|
||||
|
||||
// Add an entry for a local symbol to the GOT. This returns true if
|
||||
// this is a new GOT entry, false if the symbol already has a GOT
|
||||
// entry.
|
||||
bool
|
||||
add_local(Sized_relobj_file<size, big_endian>* object, unsigned int sym_index,
|
||||
unsigned int got_type);
|
||||
add_local(Relobj* object, unsigned int sym_index, unsigned int got_type);
|
||||
|
||||
// Like add_local, but use the PLT offset of the local symbol if it
|
||||
// has one.
|
||||
bool
|
||||
add_local_plt(Sized_relobj_file<size, big_endian>* object,
|
||||
unsigned int sym_index,
|
||||
unsigned int got_type);
|
||||
add_local_plt(Relobj* object, unsigned int sym_index, unsigned int got_type);
|
||||
|
||||
// Add an entry for a local symbol to the GOT, and add a dynamic
|
||||
// relocation of type R_TYPE for the GOT entry.
|
||||
void
|
||||
add_local_with_rel(Sized_relobj_file<size, big_endian>* object,
|
||||
unsigned int sym_index, unsigned int got_type,
|
||||
Rel_dyn* rel_dyn, unsigned int r_type);
|
||||
|
||||
void
|
||||
add_local_with_rela(Sized_relobj_file<size, big_endian>* object,
|
||||
unsigned int sym_index, unsigned int got_type,
|
||||
Rela_dyn* rela_dyn, unsigned int r_type);
|
||||
add_local_with_rel(Relobj* object, unsigned int sym_index,
|
||||
unsigned int got_type, Output_data_reloc_generic* rel_dyn,
|
||||
unsigned int r_type);
|
||||
|
||||
// Add a pair of entries for a local symbol to the GOT, and add
|
||||
// dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively.
|
||||
void
|
||||
add_local_pair_with_rel(Sized_relobj_file<size, big_endian>* object,
|
||||
unsigned int sym_index, unsigned int shndx,
|
||||
unsigned int got_type, Rel_dyn* rel_dyn,
|
||||
unsigned int r_type_1, unsigned int r_type_2);
|
||||
|
||||
void
|
||||
add_local_pair_with_rela(Sized_relobj_file<size, big_endian>* object,
|
||||
unsigned int sym_index, unsigned int shndx,
|
||||
unsigned int got_type, Rela_dyn* rela_dyn,
|
||||
add_local_pair_with_rel(Relobj* object, unsigned int sym_index,
|
||||
unsigned int shndx, unsigned int got_type,
|
||||
Output_data_reloc_generic* rel_dyn,
|
||||
unsigned int r_type_1, unsigned int r_type_2);
|
||||
|
||||
// Add a constant to the GOT. This returns the offset of the new
|
||||
@ -2084,12 +2234,12 @@ class Output_data_got : public Output_section_data_build
|
||||
// Reserve a slot in the GOT.
|
||||
void
|
||||
reserve_slot(unsigned int i)
|
||||
{ this->free_list_.remove(i * size / 8, (i + 1) * size / 8); }
|
||||
{ this->free_list_.remove(i * got_size / 8, (i + 1) * got_size / 8); }
|
||||
|
||||
// Reserve a slot in the GOT for a local symbol.
|
||||
void
|
||||
reserve_local(unsigned int i, Sized_relobj<size, big_endian>* object,
|
||||
unsigned int sym_index, unsigned int got_type);
|
||||
reserve_local(unsigned int i, Relobj* object, unsigned int sym_index,
|
||||
unsigned int got_type);
|
||||
|
||||
// Reserve a slot in the GOT for a global symbol.
|
||||
void
|
||||
@ -2121,8 +2271,8 @@ class Output_data_got : public Output_section_data_build
|
||||
{ this->u_.gsym = gsym; }
|
||||
|
||||
// Create a local symbol entry.
|
||||
Got_entry(Sized_relobj_file<size, big_endian>* object,
|
||||
unsigned int local_sym_index, bool use_plt_offset)
|
||||
Got_entry(Relobj* object, unsigned int local_sym_index,
|
||||
bool use_plt_offset)
|
||||
: local_sym_index_(local_sym_index), use_plt_offset_(use_plt_offset)
|
||||
{
|
||||
gold_assert(local_sym_index != GSYM_CODE
|
||||
@ -2153,7 +2303,7 @@ class Output_data_got : public Output_section_data_build
|
||||
union
|
||||
{
|
||||
// For a local symbol, the object.
|
||||
Sized_relobj_file<size, big_endian>* object;
|
||||
Relobj* object;
|
||||
// For a global symbol, the symbol.
|
||||
Symbol* gsym;
|
||||
// For a constant, the constant.
|
||||
@ -2179,7 +2329,7 @@ class Output_data_got : public Output_section_data_build
|
||||
// Return the offset into the GOT of GOT entry I.
|
||||
unsigned int
|
||||
got_offset(unsigned int i) const
|
||||
{ return i * (size / 8); }
|
||||
{ return i * (got_size / 8); }
|
||||
|
||||
// Return the offset into the GOT of the last entry added.
|
||||
unsigned int
|
||||
|
@ -1566,8 +1566,8 @@ Target_powerpc<size, big_endian>::Scan::global(
|
||||
if (gsym->is_from_dynobj()
|
||||
|| gsym->is_undefined()
|
||||
|| gsym->is_preemptible())
|
||||
got->add_global_with_rela(gsym, GOT_TYPE_STANDARD, rela_dyn,
|
||||
elfcpp::R_POWERPC_GLOB_DAT);
|
||||
got->add_global_with_rel(gsym, GOT_TYPE_STANDARD, rela_dyn,
|
||||
elfcpp::R_POWERPC_GLOB_DAT);
|
||||
else if (!gsym->has_got_offset(GOT_TYPE_STANDARD))
|
||||
{
|
||||
unsigned int off = got->add_constant(0);
|
||||
|
@ -1998,14 +1998,14 @@ Target_sparc<size, big_endian>::Scan::local(
|
||||
object->error(_("local symbol %u has bad shndx %u"),
|
||||
r_sym, shndx);
|
||||
else
|
||||
got->add_local_pair_with_rela(object, r_sym,
|
||||
lsym.get_st_shndx(),
|
||||
GOT_TYPE_TLS_PAIR,
|
||||
target->rela_dyn_section(layout),
|
||||
(size == 64
|
||||
? elfcpp::R_SPARC_TLS_DTPMOD64
|
||||
: elfcpp::R_SPARC_TLS_DTPMOD32),
|
||||
0);
|
||||
got->add_local_pair_with_rel(object, r_sym,
|
||||
lsym.get_st_shndx(),
|
||||
GOT_TYPE_TLS_PAIR,
|
||||
target->rela_dyn_section(layout),
|
||||
(size == 64
|
||||
? elfcpp::R_SPARC_TLS_DTPMOD64
|
||||
: elfcpp::R_SPARC_TLS_DTPMOD32),
|
||||
0);
|
||||
if (r_type == elfcpp::R_SPARC_TLS_GD_CALL)
|
||||
generate_tls_call(symtab, layout, target);
|
||||
}
|
||||
@ -2339,8 +2339,8 @@ Target_sparc<size, big_endian>::Scan::global(
|
||||
if (gsym->is_from_dynobj()
|
||||
|| gsym->is_undefined()
|
||||
|| gsym->is_preemptible())
|
||||
got->add_global_with_rela(gsym, GOT_TYPE_STANDARD, rela_dyn,
|
||||
elfcpp::R_SPARC_GLOB_DAT);
|
||||
got->add_global_with_rel(gsym, GOT_TYPE_STANDARD, rela_dyn,
|
||||
elfcpp::R_SPARC_GLOB_DAT);
|
||||
else if (!gsym->has_got_offset(GOT_TYPE_STANDARD))
|
||||
{
|
||||
unsigned int off = got->add_constant(0);
|
||||
@ -2389,14 +2389,14 @@ Target_sparc<size, big_endian>::Scan::global(
|
||||
// dtv-relative offset.
|
||||
Output_data_got<size, big_endian>* got
|
||||
= target->got_section(symtab, layout);
|
||||
got->add_global_pair_with_rela(gsym, GOT_TYPE_TLS_PAIR,
|
||||
target->rela_dyn_section(layout),
|
||||
(size == 64 ?
|
||||
elfcpp::R_SPARC_TLS_DTPMOD64 :
|
||||
elfcpp::R_SPARC_TLS_DTPMOD32),
|
||||
(size == 64 ?
|
||||
elfcpp::R_SPARC_TLS_DTPOFF64 :
|
||||
elfcpp::R_SPARC_TLS_DTPOFF32));
|
||||
got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR,
|
||||
target->rela_dyn_section(layout),
|
||||
(size == 64
|
||||
? elfcpp::R_SPARC_TLS_DTPMOD64
|
||||
: elfcpp::R_SPARC_TLS_DTPMOD32),
|
||||
(size == 64
|
||||
? elfcpp::R_SPARC_TLS_DTPOFF64
|
||||
: elfcpp::R_SPARC_TLS_DTPOFF32));
|
||||
|
||||
// Emit R_SPARC_WPLT30 against "__tls_get_addr"
|
||||
if (r_type == elfcpp::R_SPARC_TLS_GD_CALL)
|
||||
@ -2407,11 +2407,11 @@ Target_sparc<size, big_endian>::Scan::global(
|
||||
// Create a GOT entry for the tp-relative offset.
|
||||
Output_data_got<size, big_endian>* got
|
||||
= target->got_section(symtab, layout);
|
||||
got->add_global_with_rela(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
(size == 64 ?
|
||||
elfcpp::R_SPARC_TLS_TPOFF64 :
|
||||
elfcpp::R_SPARC_TLS_TPOFF32));
|
||||
got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
(size == 64 ?
|
||||
elfcpp::R_SPARC_TLS_TPOFF64 :
|
||||
elfcpp::R_SPARC_TLS_TPOFF32));
|
||||
}
|
||||
else if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
unsupported_reloc_global(object, r_type, gsym);
|
||||
@ -2462,11 +2462,11 @@ Target_sparc<size, big_endian>::Scan::global(
|
||||
// Create a GOT entry for the tp-relative offset.
|
||||
Output_data_got<size, big_endian>* got
|
||||
= target->got_section(symtab, layout);
|
||||
got->add_global_with_rela(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
(size == 64 ?
|
||||
elfcpp::R_SPARC_TLS_TPOFF64 :
|
||||
elfcpp::R_SPARC_TLS_TPOFF32));
|
||||
got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
(size == 64
|
||||
? elfcpp::R_SPARC_TLS_TPOFF64
|
||||
: elfcpp::R_SPARC_TLS_TPOFF32));
|
||||
}
|
||||
else if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
unsupported_reloc_global(object, r_type, gsym);
|
||||
|
@ -2137,11 +2137,11 @@ Target_x86_64::Scan::local(Symbol_table* symtab,
|
||||
object->error(_("local symbol %u has bad shndx %u"),
|
||||
r_sym, shndx);
|
||||
else
|
||||
got->add_local_pair_with_rela(object, r_sym,
|
||||
shndx,
|
||||
GOT_TYPE_TLS_PAIR,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_DTPMOD64, 0);
|
||||
got->add_local_pair_with_rel(object, r_sym,
|
||||
shndx,
|
||||
GOT_TYPE_TLS_PAIR,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_DTPMOD64, 0);
|
||||
}
|
||||
else if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
unsupported_reloc_local(object, r_type);
|
||||
@ -2207,9 +2207,9 @@ Target_x86_64::Scan::local(Symbol_table* symtab,
|
||||
Output_data_got<64, false>* got
|
||||
= target->got_section(symtab, layout);
|
||||
unsigned int r_sym = elfcpp::elf_r_sym<64>(reloc.get_r_info());
|
||||
got->add_local_with_rela(object, r_sym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_TPOFF64);
|
||||
got->add_local_with_rel(object, r_sym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_TPOFF64);
|
||||
}
|
||||
else if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
unsupported_reloc_local(object, r_type);
|
||||
@ -2481,8 +2481,8 @@ Target_x86_64::Scan::global(Symbol_table* symtab,
|
||||
&& parameters->options().shared())
|
||||
|| (gsym->type() == elfcpp::STT_GNU_IFUNC
|
||||
&& parameters->options().output_is_position_independent()))
|
||||
got->add_global_with_rela(gsym, GOT_TYPE_STANDARD, rela_dyn,
|
||||
elfcpp::R_X86_64_GLOB_DAT);
|
||||
got->add_global_with_rel(gsym, GOT_TYPE_STANDARD, rela_dyn,
|
||||
elfcpp::R_X86_64_GLOB_DAT);
|
||||
else
|
||||
{
|
||||
// For a STT_GNU_IFUNC symbol we want to write the PLT
|
||||
@ -2580,19 +2580,19 @@ Target_x86_64::Scan::global(Symbol_table* symtab,
|
||||
// dtv-relative offset.
|
||||
Output_data_got<64, false>* got
|
||||
= target->got_section(symtab, layout);
|
||||
got->add_global_pair_with_rela(gsym, GOT_TYPE_TLS_PAIR,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_DTPMOD64,
|
||||
elfcpp::R_X86_64_DTPOFF64);
|
||||
got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_DTPMOD64,
|
||||
elfcpp::R_X86_64_DTPOFF64);
|
||||
}
|
||||
else if (optimized_type == tls::TLSOPT_TO_IE)
|
||||
{
|
||||
// Create a GOT entry for the tp-relative offset.
|
||||
Output_data_got<64, false>* got
|
||||
= target->got_section(symtab, layout);
|
||||
got->add_global_with_rela(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_TPOFF64);
|
||||
got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_TPOFF64);
|
||||
}
|
||||
else if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
unsupported_reloc_global(object, r_type, gsym);
|
||||
@ -2613,17 +2613,17 @@ Target_x86_64::Scan::global(Symbol_table* symtab,
|
||||
target->got_section(symtab, layout);
|
||||
Output_data_got<64, false>* got = target->got_tlsdesc_section();
|
||||
Reloc_section* rt = target->rela_tlsdesc_section(layout);
|
||||
got->add_global_pair_with_rela(gsym, GOT_TYPE_TLS_DESC, rt,
|
||||
elfcpp::R_X86_64_TLSDESC, 0);
|
||||
got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_DESC, rt,
|
||||
elfcpp::R_X86_64_TLSDESC, 0);
|
||||
}
|
||||
else if (optimized_type == tls::TLSOPT_TO_IE)
|
||||
{
|
||||
// Create a GOT entry for the tp-relative offset.
|
||||
Output_data_got<64, false>* got
|
||||
= target->got_section(symtab, layout);
|
||||
got->add_global_with_rela(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_TPOFF64);
|
||||
got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_TPOFF64);
|
||||
}
|
||||
else if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
unsupported_reloc_global(object, r_type, gsym);
|
||||
@ -2653,9 +2653,9 @@ Target_x86_64::Scan::global(Symbol_table* symtab,
|
||||
// Create a GOT entry for the tp-relative offset.
|
||||
Output_data_got<64, false>* got
|
||||
= target->got_section(symtab, layout);
|
||||
got->add_global_with_rela(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_TPOFF64);
|
||||
got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
|
||||
target->rela_dyn_section(layout),
|
||||
elfcpp::R_X86_64_TPOFF64);
|
||||
}
|
||||
else if (optimized_type != tls::TLSOPT_TO_LE)
|
||||
unsupported_reloc_global(object, r_type, gsym);
|
||||
|
Loading…
x
Reference in New Issue
Block a user