aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-mn10300.c
diff options
context:
space:
mode:
authorEric Christopher <echristo@gmail.com>2000-08-22 01:20:41 +0000
committerEric Christopher <echristo@gmail.com>2000-08-22 01:20:41 +0000
commit58a77e418b6999bee8e5e54e5483d24536bb93c0 (patch)
tree6cdd7c1cc691efcf1798178c6841ff38f1777772 /gas/config/tc-mn10300.c
parent7a9af8c4a0fdb228854799a8b96eef29932a2004 (diff)
downloadfsf-binutils-gdb-58a77e418b6999bee8e5e54e5483d24536bb93c0.zip
fsf-binutils-gdb-58a77e418b6999bee8e5e54e5483d24536bb93c0.tar.gz
fsf-binutils-gdb-58a77e418b6999bee8e5e54e5483d24536bb93c0.tar.bz2
2000-08-22 Eric Christopher <echristo@cygnus.com>
* config/tc-mn10300.c: (md_apply_fix): New function. (mn10300_force_relocation): New function. (mn10300_fix_adjustable): New function. * config/tc-mn10300.h: (TC_FORCE_RELOCATION): Define. (TC_HANDLES_FX_DONE): Define. (obj_fix_adjustable): Define. (MD_APPLY_FIX3): Define. (TC_LINKRELAX_FIXUP): Define. * write.c: (TC_LINKRELAX_FIXUP): Define if not previously defined. (fixup_segment): Use TC_LINKRELAX_FIXUP. * doc/internals.texi: Document TC_LINKRELAX_FIXUP.
Diffstat (limited to 'gas/config/tc-mn10300.c')
-rw-r--r--gas/config/tc-mn10300.c84
1 files changed, 82 insertions, 2 deletions
diff --git a/gas/config/tc-mn10300.c b/gas/config/tc-mn10300.c
index cc30591..18db9fd 100644
--- a/gas/config/tc-mn10300.c
+++ b/gas/config/tc-mn10300.c
@@ -1920,10 +1920,90 @@ md_apply_fix3 (fixp, valuep, seg)
valueT *valuep;
segT seg;
{
- /* We shouldn't ever get here because linkrelax is nonzero. */
- abort ();
+
+ valueT value = *valuep;
+ char *fixpos = fixp->fx_where + fixp->fx_frag->fr_literal;
+ int size = 0;
+
+ assert (fixp->fx_r_type < BFD_RELOC_UNUSED);
+
+ /* This should never happen. */
+ if (seg->flags & SEC_ALLOC)
+ abort ();
+
+ /* If the fix is relative to a symbol which is not defined, or not
+ in the same segment as the fix, we cannot resolve it here. */
+ if (fixp->fx_addsy != NULL
+ && (! S_IS_DEFINED (fixp->fx_addsy)
+ || (S_GET_SEGMENT (fixp->fx_addsy) != seg)))
+ {
+ fixp->fx_done = 0;
+ return 0;
+ }
+
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_8:
+ size = 1;
+ break;
+
+ case BFD_RELOC_16:
+ size = 2;
+ break;
+
+ case BFD_RELOC_32:
+ size = 4;
+ break;
+
+ case BFD_RELOC_VTABLE_INHERIT:
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixp->fx_done = 0;
+ return 1;
+
+ case BFD_RELOC_NONE:
+ default:
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("Bad relocation fixup type (%d)"), fixp->fx_r_type);
+ }
+
+ md_number_to_chars (fixpos, fixp->fx_offset, size);
+
fixp->fx_done = 1;
return 0;
+
+}
+
+/* Return nonzero if the fixup in FIXP will require a relocation,
+ even it if appears that the fixup could be completely handled
+ within GAS. */
+
+int
+mn10300_force_relocation (fixp)
+ struct fix *fixp;
+{
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+
+ return 0;
+}
+
+/* Return zero if the fixup in fixp should be left alone and not
+ adjusted. */
+
+boolean
+mn10300_fix_adjustable (fixp)
+ struct fix *fixp;
+{
+ /* Prevent all adjustments to global symbols. */
+ if (S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy))
+ return 0;
+
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
+
+ return 1;
}
/* Insert an operand value into an instruction. */