return multiple_symbols_mode;
}
-/* The single non-language-specific builtin type */
-struct type *builtin_type_error;
-
/* Block in which the most recently searched-for symbol was found.
Might be better to make this a parameter to lookup_symbol and
value_of_this. */
void
init_sal (struct symtab_and_line *sal)
{
+ sal->pspace = NULL;
sal->symtab = 0;
sal->section = 0;
sal->line = 0;
sym = lookup_symbol_aux_block (name, linkage_name, block, domain);
if (sym != NULL)
return sym;
+
+ if (BLOCK_FUNCTION (block) != NULL && block_inlined_p (block))
+ break;
block = BLOCK_SUPERBLOCK (block);
}
- /* We've reached the static block without finding a result. */
+ /* We've reached the edge of the function without finding a result. */
return NULL;
}
struct symtab *best_s = NULL;
struct partial_symtab *ps;
struct objfile *objfile;
+ struct program_space *pspace;
CORE_ADDR distance = 0;
struct minimal_symbol *msymbol;
+ pspace = current_program_space;
+
/* If we know that this is not a text address, return failure. This is
necessary because we loop based on the block's high and low code
addresses, which do not include the data ranges, and because
will cause a core dump), but maybe we can successfully
continue, so let's not. */
warning (_("\
-(Internal error: pc 0x%s in read in psymtab, but not in symtab.)\n"),
- paddr_nz (pc));
+(Internal error: pc %s in read in psymtab, but not in symtab.)\n"),
+ paddress (get_objfile_arch (ps->objfile), pc));
s = PSYMTAB_TO_SYMTAB (ps);
}
return (s);
init_sal (&val); /* initialize to zeroes */
+ val.pspace = current_program_space;
+
/* It's tempting to assume that, if we can't find debugging info for
any function enclosing PC, that we shouldn't search for line
number info, either. However, GAS can emit line number info for
return pc;
}
+/* Given a function start address FUNC_ADDR and SYMTAB, find the first
+ address for that function that has an entry in SYMTAB's line info
+ table. If such an entry cannot be found, return FUNC_ADDR
+ unaltered. */
+CORE_ADDR
+skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab)
+{
+ CORE_ADDR func_start, func_end;
+ struct linetable *l;
+ int ind, i, len;
+ int best_lineno = 0;
+ CORE_ADDR best_pc = func_addr;
+
+ /* Give up if this symbol has no lineinfo table. */
+ l = LINETABLE (symtab);
+ if (l == NULL)
+ return func_addr;
+
+ /* Get the range for the function's PC values, or give up if we
+ cannot, for some reason. */
+ if (!find_pc_partial_function (func_addr, NULL, &func_start, &func_end))
+ return func_addr;
+
+ /* Linetable entries are ordered by PC values, see the commentary in
+ symtab.h where `struct linetable' is defined. Thus, the first
+ entry whose PC is in the range [FUNC_START..FUNC_END[ is the
+ address we are looking for. */
+ for (i = 0; i < l->nitems; i++)
+ {
+ struct linetable_entry *item = &(l->item[i]);
+
+ /* Don't use line numbers of zero, they mark special entries in
+ the table. See the commentary on symtab.h before the
+ definition of struct linetable. */
+ if (item->line > 0 && func_start <= item->pc && item->pc < func_end)
+ return item->pc;
+ }
+
+ return func_addr;
+}
+
/* 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
CORE_ADDR pc;
struct symtab_and_line sal;
+ struct block *b, *function_block;
+
+ struct cleanup *old_chain;
+
+ old_chain = save_current_space_and_thread ();
+ switch_to_program_space_and_thread (objfile->pspace);
pc = BLOCK_START (block);
fixup_symbol_section (sym, objfile);
to `__main' in `main' between the prologue and before user
code. */
if (funfirstline
- && gdbarch_skip_main_prologue_p (current_gdbarch)
+ && gdbarch_skip_main_prologue_p (gdbarch)
&& SYMBOL_LINKAGE_NAME (sym)
&& strcmp (SYMBOL_LINKAGE_NAME (sym), "main") == 0)
{
- pc = gdbarch_skip_main_prologue (current_gdbarch, pc);
+ pc = gdbarch_skip_main_prologue (gdbarch, pc);
/* Recalculate the line number (might not be N+1). */
sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
}
+ /* If we still don't have a valid source line, try to find the first
+ PC in the lineinfo table that belongs to the same function. This
+ happens with COFF debug info, which does not seem to have an
+ entry in lineinfo table for the code after the prologue which has
+ no direct relation to source. For example, this was found to be
+ the case with the DJGPP target using "gcc -gcoff" when the
+ compiler inserted code after the prologue to make sure the stack
+ is aligned. */
+ if (funfirstline && sal.symtab == NULL)
+ {
+ pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym));
+ /* Recalculate the line number. */
+ sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0);
+ }
+
sal.pc = pc;
+ sal.pspace = objfile->pspace;
+
+ /* Check if we are now inside an inlined function. If we can,
+ use the call site of the function instead. */
+ b = block_for_pc_sect (sal.pc, SYMBOL_OBJ_SECTION (sym));
+ function_block = NULL;
+ while (b != NULL)
+ {
+ if (BLOCK_FUNCTION (b) != NULL && block_inlined_p (b))
+ function_block = b;
+ else if (BLOCK_FUNCTION (b) != NULL)
+ break;
+ b = BLOCK_SUPERBLOCK (b);
+ }
+ if (function_block != NULL
+ && SYMBOL_LINE (BLOCK_FUNCTION (function_block)) != 0)
+ {
+ sal.line = SYMBOL_LINE (BLOCK_FUNCTION (function_block));
+ sal.symtab = SYMBOL_SYMTAB (BLOCK_FUNCTION (function_block));
+ }
+ do_cleanups (old_chain);
return sal;
}
{
ALL_MSYMBOLS (objfile, msymbol)
{
+ QUIT;
+
if (MSYMBOL_TYPE (msymbol) == ourtype ||
MSYMBOL_TYPE (msymbol) == ourtype2 ||
MSYMBOL_TYPE (msymbol) == ourtype3 ||
{
ALL_MSYMBOLS (objfile, msymbol)
{
+ QUIT;
+
if (MSYMBOL_TYPE (msymbol) == ourtype ||
MSYMBOL_TYPE (msymbol) == ourtype2 ||
MSYMBOL_TYPE (msymbol) == ourtype3 ||
static void
print_msymbol_info (struct minimal_symbol *msymbol)
{
+ struct gdbarch *gdbarch = get_objfile_arch (msymbol_objfile (msymbol));
char *tmp;
- if (gdbarch_addr_bit (current_gdbarch) <= 32)
+ if (gdbarch_addr_bit (gdbarch) <= 32)
tmp = hex_string_custom (SYMBOL_VALUE_ADDRESS (msymbol)
& (CORE_ADDR) 0xffffffff,
8);
return p;
}
+static void
+completion_list_add_fields (struct symbol *sym, char *sym_text,
+ int sym_text_len, char *text, char *word)
+{
+ if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+ {
+ struct type *t = SYMBOL_TYPE (sym);
+ enum type_code c = TYPE_CODE (t);
+ int j;
+
+ if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
+ for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
+ if (TYPE_FIELD_NAME (t, j))
+ completion_list_add_name (TYPE_FIELD_NAME (t, j),
+ sym_text, sym_text_len, text, word);
+ }
+}
+
/* Type of the user_data argument passed to add_macro_name. The
contents are simply whatever is needed by
completion_list_add_name. */
struct partial_symtab *ps;
struct minimal_symbol *msymbol;
struct objfile *objfile;
- struct block *b, *surrounding_static_block = 0;
+ struct block *b;
+ const struct block *surrounding_static_block, *surrounding_global_block;
struct dict_iterator iter;
- int j;
struct partial_symbol **psym;
/* The symbol we are completing on. Points in same buffer as text. */
char *sym_text;
which are in symbols. */
while (p > text)
{
- if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
+ if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0'
+ || p[-1] == ':')
--p;
else
break;
}
/* Search upwards from currently selected frame (so that we can
- complete on local vars. */
+ complete on local vars). Also catch fields of types defined in
+ this places which match our text string. Only complete on types
+ visible from current context. */
+
+ b = get_selected_block (0);
+ surrounding_static_block = block_static_block (b);
+ surrounding_global_block = block_global_block (b);
+ if (surrounding_static_block != NULL)
+ while (b != surrounding_static_block)
+ {
+ QUIT;
- for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
- {
- if (!BLOCK_SUPERBLOCK (b))
- {
- surrounding_static_block = b; /* For elmin of dups */
- }
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text,
+ word);
+ completion_list_add_fields (sym, sym_text, sym_text_len, text,
+ word);
+ }
- /* Also catch fields of types defined in this places which match our
- text string. Only complete on types visible from current context. */
+ /* Stop when we encounter an enclosing function. Do not stop for
+ non-inlined functions - the locals of the enclosing function
+ are in scope for a nested function. */
+ if (BLOCK_FUNCTION (b) != NULL && block_inlined_p (b))
+ break;
+ b = BLOCK_SUPERBLOCK (b);
+ }
- ALL_BLOCK_SYMBOLS (b, iter, sym)
- {
- QUIT;
- COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
- if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
- {
- struct type *t = SYMBOL_TYPE (sym);
- enum type_code c = TYPE_CODE (t);
+ /* Add fields from the file's types; symbols will be added below. */
- if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
- {
- for (j = TYPE_N_BASECLASSES (t); j < TYPE_NFIELDS (t); j++)
- {
- if (TYPE_FIELD_NAME (t, j))
- {
- completion_list_add_name (TYPE_FIELD_NAME (t, j),
- sym_text, sym_text_len, text, word);
- }
- }
- }
- }
- }
- }
+ if (surrounding_static_block != NULL)
+ ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym)
+ completion_list_add_fields (sym, sym_text, sym_text_len, text, word);
+
+ if (surrounding_global_block != NULL)
+ ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym)
+ completion_list_add_fields (sym, sym_text, sym_text_len, text, word);
/* Go through the symtabs and check the externs and statics for
symbols which match. */
{
QUIT;
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
- /* Don't do this block twice. */
- if (b == surrounding_static_block)
- continue;
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
*/
int
-in_prologue (CORE_ADDR pc, CORE_ADDR func_start)
+in_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR func_start)
{
struct symtab_and_line sal;
CORE_ADDR func_addr, func_end;
if (! func_start)
return 1; /* We *might* be in a prologue. */
- prologue_end = gdbarch_skip_prologue (current_gdbarch, func_start);
+ prologue_end = gdbarch_skip_prologue (gdbarch, func_start);
return func_start <= pc && pc < prologue_end;
}
/* We don't have any good line number info, so use the minsym
information, together with the architecture-specific prologue
scanning code. */
- CORE_ADDR prologue_end = gdbarch_skip_prologue
- (current_gdbarch, func_addr);
+ CORE_ADDR prologue_end = gdbarch_skip_prologue (gdbarch, func_addr);
return func_addr <= pc && pc < prologue_end;
}
found in both ia64 and ppc). */
CORE_ADDR
-skip_prologue_using_sal (CORE_ADDR func_addr)
+skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
{
struct symtab_and_line prologue_sal;
CORE_ADDR start_pc;
/* Get an initial range for the function. */
find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
- start_pc += gdbarch_deprecated_function_start_offset (current_gdbarch);
+ start_pc += gdbarch_deprecated_function_start_offset (gdbarch);
prologue_sal = find_pc_line (start_pc, 0);
if (prologue_sal.line != 0)
line mark the prologue -> body transition. */
if (sal.line >= prologue_sal.line)
break;
+
+ /* The line number is smaller. Check that it's from the
+ same function, not something inlined. If it's inlined,
+ then there is no point comparing the line numbers. */
+ bl = block_for_pc (prologue_sal.end);
+ while (bl)
+ {
+ if (block_inlined_p (bl))
+ break;
+ if (BLOCK_FUNCTION (bl))
+ {
+ bl = NULL;
+ break;
+ }
+ bl = BLOCK_SUPERBLOCK (bl);
+ }
+ if (bl != NULL)
+ break;
+
/* The case in which compiler's optimizer/scheduler has
moved instructions into the prologue. We look ahead in
the function looking for address ranges whose
initializing it from SYMTAB, LINENO and PC. */
static void
append_expanded_sal (struct symtabs_and_lines *sal,
+ struct program_space *pspace,
struct symtab *symtab,
int lineno, CORE_ADDR pc)
{
- CORE_ADDR func_addr, func_end;
-
sal->sals = xrealloc (sal->sals,
sizeof (sal->sals[0])
* (sal->nelts + 1));
init_sal (sal->sals + sal->nelts);
+ sal->sals[sal->nelts].pspace = pspace;
sal->sals[sal->nelts].symtab = symtab;
sal->sals[sal->nelts].section = NULL;
sal->sals[sal->nelts].end = 0;
struct linetable_entry **best_item,
struct symtab **best_symtab)
{
+ struct program_space *pspace;
struct objfile *objfile;
struct symtab *symtab;
int exact = 0;
int j;
*best_item = 0;
*best_symtab = 0;
-
- ALL_SYMTABS (objfile, symtab)
+
+ ALL_PSPACES (pspace)
+ ALL_PSPACE_SYMTABS (pspace, objfile, symtab)
{
if (strcmp (filename, symtab->filename) == 0)
{
if (item->line == lineno)
{
exact = 1;
- append_expanded_sal (ret, symtab, lineno, item->pc);
+ append_expanded_sal (ret, objfile->pspace,
+ symtab, lineno, item->pc);
}
else if (!exact && item->line > lineno
&& (*best_item == NULL
return exact;
}
-/* Compute a set of all sals in
- the entire program that correspond to same file
- and line as SAL and return those. If there
- are several sals that belong to the same block,
- only one sal for the block is included in results. */
+/* Compute a set of all sals in all program spaces that correspond to
+ same file and line as SAL and return those. If there are several
+ sals that belong to the same block, only one sal for the block is
+ included in results. */
struct symtabs_and_lines
expand_line_sal (struct symtab_and_line sal)
int deleted = 0;
struct block **blocks = NULL;
int *filter;
+ struct cleanup *old_chain;
ret.nelts = 0;
ret.sals = NULL;
+ /* Only expand sals that represent file.c:line. */
if (sal.symtab == NULL || sal.line == 0 || sal.pc != 0)
{
ret.sals = xmalloc (sizeof (struct symtab_and_line));
}
else
{
+ struct program_space *pspace;
struct linetable_entry *best_item = 0;
struct symtab *best_symtab = 0;
int exact = 0;
+ char *match_filename;
lineno = sal.line;
+ match_filename = sal.symtab->filename;
/* We need to find all symtabs for a file which name
is described by sal. We cannot just directly
the right name. Then, we iterate over symtabs, knowing
that all symtabs we're interested in are loaded. */
- ALL_PSYMTABS (objfile, psymtab)
+ old_chain = save_current_program_space ();
+ ALL_PSPACES (pspace)
+ ALL_PSPACE_PSYMTABS (pspace, objfile, psymtab)
{
- if (strcmp (sal.symtab->filename,
- psymtab->filename) == 0)
- PSYMTAB_TO_SYMTAB (psymtab);
+ if (strcmp (match_filename, psymtab->filename) == 0)
+ {
+ set_current_program_space (pspace);
+
+ PSYMTAB_TO_SYMTAB (psymtab);
+ }
}
+ do_cleanups (old_chain);
/* Now search the symtab for exact matches and append them. If
none is found, append the best_item and all its exact
matches. */
- exact = append_exact_match_to_sals (sal.symtab->filename, lineno,
+ exact = append_exact_match_to_sals (match_filename, lineno,
&ret, &best_item, &best_symtab);
if (!exact && best_item)
append_exact_match_to_sals (best_symtab->filename, best_item->line,
blocks -- for each PC found above we see if there are other PCs
that are in the same block. If yes, the other PCs are filtered out. */
+ old_chain = save_current_program_space ();
filter = alloca (ret.nelts * sizeof (int));
blocks = alloca (ret.nelts * sizeof (struct block *));
for (i = 0; i < ret.nelts; ++i)
{
+ struct blockvector *bl;
+ struct block *b;
+
+ set_current_program_space (ret.sals[i].pspace);
+
filter[i] = 1;
- blocks[i] = block_for_pc (ret.sals[i].pc);
+ blocks[i] = block_for_pc_sect (ret.sals[i].pc, ret.sals[i].section);
+
}
+ do_cleanups (old_chain);
for (i = 0; i < ret.nelts; ++i)
if (blocks[i] != NULL)
Valid values are \"ask\", \"all\", \"cancel\", and the default is \"all\"."),
NULL, NULL, &setlist, &showlist);
- /* Initialize the one built-in type that isn't language dependent... */
- builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0,
- "<unknown type>", (struct objfile *) NULL);
-
observer_attach_executable_changed (symtab_observer_executable_changed);
}