-#define TC_HANDLES_FX_DONE
-
-#define TC_FORCE_RELOCATION(fixp) md_cris_force_relocation (fixp)
-extern int md_cris_force_relocation PARAMS ((struct fix *));
-
-/* This is really a workaround for a bug in write.c that resolves relocs
- for weak symbols - it should be postponed to the link stage or later.
- */
-#define tc_fix_adjustable(X) \
- ((! (X)->fx_addsy || ! S_IS_WEAK((X)->fx_addsy)) \
- && (X)->fx_r_type != BFD_RELOC_VTABLE_INHERIT \
- && (X)->fx_r_type != BFD_RELOC_VTABLE_ENTRY)
+long cris_relax_frag (segT, fragS *, long);
+
+/* GAS only handles relaxations for pc-relative data targeting addresses
+ in the same segment, so we have to handle the rest on our own. */
+#define md_relax_frag(SEG, FRAGP, STRETCH) \
+ ((FRAGP)->fr_symbol != NULL \
+ && S_GET_SEGMENT ((FRAGP)->fr_symbol) == (SEG) \
+ ? relax_frag (SEG, FRAGP, STRETCH) \
+ : cris_relax_frag (SEG, FRAGP, STRETCH))
+
+#define TC_FORCE_RELOCATION(FIX) md_cris_force_relocation (FIX)
+extern int md_cris_force_relocation (struct fix *);
+
+#define IS_CRIS_PIC_RELOC(RTYPE) \
+ ((RTYPE) == BFD_RELOC_CRIS_16_GOT \
+ || (RTYPE) == BFD_RELOC_CRIS_32_GOT \
+ || (RTYPE) == BFD_RELOC_CRIS_16_GOTPLT \
+ || (RTYPE) == BFD_RELOC_CRIS_32_GOTPLT \
+ || (RTYPE) == BFD_RELOC_CRIS_32_GOTREL \
+ || (RTYPE) == BFD_RELOC_CRIS_32_PLT_GOTREL \
+ || (RTYPE) == BFD_RELOC_CRIS_32_PLT_PCREL)
+
+/* Make sure we don't resolve fixups for which we want to emit dynamic
+ relocations. */
+#define TC_FORCE_RELOCATION_LOCAL(FIX) \
+ (GENERIC_FORCE_RELOCATION_LOCAL (FIX) \
+ || IS_CRIS_PIC_RELOC ((FIX)->fx_r_type))
+
+/* For some reloc types, don't adjust fixups by reducing to a section
+ symbol. */
+#define tc_fix_adjustable(FIX) \
+ ((FIX)->fx_r_type != BFD_RELOC_VTABLE_INHERIT \
+ && (FIX)->fx_r_type != BFD_RELOC_VTABLE_ENTRY \
+ && (! IS_CRIS_PIC_RELOC ((FIX)->fx_r_type) \
+ || (FIX)->fx_r_type == BFD_RELOC_CRIS_32_GOTREL))
+
+/* FIXME: This *should* be a redundant definition, as the
+ TC_FORCE_RELOCATION* definitions already told about the cases where
+ we *don't* want the symbol value calculated. Here we seem to answer
+ the "are you sure" question. It certainly has very little to do with
+ whether the symbol value is passed to md_apply_fix. */
+#define MD_APPLY_SYM_VALUE(FIX) 0