aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Kwan <dougkwan@google.com>2010-02-12 05:51:32 +0000
committerDoug Kwan <dougkwan@google.com>2010-02-12 05:51:32 +0000
commite4782e838130706e2d2d53a9e3c29f71419863ae (patch)
tree06d8666079258a16b125509735d9c22f3a044b6f
parentecc13e538fab510f27fb5de27f93b6be8aff983f (diff)
downloadgdb-e4782e838130706e2d2d53a9e3c29f71419863ae.zip
gdb-e4782e838130706e2d2d53a9e3c29f71419863ae.tar.gz
gdb-e4782e838130706e2d2d53a9e3c29f71419863ae.tar.bz2
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.
-rw-r--r--gold/ChangeLog18
-rw-r--r--gold/arm.cc322
-rw-r--r--gold/testsuite/Makefile.am19
-rw-r--r--gold/testsuite/Makefile.in20
-rw-r--r--gold/testsuite/arm_abs_global.s31
-rwxr-xr-xgold/testsuite/arm_abs_global.sh57
-rw-r--r--gold/testsuite/arm_abs_lib.s37
7 files changed, 361 insertions, 143 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 03191eb..0b50ead 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -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
diff --git a/gold/arm.cc b/gold/arm.cc
index 902805c..d40ab2c 100644
--- a/gold/arm.cc
+++ b/gold/arm.cc
@@ -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;
diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
index 1ffb7b0..a1889bb 100644
--- a/gold/testsuite/Makefile.am
+++ b/gold/testsuite/Makefile.am
@@ -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
diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
index a806b34..e5fd65f 100644
--- a/gold/testsuite/Makefile.in
+++ b/gold/testsuite/Makefile.in
@@ -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
index 0000000..65cb309
--- /dev/null
+++ b/gold/testsuite/arm_abs_global.s
@@ -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
index 0000000..26abc24
--- /dev/null
+++ b/gold/testsuite/arm_abs_global.sh
@@ -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
index 0000000..a2d7207
--- /dev/null
+++ b/gold/testsuite/arm_abs_lib.s
@@ -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