[GOLD] Got_offset_list: addend field

This is the first in a series of patches aimed at supporting GOT
entries against symbol plus addend generally for PowerPC64 rather than
just section symbol plus addend as gold has currently.

This patch adds an addend field to Got_offset_list, so that both local
and global symbols can have GOT entries with addend.

	PR 28192
	* object.h (Got_offset_list): Add addend_ field, init in both
	constructors.  Adjust all accessors to suit.
	(Sized_relobj::do_local_has_got_offset): Adjust to suit.
	(Sized_relobj::do_local_got_offset): Likewise.
	(Sized_relobj::do_set_local_got_offset): Likewise.
	* symtab.h (Symbol::has_got_offset): Add optional addend param.
	(Symbol::got_offset, Symbol::set_got_offset): Likewise.
	* incremental.cc (Local_got_offset_visitor::visit): Add unused
	uint64_t parameter with FIXME.
	(Global_got_offset_visitor::visit): Add unused uint64_t parameter.
This commit is contained in:
Alan Modra
2021-08-05 14:32:56 +09:30
parent 6bc2c6ee80
commit 912697efc1
3 changed files with 34 additions and 22 deletions

View File

@ -1848,7 +1848,7 @@ class Local_got_offset_visitor : public Got_offset_list::Visitor
{ }
void
visit(unsigned int got_type, unsigned int got_offset)
visit(unsigned int got_type, unsigned int got_offset, uint64_t)
{
unsigned int got_index = got_offset / this->info_.got_entry_size;
gold_assert(got_index < this->info_.got_count);
@ -1860,6 +1860,12 @@ class Local_got_offset_visitor : public Got_offset_list::Visitor
unsigned char* pov = this->info_.got_desc_p + got_index * 8;
elfcpp::Swap<32, big_endian>::writeval(pov, this->info_.sym_index);
elfcpp::Swap<32, big_endian>::writeval(pov + 4, this->info_.input_index);
// FIXME: the uint64_t addend should be written here if powerpc64
// sym+addend got entries are to be supported, with similar changes
// to Global_got_offset_visitor and support to read them back in
// do_process_got_plt.
// FIXME: don't we need this for section symbol plus addend anyway?
// (See 2015-12-03 commit 7ef8ae7c5f35)
}
private:
@ -1879,7 +1885,7 @@ class Global_got_offset_visitor : public Got_offset_list::Visitor
{ }
void
visit(unsigned int got_type, unsigned int got_offset)
visit(unsigned int got_type, unsigned int got_offset, uint64_t)
{
unsigned int got_index = got_offset / this->info_.got_entry_size;
gold_assert(got_index < this->info_.got_count);

View File

@ -214,11 +214,13 @@ class Got_offset_list
{
public:
Got_offset_list()
: got_type_(-1U), got_offset_(0), got_next_(NULL)
: got_type_(-1U), got_offset_(0), addend_(0), got_next_(NULL)
{ }
Got_offset_list(unsigned int got_type, unsigned int got_offset)
: got_type_(got_type), got_offset_(got_offset), got_next_(NULL)
Got_offset_list(unsigned int got_type, unsigned int got_offset,
uint64_t addend)
: got_type_(got_type), got_offset_(got_offset), addend_(addend),
got_next_(NULL)
{ }
~Got_offset_list()
@ -236,29 +238,31 @@ class Got_offset_list
{
this->got_type_ = -1U;
this->got_offset_ = 0;
this->addend_ = 0;
this->got_next_ = NULL;
}
// Set the offset for the GOT entry of type GOT_TYPE.
void
set_offset(unsigned int got_type, unsigned int got_offset)
set_offset(unsigned int got_type, unsigned int got_offset, uint64_t addend)
{
if (this->got_type_ == -1U)
{
this->got_type_ = got_type;
this->got_offset_ = got_offset;
this->addend_ = addend;
}
else
{
for (Got_offset_list* g = this; g != NULL; g = g->got_next_)
{
if (g->got_type_ == got_type)
if (g->got_type_ == got_type && g->addend_ == addend)
{
g->got_offset_ = got_offset;
return;
}
}
Got_offset_list* g = new Got_offset_list(got_type, got_offset);
Got_offset_list* g = new Got_offset_list(got_type, got_offset, addend);
g->got_next_ = this->got_next_;
this->got_next_ = g;
}
@ -266,11 +270,11 @@ class Got_offset_list
// Return the offset for a GOT entry of type GOT_TYPE.
unsigned int
get_offset(unsigned int got_type) const
get_offset(unsigned int got_type, uint64_t addend) const
{
for (const Got_offset_list* g = this; g != NULL; g = g->got_next_)
{
if (g->got_type_ == got_type)
if (g->got_type_ == got_type && g->addend_ == addend)
return g->got_offset_;
}
return -1U;
@ -297,7 +301,7 @@ class Got_offset_list
{ }
virtual void
visit(unsigned int, unsigned int) = 0;
visit(unsigned int, unsigned int, uint64_t) = 0;
};
// Loop over all GOT offset entries, calling a visitor class V for each.
@ -307,12 +311,13 @@ class Got_offset_list
if (this->got_type_ == -1U)
return;
for (const Got_offset_list* g = this; g != NULL; g = g->got_next_)
v->visit(g->got_type_, g->got_offset_);
v->visit(g->got_type_, g->got_offset_, g->addend_);
}
private:
unsigned int got_type_;
unsigned int got_offset_;
uint64_t addend_;
Got_offset_list* got_next_;
};
@ -2134,7 +2139,7 @@ class Sized_relobj : public Relobj
Local_got_offsets::const_iterator p =
this->local_got_offsets_.find(key);
return (p != this->local_got_offsets_.end()
&& p->second->get_offset(got_type) != -1U);
&& p->second->get_offset(got_type, addend) != -1U);
}
// Return the GOT offset of type GOT_TYPE of the local symbol
@ -2147,7 +2152,7 @@ class Sized_relobj : public Relobj
Local_got_offsets::const_iterator p =
this->local_got_offsets_.find(key);
gold_assert(p != this->local_got_offsets_.end());
unsigned int off = p->second->get_offset(got_type);
unsigned int off = p->second->get_offset(got_type, addend);
gold_assert(off != -1U);
return off;
}
@ -2162,10 +2167,10 @@ class Sized_relobj : public Relobj
Local_got_offsets::const_iterator p =
this->local_got_offsets_.find(key);
if (p != this->local_got_offsets_.end())
p->second->set_offset(got_type, got_offset);
p->second->set_offset(got_type, got_offset, addend);
else
{
Got_offset_list* g = new Got_offset_list(got_type, got_offset);
Got_offset_list* g = new Got_offset_list(got_type, got_offset, addend);
std::pair<Local_got_offsets::iterator, bool> ins =
this->local_got_offsets_.insert(std::make_pair(key, g));
gold_assert(ins.second);

View File

@ -428,22 +428,23 @@ class Symbol
// Return whether this symbol has an entry in the GOT section.
// For a TLS symbol, this GOT entry will hold its tp-relative offset.
bool
has_got_offset(unsigned int got_type) const
{ return this->got_offsets_.get_offset(got_type) != -1U; }
has_got_offset(unsigned int got_type, uint64_t addend = 0) const
{ return this->got_offsets_.get_offset(got_type, addend) != -1U; }
// Return the offset into the GOT section of this symbol.
unsigned int
got_offset(unsigned int got_type) const
got_offset(unsigned int got_type, uint64_t addend = 0) const
{
unsigned int got_offset = this->got_offsets_.get_offset(got_type);
unsigned int got_offset = this->got_offsets_.get_offset(got_type, addend);
gold_assert(got_offset != -1U);
return got_offset;
}
// Set the GOT offset of this symbol.
void
set_got_offset(unsigned int got_type, unsigned int got_offset)
{ this->got_offsets_.set_offset(got_type, got_offset); }
set_got_offset(unsigned int got_type, unsigned int got_offset,
uint64_t addend = 0)
{ this->got_offsets_.set_offset(got_type, got_offset, addend); }
// Return the GOT offset list.
const Got_offset_list*