aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-03-12 15:58:37 +0000
committerNick Clifton <nickc@redhat.com>2015-03-12 15:58:37 +0000
commit93ef582debb0a179916965a882f4344223569219 (patch)
treeb48d6097849db2a37cf5664fe18294a81c2c9f78
parent811a659a779fdf93293fe1105d99e9db171a8b68 (diff)
downloadfsf-binutils-gdb-93ef582debb0a179916965a882f4344223569219.zip
fsf-binutils-gdb-93ef582debb0a179916965a882f4344223569219.tar.gz
fsf-binutils-gdb-93ef582debb0a179916965a882f4344223569219.tar.bz2
Fixes a problem generating relocs for thumb function calls to local symbols defined in other sections.
PR gas/17444 * config/tc-arm.h (MD_APPLY_SYM_VALUE): Pass the current segment to arm_apply_sym_value. Update prototype. * config/tc-arm.c (arm_apply_sym_value): Add segment argument. Do not apply the value if the symbol is in a different segment to the current segment.
-rw-r--r--gas/ChangeLog9
-rw-r--r--gas/config/tc-arm.c14
-rw-r--r--gas/config/tc-arm.h4
3 files changed, 20 insertions, 7 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index d98b8cb..36f0f32 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,12 @@
+2015-03-12 Nick Clifton <nickc@redhat.com>
+
+ PR gas/17444
+ * config/tc-arm.h (MD_APPLY_SYM_VALUE): Pass the current segment
+ to arm_apply_sym_value. Update prototype.
+ * config/tc-arm.c (arm_apply_sym_value): Add segment argument.
+ Do not apply the value if the symbol is in a different segment to
+ the current segment.
+
2015-03-11 Alan Modra <amodra@gmail.com>
* config/tc-ppc.c (md_assemble): Don't abort on 8 byte insn fixups.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 1f15116..e97036a 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -25647,14 +25647,18 @@ arm_convert_symbolic_attribute (const char *name)
}
-/* Apply sym value for relocations only in the case that
- they are for local symbols and you have the respective
- architectural feature for blx and simple switches. */
+/* Apply sym value for relocations only in the case that they are for
+ local symbols in the same segment as the fixup and you have the
+ respective architectural feature for blx and simple switches. */
int
-arm_apply_sym_value (struct fix * fixP)
+arm_apply_sym_value (struct fix * fixP, segT this_seg)
{
if (fixP->fx_addsy
&& ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
+ /* PR 17444: If the local symbol is in a different section then a reloc
+ will always be generated for it, so applying the symbol value now
+ will result in a double offset being stored in the relocation. */
+ && (S_GET_SEGMENT (fixP->fx_addsy) == this_seg)
&& !S_FORCE_RELOC (fixP->fx_addsy, TRUE))
{
switch (fixP->fx_r_type)
@@ -25668,7 +25672,7 @@ arm_apply_sym_value (struct fix * fixP)
case BFD_RELOC_ARM_PCREL_CALL:
case BFD_RELOC_THUMB_PCREL_BLX:
if (THUMB_IS_FUNC (fixP->fx_addsy))
- return 1;
+ return 1;
break;
default:
diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h
index 91db285..b604f04 100644
--- a/gas/config/tc-arm.h
+++ b/gas/config/tc-arm.h
@@ -327,7 +327,7 @@ struct arm_segment_info_type
#ifdef OBJ_ELF
/* Values passed to md_apply_fix don't include the symbol value. */
-# define MD_APPLY_SYM_VALUE(FIX) arm_apply_sym_value (FIX)
+# define MD_APPLY_SYM_VALUE(FIX) arm_apply_sym_value (FIX, this_segment)
#endif
#ifdef OBJ_COFF
@@ -372,7 +372,7 @@ void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int);
#ifdef OBJ_ELF
#define CONVERT_SYMBOLIC_ATTRIBUTE(name) arm_convert_symbolic_attribute (name)
extern int arm_convert_symbolic_attribute (const char *);
-extern int arm_apply_sym_value (struct fix *);
+extern int arm_apply_sym_value (struct fix *, segT);
#endif
#define tc_comment_chars arm_comment_chars