diff options
Diffstat (limited to 'contrib/binutils/gas/stabs.c')
-rw-r--r-- | contrib/binutils/gas/stabs.c | 191 |
1 files changed, 164 insertions, 27 deletions
diff --git a/contrib/binutils/gas/stabs.c b/contrib/binutils/gas/stabs.c index e58e6ff..7c13c2f 100644 --- a/contrib/binutils/gas/stabs.c +++ b/contrib/binutils/gas/stabs.c @@ -1,5 +1,5 @@ /* Generic stabs parsing for gas. - Copyright (C) 1989, 90, 91, 93, 94, 95, 96, 97, 1998 + Copyright (C) 1989, 90, 91, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "aout/stab_gnu.h" static void s_stab_generic PARAMS ((int, char *, char *)); +static void generate_asm_file PARAMS ((int, char *)); /* Allow backends to override the names used for the stab sections. */ #ifndef STAB_SECTION_NAME @@ -40,6 +41,15 @@ static void s_stab_generic PARAMS ((int, char *, char *)); #define STAB_STRING_SECTION_NAME ".stabstr" #endif +/* Non-zero if we're in the middle of a .func function, in which case + stabs_generate_asm_lineno emits function relative line number stabs. + Otherwise it emits line number stabs with absolute addresses. Note that + both cases only apply to assembler code assembled with -gstabs. */ +static int in_dot_func_p; + +/* Label at start of current function if in_dot_func_p != 0. */ +static const char *current_function_label; + /* * Handle .stabX directives, which used to be open-coded. * So much creeping featurism overloaded the semantics that we decided @@ -142,14 +152,14 @@ aout_process_stab (what, string, type, other, desc) if (what == 's' || what == 'n') { /* Pick up the value from the input line. */ - symbol->sy_frag = &zero_address_frag; + symbol_set_frag (symbol, &zero_address_frag); pseudo_set (symbol); } else { /* .stabd sets the name to NULL. Why? */ S_SET_NAME (symbol, NULL); - symbol->sy_frag = frag_now; + symbol_set_frag (symbol, frag_now); S_SET_VALUE (symbol, (valueT) frag_now_fix ()); } @@ -196,7 +206,7 @@ s_stab_generic (what, stab_secname, stabstr_secname) input_line_pointer++; else { - as_warn (".stabs: Missing comma"); + as_warn (_(".stabs: Missing comma")); ignore_rest_of_line (); return; } @@ -204,7 +214,7 @@ s_stab_generic (what, stab_secname, stabstr_secname) if (get_absolute_expression_and_terminator (&longint) != ',') { - as_warn (".stab%c: Missing comma", what); + as_warn (_(".stab%c: Missing comma"), what); ignore_rest_of_line (); return; } @@ -212,7 +222,7 @@ s_stab_generic (what, stab_secname, stabstr_secname) if (get_absolute_expression_and_terminator (&longint) != ',') { - as_warn (".stab%c: Missing comma", what); + as_warn (_(".stab%c: Missing comma"), what); ignore_rest_of_line (); return; } @@ -223,7 +233,7 @@ s_stab_generic (what, stab_secname, stabstr_secname) { if (*input_line_pointer != ',') { - as_warn (".stab%c: Missing comma", what); + as_warn (_(".stab%c: Missing comma"), what); ignore_rest_of_line (); return; } @@ -288,6 +298,10 @@ s_stab_generic (what, stab_secname, stabstr_secname) dot = frag_now_fix (); +#ifdef md_flush_pending_output + md_flush_pending_output (); +#endif + if (cached_secname && !strcmp (cached_secname, stab_secname)) { seg = cached_sec; @@ -398,7 +412,7 @@ s_xstab (what) input_line_pointer++; else { - as_bad ("comma missing in .xstabs"); + as_bad (_("comma missing in .xstabs")); ignore_rest_of_line (); return; } @@ -443,7 +457,7 @@ s_desc (ignore) if (*input_line_pointer != ',') { *p = 0; - as_bad ("Expected comma after name \"%s\"", name); + as_bad (_("Expected comma after name \"%s\""), name); *p = c; ignore_rest_of_line (); } @@ -461,18 +475,30 @@ s_desc (ignore) #endif /* defined (S_SET_DESC) */ -/* Generate stabs debugging information for the current line. This is - used to produce debugging information for an assembler file. */ +/* Generate stabs debugging information to denote the main source file. */ void -stabs_generate_asm_lineno () +stabs_generate_asm_file () { - static char *last_file; - static int lineno_count; - char *hold; char *file; unsigned int lineno; - char buf[100]; + + as_where (&file, &lineno); + generate_asm_file (N_SO, file); +} + +/* Generate stabs debugging information to denote the source file. + TYPE is one of N_SO, N_SOL. */ + +static void +generate_asm_file (type, file) + int type; + char *file; +{ + static char *last_file; + static int label_count; + char *hold; + char *buf = xmalloc (2 * strlen (file) + 10); char sym[30]; /* Rather than try to do this in some efficient fashion, we just @@ -482,17 +508,31 @@ stabs_generate_asm_lineno () hold = input_line_pointer; - as_where (&file, &lineno); - if (last_file == NULL || strcmp (last_file, file) != 0) { - sprintf (sym, "%sF%d", FAKE_LABEL_NAME, lineno_count); - ++lineno_count; - - sprintf (buf, "\"%s\",%d,0,0,%s\n", file, - last_file == NULL ? N_SO : N_SOL, - sym); + char *tmp = file; + char *endp = file + strlen(file); + char *bufp = buf; + + sprintf (sym, "%sF%d", FAKE_LABEL_NAME, label_count); + ++label_count; + + *bufp++ = '"'; + while (tmp < endp) + { + char *bslash = strchr (tmp, '\\'); + int len = (bslash ? (bslash - tmp + 1) : strlen (tmp)); + /* double all backslashes, since demand_copy_C_string (used by + s_stab to extract the part in quotes) will try to replace them as + escape sequences. backslash may appear in a filespec. */ + strncpy (bufp, tmp, len); + tmp += len; + bufp += len; + if (bslash != NULL) + *bufp++ = '\\'; + } + sprintf (bufp, "\",%d,0,0,%s\n", type, sym); input_line_pointer = buf; s_stab ('s'); colon (sym); @@ -502,13 +542,110 @@ stabs_generate_asm_lineno () last_file = xstrdup (file); } - sprintf (sym, "%sL%d", FAKE_LABEL_NAME, lineno_count); - ++lineno_count; + input_line_pointer = hold; + free (buf); +} + +/* Generate stabs debugging information for the current line. This is + used to produce debugging information for an assembler file. */ + +void +stabs_generate_asm_lineno () +{ + static int label_count; + char *hold; + char *file; + unsigned int lineno; + char *buf; + char sym[30]; + + /* Rather than try to do this in some efficient fashion, we just + generate a string and then parse it again. That lets us use the + existing stabs hook, which expect to see a string, rather than + inventing new ones. */ + + hold = input_line_pointer; + + as_where (&file, &lineno); + + generate_asm_file (N_SOL, file); - sprintf (buf, "%d,0,%d,%s\n", N_SLINE, lineno, sym); + sprintf (sym, "%sL%d", FAKE_LABEL_NAME, label_count); + ++label_count; + + if (in_dot_func_p) + { + buf = (char *) alloca (100 + strlen (current_function_label)); + sprintf (buf, "%d,0,%d,%s-%s\n", N_SLINE, lineno, + sym, current_function_label); + } + else + { + buf = (char *) alloca (100); + sprintf (buf, "%d,0,%d,%s\n", N_SLINE, lineno, sym); + } input_line_pointer = buf; s_stab ('n'); colon (sym); input_line_pointer = hold; } + +/* Emit a function stab. + All assembler functions are assumed to have return type `void'. */ + +void +stabs_generate_asm_func (funcname, startlabname) + const char *funcname; + const char *startlabname; +{ + static int void_emitted_p; + char *hold = input_line_pointer; + char *buf; + char *file; + unsigned int lineno; + + if (! void_emitted_p) + { + input_line_pointer = "\"void:t1=1\",128,0,0,0"; + s_stab ('s'); + void_emitted_p = 1; + } + + as_where (&file, &lineno); + asprintf (&buf, "\"%s:F1\",%d,0,%d,%s", + funcname, N_FUN, lineno + 1, startlabname); + input_line_pointer = buf; + s_stab ('s'); + free (buf); + + input_line_pointer = hold; + current_function_label = xstrdup (startlabname); + in_dot_func_p = 1; +} + +/* Emit a stab to record the end of a function. */ + +void +stabs_generate_asm_endfunc (funcname, startlabname) + const char *funcname ATTRIBUTE_UNUSED; + const char *startlabname; +{ + static int label_count; + char *hold = input_line_pointer; + char *buf; + char sym[30]; + + sprintf (sym, "%sendfunc%d", FAKE_LABEL_NAME, label_count); + ++label_count; + colon (sym); + + asprintf (&buf, "\"\",%d,0,0,%s-%s", N_FUN, sym, startlabname); + input_line_pointer = buf; + s_stab ('s'); + free (buf); + + input_line_pointer = hold; + in_dot_func_p = 0; + current_function_label = NULL; +} |