[PATCH] [aarch64] Fix handling of stubs to weak and section symbols
Eric Christopher
echristo@gmail.com
Tue Jun 20 00:49:00 GMT 2017
Hi Cary, Han,
This patch has 3 notable changes:
- symval.set_output_value(this->plt_section()->address()
- + gsym->plt_offset());
+ symval.set_output_value(this->plt_address_for_global(gsym));
which is just a boring fix to update to use the correct API. Looks
like it didn't get updated with the others.
+ // We don't create stubs for undefined symbols, but do for weak.
+ if (gsym
+ && !gsym->use_plt_offset(arp->reference_flags())
+ && gsym->is_undefined())
which is a small fix on top of my previous one for undefined symbols
to match the associated code in scan_reloc_for_stub by including stubs
for undefined weak symbols.
and finally:
- // If symbol is a section symbol, we don't know the actual type of
- // destination. Give up.
- if (psymval->is_section_symbol())
- continue;
which appears to have been pulled from the arm port when the aarch64
port was created. I looked and this was put into the arm port when
stub creation was first put in with no other comments. I can't think
of a reason why we wouldn't want to be able to have stubs to section
symbols - at least not as long as they're STT_FUNC or in separate
sections (these are all likely to be both). I think the original idea
was the return if we didn't know if the symbol was STT_FUNC, but not
entirely positive (cc'ing Doug in case someone sees this discussion in
the future and he wants to chime in). It might be possible to put a
suitable assert or verification into the stub creation in order to
verify that all of the bits of the ABI are satisfied:
The target symbol has type STT_FUNC.
Or, the target symbol and relocated place are in separate sections
input to the linker.
Or, the target symbol is undefined (external to the link unit).
but it's a little harder to figure out the best when/where since a lot
of this code is spread out.
At any rate, I'm convinced that this is safe given that we're now able
to link and execute a bunch of code that wouldn't work before on some
fairly extensive internal testing.
Thoughts? OK?
-eric
2017-06-19 Eric Christopher <echristo@gmail.com>
* aarch64.cc (scan_reloc_for_stub): Use plt_address_for_global to
calculate the symbol value.
(scan_reloc_section_for_stubs): Allow stubs to be created for
section symbols.
(maybe_apply_stub): Handle creating stubs for weak symbols to
match the code in scan_reloc_for_stub.
-------------- next part --------------
diff --git a/gold/aarch64.cc b/gold/aarch64.cc
index 33f7abe6b7..11bb48e3b0 100644
--- a/gold/aarch64.cc
+++ b/gold/aarch64.cc
@@ -3768,8 +3768,7 @@ Target_aarch64<size, big_endian>::scan_reloc_for_stub(
if (gsym->use_plt_offset(arp->reference_flags()))
{
// This uses a PLT, change the symbol value.
- symval.set_output_value(this->plt_section()->address()
- + gsym->plt_offset());
+ symval.set_output_value(this->plt_address_for_global(gsym));
psymval = &symval;
}
else if (gsym->is_undefined())
@@ -4002,11 +4001,6 @@ Target_aarch64<size, big_endian>::scan_reloc_section_for_stubs(
psymval = &symval2;
}
- // If symbol is a section symbol, we don't know the actual type of
- // destination. Give up.
- if (psymval->is_section_symbol())
- continue;
-
this->scan_reloc_for_stub(relinfo, r_type, sym, r_sym, psymval,
addend, view_address + offset);
} // End of iterating relocs in a section
@@ -5438,8 +5432,14 @@ maybe_apply_stub(unsigned int r_type,
const The_aarch64_relobj* aarch64_relobj =
static_cast<const The_aarch64_relobj*>(object);
- // We don't create stubs for undefined symbols so don't look for one.
- if (gsym && gsym->is_undefined())
+ const AArch64_reloc_property* arp =
+ aarch64_reloc_property_table->get_reloc_property(r_type);
+ gold_assert(arp != NULL);
+
+ // We don't create stubs for undefined symbols, but do for weak.
+ if (gsym
+ && !gsym->use_plt_offset(arp->reference_flags())
+ && gsym->is_undefined())
{
gold_debug(DEBUG_TARGET,
"stub: looking for a stub for undefined symbol %s in file %s",
@@ -5458,9 +5458,6 @@ maybe_apply_stub(unsigned int r_type,
Address new_branch_target = stub_table->address() + stub->offset();
typename elfcpp::Swap<size, big_endian>::Valtype branch_offset =
new_branch_target - address;
- const AArch64_reloc_property* arp =
- aarch64_reloc_property_table->get_reloc_property(r_type);
- gold_assert(arp != NULL);
typename This::Status status = This::template
rela_general<32>(view, branch_offset, 0, arp);
if (status != This::STATUS_OKAY)
More information about the Binutils
mailing list