mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-25 10:54:26 +00: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:
parent
6a11bac307
commit
0cfdc76718
@ -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>
|
||||
|
||||
PR gold/15354
|
||||
|
@ -1085,7 +1085,7 @@ class Target_powerpc : public Sized_target<size, big_endian>
|
||||
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
|
||||
group_sections(Layout*, const Task*);
|
||||
|
||||
@ -2226,7 +2226,7 @@ class Stub_control
|
||||
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.
|
||||
|
||||
bool
|
||||
@ -2258,7 +2258,9 @@ Stub_control::can_add_to_stub_group(Output_section* o,
|
||||
i->relobj()->section_name(i->shndx()).c_str());
|
||||
|
||||
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->output_section_ = o;
|
||||
@ -2331,7 +2333,25 @@ Target_powerpc<size, big_endian>::group_sections(Layout* layout,
|
||||
}
|
||||
}
|
||||
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.
|
||||
@ -2429,17 +2449,26 @@ Target_powerpc<size, big_endian>::Branch_info::make_stub(
|
||||
to += this->addend_;
|
||||
if (stub_table == NULL)
|
||||
stub_table = this->object_->stub_table(this->shndx_);
|
||||
gold_assert(stub_table != NULL);
|
||||
if (size == 64 && is_branch_reloc(this->r_type_))
|
||||
{
|
||||
unsigned int dest_shndx;
|
||||
to = stub_table->targ()->symval_for_branch(symtab, to, gsym,
|
||||
this->object_,
|
||||
&dest_shndx);
|
||||
Target_powerpc<size, big_endian>* target =
|
||||
static_cast<Target_powerpc<size, big_endian>*>(
|
||||
parameters->sized_target<size, big_endian>());
|
||||
to = target->symval_for_branch(symtab, to, gsym,
|
||||
this->object_, &dest_shndx);
|
||||
}
|
||||
Address delta = to - from;
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -6590,10 +6619,13 @@ Target_powerpc<size, big_endian>::Relocate::relocate(
|
||||
{
|
||||
Stub_table<size, big_endian>* stub_table
|
||||
= object->stub_table(relinfo->data_shndx);
|
||||
gold_assert(stub_table != NULL);
|
||||
Address off = stub_table->find_long_branch_entry(object, value);
|
||||
if (off != invalid_address)
|
||||
value = stub_table->stub_address() + stub_table->plt_size() + off;
|
||||
if (stub_table != NULL)
|
||||
{
|
||||
Address off = stub_table->find_long_branch_entry(object, value);
|
||||
if (off != invalid_address)
|
||||
value = (stub_table->stub_address() + stub_table->plt_size()
|
||||
+ off);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user