2010-01-22 Viktor Kutuzov <vkutuzov@accesssoftek.com>
authorDoug Kwan <dougkwan@google.com>
Fri, 22 Jan 2010 19:43:00 +0000 (19:43 +0000)
committerDoug Kwan <dougkwan@google.com>
Fri, 22 Jan 2010 19:43:00 +0000 (19:43 +0000)
* gold/arm.cc (Target_arm): Updated fix_v4bx method and usage of
Fix_v4bx enum values .
* gold/options.h (General_options): New option definitions.
(General_options::fix_v4bx): New method.
(General_options::Fix_v4bx): New enum.
* gold/options.cc (General_options::parse_fix_v4bx): New method.
(General_options::parse_fix_v4bx_interworking): New method.

gold/ChangeLog
gold/arm.cc
gold/options.cc
gold/options.h

index 69d7c74..0e94f26 100644 (file)
@@ -1,3 +1,13 @@
+2010-01-22  Viktor Kutuzov  <vkutuzov@accesssoftek.com>
+
+       * gold/arm.cc (Target_arm): Updated fix_v4bx method and usage of
+       Fix_v4bx enum values .
+       * gold/options.h (General_options): New option definitions.
+       (General_options::fix_v4bx): New method.
+       (General_options::Fix_v4bx): New enum.
+       * gold/options.cc (General_options::parse_fix_v4bx): New method.
+       (General_options::parse_fix_v4bx_interworking): New method.
+
 2010-01-22  Doug Kwan  <dougkwan@google.com>
 
        * arm.cc (Arm_exidx_fixup): New class.
index 4075c2e..f655d59 100644 (file)
@@ -1812,7 +1812,7 @@ class Target_arm : public Sized_target<32, big_endian>
       stub_factory_(Stub_factory::get_instance()), may_use_blx_(false),
       should_force_pic_veneer_(false), arm_input_section_map_(),
       attributes_section_data_(NULL), fix_cortex_a8_(false),
-      cortex_a8_relocs_info_(), fix_v4bx_(0)
+      cortex_a8_relocs_info_()
   { }
 
   // Whether we can use BLX.
@@ -2049,9 +2049,9 @@ class Target_arm : public Sized_target<32, big_endian>
   // 0 - do not fix
   // 1 - replace with MOV instruction (armv4 target)
   // 2 - make interworking veneer (>= armv4t targets only)
-  int
+  General_options::Fix_v4bx
   fix_v4bx() const
-  { return this->fix_v4bx_; }
+  { return parameters->options().fix_v4bx(); }
 
   // Scan a span of THUMB code section for Cortex-A8 erratum.
   void
@@ -2415,8 +2415,6 @@ class Target_arm : public Sized_target<32, big_endian>
   bool fix_cortex_a8_;
   // Map addresses to relocs for Cortex-A8 erratum.
   Cortex_a8_relocs_info cortex_a8_relocs_info_;
-  // Whether we need to fix code for V4BX relocations.
-  int fix_v4bx_;
 };
 
 template<bool big_endian>
@@ -6451,7 +6449,8 @@ Target_arm<big_endian>::do_finalize_sections(
   // Check if we can use V4BX interworking.
   // The V4BX interworking stub contains BX instruction,
   // which is not specified for some profiles.
-  if (this->fix_v4bx() == 2 && !this->may_use_blx())
+  if (this->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING
+      && !this->may_use_blx())
     gold_error(_("unable to provide V4BX reloc interworking fix up; "
                 "the target profile does not support BX instruction"));
 
@@ -6943,10 +6942,14 @@ Target_arm<big_endian>::Relocate::relocate(
       break;
 
     case elfcpp::R_ARM_V4BX:
-      if (target->fix_v4bx() > 0)
-       reloc_status =
-         Arm_relocate_functions::v4bx(relinfo, view, object, address,
-                                      (target->fix_v4bx() == 2));
+      if (target->fix_v4bx() > General_options::FIX_V4BX_NONE)
+       {
+         const bool is_v4bx_interworking =
+             (target->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING);
+         reloc_status =
+           Arm_relocate_functions::v4bx(relinfo, view, object, address,
+                                        is_v4bx_interworking);
+       }
       break;
 
     case elfcpp::R_ARM_TARGET1:
@@ -8245,7 +8248,8 @@ Target_arm<big_endian>::scan_reloc_for_stub(
   if (r_type == elfcpp::R_ARM_V4BX)
     {
       const uint32_t reg = (addend & 0xf);
-      if (this->fix_v4bx() == 2 && reg < 0xf)
+      if (this->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING
+         && reg < 0xf)
        {
          // Try looking up an existing stub from a stub table.
          Stub_table<big_endian>* stub_table =
index 6c0fa04..f377387 100644 (file)
@@ -586,6 +586,20 @@ General_options::string_to_object_format(const char* arg)
     }
 }
 
+void
+General_options::parse_fix_v4bx(const char*, const char*,
+                                Command_line*)
+{
+  this->fix_v4bx_ = FIX_V4BX_REPLACE;
+}
+
+void
+General_options::parse_fix_v4bx_interworking(const char*, const char*,
+                                            Command_line*)
+{
+  this->fix_v4bx_ = FIX_V4BX_INTERWORKING;
+}
+
 } // End namespace gold.
 
 namespace
index c13601c..22662db 100644 (file)
@@ -726,6 +726,15 @@ class General_options
              N_("(ARM only) Fix binaries for Cortex-A8 erratum."),
              N_("(ARM only) Do not fix binaries for Cortex-A8 erratum."));
 
+  DEFINE_special(fix_v4bx, options::TWO_DASHES, '\0',
+                 N_("(ARM only) Rewrite BX rn as MOV pc, rn for ARMv4"),
+                 NULL);
+
+  DEFINE_special(fix_v4bx_interworking, options::TWO_DASHES, '\0',
+                 N_("(ARM only) Rewrite BX rn branch to ARMv4 interworking "
+                    "veneer"),
+                 NULL);
+
   DEFINE_bool(g, options::EXACTLY_ONE_DASH, '\0', false,
              N_("Ignored"), NULL);
 
@@ -1218,6 +1227,20 @@ class General_options
   bool
   section_start(const char* secname, uint64_t* paddr) const;
 
+  enum Fix_v4bx
+  {
+    // Leave original instruction.
+    FIX_V4BX_NONE,
+    // Replace instruction.
+    FIX_V4BX_REPLACE,
+    // Generate an interworking veneer.
+    FIX_V4BX_INTERWORKING
+  };
+
+  Fix_v4bx
+  fix_v4bx() const
+  { return (this->fix_v4bx_); }
+
  private:
   // Don't copy this structure.
   General_options(const General_options&);
@@ -1307,6 +1330,8 @@ class General_options
   Unordered_set<std::string> symbols_to_retain_;
   // Map from section name to address from --section-start.
   std::map<std::string, uint64_t> section_starts_;
+  // Whether to process armv4 bx instruction relocation.
+  Fix_v4bx fix_v4bx_;
 };
 
 // The position-dependent options.  We use this to store the state of