/* We needed an unused char for line separation to work around the
lack of macros, using sed and such. */
-const char line_separator_chars[] = "";
+const char line_separator_chars[] = "@";
/* Chars that can be used to separate mant from exp in floating point nums */
const char EXP_CHARS[] = "eE";
case RELOC_JUMPTARG: /* 00XX00XX pattern in a word */
if (!fixP->fx_done)
- /* let linker deal */
- ;
+ {
+ /* The linker tries to support both AMD and old GNU style
+ R_IREL relocs. That means that if the addend is exactly
+ the negative of the address within the section, the
+ linker will not handle it correctly. */
+ if (fixP->fx_pcrel
+ && val != 0
+ && val == - (fixP->fx_frag->fr_address + fixP->fx_where))
+ as_bad_where
+ (fixP->fx_file, fixP->fx_line,
+ "the linker will not handle this relocation correctly");
+ }
else if (fixP->fx_pcrel)
{
- long v = val >> 16;
+ long v = val >> 17;
if (v != 0 && v != -1)
as_bad_where (fixP->fx_file, fixP->fx_line,
"call/jmp target out of range");
{
}
\f
+/* This is called when a line is unrecognized. This is used to handle
+ definitions of a29k style local labels. */
+
+int
+a29k_unrecognized_line (c)
+ int c;
+{
+ int lab;
+ char *s;
+
+ if (c != '$'
+ || ! isdigit ((unsigned char) input_line_pointer[0]))
+ return 0;
+
+ s = input_line_pointer;
+
+ lab = 0;
+ while (isdigit ((unsigned char) *s))
+ {
+ lab = lab * 10 + *s - '0';
+ ++s;
+ }
+
+ if (*s != ':')
+ {
+ /* Not a label definition. */
+ return 0;
+ }
+
+ if (dollar_label_defined (lab))
+ {
+ as_bad ("label \"$%d\" redefined", lab);
+ return 0;
+ }
+
+ define_dollar_label (lab);
+ colon (dollar_label_name (lab, 0));
+ input_line_pointer = s + 1;
+
+ return 1;
+}
+
/* Default the values of symbols known that should be "predefined". We
don't bother to predefine them unless you actually use one, since there
are a lot of them. */
else
expressionP->X_op = O_constant;
}
+ else if (input_line_pointer[0] == '$'
+ && isdigit ((unsigned char) input_line_pointer[1]))
+ {
+ long lab;
+ char *name;
+ symbolS *sym;
+
+ /* This is a local label. */
+ ++input_line_pointer;
+ lab = (long) get_absolute_expression ();
+ if (dollar_label_defined (lab))
+ {
+ name = dollar_label_name (lab, 0);
+ sym = symbol_find (name);
+ }
+ else
+ {
+ name = dollar_label_name (lab, 1);
+ sym = symbol_find_or_make (name);
+ }
+
+ expressionP->X_op = O_symbol;
+ expressionP->X_add_symbol = sym;
+ expressionP->X_add_number = 0;
+ }
else if (input_line_pointer[0] == '$')
{
char *s;
}
else
{
- /* FIXME: We should handle a29k local labels here. */
return;
}