mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 19:09:31 +08:00
* powerpc.cc (Stub_control::can_add_to_stub_group): Don't set
owner when sections are not adjacent and exceed group size. (Target_powerpc::group_sections): Handle corner case. (Target_powerpc::Branch_info::make_stub): Handle case where stub table doesn't exist due to branches in non-exec sections. (Target_powerpc::Relocate::relocate): Likewise.
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
2013-04-13 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* powerpc.cc (Stub_control::can_add_to_stub_group): Don't set
|
||||||
|
owner when sections are not adjacent and exceed group size.
|
||||||
|
(Target_powerpc::group_sections): Handle corner case.
|
||||||
|
(Target_powerpc::Branch_info::make_stub): Handle case where
|
||||||
|
stub table doesn't exist due to branches in non-exec sections.
|
||||||
|
(Target_powerpc::Relocate::relocate): Likewise.
|
||||||
|
|
||||||
2013-04-11 Alan Modra <amodra@gmail.com>
|
2013-04-11 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
PR gold/15354
|
PR gold/15354
|
||||||
|
@ -1085,7 +1085,7 @@ class Target_powerpc : public Sized_target<size, big_endian>
|
|||||||
reloc, this->rela_dyn_section(layout));
|
reloc, this->rela_dyn_section(layout));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look over all the input sections, deciding where to place stub.
|
// Look over all the input sections, deciding where to place stubs.
|
||||||
void
|
void
|
||||||
group_sections(Layout*, const Task*);
|
group_sections(Layout*, const Task*);
|
||||||
|
|
||||||
@ -2226,7 +2226,7 @@ class Stub_control
|
|||||||
Output_section* output_section_;
|
Output_section* output_section_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return true iff input section can be handled by current stub/
|
// Return true iff input section can be handled by current stub
|
||||||
// group.
|
// group.
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -2258,7 +2258,9 @@ Stub_control::can_add_to_stub_group(Output_section* o,
|
|||||||
i->relobj()->section_name(i->shndx()).c_str());
|
i->relobj()->section_name(i->shndx()).c_str());
|
||||||
|
|
||||||
if (this->state_ != HAS_STUB_SECTION
|
if (this->state_ != HAS_STUB_SECTION
|
||||||
&& (!whole_sec || this->output_section_ != o))
|
&& (!whole_sec || this->output_section_ != o)
|
||||||
|
&& (this->state_ == NO_GROUP
|
||||||
|
|| this->group_end_addr_ - end_addr < group_size))
|
||||||
{
|
{
|
||||||
this->owner_ = i;
|
this->owner_ = i;
|
||||||
this->output_section_ = o;
|
this->output_section_ = o;
|
||||||
@ -2331,7 +2333,25 @@ Target_powerpc<size, big_endian>::group_sections(Layout* layout,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stub_table != NULL)
|
if (stub_table != NULL)
|
||||||
stub_table->init(stub_control.owner(), stub_control.output_section());
|
{
|
||||||
|
const Output_section::Input_section* i = stub_control.owner();
|
||||||
|
if (!i->is_input_section())
|
||||||
|
{
|
||||||
|
// Corner case. A new stub group was made for the first
|
||||||
|
// section (last one looked at here) for some reason, but
|
||||||
|
// the first section is already being used as the owner for
|
||||||
|
// a stub table for following sections. Force it into that
|
||||||
|
// stub group.
|
||||||
|
gold_assert(this->stub_tables_.size() >= 2);
|
||||||
|
this->stub_tables_.pop_back();
|
||||||
|
delete stub_table;
|
||||||
|
Powerpc_relobj<size, big_endian>* ppcobj = static_cast
|
||||||
|
<Powerpc_relobj<size, big_endian>*>(i->relobj());
|
||||||
|
ppcobj->set_stub_table(i->shndx(), this->stub_tables_.back());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
stub_table->init(i, stub_control.output_section());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this branch needs a plt call stub, or a long branch stub, make one.
|
// If this branch needs a plt call stub, or a long branch stub, make one.
|
||||||
@ -2429,17 +2449,26 @@ Target_powerpc<size, big_endian>::Branch_info::make_stub(
|
|||||||
to += this->addend_;
|
to += this->addend_;
|
||||||
if (stub_table == NULL)
|
if (stub_table == NULL)
|
||||||
stub_table = this->object_->stub_table(this->shndx_);
|
stub_table = this->object_->stub_table(this->shndx_);
|
||||||
gold_assert(stub_table != NULL);
|
|
||||||
if (size == 64 && is_branch_reloc(this->r_type_))
|
if (size == 64 && is_branch_reloc(this->r_type_))
|
||||||
{
|
{
|
||||||
unsigned int dest_shndx;
|
unsigned int dest_shndx;
|
||||||
to = stub_table->targ()->symval_for_branch(symtab, to, gsym,
|
Target_powerpc<size, big_endian>* target =
|
||||||
this->object_,
|
static_cast<Target_powerpc<size, big_endian>*>(
|
||||||
&dest_shndx);
|
parameters->sized_target<size, big_endian>());
|
||||||
|
to = target->symval_for_branch(symtab, to, gsym,
|
||||||
|
this->object_, &dest_shndx);
|
||||||
}
|
}
|
||||||
Address delta = to - from;
|
Address delta = to - from;
|
||||||
if (delta + max_branch_offset >= 2 * max_branch_offset)
|
if (delta + max_branch_offset >= 2 * max_branch_offset)
|
||||||
{
|
{
|
||||||
|
if (stub_table == NULL)
|
||||||
|
{
|
||||||
|
gold_warning(_("%s:%s: branch in non-executable section,"
|
||||||
|
" no long branch stub for you"),
|
||||||
|
this->object_->name().c_str(),
|
||||||
|
this->object_->section_name(this->shndx_).c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
stub_table->add_long_branch_entry(this->object_, to);
|
stub_table->add_long_branch_entry(this->object_, to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6590,10 +6619,13 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|
|||||||
{
|
{
|
||||||
Stub_table<size, big_endian>* stub_table
|
Stub_table<size, big_endian>* stub_table
|
||||||
= object->stub_table(relinfo->data_shndx);
|
= object->stub_table(relinfo->data_shndx);
|
||||||
gold_assert(stub_table != NULL);
|
if (stub_table != NULL)
|
||||||
Address off = stub_table->find_long_branch_entry(object, value);
|
{
|
||||||
if (off != invalid_address)
|
Address off = stub_table->find_long_branch_entry(object, value);
|
||||||
value = stub_table->stub_address() + stub_table->plt_size() + off;
|
if (off != invalid_address)
|
||||||
|
value = (stub_table->stub_address() + stub_table->plt_size()
|
||||||
|
+ off);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user