aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2011-05-31 13:40:04 +0000
committerPaul Brook <paul@codesourcery.com>2011-05-31 13:40:04 +0000
commit6e7ce2cdd34f7e3ad720e1d43a19635d79ce17b4 (patch)
treed8a159765825d07d54e8c5480dff705e6d356b1f /gas
parent12352d3f854285aaaecf6bc89df80e6247968a63 (diff)
downloadgdb-6e7ce2cdd34f7e3ad720e1d43a19635d79ce17b4.zip
gdb-6e7ce2cdd34f7e3ad720e1d43a19635d79ce17b4.tar.gz
gdb-6e7ce2cdd34f7e3ad720e1d43a19635d79ce17b4.tar.bz2
2011-05-31 Paul Brook <paul@codesourcery.com>
Nathan Sidwell <nathan@codesourcery.com> gas/ * config/tc-arm.c (fix_new_arm): Create an absolute symbol for pc-relative fixes to constants. * config/tc-arm.h (TC_FORCE_RELOCATATION_ABS): Define. ld/testsuite/ * ld-arm/abs-call-1.d: New. * ld-arm/abs-call-1.s: New. * ld-arm/arm-elf.exp: Add it.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-arm.c23
-rw-r--r--gas/config/tc-arm.h6
3 files changed, 36 insertions, 0 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index cd4546c..456f14a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,10 @@
+2011-05-31 Paul Brook <paul@codesourcery.com>
+ Nathan Sidwell <nathan@codesourcery.com>
+
+ * config/tc-arm.c (fix_new_arm): Create an absolute symbol for
+ pc-relative fixes to constants.
+ * config/tc-arm.h (TC_FORCE_RELOCATATION_ABS): Define.
+
2011-05-27 Nick Clifton <nickc@redhat.com>
* config/tc-s390.c (md_begin): Remove unused variable dup_insn.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index a9839cd..375ff82 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -15434,6 +15434,29 @@ fix_new_arm (fragS * frag,
switch (exp->X_op)
{
case O_constant:
+ if (pc_rel)
+ {
+ /* Create an absolute valued symbol, so we have something to
+ refer to in the object file. Unfortunately for us, gas's
+ generic expression parsing will already have folded out
+ any use of .set foo/.type foo %function that may have
+ been used to set type information of the target location,
+ that's being specified symbolically. We have to presume
+ the user knows what they are doing. */
+ char name[16 + 8];
+ symbolS *symbol;
+
+ sprintf (name, "*ABS*0x%lx", (unsigned long)exp->X_add_number);
+
+ symbol = symbol_find_or_make (name);
+ S_SET_SEGMENT (symbol, absolute_section);
+ symbol_set_frag (symbol, &zero_address_frag);
+ S_SET_VALUE (symbol, exp->X_add_number);
+ exp->X_op = O_symbol;
+ exp->X_add_symbol = symbol;
+ exp->X_add_number = 0;
+ }
+ /* FALLTHROUGH */
case O_symbol:
case O_add:
case O_subtract:
diff --git a/gas/config/tc-arm.h b/gas/config/tc-arm.h
index 702e405..2916ae1 100644
--- a/gas/config/tc-arm.h
+++ b/gas/config/tc-arm.h
@@ -192,6 +192,12 @@ void arm_copy_symbol_attributes (symbolS *, symbolS *);
(THUMB_IS_FUNC ((FIX)->fx_addsy) \
|| !SEG_NORMAL (SEG))
+#define TC_FORCE_RELOCATION_ABS(FIX) \
+ (((FIX)->fx_pcrel \
+ && (FIX)->fx_r_type != BFD_RELOC_32 \
+ && (FIX)->fx_r_type != BFD_RELOC_ARM_GOT32) \
+ || TC_FORCE_RELOCATION(FIX))
+
#define TC_CONS_FIX_NEW cons_fix_new_arm
#define MAX_MEM_ALIGNMENT_BYTES 6