[AARCH64] Positively emit symbols for alignment
[deliverable/binutils-gdb.git] / gold / mips.cc
index 450883efdfa02222065866a5dd2acc75f717bbd7..acf76cffaeca604cb466f3c251a093851468973d 100644 (file)
@@ -1,6 +1,6 @@
 // mips.cc -- mips target support for gold.
 
-// Copyright (C) 2011-2014 Free Software Foundation, Inc.
+// Copyright (C) 2011-2015 Free Software Foundation, Inc.
 // Written by Sasa Stankovic <sasa.stankovic@imgtec.com>
 //        and Aleksandar Simeonov <aleksandar.simeonov@rt-rk.com>.
 // This file contains borrowed and adapted code from bfd/elfxx-mips.c.
@@ -44,6 +44,7 @@
 #include "tls.h"
 #include "errors.h"
 #include "gc.h"
+#include "nacl.h"
 
 namespace
 {
@@ -3711,7 +3712,7 @@ class Target_mips : public Sized_target<size, big_endian>
 
   // Information about this specific target which we pass to the
   // general Target structure.
-  static Target::Target_info mips_info;
+  static const Target::Target_info mips_info;
   // The GOT section.
   Mips_output_data_got<size, big_endian>* got_;
   // gp symbol.  It has the value of .got + 0x7FF0.
@@ -3760,11 +3761,11 @@ struct reloc_high
 
   reloc_high(unsigned char* _view, const Mips_relobj<size, big_endian>* _object,
              const Symbol_value<size>* _psymval, Mips_address _addend,
-             unsigned int _r_type, bool _extract_addend,
+             unsigned int _r_type, unsigned int _r_sym, bool _extract_addend,
              Mips_address _address = 0, bool _gp_disp = false)
     : view(_view), object(_object), psymval(_psymval), addend(_addend),
-      r_type(_r_type), extract_addend(_extract_addend), address(_address),
-      gp_disp(_gp_disp)
+      r_type(_r_type), r_sym(_r_sym), extract_addend(_extract_addend),
+      address(_address), gp_disp(_gp_disp)
   { }
 
   unsigned char* view;
@@ -3772,6 +3773,7 @@ struct reloc_high
   const Symbol_value<size>* psymval;
   Mips_address addend;
   unsigned int r_type;
+  unsigned int r_sym;
   bool extract_addend;
   Mips_address address;
   bool gp_disp;
@@ -4265,11 +4267,12 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
   relhi16(unsigned char* view, const Mips_relobj<size, big_endian>* object,
           const Symbol_value<size>* psymval, Mips_address addend,
           Mips_address address, bool gp_disp, unsigned int r_type,
-          bool extract_addend)
+          unsigned int r_sym, bool extract_addend)
   {
     // Record the relocation.  It will be resolved when we find lo16 part.
     hi16_relocs.push_back(reloc_high<size, big_endian>(view, object, psymval,
-                          addend, r_type, extract_addend, address, gp_disp));
+                          addend, r_type, r_sym, extract_addend, address,
+                          gp_disp));
     return This::STATUS_OKAY;
   }
 
@@ -4330,11 +4333,11 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
   relgot16_local(unsigned char* view,
                  const Mips_relobj<size, big_endian>* object,
                  const Symbol_value<size>* psymval, Mips_address addend_a,
-                 bool extract_addend, unsigned int r_type)
+                 bool extract_addend, unsigned int r_type, unsigned int r_sym)
   {
     // Record the relocation.  It will be resolved when we find lo16 part.
     got16_relocs.push_back(reloc_high<size, big_endian>(view, object, psymval,
-                           addend_a, r_type, extract_addend));
+                           addend_a, r_type, r_sym, extract_addend));
     return This::STATUS_OKAY;
   }
 
@@ -4376,7 +4379,7 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
           const Mips_relobj<size, big_endian>* object,
           const Symbol_value<size>* psymval, Mips_address addend_a,
           bool extract_addend, Mips_address address, bool is_gp_disp,
-          unsigned int r_type)
+          unsigned int r_type, unsigned int r_sym)
   {
     mips_reloc_unshuffle(view, r_type, false);
     Valtype32* wv = reinterpret_cast<Valtype32*>(view);
@@ -4391,7 +4394,8 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
     while (it != hi16_relocs.end())
       {
         reloc_high<size, big_endian> hi16 = *it;
-        if (hi16.psymval->value(hi16.object, 0) == psymval->value(object, 0))
+        if (hi16.r_sym == r_sym
+            && is_matching_lo16_reloc(hi16.r_type, r_type))
           {
             if (do_relhi16(hi16.view, hi16.object, hi16.psymval, hi16.addend,
                            hi16.address, hi16.gp_disp, hi16.r_type,
@@ -4410,7 +4414,8 @@ class Mips_relocate_functions : public Relocate_functions<size, big_endian>
     while (it2 != got16_relocs.end())
       {
         reloc_high<size, big_endian> got16 = *it2;
-        if (got16.psymval->value(got16.object, 0) == psymval->value(object, 0))
+        if (got16.r_sym == r_sym
+            && is_matching_lo16_reloc(got16.r_type, r_type))
           {
             if (do_relgot16_local(got16.view, got16.object, got16.psymval,
                                   got16.addend, got16.r_type,
@@ -9907,7 +9912,7 @@ Target_mips<size, big_endian>::Relocate::relocate(
     case elfcpp::R_MIPS16_HI16:
     case elfcpp::R_MICROMIPS_HI16:
       reloc_status = Reloc_funcs::relhi16(view, object, psymval, r_addend,
-                                          address, gp_disp, r_type,
+                                          address, gp_disp, r_type, r_sym,
                                           extract_addend);
       break;
 
@@ -9917,7 +9922,7 @@ Target_mips<size, big_endian>::Relocate::relocate(
     case elfcpp::R_MICROMIPS_HI0_LO16:
       reloc_status = Reloc_funcs::rello16(target, view, object, psymval,
                                           r_addend, extract_addend, address,
-                                          gp_disp, r_type);
+                                          gp_disp, r_type, r_sym);
       break;
 
     case elfcpp::R_MIPS_LITERAL:
@@ -10032,7 +10037,7 @@ Target_mips<size, big_endian>::Relocate::relocate(
       else
         reloc_status = Reloc_funcs::relgot16_local(view, object, psymval,
                                                    r_addend, extract_addend,
-                                                   r_type);
+                                                   r_type, r_sym);
       update_got_entry = changed_symbol_value;
       break;
 
@@ -10462,7 +10467,7 @@ Target_mips<size, big_endian>::elf_mips_mach_name(elfcpp::Elf_Word e_flags)
 }
 
 template<int size, bool big_endian>
-Target::Target_info Target_mips<size, big_endian>::mips_info =
+const Target::Target_info Target_mips<size, big_endian>::mips_info =
 {
   size,                 // size
   big_endian,           // is_big_endian
@@ -10488,7 +10493,47 @@ Target::Target_info Target_mips<size, big_endian>::mips_info =
   "__start"            // entry_symbol_name
 };
 
-// The selector for mips object files.
+template<int size, bool big_endian>
+class Target_mips_nacl : public Target_mips<size, big_endian>
+{
+ public:
+  Target_mips_nacl()
+    : Target_mips<size, big_endian>(&mips_nacl_info)
+  { }
+
+ private:
+  static const Target::Target_info mips_nacl_info;
+};
+
+template<int size, bool big_endian>
+const Target::Target_info Target_mips_nacl<size, big_endian>::mips_nacl_info =
+{
+  size,                 // size
+  big_endian,           // is_big_endian
+  elfcpp::EM_MIPS,      // machine_code
+  true,                 // has_make_symbol
+  false,                // has_resolve
+  false,                // has_code_fill
+  true,                 // is_default_stack_executable
+  false,                // can_icf_inline_merge_sections
+  '\0',                 // wrap_char
+  "/lib/ld.so.1",       // dynamic_linker
+  0x20000,              // default_text_segment_address
+  0x10000,              // abi_pagesize (overridable by -z max-page-size)
+  0x10000,              // common_pagesize (overridable by -z common-page-size)
+  true,                 // isolate_execinstr
+  0x10000000,           // rosegment_gap
+  elfcpp::SHN_UNDEF,    // small_common_shndx
+  elfcpp::SHN_UNDEF,    // large_common_shndx
+  0,                    // small_common_section_flags
+  0,                    // large_common_section_flags
+  NULL,                 // attributes_section
+  NULL,                 // attributes_vendor
+  "_start"              // entry_symbol_name
+};
+
+// Target selector for Mips.  Note this is never instantiated directly.
+// It's only used in Target_selector_mips_nacl, below.
 
 template<int size, bool big_endian>
 class Target_selector_mips : public Target_selector
@@ -10508,10 +10553,23 @@ public:
   { return new Target_mips<size, big_endian>(); }
 };
 
-Target_selector_mips<32, true> target_selector_mips32be;
-Target_selector_mips<32, false> target_selector_mips32;
-Target_selector_mips<64, true> target_selector_mips64be;
-Target_selector_mips<64, false> target_selector_mips64;
+template<int size, bool big_endian>
+class Target_selector_mips_nacl
+  : public Target_selector_nacl<Target_selector_mips<size, big_endian>,
+                                Target_mips_nacl<size, big_endian> >
+{
+ public:
+  Target_selector_mips_nacl()
+    : Target_selector_nacl<Target_selector_mips<size, big_endian>,
+                           Target_mips_nacl<size, big_endian> >(
+        // NaCl currently supports only MIPS32 little-endian.
+        "mipsel", "elf32-tradlittlemips-nacl", "elf32-tradlittlemips-nacl")
+  { }
+};
 
+Target_selector_mips_nacl<32, true> target_selector_mips32;
+Target_selector_mips_nacl<32, false> target_selector_mips32el;
+Target_selector_mips_nacl<64, true> target_selector_mips64;
+Target_selector_mips_nacl<64, false> target_selector_mips64el;
 
 } // End anonymous namespace.
This page took 0.028594 seconds and 4 git commands to generate.