2010-02-11 Doug Kwan <dougkwan@google.com>
authorDoug Kwan <dougkwan@google.com>
Fri, 12 Feb 2010 05:51:32 +0000 (05:51 +0000)
committerDoug Kwan <dougkwan@google.com>
Fri, 12 Feb 2010 05:51:32 +0000 (05:51 +0000)
* arm.cc (Target_arm::Scan::local): Fix bugs in relocation handling.
(Target_arm::Scan::global): Ditto.  Also remove a comment before the
beginning of function.
(Target_arm::Relocate::relocate): Remove error messages for MOVW_ABS
and MOVT_ABS relocations.  Those are non issued in scanning.  Fix
parameter is_32bit in calls to should_apply_static_reloc.
* testsuite/Makefile.am (check_SCRIPTS): Add arm_abs_global.sh.
(check_DATA): Add arm_abs_global.stdout.
(arm_abs_lib.o, libarm_abs.so, arm_abs_global.o, arm_abs_global,
arm_abs_global.stdout): New rules.
(MOSTLLYCLEANFILES): Add arm_abs_global
* Makefile.in: Regenerate.
* testsuite/arm_abs_global.s: New file.
* testsuite/arm_abs_global.sh: Ditto.
* testsuite/arm_abs_lib.s: Ditto.

gold/ChangeLog
gold/arm.cc
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/arm_abs_global.s [new file with mode: 0644]
gold/testsuite/arm_abs_global.sh [new file with mode: 0755]
gold/testsuite/arm_abs_lib.s [new file with mode: 0644]

index 03191eb..0b50ead 100644 (file)
@@ -1,3 +1,21 @@
+2010-02-11  Doug Kwan  <dougkwan@google.com>
+
+       * arm.cc (Target_arm::Scan::local): Fix bugs in relocation handling.
+       (Target_arm::Scan::global): Ditto.  Also remove a comment before the
+       beginning of function.
+       (Target_arm::Relocate::relocate): Remove error messages for MOVW_ABS
+       and MOVT_ABS relocations.  Those are non issued in scanning.  Fix
+       parameter is_32bit in calls to should_apply_static_reloc.
+       * testsuite/Makefile.am (check_SCRIPTS): Add arm_abs_global.sh.
+       (check_DATA): Add arm_abs_global.stdout.
+       (arm_abs_lib.o, libarm_abs.so, arm_abs_global.o, arm_abs_global,
+       arm_abs_global.stdout): New rules.
+       (MOSTLLYCLEANFILES): Add arm_abs_global
+       * Makefile.in: Regenerate.
+       * testsuite/arm_abs_global.s: New file.
+       * testsuite/arm_abs_global.sh: Ditto.
+       * testsuite/arm_abs_lib.s: Ditto.
+
 2010-02-11  Ian Lance Taylor  <iant@google.com>
 
        * gold.cc (queue_middle_gc_tasks): Use a separate blocker for each
index 902805c..d40ab2c 100644 (file)
@@ -6572,12 +6572,15 @@ Target_arm<big_endian>::Scan::local(Symbol_table* symtab,
                                    Output_section* output_section,
                                    const elfcpp::Rel<32, big_endian>& reloc,
                                    unsigned int r_type,
-                                   const elfcpp::Sym<32, big_endian>&)
+                                   const elfcpp::Sym<32, big_endian>& lsym)
 {
   r_type = get_real_reloc_type(r_type);
   switch (r_type)
     {
     case elfcpp::R_ARM_NONE:
+    case elfcpp::R_ARM_V4BX:
+    case elfcpp::R_ARM_GNU_VTENTRY:
+    case elfcpp::R_ARM_GNU_VTINHERIT:
       break;
 
     case elfcpp::R_ARM_ABS32:
@@ -6600,79 +6603,116 @@ Target_arm<big_endian>::Scan::local(Symbol_table* symtab,
        }
       break;
 
-    case elfcpp::R_ARM_REL32:
-    case elfcpp::R_ARM_THM_CALL:
-    case elfcpp::R_ARM_CALL:
-    case elfcpp::R_ARM_PREL31:
-    case elfcpp::R_ARM_JUMP24:
-    case elfcpp::R_ARM_THM_JUMP24:
-    case elfcpp::R_ARM_THM_JUMP19:
-    case elfcpp::R_ARM_PLT32:
+    case elfcpp::R_ARM_ABS16:
+    case elfcpp::R_ARM_ABS12:
     case elfcpp::R_ARM_THM_ABS5:
     case elfcpp::R_ARM_ABS8:
-    case elfcpp::R_ARM_ABS12:
-    case elfcpp::R_ARM_ABS16:
     case elfcpp::R_ARM_BASE_ABS:
     case elfcpp::R_ARM_MOVW_ABS_NC:
     case elfcpp::R_ARM_MOVT_ABS:
     case elfcpp::R_ARM_THM_MOVW_ABS_NC:
     case elfcpp::R_ARM_THM_MOVT_ABS:
+      // If building a shared library (or a position-independent
+      // executable), we need to create a dynamic relocation for
+      // this location. Because the addend needs to remain in the
+      // data section, we need to be careful not to apply this
+      // relocation statically.
+      if (parameters->options().output_is_position_independent())
+        {
+         check_non_pic(object, r_type);
+          Reloc_section* rel_dyn = target->rel_dyn_section(layout);
+         unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
+          if (lsym.get_st_type() != elfcpp::STT_SECTION)
+           rel_dyn->add_local(object, r_sym, r_type, output_section,
+                              data_shndx, reloc.get_r_offset());
+          else
+            {
+              gold_assert(lsym.get_st_value() == 0);
+             unsigned int shndx = lsym.get_st_shndx();
+             bool is_ordinary;
+             shndx = object->adjust_sym_shndx(r_sym, shndx,
+                                              &is_ordinary);
+             if (!is_ordinary)
+               object->error(_("section symbol %u has bad shndx %u"),
+                             r_sym, shndx);
+             else
+               rel_dyn->add_local_section(object, shndx,
+                                          r_type, output_section,
+                                          data_shndx, reloc.get_r_offset());
+            }
+        }
+      break;
+
+    case elfcpp::R_ARM_PC24:
+    case elfcpp::R_ARM_REL32:
+    case elfcpp::R_ARM_LDR_PC_G0:
+    case elfcpp::R_ARM_SBREL32:
+    case elfcpp::R_ARM_THM_CALL:
+    case elfcpp::R_ARM_THM_PC8:
+    case elfcpp::R_ARM_BASE_PREL:
+    case elfcpp::R_ARM_PLT32:
+    case elfcpp::R_ARM_CALL:
+    case elfcpp::R_ARM_JUMP24:
+    case elfcpp::R_ARM_THM_JUMP24:
+    case elfcpp::R_ARM_LDR_SBREL_11_0_NC:
+    case elfcpp::R_ARM_ALU_SBREL_19_12_NC:
+    case elfcpp::R_ARM_ALU_SBREL_27_20_CK:
+    case elfcpp::R_ARM_SBREL31:
+    case elfcpp::R_ARM_PREL31:
     case elfcpp::R_ARM_MOVW_PREL_NC:
     case elfcpp::R_ARM_MOVT_PREL:
     case elfcpp::R_ARM_THM_MOVW_PREL_NC:
     case elfcpp::R_ARM_THM_MOVT_PREL:
-    case elfcpp::R_ARM_MOVW_BREL_NC:
-    case elfcpp::R_ARM_MOVT_BREL:
-    case elfcpp::R_ARM_MOVW_BREL:
-    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
-    case elfcpp::R_ARM_THM_MOVT_BREL:
-    case elfcpp::R_ARM_THM_MOVW_BREL:
+    case elfcpp::R_ARM_THM_JUMP19:
     case elfcpp::R_ARM_THM_JUMP6:
-    case elfcpp::R_ARM_THM_JUMP8:
-    case elfcpp::R_ARM_THM_JUMP11:
-    case elfcpp::R_ARM_V4BX:
-    case elfcpp::R_ARM_THM_PC8:
-    case elfcpp::R_ARM_THM_PC12:
     case elfcpp::R_ARM_THM_ALU_PREL_11_0:
+    case elfcpp::R_ARM_THM_PC12:
+    case elfcpp::R_ARM_REL32_NOI:
     case elfcpp::R_ARM_ALU_PC_G0_NC:
     case elfcpp::R_ARM_ALU_PC_G0:
     case elfcpp::R_ARM_ALU_PC_G1_NC:
     case elfcpp::R_ARM_ALU_PC_G1:
     case elfcpp::R_ARM_ALU_PC_G2:
+    case elfcpp::R_ARM_LDR_PC_G1:
+    case elfcpp::R_ARM_LDR_PC_G2:
+    case elfcpp::R_ARM_LDRS_PC_G0:
+    case elfcpp::R_ARM_LDRS_PC_G1:
+    case elfcpp::R_ARM_LDRS_PC_G2:
+    case elfcpp::R_ARM_LDC_PC_G0:
+    case elfcpp::R_ARM_LDC_PC_G1:
+    case elfcpp::R_ARM_LDC_PC_G2:
     case elfcpp::R_ARM_ALU_SB_G0_NC:
     case elfcpp::R_ARM_ALU_SB_G0:
     case elfcpp::R_ARM_ALU_SB_G1_NC:
     case elfcpp::R_ARM_ALU_SB_G1:
     case elfcpp::R_ARM_ALU_SB_G2:
-    case elfcpp::R_ARM_LDR_PC_G0:
-    case elfcpp::R_ARM_LDR_PC_G1:
-    case elfcpp::R_ARM_LDR_PC_G2:
     case elfcpp::R_ARM_LDR_SB_G0:
     case elfcpp::R_ARM_LDR_SB_G1:
     case elfcpp::R_ARM_LDR_SB_G2:
-    case elfcpp::R_ARM_LDRS_PC_G0:
-    case elfcpp::R_ARM_LDRS_PC_G1:
-    case elfcpp::R_ARM_LDRS_PC_G2:
     case elfcpp::R_ARM_LDRS_SB_G0:
     case elfcpp::R_ARM_LDRS_SB_G1:
     case elfcpp::R_ARM_LDRS_SB_G2:
-    case elfcpp::R_ARM_LDC_PC_G0:
-    case elfcpp::R_ARM_LDC_PC_G1:
-    case elfcpp::R_ARM_LDC_PC_G2:
     case elfcpp::R_ARM_LDC_SB_G0:
     case elfcpp::R_ARM_LDC_SB_G1:
     case elfcpp::R_ARM_LDC_SB_G2:
+    case elfcpp::R_ARM_MOVW_BREL_NC:
+    case elfcpp::R_ARM_MOVT_BREL:
+    case elfcpp::R_ARM_MOVW_BREL:
+    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
+    case elfcpp::R_ARM_THM_MOVT_BREL:
+    case elfcpp::R_ARM_THM_MOVW_BREL:
+    case elfcpp::R_ARM_THM_JUMP11:
+    case elfcpp::R_ARM_THM_JUMP8:
+      // We don't need to do anything for a relative addressing relocation
+      // against a local symbol if it does not reference the GOT.
       break;
 
     case elfcpp::R_ARM_GOTOFF32:
+    case elfcpp::R_ARM_GOTOFF12:
       // We need a GOT section:
       target->got_section(symtab, layout);
       break;
 
-    case elfcpp::R_ARM_BASE_PREL:
-      // FIXME: What about this?
-      break;
-
     case elfcpp::R_ARM_GOT_BREL:
     case elfcpp::R_ARM_GOT_PREL:
       {
@@ -6697,6 +6737,7 @@ Target_arm<big_endian>::Scan::local(Symbol_table* symtab,
       break;
 
     case elfcpp::R_ARM_TARGET1:
+    case elfcpp::R_ARM_TARGET2:
       // This should have been mapped to another type already.
       // Fall through.
     case elfcpp::R_ARM_COPY:
@@ -6729,8 +6770,6 @@ Target_arm<big_endian>::Scan::unsupported_reloc_global(
 }
 
 // Scan a relocation for a global symbol.
-// FIXME: This only handles a subset of relocation types used by Android
-// on ARM v5te devices.
 
 template<bool big_endian>
 inline void
@@ -6748,109 +6787,118 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab,
   switch (r_type)
     {
     case elfcpp::R_ARM_NONE:
+    case elfcpp::R_ARM_V4BX:
+    case elfcpp::R_ARM_GNU_VTENTRY:
+    case elfcpp::R_ARM_GNU_VTINHERIT:
       break;
 
     case elfcpp::R_ARM_ABS32:
+    case elfcpp::R_ARM_ABS16:
+    case elfcpp::R_ARM_ABS12:
+    case elfcpp::R_ARM_THM_ABS5:
+    case elfcpp::R_ARM_ABS8:
+    case elfcpp::R_ARM_BASE_ABS:
+    case elfcpp::R_ARM_MOVW_ABS_NC:
+    case elfcpp::R_ARM_MOVT_ABS:
+    case elfcpp::R_ARM_THM_MOVW_ABS_NC:
+    case elfcpp::R_ARM_THM_MOVT_ABS:
     case elfcpp::R_ARM_ABS32_NOI:
+      // Absolute addressing relocations.
       {
-       // Make a dynamic relocation if necessary.
-       if (gsym->needs_dynamic_reloc(Symbol::ABSOLUTE_REF))
-         {
-           if (target->may_need_copy_reloc(gsym))
-             {
-               target->copy_reloc(symtab, layout, object,
-                                  data_shndx, output_section, gsym, reloc);
-             }
-           else if (gsym->can_use_relative_reloc(false))
-             {
-               // If we are to add more other reloc types than R_ARM_ABS32,
-               // we need to add check_non_pic(object, r_type) here.
-               Reloc_section* rel_dyn = target->rel_dyn_section(layout);
-               rel_dyn->add_global_relative(gsym, elfcpp::R_ARM_RELATIVE,
-                                            output_section, object,
-                                            data_shndx, reloc.get_r_offset());
-             }
-           else
-             {
-               // If we are to add more other reloc types than R_ARM_ABS32,
-               // we need to add check_non_pic(object, r_type) here.
-               Reloc_section* rel_dyn = target->rel_dyn_section(layout);
-               rel_dyn->add_global(gsym, r_type, output_section, object,
-                                   data_shndx, reloc.get_r_offset());
-             }
-         }
+        // Make a PLT entry if necessary.
+        if (this->symbol_needs_plt_entry(gsym))
+          {
+            target->make_plt_entry(symtab, layout, gsym);
+            // Since this is not a PC-relative relocation, we may be
+            // taking the address of a function. In that case we need to
+            // set the entry in the dynamic symbol table to the address of
+            // the PLT entry.
+            if (gsym->is_from_dynobj() && !parameters->options().shared())
+              gsym->set_needs_dynsym_value();
+          }
+        // Make a dynamic relocation if necessary.
+        if (gsym->needs_dynamic_reloc(Symbol::ABSOLUTE_REF))
+          {
+            if (gsym->may_need_copy_reloc())
+              {
+               target->copy_reloc(symtab, layout, object,
+                                  data_shndx, output_section, gsym, reloc);
+              }
+            else if ((r_type == elfcpp::R_ARM_ABS32
+                     || r_type == elfcpp::R_ARM_ABS32_NOI)
+                     && gsym->can_use_relative_reloc(false))
+              {
+                Reloc_section* rel_dyn = target->rel_dyn_section(layout);
+                rel_dyn->add_global_relative(gsym, elfcpp::R_ARM_RELATIVE,
+                                             output_section, object,
+                                             data_shndx, reloc.get_r_offset());
+              }
+            else
+              {
+               check_non_pic(object, r_type);
+                Reloc_section* rel_dyn = target->rel_dyn_section(layout);
+                rel_dyn->add_global(gsym, r_type, output_section, object,
+                                    data_shndx, reloc.get_r_offset());
+              }
+          }
       }
       break;
 
-    case elfcpp::R_ARM_MOVW_ABS_NC:
-    case elfcpp::R_ARM_MOVT_ABS:
-    case elfcpp::R_ARM_THM_MOVW_ABS_NC:
-    case elfcpp::R_ARM_THM_MOVT_ABS:
+    case elfcpp::R_ARM_GOTOFF32:
+    case elfcpp::R_ARM_GOTOFF12:
+      // We need a GOT section.
+      target->got_section(symtab, layout);
+      break;
+      
+    case elfcpp::R_ARM_REL32:
+    case elfcpp::R_ARM_LDR_PC_G0:
+    case elfcpp::R_ARM_SBREL32:
+    case elfcpp::R_ARM_THM_PC8:
+    case elfcpp::R_ARM_BASE_PREL:
+    case elfcpp::R_ARM_LDR_SBREL_11_0_NC:
+    case elfcpp::R_ARM_ALU_SBREL_19_12_NC:
+    case elfcpp::R_ARM_ALU_SBREL_27_20_CK:
     case elfcpp::R_ARM_MOVW_PREL_NC:
     case elfcpp::R_ARM_MOVT_PREL:
     case elfcpp::R_ARM_THM_MOVW_PREL_NC:
     case elfcpp::R_ARM_THM_MOVT_PREL:
-    case elfcpp::R_ARM_MOVW_BREL_NC:
-    case elfcpp::R_ARM_MOVT_BREL:
-    case elfcpp::R_ARM_MOVW_BREL:
-    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
-    case elfcpp::R_ARM_THM_MOVT_BREL:
-    case elfcpp::R_ARM_THM_MOVW_BREL:
-    case elfcpp::R_ARM_THM_JUMP6:
-    case elfcpp::R_ARM_THM_JUMP8:
-    case elfcpp::R_ARM_THM_JUMP11:
-    case elfcpp::R_ARM_V4BX:
-    case elfcpp::R_ARM_THM_PC8:
-    case elfcpp::R_ARM_THM_PC12:
     case elfcpp::R_ARM_THM_ALU_PREL_11_0:
+    case elfcpp::R_ARM_THM_PC12:
+    case elfcpp::R_ARM_REL32_NOI:
     case elfcpp::R_ARM_ALU_PC_G0_NC:
     case elfcpp::R_ARM_ALU_PC_G0:
     case elfcpp::R_ARM_ALU_PC_G1_NC:
     case elfcpp::R_ARM_ALU_PC_G1:
     case elfcpp::R_ARM_ALU_PC_G2:
+    case elfcpp::R_ARM_LDR_PC_G1:
+    case elfcpp::R_ARM_LDR_PC_G2:
+    case elfcpp::R_ARM_LDRS_PC_G0:
+    case elfcpp::R_ARM_LDRS_PC_G1:
+    case elfcpp::R_ARM_LDRS_PC_G2:
+    case elfcpp::R_ARM_LDC_PC_G0:
+    case elfcpp::R_ARM_LDC_PC_G1:
+    case elfcpp::R_ARM_LDC_PC_G2:
     case elfcpp::R_ARM_ALU_SB_G0_NC:
     case elfcpp::R_ARM_ALU_SB_G0:
     case elfcpp::R_ARM_ALU_SB_G1_NC:
     case elfcpp::R_ARM_ALU_SB_G1:
     case elfcpp::R_ARM_ALU_SB_G2:
-    case elfcpp::R_ARM_LDR_PC_G0:
-    case elfcpp::R_ARM_LDR_PC_G1:
-    case elfcpp::R_ARM_LDR_PC_G2:
     case elfcpp::R_ARM_LDR_SB_G0:
     case elfcpp::R_ARM_LDR_SB_G1:
     case elfcpp::R_ARM_LDR_SB_G2:
-    case elfcpp::R_ARM_LDRS_PC_G0:
-    case elfcpp::R_ARM_LDRS_PC_G1:
-    case elfcpp::R_ARM_LDRS_PC_G2:
     case elfcpp::R_ARM_LDRS_SB_G0:
     case elfcpp::R_ARM_LDRS_SB_G1:
     case elfcpp::R_ARM_LDRS_SB_G2:
-    case elfcpp::R_ARM_LDC_PC_G0:
-    case elfcpp::R_ARM_LDC_PC_G1:
-    case elfcpp::R_ARM_LDC_PC_G2:
     case elfcpp::R_ARM_LDC_SB_G0:
     case elfcpp::R_ARM_LDC_SB_G1:
     case elfcpp::R_ARM_LDC_SB_G2:
-      break;
-
-    case elfcpp::R_ARM_THM_ABS5:
-    case elfcpp::R_ARM_ABS8:
-    case elfcpp::R_ARM_ABS12:
-    case elfcpp::R_ARM_ABS16:
-    case elfcpp::R_ARM_BASE_ABS:
-      {
-       // No dynamic relocs of this kinds.
-       // Report the error in case of PIC.
-       int flags = Symbol::NON_PIC_REF;
-       if (gsym->type() == elfcpp::STT_FUNC
-           || gsym->type() == elfcpp::STT_ARM_TFUNC)
-         flags |= Symbol::FUNCTION_CALL;
-       if (gsym->needs_dynamic_reloc(flags))
-         check_non_pic(object, r_type);
-      }
-      break;
-
-    case elfcpp::R_ARM_REL32:
+    case elfcpp::R_ARM_MOVW_BREL_NC:
+    case elfcpp::R_ARM_MOVT_BREL:
+    case elfcpp::R_ARM_MOVW_BREL:
+    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
+    case elfcpp::R_ARM_THM_MOVT_BREL:
+    case elfcpp::R_ARM_THM_MOVW_BREL:
+      // Relative addressing relocations.
       {
        // Make a dynamic relocation if necessary.
        int flags = Symbol::NON_PIC_REF;
@@ -6872,14 +6920,27 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab,
       }
       break;
 
-    case elfcpp::R_ARM_JUMP24:
-    case elfcpp::R_ARM_THM_JUMP24:
-    case elfcpp::R_ARM_THM_JUMP19:
-    case elfcpp::R_ARM_CALL:
+    case elfcpp::R_ARM_PC24:
     case elfcpp::R_ARM_THM_CALL:
     case elfcpp::R_ARM_PLT32:
+    case elfcpp::R_ARM_CALL:
+    case elfcpp::R_ARM_JUMP24:
+    case elfcpp::R_ARM_THM_JUMP24:
+    case elfcpp::R_ARM_SBREL31:
     case elfcpp::R_ARM_PREL31:
-    case elfcpp::R_ARM_PC24:
+    case elfcpp::R_ARM_THM_JUMP19:
+    case elfcpp::R_ARM_THM_JUMP6:
+    case elfcpp::R_ARM_THM_JUMP11:
+    case elfcpp::R_ARM_THM_JUMP8:
+      // All the relocation above are branches except for the PREL31 ones.
+      // A PREL31 relocation can point to a personality function in a shared
+      // library.  In that case we want to use a PLT because we want to
+      // call the personality routine and the dyanmic linkers we care about
+      // do not support dynamic PREL31 relocations. An REL31 relocation may
+      // point to a function whose unwinding behaviour is being described but
+      // we will not mistakenly generate a PLT for that because we should use
+      // a local section symbol.
+
       // If the symbol is fully resolved, this is just a relative
       // local reloc.  Otherwise we need a PLT entry.
       if (gsym->final_value_is_known())
@@ -6894,16 +6955,8 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab,
       target->make_plt_entry(symtab, layout, gsym);
       break;
 
-    case elfcpp::R_ARM_GOTOFF32:
-      // We need a GOT section.
-      target->got_section(symtab, layout);
-      break;
-
-    case elfcpp::R_ARM_BASE_PREL:
-      // FIXME: What about this?
-      break;
-      
     case elfcpp::R_ARM_GOT_BREL:
+    case elfcpp::R_ARM_GOT_ABS:
     case elfcpp::R_ARM_GOT_PREL:
       {
        // The symbol requires a GOT entry.
@@ -6933,7 +6986,8 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab,
       break;
 
     case elfcpp::R_ARM_TARGET1:
-      // This should have been mapped to another type already.
+    case elfcpp::R_ARM_TARGET2:
+      // These should have been mapped to other types already.
       // Fall through.
     case elfcpp::R_ARM_COPY:
     case elfcpp::R_ARM_GLOB_DAT:
@@ -7403,43 +7457,31 @@ Target_arm<big_endian>::Relocate::relocate(
       break;
 
     case elfcpp::R_ARM_MOVW_ABS_NC:
-      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true,
+      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false,
                                    output_section))
        reloc_status = Arm_relocate_functions::movw(view, object, psymval,
                                                    0, thumb_bit,
                                                    check_overflow);
-      else
-       gold_error(_("relocation R_ARM_MOVW_ABS_NC cannot be used when making"
-                    "a shared object; recompile with -fPIC"));
       break;
 
     case elfcpp::R_ARM_MOVT_ABS:
-      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true,
+      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false,
                                    output_section))
        reloc_status = Arm_relocate_functions::movt(view, object, psymval, 0);
-      else
-       gold_error(_("relocation R_ARM_MOVT_ABS cannot be used when making"
-                    "a shared object; recompile with -fPIC"));
       break;
 
     case elfcpp::R_ARM_THM_MOVW_ABS_NC:
-      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true,
+      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false,
                                    output_section))
        reloc_status = Arm_relocate_functions::thm_movw(view, object, psymval,
                                                                0, thumb_bit, false);
-      else
-       gold_error(_("relocation R_ARM_THM_MOVW_ABS_NC cannot be used when"
-                    "making a shared object; recompile with -fPIC"));
       break;
 
     case elfcpp::R_ARM_THM_MOVT_ABS:
-      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true,
+      if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false,
                                    output_section))
        reloc_status = Arm_relocate_functions::thm_movt(view, object,
                                                        psymval, 0);
-      else
-       gold_error(_("relocation R_ARM_THM_MOVT_ABS cannot be used when"
-                    "making a shared object; recompile with -fPIC"));
       break;
 
     case elfcpp::R_ARM_MOVW_PREL_NC:
@@ -7512,7 +7554,7 @@ Target_arm<big_endian>::Relocate::relocate(
 
     case elfcpp::R_ARM_BASE_ABS:
       {
-       if (!should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true,
+       if (!should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false,
                                      output_section))
          break;
 
index 1ffb7b0..a1889bb 100644 (file)
@@ -1435,3 +1435,22 @@ MOSTLYCLEANFILES += split_x86_64_1 split_x86_64_2 split_x86_64_3 \
        split_x86_64_4 split_x86_64_r
 
 endif DEFAULT_TARGET_X86_64
+
+if DEFAULT_TARGET_ARM
+
+check_SCRIPTS += arm_abs_global.sh
+check_DATA += arm_abs_global.stdout
+arm_abs_lib.o: arm_abs_lib.s
+       $(TEST_AS) -march=armv7-a -o $@ $<
+libarm_abs.so: arm_abs_lib.o
+       ../ld-new -shared -o $@ arm_abs_lib.o
+arm_abs_global.o: arm_abs_global.s
+       $(TEST_AS) -march=armv7-a -o $@ $<
+arm_abs_global: arm_abs_global.o libarm_abs.so
+       ../ld-new -o $@ arm_abs_global.o -L. -larm_abs
+arm_abs_global.stdout: arm_abs_global
+       $(TEST_READELF) -r $< > $@
+
+MOSTLYCLEANFILES += arm_abs_global
+
+endif DEFAULT_TARGET_ARM
index a806b34..e5fd65f 100644 (file)
@@ -318,6 +318,9 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
 @DEFAULT_TARGET_X86_64_TRUE@am__append_37 = split_x86_64_1 split_x86_64_2 split_x86_64_3 \
 @DEFAULT_TARGET_X86_64_TRUE@   split_x86_64_4 split_x86_64_r
 
+@DEFAULT_TARGET_ARM_TRUE@am__append_38 = arm_abs_global.sh
+@DEFAULT_TARGET_ARM_TRUE@am__append_39 = arm_abs_global.stdout
+@DEFAULT_TARGET_ARM_TRUE@am__append_40 = arm_abs_global
 subdir = testsuite
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -1378,15 +1381,16 @@ TEST_AS = $(top_builddir)/../gas/as-new
 # the right choice for files 'make' builds that people rebuild.
 MOSTLYCLEANFILES = *.so *.syms *.stdout $(am__append_3) \
        $(am__append_8) $(am__append_17) $(am__append_25) \
-       $(am__append_29) $(am__append_34) $(am__append_37)
+       $(am__append_29) $(am__append_34) $(am__append_37) \
+       $(am__append_40)
 
 # We will add to these later, for each individual test.  Note
 # that we add each test under check_SCRIPTS or check_PROGRAMS;
 # the TESTS variable is automatically populated from these.
 check_SCRIPTS = $(am__append_1) $(am__append_23) $(am__append_27) \
-       $(am__append_32) $(am__append_35)
+       $(am__append_32) $(am__append_35) $(am__append_38)
 check_DATA = $(am__append_2) $(am__append_24) $(am__append_28) \
-       $(am__append_33) $(am__append_36)
+       $(am__append_33) $(am__append_36) $(am__append_39)
 BUILT_SOURCES = $(am__append_16)
 TESTS = $(check_SCRIPTS) $(check_PROGRAMS)
 
@@ -3193,6 +3197,16 @@ uninstall-am:
 @DEFAULT_TARGET_X86_64_TRUE@   $(TEST_OBJDUMP) -d $< > $@
 @DEFAULT_TARGET_X86_64_TRUE@split_x86_64_r.stdout: split_x86_64_1.o split_x86_64_n.o ../ld-new
 @DEFAULT_TARGET_X86_64_TRUE@   ../ld-new -r split_x86_64_1.o split_x86_64_n.o -o split_x86_64_r > $@ 2>&1 || exit 0
+@DEFAULT_TARGET_ARM_TRUE@arm_abs_lib.o: arm_abs_lib.s
+@DEFAULT_TARGET_ARM_TRUE@      $(TEST_AS) -march=armv7-a -o $@ $<
+@DEFAULT_TARGET_ARM_TRUE@libarm_abs.so: arm_abs_lib.o
+@DEFAULT_TARGET_ARM_TRUE@      ../ld-new -shared -o $@ arm_abs_lib.o
+@DEFAULT_TARGET_ARM_TRUE@arm_abs_global.o: arm_abs_global.s
+@DEFAULT_TARGET_ARM_TRUE@      $(TEST_AS) -march=armv7-a -o $@ $<
+@DEFAULT_TARGET_ARM_TRUE@arm_abs_global: arm_abs_global.o libarm_abs.so
+@DEFAULT_TARGET_ARM_TRUE@      ../ld-new -o $@ arm_abs_global.o -L. -larm_abs
+@DEFAULT_TARGET_ARM_TRUE@arm_abs_global.stdout: arm_abs_global
+@DEFAULT_TARGET_ARM_TRUE@      $(TEST_READELF) -r $< > $@
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/gold/testsuite/arm_abs_global.s b/gold/testsuite/arm_abs_global.s
new file mode 100644 (file)
index 0000000..65cb309
--- /dev/null
@@ -0,0 +1,31 @@
+       .syntax unified
+
+       .text
+       .align  2
+
+       .global _start
+       .type   _start, %function
+_start:
+       bx      lr
+       .size   _start, .-_start
+
+       .global _arm_test
+       .type   _arm_test, %function
+_arm_test:
+       movt    r0, #:upper16:_movt_abs_global
+       movw    r0, #:lower16:_movw_abs_global
+       bx      lr
+       .size   _arm_test, .-_arm_test
+
+       .thumb
+       .global _thumb_test
+_thumb_test:
+       movt    r0, #:upper16:_thm_movt_abs_global
+       movw    r0, #:lower16:_thm_movw_abs_global
+       bx      lr
+       .size   _thumb_test, .-_thumb_test
+
+       .data
+_data_test:
+       .word   _abs32_global
+       .word   _abs32_global_plt
diff --git a/gold/testsuite/arm_abs_global.sh b/gold/testsuite/arm_abs_global.sh
new file mode 100755 (executable)
index 0000000..26abc24
--- /dev/null
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# arm_abs_global.sh -- test ARM absolute relocations against global symbols.
+
+# Copyright 2010 Free Software Foundation, Inc.
+# Written by Doug Kwan <dougkwan@google.com>
+
+# This file is part of gold.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# This file goes with the assembler source file arm_abs_global.s,
+# that is assembled and linked with a shared object libarm_abs.so.  We
+# want to check that a MOV[TW] instruction referencing an external function
+# causes a PLT to be created.
+
+check()
+{
+    file=$1
+    sym=$2
+    reloc=$3
+
+    found=`grep " $sym\$" $file`
+    if test -z "$found"; then
+       echo "Symbol $sym not found."
+       exit 1
+    fi
+
+    match_reloc=`grep " $sym\$" $file | grep " $reloc "`
+    if test -z "$match_reloc"; then
+       echo "Expected symbol $sym to have relocation $reloc but found"
+       echo "$found"
+       exit 1
+    fi
+}
+
+check "arm_abs_global.stdout" "_movt_abs_global" "R_ARM_JUMP_SLOT"
+check "arm_abs_global.stdout" "_movw_abs_global" "R_ARM_JUMP_SLOT"
+check "arm_abs_global.stdout" "_thm_movt_abs_global" "R_ARM_JUMP_SLOT"
+check "arm_abs_global.stdout" "_thm_movw_abs_global" "R_ARM_JUMP_SLOT"
+check "arm_abs_global.stdout" "_abs32_global_plt" "R_ARM_JUMP_SLOT"
+check "arm_abs_global.stdout" "_abs32_global" "R_ARM_ABS32"
+
+exit 0
diff --git a/gold/testsuite/arm_abs_lib.s b/gold/testsuite/arm_abs_lib.s
new file mode 100644 (file)
index 0000000..a2d7207
--- /dev/null
@@ -0,0 +1,37 @@
+       .syntax unified
+
+       .text
+       .align  2
+       .global _movt_abs_global
+       .type   _movt_abs_global, %function
+_movt_abs_global:
+       bx      lr
+       .size   _movt_abs_global, .-_movt_abs_global
+
+       .global _movw_abs_global
+       .type   _movw_abs_global, %function
+_movw_abs_global:
+       bx      lr
+       .size   _movw_abs_global, .-_movw_abs_global
+
+       .thumb
+       .align  2
+       .global _thm_movt_abs_global
+       .type   _thm_movt_abs_global, %function
+_thm_movt_abs_global:
+       bx      lr
+       .size   _thm_movt_abs_global, .-_thm_movt_abs_global
+
+       .global _thm_movw_abs_global
+       .type   _thm_movw_abs_global, %function
+_thm_movw_abs_global:
+       bx      lr
+       .size   _thm_movw_abs_global, .-_thm_movw_abs_global
+
+       .global _abs32_global_plt
+       .type   _abs32_global_plt, %function
+_abs32_global_plt:
+       bx      lr
+       .size   _abs32_global_plt, .-_abs32_global_plt
+
+       .comm   _abs32_global,4,4