X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gas%2Fmacro.c;h=de6b4172ec292316acf2c5dff8ef8811649e4a94;hb=bb8974772177ff4c043bfc28305bba66e7badf36;hp=3e3ffb11f57a087b431940bc17263abaf70bd893;hpb=c0ba1095fd73bd3456b49bf86ef526f2bab46908;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/macro.c b/gas/macro.c index 3e3ffb11f5..de6b4172ec 100644 --- a/gas/macro.c +++ b/gas/macro.c @@ -1,6 +1,5 @@ /* macro.c - macro support for gas - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 1994-2020 Free Software Foundation, Inc. Written by Steve and Judy Chamberlain of Cygnus Support, sac@cygnus.com @@ -65,7 +64,7 @@ static int macro_strip_at; /* Function to use to parse an expression. */ -static int (*macro_expr) (const char *, int, sb *, int *); +static size_t (*macro_expr) (const char *, size_t, sb *, offsetT *); /* Number of macro expansions that have been done. */ @@ -75,7 +74,7 @@ static int macro_number; void macro_init (int alternate, int mri, int strip_at, - int (*exp) (const char *, int, sb *, int *)) + size_t (*exp) (const char *, size_t, sb *, offsetT *)) { macro_hash = hash_new (); macro_defined = 0; @@ -110,16 +109,15 @@ macro_mri_mode (int mri) int buffer_and_nest (const char *from, const char *to, sb *ptr, - int (*get_line) (sb *)) + size_t (*get_line) (sb *)) { - int from_len; - int to_len = strlen (to); + size_t from_len; + size_t to_len = strlen (to); int depth = 1; - int line_start = ptr->len; + size_t line_start = ptr->len; + size_t more = get_line (ptr); - int more = get_line (ptr); - - if (to_len == 4 && strcasecmp(to, "ENDR") == 0) + if (to_len == 4 && strcasecmp (to, "ENDR") == 0) { from = NULL; from_len = 0; @@ -130,7 +128,7 @@ buffer_and_nest (const char *from, const char *to, sb *ptr, while (more) { /* Try to find the first pseudo op on the line. */ - int i = line_start; + size_t i = line_start; bfd_boolean had_colon = FALSE; /* With normal syntax we can suck what we want till we get @@ -213,6 +211,27 @@ buffer_and_nest (const char *from, const char *to, sb *ptr, break; } } + + /* PR gas/16908 + Apply and discard .linefile directives that appear within + the macro. For long macros, one might want to report the + line number information associated with the lines within + the macro definition, but we would need more infrastructure + to make that happen correctly (e.g. resetting the line + number when expanding the macro), and since for short + macros we clearly prefer reporting the point of expansion + anyway, there's not an obviously better fix here. */ + if (strncasecmp (ptr->ptr + i, "linefile", 8) == 0) + { + char saved_eol_char = ptr->ptr[ptr->len]; + + ptr->ptr[ptr->len] = '\0'; + temp_ilp (ptr->ptr + i + 8); + s_app_line (0); + restore_ilp (); + ptr->ptr[ptr->len] = saved_eol_char; + ptr->len = line_start; + } } /* Add the original end-of-line char to the end and keep running. */ @@ -227,8 +246,8 @@ buffer_and_nest (const char *from, const char *to, sb *ptr, /* Pick up a token. */ -static int -get_token (int idx, sb *in, sb *name) +static size_t +get_token (size_t idx, sb *in, sb *name) { if (idx < in->len && is_name_beginner (in->ptr[idx])) @@ -253,8 +272,8 @@ get_token (int idx, sb *in, sb *name) /* Pick up a string. */ -static int -getstring (int idx, sb *in, sb *acc) +static size_t +getstring (size_t idx, sb *in, sb *acc) { while (idx < in->len && (in->ptr[idx] == '"' @@ -265,8 +284,8 @@ getstring (int idx, sb *in, sb *acc) { int nest = 0; idx++; - while ((in->ptr[idx] != '>' || nest) - && idx < in->len) + while (idx < in->len + && (in->ptr[idx] != '>' || nest)) { if (in->ptr[idx] == '!') { @@ -339,8 +358,8 @@ getstring (int idx, sb *in, sb *acc) (string) -> return (string-including-whitespaces) xyx -> return xyz. */ -static int -get_any_string (int idx, sb *in, sb *out) +static size_t +get_any_string (size_t idx, sb *in, sb *out) { sb_reset (out); idx = sb_skip_white (idx, in); @@ -349,13 +368,13 @@ get_any_string (int idx, sb *in, sb *out) { if (in->len > idx + 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx])) { - while (!ISSEP (in->ptr[idx])) + while (idx < in->len && !ISSEP (in->ptr[idx])) sb_add_char (out, in->ptr[idx++]); } else if (in->ptr[idx] == '%' && macro_alternate) { - int val; - char buf[20]; + offsetT val; + char buf[64]; /* Turns the next expression into a string. */ /* xgettext: no-c-format */ @@ -363,7 +382,7 @@ get_any_string (int idx, sb *in, sb *out) idx + 1, in, &val); - sprintf (buf, "%d", val); + sprintf (buf, "%" BFD_VMA_FMT "d", val); sb_add_string (out, buf); } else if (in->ptr[idx] == '"' @@ -384,7 +403,7 @@ get_any_string (int idx, sb *in, sb *out) } else { - char *br_buf = (char *) xmalloc(1); + char *br_buf = XNEWVEC (char, 1); char *in_br = br_buf; *in_br = '\0'; @@ -407,7 +426,10 @@ get_any_string (int idx, sb *in, sb *out) && in->ptr[idx] != tchar) sb_add_char (out, in->ptr[idx++]); if (idx == in->len) - return idx; + { + free (br_buf); + return idx; + } break; case '(': case '[': @@ -415,9 +437,9 @@ get_any_string (int idx, sb *in, sb *out) --in_br; else { - br_buf = (char *) xmalloc(strlen(in_br) + 2); - strcpy(br_buf + 1, in_br); - free(in_br); + br_buf = XNEWVEC (char, strlen (in_br) + 2); + strcpy (br_buf + 1, in_br); + free (in_br); in_br = br_buf; } *in_br = tchar; @@ -434,7 +456,7 @@ get_any_string (int idx, sb *in, sb *out) sb_add_char (out, tchar); ++idx; } - free(br_buf); + free (br_buf); } } @@ -448,7 +470,7 @@ new_formal (void) { formal_entry *formal; - formal = (formal_entry *) xmalloc (sizeof (formal_entry)); + formal = XNEW (formal_entry); sb_new (&formal->name); sb_new (&formal->def); @@ -471,8 +493,8 @@ del_formal (formal_entry *formal) /* Pick up the formal parameters of a macro definition. */ -static int -do_formals (macro_entry *macro, int idx, sb *in) +static size_t +do_formals (macro_entry *macro, size_t idx, sb *in) { formal_entry **p = ¯o->formals; const char *name; @@ -481,13 +503,14 @@ do_formals (macro_entry *macro, int idx, sb *in) while (idx < in->len) { formal_entry *formal = new_formal (); - int cidx; + size_t cidx; idx = get_token (idx, in, &formal->name); if (formal->name.len == 0) { if (macro->formal_count) --idx; + del_formal (formal); /* 'formal' goes out of scope. */ break; } idx = sb_skip_white (idx, in); @@ -571,9 +594,9 @@ do_formals (macro_entry *macro, int idx, sb *in) formal_entry *formal = new_formal (); /* Add a special NARG formal, which macro_expand will set to the - number of arguments. */ + number of arguments. */ /* The same MRI assemblers which treat '@' characters also use - the name $NARG. At least until we find an exception. */ + the name $NARG. At least until we find an exception. */ if (macro_strip_at) name = "$NARG"; else @@ -622,16 +645,16 @@ free_macro (macro_entry *macro) the macro which was defined. */ const char * -define_macro (int idx, sb *in, sb *label, - int (*get_line) (sb *), - char *file, unsigned int line, +define_macro (size_t idx, sb *in, sb *label, + size_t (*get_line) (sb *), + const char *file, unsigned int line, const char **namep) { macro_entry *macro; sb name; const char *error = NULL; - macro = (macro_entry *) xmalloc (sizeof (macro_entry)); + macro = XNEW (macro_entry); sb_new (¯o->sub); sb_new (&name); macro->file = file; @@ -639,7 +662,7 @@ define_macro (int idx, sb *in, sb *label, macro->formal_count = 0; macro->formals = 0; - macro->formal_hash = hash_new (); + macro->formal_hash = hash_new_sized (7); idx = sb_skip_white (idx, in); if (! buffer_and_nest ("MACRO", "ENDM", ¯o->sub, get_line)) @@ -665,7 +688,7 @@ define_macro (int idx, sb *in, sb *label, } else { - int cidx; + size_t cidx; idx = get_token (idx, in, &name); macro->name = sb_terminate (&name); @@ -702,8 +725,8 @@ define_macro (int idx, sb *in, sb *label, /* Scan a token, and then skip KIND. */ -static int -get_apost_token (int idx, sb *in, sb *name, int kind) +static size_t +get_apost_token (size_t idx, sb *in, sb *name, int kind) { idx = get_token (idx, in, name); if (idx < in->len @@ -716,11 +739,11 @@ get_apost_token (int idx, sb *in, sb *name, int kind) /* Substitute the actual value for a formal parameter. */ -static int -sub_actual (int start, sb *in, sb *t, struct hash_control *formal_hash, +static size_t +sub_actual (size_t start, sb *in, sb *t, struct hash_control *formal_hash, int kind, sb *out, int copyifnotthere) { - int src; + size_t src; formal_entry *ptr; src = get_apost_token (start, in, t, kind); @@ -748,6 +771,8 @@ sub_actual (int start, sb *in, sb *t, struct hash_control *formal_hash, /* Doing this permits people to use & in macro bodies. */ sb_add_char (out, '&'); sb_add_sb (out, t); + if (src != start && in->ptr[src - 1] == '&') + sb_add_char (out, '&'); } else if (copyifnotthere) { @@ -768,7 +793,8 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals, struct hash_control *formal_hash, const macro_entry *macro) { sb t; - int src = 0, inquote = 0, macro_line = 0; + size_t src = 0; + int inquote = 0, macro_line = 0; formal_entry *loclist = NULL; const char *err = NULL; @@ -788,9 +814,8 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals, } else { - /* FIXME: Why do we do this? */ - /* At least in alternate mode this seems correct; without this - one can't append a literal to a parameter. */ + /* Permit macro parameter substitution delineated with + an '&' prefix and optional '&' suffix. */ src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0); } } @@ -816,7 +841,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals, { /* Sub in the macro invocation number. */ - char buffer[10]; + char buffer[12]; src++; sprintf (buffer, "%d", macro_number); sb_add_string (out, buffer); @@ -945,13 +970,13 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals, if (ptr == NULL) { /* FIXME: We should really return a warning string here, - but we can't, because the == might be in the MRI - comment field, and, since the nature of the MRI - comment field depends upon the exact instruction - being used, we don't have enough information here to - figure out whether it is or not. Instead, we leave - the == in place, which should cause a syntax error if - it is not in a comment. */ + but we can't, because the == might be in the MRI + comment field, and, since the nature of the MRI + comment field depends upon the exact instruction + being used, we don't have enough information here to + figure out whether it is or not. Instead, we leave + the == in place, which should cause a syntax error if + it is not in a comment. */ sb_add_char (out, '='); sb_add_char (out, '='); sb_add_sb (out, &t); @@ -997,7 +1022,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals, body. */ static const char * -macro_expand (int idx, sb *in, macro_entry *m, sb *out) +macro_expand (size_t idx, sb *in, macro_entry *m, sb *out) { sb t; formal_entry *ptr; @@ -1018,7 +1043,7 @@ macro_expand (int idx, sb *in, macro_entry *m, sb *out) if (macro_mri) { /* The macro may be called with an optional qualifier, which may - be referred to in the macro body as \0. */ + be referred to in the macro body as \0. */ if (idx < in->len && in->ptr[idx] == '.') { /* The Microtec assembler ignores this if followed by a white space. @@ -1044,7 +1069,7 @@ macro_expand (int idx, sb *in, macro_entry *m, sb *out) idx = sb_skip_white (idx, in); while (idx < in->len) { - int scan; + size_t scan; /* Look and see if it's a positional or keyword arg. */ scan = idx; @@ -1224,13 +1249,12 @@ check_macro (const char *line, sb *expand, if (is_name_ender (*s)) ++s; - copy = (char *) alloca (s - line + 1); - memcpy (copy, line, s - line); - copy[s - line] = '\0'; + copy = xmemdup0 (line, s - line); for (cls = copy; *cls != '\0'; cls ++) *cls = TOLOWER (*cls); macro = (macro_entry *) hash_find (macro_hash, copy); + free (copy); if (macro == NULL) return 0; @@ -1262,7 +1286,7 @@ delete_macro (const char *name) macro_entry *macro; len = strlen (name); - copy = (char *) alloca (len + 1); + copy = XNEWVEC (char, len + 1); for (i = 0; i < len; ++i) copy[i] = TOLOWER (name[i]); copy[i] = '\0'; @@ -1276,7 +1300,8 @@ delete_macro (const char *name) free_macro (macro); } else - as_warn (_("Attempt to purge non-existant macro `%s'"), copy); + as_warn (_("Attempt to purge non-existing macro `%s'"), copy); + free (copy); } /* Handle the MRI IRP and IRPC pseudo-ops. These are handled as a @@ -1284,7 +1309,7 @@ delete_macro (const char *name) success, or an error message otherwise. */ const char * -expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *)) +expand_irp (int irpc, size_t idx, sb *in, sb *out, size_t (*get_line) (sb *)) { sb sub; formal_entry f; @@ -1340,11 +1365,11 @@ expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *)) { if (in->ptr[idx] == '"') { - int nxt; + size_t nxt; if (irpc) in_quotes = ! in_quotes; - + nxt = sb_skip_white (idx + 1, in); if (nxt >= in->len) {