#include "dw2gencfi.h"
#ifndef TC_START_LABEL
-#define TC_START_LABEL(x,y) (x == ':')
+#define TC_START_LABEL(x,y,z) (x == ':')
#endif
/* Set by the object-format or the target. */
};
/* In: a character.
- Out: 1 if this character ends a line. */
+ Out: 1 if this character ends a line.
+ 2 if this character is a line separator. */
char is_end_of_line[256] = {
#ifdef CR_EOL
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, /* @abcdefghijklmno */
static int hex_float (int, char *);
static segT get_known_segmented_expression (expressionS * expP);
static void pobegin (void);
-static int get_line_sb (sb *);
+static int get_non_macro_line_sb (sb *);
static void generate_file_debug (void);
-static char *_find_end_of_line (char *, int, int);
+static char *_find_end_of_line (char *, int, int, int);
\f
void
read_begin (void)
/* Use machine dependent syntax. */
for (p = line_separator_chars; *p; p++)
- is_end_of_line[(unsigned char) *p] = 1;
+ is_end_of_line[(unsigned char) *p] = 2;
/* Use more. FIXME-SOMEDAY. */
if (flag_mri)
#define HANDLE_CONDITIONAL_ASSEMBLY() \
if (ignore_input ()) \
{ \
- char *eol = find_end_of_line (input_line_pointer, flag_m68k_mri); \
+ char *eol = find_end_of_line (input_line_pointer, flag_m68k_mri); \
input_line_pointer = (input_line_pointer <= buffer_limit \
&& eol >= buffer_limit) \
? buffer_limit \
S points to the beginning of the symbol.
[In case of pseudo-op, s->'.'.]
Input_line_pointer->'\0' where c was. */
- if (TC_START_LABEL (c, input_line_pointer))
+ if (TC_START_LABEL (c, s, input_line_pointer))
{
if (flag_m68k_mri)
{
/* Input_line_pointer->after ':'. */
SKIP_WHITESPACE ();
}
- else if (input_line_pointer[1] == '='
- && (c == '='
- || ((c == ' ' || c == '\t')
- && input_line_pointer[2] == '=')))
+ else if ((c == '=' && input_line_pointer[1] == '=')
+ || ((c == ' ' || c == '\t')
+ && input_line_pointer[1] == '='
+ && input_line_pointer[2] == '='))
{
equals (s, -1);
demand_empty_rest_of_line ();
/* WARNING: c has char, which may be end-of-line. */
/* Also: input_line_pointer->`\0` where c was. */
*input_line_pointer = c;
- input_line_pointer = _find_end_of_line (input_line_pointer, flag_m68k_mri, 1);
+ input_line_pointer = _find_end_of_line (input_line_pointer, flag_m68k_mri, 1, 0);
c = *input_line_pointer;
*input_line_pointer = '\0';
md_flush_pending_output ();
#endif
+#ifdef md_cons_align
+ md_cons_align (1);
+#endif
+
get_known_segmented_expression (&rep_exp);
if (*input_line_pointer == ',')
{
}
#define skip_past_comma(str) skip_past_char (str, ',')
-/* Parse an attribute directive for VENDOR. */
-void
+/* Parse an attribute directive for VENDOR.
+ Returns the attribute number read, or zero on error. */
+int
s_vendor_attribute (int vendor)
{
expressionS exp;
int tag;
unsigned int i = 0;
char *s = NULL;
- char saved_char;
- expression (& exp);
- if (exp.X_op != O_constant)
- goto bad;
+ /* Read the first number or name. */
+ skip_whitespace (input_line_pointer);
+ s = input_line_pointer;
+ if (ISDIGIT (*input_line_pointer))
+ {
+ expression (& exp);
+ if (exp.X_op != O_constant)
+ goto bad;
+ tag = exp.X_add_number;
+ }
+ else
+ {
+ char *name;
+
+ /* A name may contain '_', but no other punctuation. */
+ for (; ISALNUM (*input_line_pointer) || *input_line_pointer == '_';
+ ++input_line_pointer)
+ i++;
+ if (i == 0)
+ goto bad;
+
+ name = alloca (i + 1);
+ memcpy (name, s, i);
+ name[i] = '\0';
+
+#ifndef CONVERT_SYMBOLIC_ATTRIBUTE
+#define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
+#endif
+
+ tag = CONVERT_SYMBOLIC_ATTRIBUTE (name);
+ if (tag == -1)
+ {
+ as_bad (_("Attribute name not recognised: %s"), name);
+ ignore_rest_of_line ();
+ return 0;
+ }
+ }
- tag = exp.X_add_number;
type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
if (skip_past_comma (&input_line_pointer) == -1)
{
as_bad (_("expected numeric constant"));
ignore_rest_of_line ();
- return;
+ return 0;
}
i = exp.X_add_number;
}
- if (type == 3
+ if ((type & 3) == 3
&& skip_past_comma (&input_line_pointer) == -1)
{
as_bad (_("expected comma"));
ignore_rest_of_line ();
- return;
+ return 0;
}
if (type & 2)
{
- skip_whitespace(input_line_pointer);
- if (*input_line_pointer != '"')
- goto bad_string;
- input_line_pointer++;
- s = input_line_pointer;
- while (*input_line_pointer && *input_line_pointer != '"')
- input_line_pointer++;
+ int len;
+
+ skip_whitespace (input_line_pointer);
if (*input_line_pointer != '"')
goto bad_string;
- saved_char = *input_line_pointer;
- *input_line_pointer = 0;
- }
- else
- {
- s = NULL;
- saved_char = 0;
+ s = demand_copy_C_string (&len);
}
- switch (type)
+ switch (type & 3)
{
case 3:
- bfd_elf_add_obj_attr_compat (stdoutput, vendor, i, s);
+ bfd_elf_add_obj_attr_int_string (stdoutput, vendor, tag, i, s);
break;
case 2:
bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
abort ();
}
- if (s)
- {
- *input_line_pointer = saved_char;
- input_line_pointer++;
- }
demand_empty_rest_of_line ();
- return;
+ return tag;
bad_string:
as_bad (_("bad string constant"));
ignore_rest_of_line ();
- return;
+ return 0;
bad:
as_bad (_("expected <tag> , <value>"));
ignore_rest_of_line ();
+ return 0;
}
/* Parse a .gnu_attribute directive. */
sb_new (&out);
- err = expand_irp (irpc, 0, &s, &out, get_line_sb);
+ err = expand_irp (irpc, 0, &s, &out, get_non_macro_line_sb);
if (err != NULL)
as_bad_where (file, line, "%s", err);
or zero if there are no more lines. */
static int
-get_line_sb (sb *line)
+get_line_sb (sb *line, int in_macro)
{
char *eol;
return 0;
}
- eol = find_end_of_line (input_line_pointer, flag_m68k_mri);
+ eol = _find_end_of_line (input_line_pointer, flag_m68k_mri, 0, in_macro);
sb_add_buffer (line, input_line_pointer, eol - input_line_pointer);
input_line_pointer = eol;
return *input_line_pointer++;
}
+static int
+get_non_macro_line_sb (sb *line)
+{
+ return get_line_sb (line, 0);
+}
+
+static int
+get_macro_line_sb (sb *line)
+{
+ return get_line_sb (line, 1);
+}
+
/* Define a macro. This is an interface to macro.c. */
void
sb_new (&label);
sb_add_string (&label, S_GET_NAME (line_label));
- err = define_macro (0, &s, &label, get_line_sb, file, line, &name);
+ err = define_macro (0, &s, &label, get_macro_line_sb, file, line, &name);
sb_kill (&label);
}
else
- err = define_macro (0, &s, NULL, get_line_sb, file, line, &name);
+ err = define_macro (0, &s, NULL, get_macro_line_sb, file, line, &name);
if (err != NULL)
as_bad_where (file, line, err, name);
else
void
s_mexit (int ignore ATTRIBUTE_UNUSED)
{
- cond_exit_macro (macro_nest);
- buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+ if (macro_nest)
+ {
+ cond_exit_macro (macro_nest);
+ buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+ }
+ else
+ as_warn (_("ignoring macro exit outside a macro definition."));
}
/* Switch in and out of MRI mode. */
sb many;
sb_new (&one);
- if (!buffer_and_nest (start, end, &one, get_line_sb))
+ if (!buffer_and_nest (start, end, &one, get_non_macro_line_sb))
{
as_bad (_("%s without %s"), start, end);
return;
md_flush_pending_output ();
#endif
+#ifdef md_cons_align
+ md_cons_align (1);
+#endif
+
if (flag_mri)
stop = mri_comment_field (&stopc);
if (exp.X_op == O_constant)
{
- long repeat;
+ offsetT repeat;
repeat = exp.X_add_number;
if (mult)
char *stop = NULL;
char stopc = 0;
+#ifdef md_cons_align
+ md_cons_align (1);
+#endif
+
if (flag_mri)
stop = mri_comment_field (&stopc);
{
expressionS *expP = symbol_get_value_expression (symp);
- assert (expP->X_op == O_symbol
+ gas_assert (expP->X_op == O_symbol
&& expP->X_add_number == 0);
symp = expP->X_add_symbol;
}
char *loop;
loop = concat (S_GET_NAME (symbolP),
- " => ", S_GET_NAME (symbolP2), NULL);
+ " => ", S_GET_NAME (symbolP2), (const char *) NULL);
symp = symbolP2;
while (symp != symbolP)
{
char *old_loop = loop;
symp = symbol_get_value_expression (symp)->X_add_symbol;
- loop = concat (loop, " => ", S_GET_NAME (symp), NULL);
+ loop = concat (loop, " => ", S_GET_NAME (symp),
+ (const char *) NULL);
free (old_loop);
}
break;
case O_register:
+#ifndef TC_GLOBAL_REGISTER_SYMBOL_OK
+ if (S_IS_EXTERNAL (symbolP))
+ {
+ as_bad ("can't equate global symbol `%s' with register name",
+ S_GET_NAME (symbolP));
+ return;
+ }
+#endif
S_SET_SEGMENT (symbolP, reg_section);
S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
set_zero_frag (symbolP);
if (need_pass_2)
return;
+ /* Grow the current frag now so that dot_value does not get invalidated
+ if the frag were to fill up in the frag_more() call below. */
+ frag_grow (nbytes);
dot_value = frag_now_fix ();
#ifndef NO_LISTING
|| (get & hibit) == 0))
{ /* Leading bits contain both 0s & 1s. */
#if defined (BFD64) && BFD_HOST_64BIT_LONG_LONG
+#ifndef __MSVCRT__
as_warn (_("value 0x%llx truncated to 0x%llx"),
(unsigned long long) get, (unsigned long long) use);
+#else
+ as_warn (_("value 0x%I64x truncated to 0x%I64x"),
+ (unsigned long long) get, (unsigned long long) use);
+#endif
#else
as_warn (_("value 0x%lx truncated to 0x%lx"),
(unsigned long) get, (unsigned long) use);
md_flush_pending_output ();
#endif
+#ifdef md_cons_align
+ md_cons_align (1);
+#endif
+
do
{
/* input_line_pointer->1st char of a flonum (we hope!). */
md_flush_pending_output ();
#endif
+#ifdef md_cons_align
+ md_cons_align (1);
+#endif
+
/* The following awkward logic is to parse ZERO or more strings,
comma separated. Recall a string expression includes spaces
before the opening '\"' and spaces after the closing '\"'.
md_flush_pending_output ();
#endif
+#ifdef md_cons_align
+ md_cons_align (1);
+#endif
+
SKIP_WHITESPACE ();
filename = demand_copy_string (& len);
if (filename == NULL)
#endif
static char *
-_find_end_of_line (char *s, int mri_string, int insn ATTRIBUTE_UNUSED)
+_find_end_of_line (char *s, int mri_string, int insn ATTRIBUTE_UNUSED,
+ int in_macro)
{
char inquote = '\0';
int inescape = 0;
#ifdef TC_EOL_IN_INSN
|| (insn && TC_EOL_IN_INSN (s))
#endif
+ /* PR 6926: When we are parsing the body of a macro the sequence
+ \@ is special - it refers to the invocation count. If the @
+ character happens to be registered as a line-separator character
+ by the target, then the is_end_of_line[] test above will have
+ returned true, but we need to ignore the line separating
+ semantics in this particular case. */
+ || (in_macro && inescape && *s == '@')
)
{
if (mri_string && *s == '\'')
char *
find_end_of_line (char *s, int mri_string)
{
- return _find_end_of_line (s, mri_string, 0);
+ return _find_end_of_line (s, mri_string, 0, 0);
}