aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJim Wilson <wilson@tuliptree.org>1992-11-06 01:59:36 +0000
committerJim Wilson <wilson@tuliptree.org>1992-11-06 01:59:36 +0000
commit0cef0e20f97bb437405f6e54dd43bcac506aeedf (patch)
tree0d27a90a82f2568fdb499c4424e0535342a45827 /gas
parent402dca80e7bb6bd2f98d238224a8b34278dbf2ae (diff)
downloadfsf-binutils-gdb-0cef0e20f97bb437405f6e54dd43bcac506aeedf.zip
fsf-binutils-gdb-0cef0e20f97bb437405f6e54dd43bcac506aeedf.tar.gz
fsf-binutils-gdb-0cef0e20f97bb437405f6e54dd43bcac506aeedf.tar.bz2
Flag error if absolute constant is too large for an immediate field.
Diffstat (limited to 'gas')
-rw-r--r--gas/config/ChangeLog6
-rw-r--r--gas/config/tc-sparc.c42
2 files changed, 43 insertions, 5 deletions
diff --git a/gas/config/ChangeLog b/gas/config/ChangeLog
index 398fb27..0c5aaeb 100644
--- a/gas/config/ChangeLog
+++ b/gas/config/ChangeLog
@@ -1,3 +1,9 @@
+Thu Nov 5 17:55:41 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
+
+ * tc-sparc.c (sparc_ip): Add code to flag error if an absolute
+ constant will not fit in an immediate field.
+ (md_apply_fix, RELOC_BASE13 case): Check for relocation overflow.
+
Wed Nov 4 07:50:46 1992 Ken Raeburn (raeburn@cygnus.com)
* obj-coff.c (callj_table): Delete global variable.
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c
index 1f6a67e..d7fba8f 100644
--- a/gas/config/tc-sparc.c
+++ b/gas/config/tc-sparc.c
@@ -525,6 +525,7 @@ char *str;
unsigned int mask = 0;
int match = 0;
int comma = 0;
+ long immediate_max = 0;
for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s)
;
@@ -707,10 +708,12 @@ char *str;
#ifndef NO_V9
case 'I':
the_insn.reloc = RELOC_11;
+ immediate_max = 0x03FF;
goto immediate;
case 'j':
the_insn.reloc = RELOC_10;
+ immediate_max = 0x01FF;
goto immediate;
case 'k':
@@ -1118,6 +1121,7 @@ char *str;
case 'i': /* 13 bit immediate */
the_insn.reloc = RELOC_BASE13;
+ immediate_max = 0x0FFF;
/*FALLTHROUGH */
@@ -1133,13 +1137,13 @@ char *str;
s+=3;
/* start-sanitize-v9 */
#ifndef NO_V9
- } else if (c == 'h'
+ } else if (c == 'u'
&& s[2] == 'h'
&& s[3] == 'i') {
the_insn.reloc = RELOC_HHI22;
s += 4;
- } else if (c == 'h'
+ } else if (c == 'u'
&& s[2] == 'l'
&& s[3] == 'o') {
the_insn.reloc = RELOC_HLO10;
@@ -1185,6 +1189,30 @@ char *str;
}
(void)getExpression(s);
s = expr_end;
+
+ /* Check for invalid constant values. Don't
+ warn if constant was inside %hi or %lo,
+ since these truncate the constant to
+ fit. */
+ if (immediate_max != 0
+ && the_insn.reloc != RELOC_LO10
+ && the_insn.reloc != RELOC_HI22
+ /* start-sanitize-v9 */
+#ifndef NO_V9
+ && the_insn.reloc != RELOC_HLO10
+ && the_insn.reloc != RELOC_HHI22
+#endif
+ /* end-sanitize-v9 */
+ && the_insn.exp.X_add_symbol == 0
+ && the_insn.exp.X_subtract_symbol == 0
+ && the_insn.exp.X_seg == SEG_ABSOLUTE
+ && (the_insn.exp.X_add_number > immediate_max
+ || the_insn.exp.X_add_number < ~immediate_max))
+ as_bad ("constant value must be between %ld and %ld",
+ ~immediate_max, immediate_max);
+ /* Reset to prevent extraneous range check. */
+ immediate_max = 0;
+
continue;
case 'a':
@@ -1514,7 +1542,7 @@ long val;
as_bad("relocation overflow.");
} /* on overflow */
- buf[2] = (val >> 8) & 0x7;
+ buf[2] |= (val >> 8) & 0x7;
buf[3] = val & 0xff;
break;
@@ -1524,7 +1552,7 @@ long val;
as_bad("relocation overflow.");
} /* on overflow */
- buf[2] = (val >> 8) & 0x3;
+ buf[2] |= (val >> 8) & 0x3;
buf[3] = val & 0xff;
break;
@@ -1582,7 +1610,7 @@ long val;
if (val & ~0x00001fff) {
as_bad("relocation overflow");
} /* on overflow */
- buf[2] = (val >> 8) & 0x1f;
+ buf[2] |= (val >> 8) & 0x1f;
buf[3] = val & 0xff;
break;
@@ -1607,6 +1635,10 @@ long val;
case RELOC_BASE10:
#endif
case RELOC_BASE13:
+ if (((val > 0) && (val & ~0x00001fff))
+ || ((val < 0) && (~(val - 1) & ~0x00001fff))) {
+ as_bad("relocation overflow");
+ } /* on overflow */
buf[2] |= (val >> 8) & 0x1f;
buf[3] = val;
break;