Add aarch64-specific --no-apply-dynamic-relocs option.
authorCary Coutant <ccoutant@gmail.com>
Thu, 5 Nov 2015 20:24:14 +0000 (12:24 -0800)
committerCary Coutant <ccoutant@gmail.com>
Thu, 5 Nov 2015 20:24:14 +0000 (12:24 -0800)
With --no-apply-dynamic-relocs on aarch64 targets, gold will not apply
link-time values for absolute relocations that become dynamic relocations.
This provides a workaround for broken Android dynamic linkers that use
the link-time value as an extra addend to the relocation.

gold/
PR gold/19163
* aarch64.cc (Target_aarch64::Relocate::relocate): Don't apply
certain relocations if --no-apply-dynamic-relocs is set.
* options.h (--apply-dynamic-relocs): New aarch64-specific option.

gold/ChangeLog
gold/aarch64.cc
gold/options.h

index 5aa49d4787a5a57714240cf8d5022df74c4f4426..e38943822c00eb3ede21944cda212ce6e84eb4ef 100644 (file)
@@ -1,3 +1,10 @@
+2015-11-05  Cary Coutant  <ccoutant@gmail.com>
+
+       PR gold/19163
+       * aarch64.cc (Target_aarch64::Relocate::relocate): Don't apply
+       certain relocations if --no-apply-dynamic-relocs is set.
+       * options.h (--apply-dynamic-relocs): New aarch64-specific option.
+
 2015-11-03  Alan Modra  <amodra@gmail.com>
 
        * po/POTFILES.in: Regenerate.
index 2dcd6204cdd7166f3468ec48326f259d2bde676e..bc85c833415cbfb0ef9a22951908eac54eb079fd 100644 (file)
@@ -6911,16 +6911,41 @@ Target_aarch64<size, big_endian>::Relocate::relocate(
       break;
 
     case elfcpp::R_AARCH64_ABS64:
+      if (!parameters->options().apply_dynamic_relocs()
+          && parameters->options().output_is_position_independent()
+          && gsym != NULL
+          && gsym->needs_dynamic_reloc(reloc_property->reference_flags())
+          && !gsym->can_use_relative_reloc(false))
+        // We have generated an absolute dynamic relocation, so do not
+        // apply the relocation statically. (Works around bugs in older
+        // Android dynamic linkers.)
+        break;
       reloc_status = Reloc::template rela_ua<64>(
        view, object, psymval, addend, reloc_property);
       break;
 
     case elfcpp::R_AARCH64_ABS32:
+      if (!parameters->options().apply_dynamic_relocs()
+          && parameters->options().output_is_position_independent()
+          && gsym != NULL
+          && gsym->needs_dynamic_reloc(reloc_property->reference_flags()))
+        // We have generated an absolute dynamic relocation, so do not
+        // apply the relocation statically. (Works around bugs in older
+        // Android dynamic linkers.)
+        break;
       reloc_status = Reloc::template rela_ua<32>(
        view, object, psymval, addend, reloc_property);
       break;
 
     case elfcpp::R_AARCH64_ABS16:
+      if (!parameters->options().apply_dynamic_relocs()
+          && parameters->options().output_is_position_independent()
+          && gsym != NULL
+          && gsym->needs_dynamic_reloc(reloc_property->reference_flags()))
+        // We have generated an absolute dynamic relocation, so do not
+        // apply the relocation statically. (Works around bugs in older
+        // Android dynamic linkers.)
+        break;
       reloc_status = Reloc::template rela_ua<16>(
        view, object, psymval, addend, reloc_property);
       break;
index 4d6522572c7f0d51ed8f577ee962de8fa535821e..57560140027571e435b401491d3c5c76c0e4f188 100644 (file)
@@ -644,6 +644,11 @@ class General_options
              N_("Allow unresolved references in shared libraries"),
              N_("Do not allow unresolved references in shared libraries"));
 
+  DEFINE_bool(apply_dynamic_relocs, options::TWO_DASHES, '\0', true,
+             N_("Apply link-time values for dynamic relocations (default)"),
+             N_("(aarch64 only) Do not apply link-time values "
+                "for dynamic relocations"));
+
   DEFINE_bool(as_needed, options::TWO_DASHES, '\0', false,
              N_("Only set DT_NEEDED for shared libraries if used"),
              N_("Always DT_NEEDED for shared libraries"));