/* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
- Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- 2009 Free Software Foundation, Inc.
+ Copyright (C) 1999-2016 Free Software Foundation, Inc.
Contributed by Timothy Wall (twall@cygnus.com)
This file is part of GAS, the GNU Assembler.
COFF1 limits section names to 8 characters.
Some of the default behavior changed from COFF1 to COFF2. */
-#include <limits.h>
#include "as.h"
+#include <limits.h>
#include "safe-ctype.h"
#include "sb.h"
#include "macro.h"
int c;
char *name;
char *str;
- char *tmp;
int quoted = *input_line_pointer == '"';
ILLEGAL_WITHIN_STRUCT ();
return;
}
- name = ++input_line_pointer;
- c = get_symbol_end (); /* Get terminator. */
+ ++input_line_pointer;
+ c = get_symbol_name (&name); /* Get terminator. */
if (!ISALPHA (*name))
{
as_bad (_("symbols assigned with .asg must begin with a letter"));
return;
}
- tmp = xmalloc (strlen (str) + 1);
- strcpy (tmp, str);
- str = tmp;
- tmp = xmalloc (strlen (name) + 1);
- strcpy (tmp, name);
- name = tmp;
+ str = xstrdup (str);
+ name = xstrdup (name);
subsym_create_or_replace (name, str);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
demand_empty_rest_of_line ();
}
ignore_rest_of_line ();
return;
}
- name = input_line_pointer;
- c = get_symbol_end (); /* Get terminator. */
+ c = get_symbol_name (&name); /* Get terminator. */
tmp = xmalloc (strlen (name) + 1);
name = strcpy (tmp, name);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
if (!ISALPHA (*name))
{
current_seg = now_seg; /* Save current seg. */
current_subseg = now_subseg; /* Save current subseg. */
- name = input_line_pointer;
- c = get_symbol_end (); /* Get terminator. */
+ c = get_symbol_name (&name); /* Get terminator. */
+ if (c == '"')
+ c = * ++ input_line_pointer;
if (c != ',')
{
as_bad (_(".bss size argument missing\n"));
symbolS *rootsym,
const char *root_stag_name)
{
- char prefix[strlen (path) + 2];
+ char * prefix;
struct stag_field *field = stag->field;
/* Construct a symbol for every field contained within this structure
including fields within structure fields. */
- strcpy (prefix, path);
- if (*path)
- strcat (prefix, ".");
+ prefix = concat (path, *path ? "." : "", NULL);
while (field != NULL)
{
- int len = strlen (prefix) + strlen (field->name) + 2;
- char *name = xmalloc (len);
- strcpy (name, prefix);
- strcat (name, field->name);
+ char *name = concat (prefix, field->name, NULL);
if (rootsym == NULL)
{
}
else
{
- char *replacement = xmalloc (strlen (name)
- + strlen (stag->name) + 2);
- strcpy (replacement, S_GET_NAME (rootsym));
- strcat (replacement, "+");
- strcat (replacement, root_stag_name);
- strcat (replacement, name + strlen (S_GET_NAME (rootsym)));
+ char *replacement;
+
+ replacement = concat (S_GET_NAME (rootsym), "+", root_stag_name,
+ name + strlen (S_GET_NAME (rootsym)), NULL);
hash_insert (subsym_hash[0], name, replacement);
}
field->offset,
rootsym, root_stag_name);
field = field->next;
+ free (name);
}
+ free (prefix);
}
/* Keep track of stag fields so that when structures are nested we can add the
}
else
{
- char label[strlen (S_GET_NAME (line_label)) + 1];
- strcpy (label, S_GET_NAME (line_label));
- current_stag->sym = symbol_new (label, absolute_section,
+ char * label = xstrdup (S_GET_NAME (line_label));
+ current_stag->sym = symbol_new (label,
+ absolute_section,
(valueT) abs_section_offset,
&zero_address_frag);
+ free (label);
}
current_stag->name = S_GET_NAME (current_stag->sym);
SF_SET_LOCAL (current_stag->sym);
static void
tic54x_tag (int ignore ATTRIBUTE_UNUSED)
{
- char *name = input_line_pointer;
- int c = get_symbol_end ();
+ char *name;
+ int c = get_symbol_name (&name);
struct stag *stag = (struct stag *) hash_find (stag_hash, name);
if (!stag)
}
else
{
- char label[strlen (S_GET_NAME (line_label)) + 1];
+ char * label;
- strcpy (label, S_GET_NAME (line_label));
+ label = xstrdup (S_GET_NAME (line_label));
if (current_stag != NULL)
stag_add_field (current_stag, label,
abs_section_offset - S_GET_VALUE (current_stag->sym),
{
as_bad (_(".tag target '%s' undefined"), label);
ignore_rest_of_line ();
+ free (label);
return;
}
stag_add_field_symbols (stag, S_GET_NAME (sym),
S_GET_VALUE (stag->sym), sym, stag->name);
}
+ free (label);
}
/* Bump by the struct size, but only if we're within a .struct section. */
if (current_stag != NULL && !current_stag->is_union)
abs_section_offset += stag->size;
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
demand_empty_rest_of_line ();
line_label = NULL;
}
}
else
{
- char label[strlen (S_GET_NAME (line_label) + 1)];
+ char * label;
- strcpy (label, S_GET_NAME (line_label));
+ label = xstrdup (S_GET_NAME (line_label));
stag_add_field (current_stag, label,
abs_section_offset - S_GET_VALUE (current_stag->sym),
NULL);
+ free (label);
}
if (current_stag->is_union)
do
{
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
symbolP = symbol_find_or_make (name);
+ c = restore_line_pointer (c);
- *input_line_pointer = c;
S_SET_STORAGE_CLASS (symbolP, C_EXT);
if (c == ',')
{
else
{
int c;
- name = input_line_pointer;
- c = get_symbol_end ();
+
+ c = get_symbol_name (&name);
len = strlen(name);
name = strcpy (xmalloc (len + 10), name);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
demand_empty_rest_of_line ();
}
+
/* Make sure all named initialized sections flagged properly. If we
encounter instructions, we'll flag it with SEC_CODE as well. */
strcat (name, ",\"w\"\n");
current_seg = now_seg; /* Save current seg. */
current_subseg = now_subseg; /* Save current subseg. */
- if (*input_line_pointer == '"')
- input_line_pointer++;
- section_name = input_line_pointer;
- c = get_symbol_end (); /* Get terminator. */
- input_line_pointer++; /* Skip null symbol terminator. */
+ c = get_symbol_name (§ion_name); /* Get terminator. */
name = xmalloc (input_line_pointer - section_name + 1);
strcpy (name, section_name);
-
- if (*input_line_pointer == ',')
+ c = restore_line_pointer (c);
+
+ if (c == ',')
++input_line_pointer;
- else if (c != ',')
+ else
{
as_bad (_("Missing size argument"));
ignore_rest_of_line ();
tic54x_stringer (int type)
{
unsigned int c;
- char *start;
int append_zero = type == 'S' || type == 'P';
int packed = type == 'p' || type == 'P';
int last_char = -1; /* Packed strings need two bytes at a time to encode. */
}
case '\"':
++input_line_pointer; /* -> 1st char of string. */
- start = input_line_pointer;
while (is_a_char (c = next_char_of_string ()))
{
if (!packed)
static void
tic54x_set_default_include (int dot)
{
- char *dir = ".";
+ const char *dir = ".";
char *tmp = NULL;
if (!dot)
{
- char *curfile;
+ const char *curfile;
unsigned lineno;
- as_where (&curfile, &lineno);
+ curfile = as_where (&lineno);
dir = strcpy (xmalloc (strlen (curfile) + 1), curfile);
tmp = strrchr (dir, '/');
}
len = strlen (dir);
if (include_dir_count == 0)
{
- include_dirs = (char **) xmalloc (sizeof (*include_dirs));
+ include_dirs = XNEWVEC (const char *, 1);
include_dir_count = 1;
}
include_dirs[0] = dir;
static void
tic54x_label (int ignored ATTRIBUTE_UNUSED)
{
- char *name = input_line_pointer;
+ char *name;
symbolS *symbolP;
int c;
ILLEGAL_WITHIN_STRUCT ();
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
symbolP = colon (name);
S_SET_STORAGE_CLASS (symbolP, C_STATLAB);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
demand_empty_rest_of_line ();
}
}
else
{
- char *section_name = input_line_pointer;
+ char *section_name;
- c = get_symbol_end ();
+ c = get_symbol_name (§ion_name);
name = xmalloc (strlen (section_name) + 1);
strcpy (name, section_name);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
}
seg = bfd_get_section_by_name (stdoutput, name);
ignore_rest_of_line ();
return;
}
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
/* .var symbols start out with a null string. */
name = strcpy (xmalloc (strlen (name) + 1), name);
hash_insert (subsym_hash[macro_level], name, empty);
- *input_line_pointer = c;
+ c = restore_line_pointer (c);
if (c == ',')
{
++input_line_pointer;
FILE *ftmp;
/* We're not sure how big it is, but it will be smaller than "size". */
- bfd_bread (buf, size, mbfd);
+ size = bfd_bread (buf, size, mbfd);
/* Write to a temporary file, then use s_include to include it
a bit of a hack. */
ftmp = fopen (fname, "w+b");
fwrite ((void *) buf, size, 1, ftmp);
- if (buf[size - 1] != '\n')
+ if (size == 0 || buf[size - 1] != '\n')
fwrite ("\n", 1, 1, ftmp);
fclose (ftmp);
free (buf);
};
int
-md_parse_option (int c, char *arg)
+md_parse_option (int c, const char *arg)
{
switch (c)
{
break;
case OPTION_STDERR_TO_FILE:
{
- char *filename = arg;
+ const char *filename = arg;
FILE *fp = fopen (filename, "w+");
if (fp == NULL)
/* Built-in substitution symbol functions and math functions. */
typedef struct
{
- char *name;
+ const char *name;
int (*proc) (char *, char *);
int nargs;
} subsym_proc_entry;
typedef struct
{
- char *name;
+ const char *name;
float (*proc) (float, float);
int nargs;
int int_return;
replacement on the value. */
static char *
-subsym_get_arg (char *line, char *terminators, char **str, int nosub)
+subsym_get_arg (char *line, const char *terminators, char **str, int nosub)
{
char *ptr = line;
char *endp;
}
else
{
- char *term = terminators;
+ const char *term = terminators;
char *value = NULL;
while (*ptr && *ptr != *term)
if (forced)
++ptr;
- name = input_line_pointer = ptr;
- c = get_symbol_end ();
+ input_line_pointer = ptr;
+ c = get_symbol_name (&name);
/* '?' is not normally part of a symbol, but it IS part of a local
label. */
if (c == '?')
if (value == NULL)
{
char digit[11];
- char *namecopy = strcpy (xmalloc (strlen (name) + 1), name);
+ char *namecopy = xstrdup (name);
value = strcpy (xmalloc (strlen (name) + sizeof (digit) + 1),
name);
substitutions are performed, or a substitution that has been
previously made is encountered again.
- put the symbol into the recursion hash table so we only
+ Put the symbol into the recursion hash table so we only
try to replace a symbol once. */
if (recurse)
{
line[endp - input_line_pointer] = 0;
/* Scan ahead for parallel insns. */
- parallel_on_next_line_hint = next_line_shows_parallel (endp + 1);
+ parallel_on_next_line_hint = next_line_shows_parallel (endp);
/* If within a macro, first process forced replacements. */
if (macro_level > 0)
int c;
input_line_pointer = line;
- c = get_symbol_end ();
+ c = get_symbol_name (&line);
if (cpu == VNONE)
cpu = V542;
if (symbol_rootP == NULL
|| S_GET_STORAGE_CLASS (symbol_rootP) != C_FILE)
{
- char *filename;
unsigned lineno;
- as_where (&filename, &lineno);
+ const char * filename = as_where (&lineno);
c_dot_file_symbol (filename, 0);
}
}
/* Handle cons expressions. */
void
-tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn)
+tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn,
+ bfd_reloc_code_real_type r)
{
- bfd_reloc_code_real_type r;
-
switch (octets)
{
default:
syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
I guess, except I've never seen a definition of MRI syntax).
- C is the character that used to be at *REST, which points to the end of the
- label.
-
Don't allow labels to start with '.' */
int
-tic54x_start_label (int c, char *rest)
+tic54x_start_label (int nul_char, int next_char)
{
+ char *rest;
+
/* If within .struct/.union, no auto line labels, please. */
if (current_stag != NULL)
return 0;
/* Disallow labels starting with "." */
- if (c != ':')
+ if (next_char != ':')
{
- char *label = rest;
+ char *label = input_line_pointer;
while (!is_end_of_line[(int) label[-1]])
--label;
}
}
- if (is_end_of_line[(int) c])
+ if (is_end_of_line[(int) next_char])
return 1;
- if (ISSPACE (c))
- while (ISSPACE (c = *++rest))
- ;
- if (c == '.')
- {
- /* Don't let colon () define a label for any of these... */
- return (strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4]))
- && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7]))
- && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6]))
- && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6]))
- && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4]))
- && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4]));
- }
+ rest = input_line_pointer;
+ if (nul_char == '"')
+ ++rest;
+ while (ISSPACE (next_char))
+ next_char = *++rest;
+ if (next_char != '.')
+ return 1;
- return 1;
+ /* Don't let colon () define a label for any of these... */
+ return ((strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4]))
+ && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7]))
+ && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6]))
+ && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6]))
+ && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4]))
+ && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4])));
}