summaryrefslogtreecommitdiff
path: root/gas/write.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2007-02-17 23:13:49 +0000
committerAlan Modra <amodra@bigpond.net.au>2007-02-17 23:13:49 +0000
commit01c668e3e3be56e15d5440396e00f96979efefee (patch)
tree3be377f45fe180eeb9ee9b8283c92030be0a24a0 /gas/write.c
parent6f26604ec294cbd70c5fb7b783dce5ecf214eb07 (diff)
downloadbinutils-redhat-01c668e3e3be56e15d5440396e00f96979efefee.tar.gz
* write.c (TC_FX_SIZE_SLACK): Define.
(write_relocs): Reinstate check for fixup within frag. * config/tc-bfin.h (TC_FX_SIZE_SLACK): Define. * config/tc-h8300.h (TC_FX_SIZE_SLACK): Define. * config/tc-mmix.h (TC_FX_SIZE_SLACK): Define. * config/tc-sh.h (TC_FX_SIZE_SLACK): Define. * config/tc-xstormy16.h (TC_FX_SIZE_SLACK): Define.
Diffstat (limited to 'gas/write.c')
-rw-r--r--gas/write.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/gas/write.c b/gas/write.c
index afce60438a..46549b834d 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -97,6 +97,16 @@
#define TC_FAKE_LABEL(NAME) (strcmp ((NAME), FAKE_LABEL_NAME) == 0)
#endif
+/* Positive values of TC_FX_SIZE_SLACK allow a target to define
+ fixups that far past the end of a frag. Having such fixups
+ is of course most most likely a bug in setting fx_size correctly.
+ A negative value disables the fixup check entirely, which is
+ appropriate for something like the Renesas / SuperH SH_COUNT
+ reloc. */
+#ifndef TC_FX_SIZE_SLACK
+#define TC_FX_SIZE_SLACK(FIX) 0
+#endif
+
/* Used to control final evaluation of expressions. */
int finalize_syms = 0;
@@ -1017,6 +1027,8 @@ write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
{
arelent *reloc;
bfd_reloc_status_type s;
+ int fx_size, slack;
+ offsetT loc;
if (fixp->fx_done)
{
@@ -1031,12 +1043,15 @@ write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
continue;
}
- /*
- This test is triggered inappropriately for the SH:
- if (fixp->fx_where + fixp->fx_size
- > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
- abort ();
- */
+ fx_size = fixp->fx_size;
+ slack = TC_FX_SIZE_SLACK (fixp);
+ if (slack > 0)
+ fx_size = fx_size > slack ? fx_size - slack : 0;
+ loc = fixp->fx_where + fx_size;
+ if (slack >= 0
+ && loc > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
+ as_bad_where (fixp->fx_file, fixp->fx_line,
+ _("internal error: fixup not contained within frag"));
s = bfd_install_relocation (stdoutput, reloc,
fixp->fx_frag->fr_literal,
@@ -1071,6 +1086,8 @@ write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
arelent **reloc;
bfd_reloc_status_type s;
int j;
+ int fx_size, slack;
+ offsetT loc;
if (fixp->fx_done)
{
@@ -1085,10 +1102,17 @@ write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
relocs[i++] = reloc[j];
assert (i <= n);
}
- if (fixp->fx_where + fixp->fx_size
- > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
+
+ fx_size = fixp->fx_size;
+ slack = TC_FX_SIZE_SLACK (fixp);
+ if (slack > 0)
+ fx_size = fx_size > slack ? fx_size - slack : 0;
+ loc = fixp->fx_where + fx_size;
+ if (slack >= 0
+ && loc > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
as_bad_where (fixp->fx_file, fixp->fx_line,
_("internal error: fixup not contained within frag"));
+
for (j = 0; reloc[j]; j++)
{
s = bfd_install_relocation (stdoutput, reloc[j],