aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorJames Clarke <jrtc27@jrtc27.com>2017-08-23 05:46:45 -0700
committerJose E. Marchesi <jose.marchesi@oracle.com>2017-08-23 05:46:45 -0700
commitf6a36b0c9e537e4525f3b0687a4f76b4f77bf173 (patch)
treed8dba9f162f51dbef42ab479295c4c2fdc19bda7 /gas/config
parentb80c727008fc32d5271f3966be4e2a43badf8055 (diff)
downloadgdb-f6a36b0c9e537e4525f3b0687a4f76b4f77bf173.zip
gdb-f6a36b0c9e537e4525f3b0687a4f76b4f77bf173.tar.gz
gdb-f6a36b0c9e537e4525f3b0687a4f76b4f77bf173.tar.bz2
gas: enable PC-relative diff relocations on sparc64
gas/ * config/tc-sparc.c (tc_gen_reloc): Convert BFD_RELOC_8/16/32/64 into the corresponding BFD_RELOC_8/16/32/64_PCREL relocation when requested. * config/tc-sparc.h (DIFF_EXPR_OK): Define to enable PC-relative diff relocations. (TC_FORCE_RELOCATION_SUB_LOCAL): Define to ensure only supported relocations are made PC-relative. (CFI_DIFF_EXPR_OK): Define to 0 to force BFD_RELOC_32_PCREL to be used directly, since otherwise BFD_RELOC_SPARC_UA32 will be used for .eh_frame which cannot in general be converted to a BFD_RELOC_32_PCREL due to alignment requirements.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-sparc.c26
-rw-r--r--gas/config/tc-sparc.h17
2 files changed, 42 insertions, 1 deletions
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c
index 692a187..6d1b038 100644
--- a/gas/config/tc-sparc.c
+++ b/gas/config/tc-sparc.c
@@ -3946,8 +3946,33 @@ tc_gen_reloc (asection *section, fixS *fixp)
switch (fixp->fx_r_type)
{
+ case BFD_RELOC_8:
case BFD_RELOC_16:
case BFD_RELOC_32:
+ case BFD_RELOC_64:
+ if (fixp->fx_pcrel)
+ {
+ switch (fixp->fx_size)
+ {
+ default:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("can not do %d byte pc-relative relocation"),
+ fixp->fx_size);
+ code = fixp->fx_r_type;
+ fixp->fx_pcrel = 0;
+ break;
+ case 1: code = BFD_RELOC_8_PCREL; break;
+ case 2: code = BFD_RELOC_16_PCREL; break;
+ case 4: code = BFD_RELOC_32_PCREL; break;
+#ifdef BFD64
+ case 8: code = BFD_RELOC_64_PCREL; break;
+#endif
+ }
+ if (fixp->fx_pcrel)
+ fixp->fx_addnumber = fixp->fx_offset;
+ break;
+ }
+ /* Fall through. */
case BFD_RELOC_HI22:
case BFD_RELOC_LO10:
case BFD_RELOC_32_PCREL_S2:
@@ -3960,7 +3985,6 @@ tc_gen_reloc (asection *section, fixS *fixp)
case BFD_RELOC_SPARC_WDISP16:
case BFD_RELOC_SPARC_WDISP19:
case BFD_RELOC_SPARC_WDISP22:
- case BFD_RELOC_64:
case BFD_RELOC_SPARC_5:
case BFD_RELOC_SPARC_6:
case BFD_RELOC_SPARC_7:
diff --git a/gas/config/tc-sparc.h b/gas/config/tc-sparc.h
index 3dd2483..f24460c 100644
--- a/gas/config/tc-sparc.h
+++ b/gas/config/tc-sparc.h
@@ -77,6 +77,8 @@ extern void sparc_handle_align (struct frag *);
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4 + 4)
+#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */
+
/* I know that "call 0" fails in sparc-coff if this doesn't return 1. I
don't know about other relocation types, or other formats, yet. */
#ifdef OBJ_COFF
@@ -128,6 +130,15 @@ extern void sparc_handle_align (struct frag *);
/* Finish up the entire symtab. */
#define tc_adjust_symtab() sparc_adjust_symtab ()
extern void sparc_adjust_symtab (void);
+
+/* Don't allow the generic code to convert fixups involving the
+ subtraction of a label in the current section to pc-relative if we
+ don't have the necessary pc-relative relocation. */
+#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) \
+ (!((FIX)->fx_r_type == BFD_RELOC_64 \
+ || (FIX)->fx_r_type == BFD_RELOC_32 \
+ || (FIX)->fx_r_type == BFD_RELOC_16 \
+ || (FIX)->fx_r_type == BFD_RELOC_8))
#endif
#ifdef OBJ_AOUT
@@ -200,4 +211,10 @@ extern int sparc_cie_data_alignment;
#define DWARF2_DEFAULT_RETURN_COLUMN 15
#define DWARF2_CIE_DATA_ALIGNMENT sparc_cie_data_alignment
+/* cons_fix_new_sparc will chooose BFD_RELOC_SPARC_UA32 for the difference
+ expressions, but there is no corresponding PC-relative relocation; as this
+ is for debugging info though, alignment does not matter, so by disabling
+ this, BFD_RELOC_32_PCREL will be emitted directly instead. */
+#define CFI_DIFF_EXPR_OK 0
+
/* end of tc-sparc.h */