X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsymtab.c;h=840efb0ac8f192bb169c71c11d9edf98f3a819c0;hb=cc7ef3c3063a4e6bd6799d418b1bfbd37bc5d927;hp=0a639641d71abd0644fa5cb6a52e291259b0768f;hpb=1c95d7ab2e12e00756d21ef44c7539f8f9edc56f;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symtab.c b/gdb/symtab.c index 0a639641d7..840efb0ac8 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -16,7 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "defs.h" #include "symtab.h" @@ -29,18 +29,17 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "objfiles.h" #include "gdbcmd.h" #include "call-cmds.h" -#include "regex.h" +#include "gnu-regex.h" #include "expression.h" #include "language.h" #include "demangle.h" #include -#include #include #include -#include -#include +#include "gdb_string.h" +#include "gdb_stat.h" #include /* Prototypes for local functions */ @@ -291,7 +290,6 @@ gdb_mangle_name (type, i, j) if (!is_destructor) is_destructor = (strncmp(physname, "__dt", 4) == 0); -#ifndef GCC_MANGLE_BUG if (is_destructor || is_full_physname_constructor) { mangled_name = (char*) xmalloc(strlen(physname)+1); @@ -305,6 +303,13 @@ gdb_mangle_name (type, i, j) if (strcmp(buf, "__") == 0) buf[0] = '\0'; } + else if (newname != NULL && strchr (newname, '<') != NULL) + { + /* Template methods are fully mangled. */ + sprintf (buf, "__%s%s", const_prefix, volatile_prefix); + newname = NULL; + len = 0; + } else { sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len); @@ -343,51 +348,6 @@ gdb_mangle_name (type, i, j) if (newname != NULL) strcat (mangled_name, newname); -#else - - if (is_constructor) - { - buf[0] = '\0'; - } - else - { - sprintf (buf, "__%s%s", const_prefix, volatile_prefix); - } - - mangled_name_len = ((is_constructor ? 0 : strlen (field_name)) - + strlen (buf) + strlen (physname) + 1); - - /* Only needed for GNU-mangled names. ANSI-mangled names - work with the normal mechanisms. */ - if (OPNAME_PREFIX_P (field_name)) - { - char *opname; - opname = cplus_mangle_opname (field_name + 3, 0); - if (opname == NULL) - { - error ("No mangling for \"%s\"", field_name); - } - mangled_name_len += strlen (opname); - mangled_name = (char *) xmalloc (mangled_name_len); - - strncpy (mangled_name, field_name, 3); - strcpy (mangled_name + 3, opname); - } - else - { - mangled_name = (char *) xmalloc (mangled_name_len); - if (is_constructor) - { - mangled_name[0] = '\0'; - } - else - { - strcpy (mangled_name, field_name); - } - } - strcat (mangled_name, buf); - -#endif strcat (mangled_name, physname); return (mangled_name); } @@ -405,7 +365,36 @@ find_pc_psymtab (pc) ALL_PSYMTABS (objfile, pst) { if (pc >= pst->textlow && pc < pst->texthigh) - return (pst); + { + struct minimal_symbol *msymbol; + struct partial_symtab *tpst; + + /* An objfile that has its functions reordered might have + many partial symbol tables containing the PC, but + we want the partial symbol table that contains the + function containing the PC. */ + if (!(objfile->flags & OBJF_REORDERED)) + return (pst); + + msymbol = lookup_minimal_symbol_by_pc (pc); + if (msymbol == NULL) + return (pst); + + for (tpst = pst; tpst != NULL; tpst = tpst->next) + { + if (pc >= tpst->textlow && pc < tpst->texthigh) + { + struct partial_symbol *p; + + p = find_pc_psymbol (tpst, pc); + if (p != NULL + && SYMBOL_VALUE_ADDRESS(p) + == SYMBOL_VALUE_ADDRESS (msymbol)) + return (tpst); + } + } + return (pst); + } } return (NULL); } @@ -590,20 +579,19 @@ found: } } - /* Check for the possibility of the symbol being a global function - that is stored in one of the minimal symbol tables. Eventually, all - global symbols might be resolved in this way. */ + /* Check for the possibility of the symbol being a function or + a mangled variable that is stored in one of the minimal symbol tables. + Eventually, all global symbols might be resolved in this way. */ if (namespace == VAR_NAMESPACE) { - msymbol = lookup_minimal_symbol (name, (struct objfile *) NULL); + msymbol = lookup_minimal_symbol (name, NULL, NULL); if (msymbol != NULL) { s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)); - /* If S is NULL, there are no debug symbols for this file. - Skip this stuff and check for matching static symbols below. */ if (s != NULL) { + /* This is a function which has a symtab for its address. */ bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol), @@ -633,6 +621,18 @@ found: *symtab = s; return sym; } + else if (MSYMBOL_TYPE (msymbol) != mst_text + && MSYMBOL_TYPE (msymbol) != mst_file_text + && !STREQ (name, SYMBOL_NAME (msymbol))) + { + /* This is a mangled variable, look it up by its + mangled name. */ + return lookup_symbol (SYMBOL_NAME (msymbol), block, + namespace, is_a_field_of_this, symtab); + } + /* There are no debug symbols for this file, or we are looking + for an unmangled variable. + Try to find a matching static symbol below. */ } } @@ -686,42 +686,6 @@ found: } } - /* Now search all per-file blocks for static mangled symbols. - Do the symtabs first, then check the psymtabs. */ - - if (namespace == VAR_NAMESPACE) - { - ALL_SYMTABS (objfile, s) - { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, VAR_NAMESPACE); - if (sym) - { - block_found = block; - if (symtab != NULL) - *symtab = s; - return sym; - } - } - - ALL_PSYMTABS (objfile, ps) - { - if (!ps->readin && lookup_partial_symbol (ps, name, 0, VAR_NAMESPACE)) - { - s = PSYMTAB_TO_SYMTAB(ps); - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, VAR_NAMESPACE); - if (!sym) - error ("Internal: mangled static symbol `%s' found in %s psymtab but not in symtab", name, ps->filename); - if (symtab != NULL) - *symtab = s; - return sym; - } - } - } - if (symtab != NULL) *symtab = NULL; return 0; @@ -765,7 +729,8 @@ lookup_partial_symbol (pst, name, global, namespace) while (top > bottom) { center = bottom + (top - bottom) / 2; - assert (center < top); + if (!(center < top)) + abort (); if (!do_linear_search && SYMBOL_LANGUAGE (center) == language_cplus) { do_linear_search = 1; @@ -779,7 +744,8 @@ lookup_partial_symbol (pst, name, global, namespace) bottom = center + 1; } } - assert (top == bottom); + if (!(top == bottom)) + abort (); while (STREQ (SYMBOL_NAME (top), name)) { if (SYMBOL_NAMESPACE (top) == namespace) @@ -1003,8 +969,15 @@ find_pc_symtab (pc) to deal with a case like symtab a is at 0x1000-0x2000 and 0x3000-0x4000 and symtab b is at 0x2000-0x3000. So the GLOBAL_BLOCK for a is from 0x1000-0x4000, but for address 0x2345 we want to return symtab b. - This is said to happen for the mips; it might be swifter to create - several symtabs with the same name like xcoff does (I'm not sure). */ + + This happens for native ecoff format, where code from included files + gets its own symtab. The symtab for the included file should have + been read in already via the dependency mechanism. + It might be swifter to create several symtabs with the same name + like xcoff does (I'm not sure). + + It also happens for objfiles that have their functions reordered. + For these, the symtab we are looking for is not necessarily read in. */ ALL_SYMTABS (objfile, s) { @@ -1015,6 +988,18 @@ find_pc_symtab (pc) && (distance == 0 || BLOCK_END (b) - BLOCK_START (b) < distance)) { + /* For an objfile that has its functions reordered, + find_pc_psymtab will find the proper partial symbol table + and we simply return its corresponding symtab. */ + if (objfile->flags & OBJF_REORDERED) + { + ps = find_pc_psymtab (pc); + if (ps) + s = PSYMTAB_TO_SYMTAB (ps); + else + s = NULL; + return (s); + } distance = BLOCK_END (b) - BLOCK_START (b); best_s = s; } @@ -1261,6 +1246,10 @@ find_pc_line (pc, notcurrent) { val.symtab = alt_symtab; val.line = alt->line - 1; + + /* Don't return line 0, that means that we didn't find the line. */ + if (val.line == 0) ++val.line; + val.pc = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)); val.end = alt->pc; } @@ -1500,6 +1489,51 @@ find_pc_line_pc_range (pc, startptr, endptr) *endptr = sal.end; return sal.symtab != 0; } + +/* Given a function symbol SYM, find the symtab and line for the start + of the function. + If the argument FUNFIRSTLINE is nonzero, we want the first line + of real code inside the function. */ + +static struct symtab_and_line +find_function_start_sal PARAMS ((struct symbol *sym, int)); + +static struct symtab_and_line +find_function_start_sal (sym, funfirstline) + struct symbol *sym; + int funfirstline; +{ + CORE_ADDR pc; + struct symtab_and_line sal; + + pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + if (funfirstline) + { + pc += FUNCTION_START_OFFSET; + SKIP_PROLOGUE (pc); + } + sal = find_pc_line (pc, 0); + +#ifdef PROLOGUE_FIRSTLINE_OVERLAP + /* Convex: no need to suppress code on first line, if any */ + sal.pc = pc; +#else + /* Check if SKIP_PROLOGUE left us in mid-line, and the next + line is still part of the same function. */ + if (sal.pc != pc + && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= sal.end + && sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) + { + /* First pc of next line */ + pc = sal.end; + /* Recalculate the line number (might not be N+1). */ + sal = find_pc_line (pc, 0); + } + sal.pc = pc; +#endif + + return sal; +} /* If P is of the form "operator[ \t]+..." where `...' is some legitimate operator text, return a pointer to the @@ -1586,14 +1620,35 @@ operator_chars (p, end) return *end; } +/* Return the number of methods described for TYPE, including the + methods from types it derives from. This can't be done in the symbol + reader because the type of the baseclass might still be stubbed + when the definition of the derived class is parsed. */ + +static int total_number_of_methods PARAMS ((struct type *type)); + +static int +total_number_of_methods (type) + struct type *type; +{ + int n; + int count; + + check_stub_type (type); + count = TYPE_NFN_FIELDS_TOTAL (type); + + for (n = 0; n < TYPE_N_BASECLASSES (type); n++) + count += total_number_of_methods (TYPE_BASECLASS (type, n)); + + return count; +} + /* Recursive helper function for decode_line_1. - * Look for methods named NAME in type T. - * Return number of matches. - * Put matches in SYM_ARR (which better be big enough!). - * These allocations seem to define "big enough": - * sym_arr = (struct symbol **) alloca(TYPE_NFN_FIELDS_TOTAL (t) * sizeof(struct symbol*)); - * Note that this function is g++ specific. - */ + Look for methods named NAME in type T. + Return number of matches. + Put matches in SYM_ARR, which should have been allocated with + a size of total_number_of_methods (T) * sizeof (struct symbol *). + Note that this function is g++ specific. */ int find_methods (t, name, sym_arr) @@ -1752,7 +1807,8 @@ build_canonical_line_spec (sal, symname, canonical) FUNCTION may be an undebuggable function found in minimal symbol table. If the argument FUNFIRSTLINE is nonzero, we want the first line - of real code inside a function when a function is specified. + of real code inside a function when a function is specified, and it is + not OK to specify a variable or type to get its line number. DEFAULT_SYMTAB specifies the file to use if none is specified. It defaults to current_source_symtab. @@ -1846,17 +1902,13 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) if (**argptr == '*') { - if (**argptr == '*') - { - (*argptr)++; - } + (*argptr)++; pc = parse_and_eval_address_1 (argptr); values.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); values.nelts = 1; values.sals[0] = find_pc_line (pc, 0); values.sals[0].pc = pc; - build_canonical_line_spec (values.sals, NULL, canonical); return values; } @@ -1871,7 +1923,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) { if (p[0] == '<') { - while(!++p && *p != '>'); + while(++p && *p != '>'); if (!p) { error ("non-matching '<' and '>' in command"); @@ -1957,7 +2009,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) sym = 0; i1 = 0; /* counter for the symbol array */ t = SYMBOL_TYPE (sym_class); - sym_arr = (struct symbol **) alloca(TYPE_NFN_FIELDS_TOTAL (t) * sizeof(struct symbol*)); + sym_arr = (struct symbol **) alloca(total_number_of_methods (t) + * sizeof(struct symbol *)); /* Cfront objects don't have fieldlists. */ if (destructor_name_p (copy, t) && TYPE_FN_FIELDLISTS (t) != NULL) @@ -1988,17 +2041,10 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) { - /* Arg is the name of a function */ - pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); - if (funfirstline) - { - pc += FUNCTION_START_OFFSET; - SKIP_PROLOGUE (pc); - } values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line)); values.nelts = 1; - values.sals[0] = find_pc_line (pc, 0); - values.sals[0].pc = (values.sals[0].end && values.sals[0].pc != pc) ? values.sals[0].end : pc; + values.sals[0] = find_function_start_sal (sym, + funfirstline); } else { @@ -2144,7 +2190,9 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) /* Arg token is not digits => try it as a variable name Find the next token (everything up to end or next whitespace). */ - if (is_quoted) + if (**argptr == '$') /* Convenience variable */ + p = skip_quoted (*argptr + 1); + else if (is_quoted) { p = skip_quoted (*argptr); if (p[-1] != '\'') @@ -2172,6 +2220,32 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) while (*p == ' ' || *p == '\t') p++; *argptr = p; + /* See if it's a convenience variable */ + + if (*copy == '$') + { + value_ptr valx; + int need_canonical = (s == 0) ? 1 : 0; + + valx = value_of_internalvar (lookup_internalvar (copy + 1)); + if (TYPE_CODE (VALUE_TYPE (valx)) != TYPE_CODE_INT) + error ("Convenience variables used in line specs must have integer values."); + + val.symtab = s ? s : default_symtab; + val.line = value_as_long (valx); + val.pc = 0; + + values.sals = (struct symtab_and_line *)xmalloc (sizeof val); + values.sals[0] = val; + values.nelts = 1; + + if (need_canonical) + build_canonical_line_spec (values.sals, NULL, canonical); + + return values; + } + + /* Look up that token as a variable. If file specified, use that file's per-file block to start with. */ @@ -2185,32 +2259,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) if (SYMBOL_CLASS (sym) == LOC_BLOCK) { /* Arg is the name of a function */ - pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); - if (funfirstline) - { - pc += FUNCTION_START_OFFSET; - SKIP_PROLOGUE (pc); - } - val = find_pc_line (pc, 0); -#ifdef PROLOGUE_FIRSTLINE_OVERLAP - /* Convex: no need to suppress code on first line, if any */ - val.pc = pc; -#else - /* Check if SKIP_PROLOGUE left us in mid-line, and the next - line is still part of the same function. */ - if (val.pc != pc - && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= val.end - && val.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) - { - /* First pc of next line */ - pc = val.end; - /* Recalculate the line number (might not be N+1). */ - val = find_pc_line (pc, 0); - } - val.pc = pc; -#endif values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line)); - values.sals[0] = val; + values.sals[0] = find_function_start_sal (sym, funfirstline); values.nelts = 1; /* Don't use the SYMBOL_LINE; if used at all it points to @@ -2228,26 +2278,32 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) } return values; } - else if (SYMBOL_LINE (sym) != 0) + else { - /* We know its line number. */ - values.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); - values.nelts = 1; - memset (&values.sals[0], 0, sizeof (values.sals[0])); - values.sals[0].symtab = sym_symtab; - values.sals[0].line = SYMBOL_LINE (sym); - return values; + if (funfirstline) + error ("\"%s\" is not a function", copy); + else if (SYMBOL_LINE (sym) != 0) + { + /* We know its line number. */ + values.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + values.nelts = 1; + memset (&values.sals[0], 0, sizeof (values.sals[0])); + values.sals[0].symtab = sym_symtab; + values.sals[0].line = SYMBOL_LINE (sym); + return values; + } + else + /* This can happen if it is compiled with a compiler which doesn't + put out line numbers for variables. */ + /* FIXME: Shouldn't we just set .line and .symtab to zero + and return? For example, "info line foo" could print + the address. */ + error ("Line number not known for symbol \"%s\"", copy); } - else - /* This can happen if it is compiled with a compiler which doesn't - put out line numbers for variables. */ - /* FIXME: Shouldn't we just set .line and .symtab to zero and - return? For example, "info line foo" could print the address. */ - error ("Line number not known for symbol \"%s\"", copy); } - msymbol = lookup_minimal_symbol (copy, (struct objfile *) NULL); + msymbol = lookup_minimal_symbol (copy, NULL, NULL); if (msymbol != NULL) { val.symtab = 0; @@ -2301,7 +2357,6 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical) char ***canonical; { struct symtabs_and_lines values, return_values; - register CORE_ADDR pc; char *args, *arg1; int i; char *prompt; @@ -2327,20 +2382,15 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical) { if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK) { - /* Arg is the name of a function */ - pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym_arr[i])); - if (funfirstline) - { - pc += FUNCTION_START_OFFSET; - SKIP_PROLOGUE (pc); - } - values.sals[i] = find_pc_line (pc, 0); - values.sals[i].pc = (values.sals[i].end && values.sals[i].pc != pc) ? - values.sals[i].end : pc; - printf_unfiltered("[%d] %s at %s:%d\n", (i+2), SYMBOL_SOURCE_NAME (sym_arr[i]), - values.sals[i].symtab->filename, values.sals[i].line); + values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline); + printf_unfiltered ("[%d] %s at %s:%d\n", + (i+2), + SYMBOL_SOURCE_NAME (sym_arr[i]), + values.sals[i].symtab->filename, + values.sals[i].line); } - else printf_unfiltered ("?HERE\n"); + else + printf_unfiltered ("?HERE\n"); i++; } @@ -2652,13 +2702,20 @@ list_symbols (regexp, class, bpt, from_tty) } } - /* Here, we search through the minimal symbol tables for functions that - match, and call find_pc_symtab on them to force their symbols to - be read. The symbol will then be found during the scan of symtabs - below. If find_pc_symtab fails, set found_misc so that we will - rescan to print any matching symbols without debug info. */ + /* Here, we search through the minimal symbol tables for functions + and variables that match, and force their symbols to be read. + This is in particular necessary for demangled variable names, + which are no longer put into the partial symbol tables. + The symbol will then be found during the scan of symtabs below. + + For functions, find_pc_symtab should succeed if we have debug info + for the function, for variables we have to call lookup_symbol + to determine if the variable has debug info. + If the lookup fails, set found_misc so that we will rescan to print + any matching symbols without debug info. + */ - if (class == 1) + if (class == 0 || class == 1) { ALL_MSYMBOLS (objfile, msymbol) { @@ -2671,7 +2728,12 @@ list_symbols (regexp, class, bpt, from_tty) { if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))) { - found_misc = 1; + if (class == 1 + || lookup_symbol (SYMBOL_NAME (msymbol), + (struct block *) NULL, + VAR_NAMESPACE, + 0, (struct symtab **) NULL) == NULL) + found_misc = 1; } } } @@ -2724,14 +2786,18 @@ list_symbols (regexp, class, bpt, from_tty) same name but in different files. In order to set breakpoints on all of them, we must give both the file name and the function name to - break_command. */ + break_command. + Quoting the symbol name gets rid of problems + with mangled symbol names that contain + CPLUS_MARKER characters. */ char *string = (char *) alloca (strlen (s->filename) + strlen (SYMBOL_NAME(sym)) - + 2); + + 4); strcpy (string, s->filename); - strcat (string, ":"); + strcat (string, ":'"); strcat (string, SYMBOL_NAME(sym)); + strcat (string, "'"); break_command (string, from_tty); } } @@ -2805,6 +2871,13 @@ list_symbols (regexp, class, bpt, from_tty) (struct block *) NULL, VAR_NAMESPACE, 0, (struct symtab **) NULL) == NULL) { + if (bpt) + { + break_command (SYMBOL_NAME (msymbol), from_tty); + printf_filtered (" %s;\n", + SYMBOL_SOURCE_NAME (msymbol)); + continue; + } if (!found_in_file) { printf_filtered ("\nNon-debugging symbols:\n"); @@ -2956,6 +3029,19 @@ completion_list_add_name (symname, sym_text, sym_text_len, text, word) strcat (new, symname); } + /* Recheck for duplicates if we intend to add a modified symbol. */ + if (word != sym_text) + { + for (i = 0; i < return_val_index; ++i) + { + if (STREQ (new, return_val[i])) + { + free (new); + return; + } + } + } + if (return_val_index + 3 > return_val_size) { newsize = (return_val_size *= 2) * sizeof (char *); @@ -3154,51 +3240,51 @@ make_symbol_completion_list (text, word) return (return_val); } - -#if 0 -/* Add the type of the symbol sym to the type of the current - function whose block we are in (assumed). The type of - this current function is contained in *TYPE. - - This basically works as follows: When we find a function - symbol (N_FUNC with a 'f' or 'F' in the symbol name), we record - a pointer to its type in the global in_function_type. Every - time we come across a parameter symbol ('p' in its name), then - this procedure adds the name and type of that parameter - to the function type pointed to by *TYPE. (Which should correspond - to in_function_type if it was called correctly). - - Note that since we are modifying a type, the result of - lookup_function_type() should be memcpy()ed before calling - this. When not in strict typing mode, the expression - evaluator can choose to ignore this. - - Assumption: All of a function's parameter symbols will - appear before another function symbol is found. The parameters - appear in the same order in the argument list as they do in the - symbol table. */ +/* Determine if PC is in the prologue of a function. The prologue is the area + between the first instruction of a function, and the first executable line. + Returns 1 if PC *might* be in prologue, 0 if definately *not* in prologue. + */ -void -add_param_to_type (type,sym) - struct type **type; - struct symbol *sym; +int +in_prologue (pc, func_start) + CORE_ADDR pc; + CORE_ADDR func_start; { - int num = ++(TYPE_NFIELDS(*type)); - - if(TYPE_NFIELDS(*type)-1) - TYPE_FIELDS(*type) = (struct field *) - (*current_objfile->xrealloc) ((char *)(TYPE_FIELDS(*type)), - num*sizeof(struct field)); - else - TYPE_FIELDS(*type) = (struct field *) - (*current_objfile->xmalloc) (num*sizeof(struct field)); - - TYPE_FIELD_BITPOS(*type,num-1) = num-1; - TYPE_FIELD_BITSIZE(*type,num-1) = 0; - TYPE_FIELD_TYPE(*type,num-1) = SYMBOL_TYPE(sym); - TYPE_FIELD_NAME(*type,num-1) = SYMBOL_NAME(sym); + struct symtab_and_line sal; + CORE_ADDR func_addr, func_end; + + if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end)) + goto nosyms; /* Might be in prologue */ + + sal = find_pc_line (func_addr, 0); + + if (sal.line == 0) + goto nosyms; + + if (sal.end > func_addr + && sal.end <= func_end) /* Is prologue in function? */ + return pc < sal.end; /* Yes, is pc in prologue? */ + + /* The line after the prologue seems to be outside the function. In this + case, tell the caller to find the prologue the hard way. */ + + return 1; + +/* Come here when symtabs don't contain line # info. In this case, it is + likely that the user has stepped into a library function w/o symbols, or + is doing a stepi/nexti through code without symbols. */ + + nosyms: + +/* We need to call the target-specific prologue skipping functions with the + function's start address because PC may be pointing at an instruction that + could be mistakenly considered part of the prologue. */ + + SKIP_PROLOGUE (func_start); + + return pc < func_start; } -#endif + void _initialize_symtab ()