diff options
author | James Clarke <jrtc27@jrtc27.com> | 2017-08-23 05:46:45 -0700 |
---|---|---|
committer | Jose E. Marchesi <jose.marchesi@oracle.com> | 2017-08-23 05:46:45 -0700 |
commit | f6a36b0c9e537e4525f3b0687a4f76b4f77bf173 (patch) | |
tree | d8dba9f162f51dbef42ab479295c4c2fdc19bda7 /gas/config | |
parent | b80c727008fc32d5271f3966be4e2a43badf8055 (diff) | |
download | gdb-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.c | 26 | ||||
-rw-r--r-- | gas/config/tc-sparc.h | 17 |
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 */ |