diff options
Diffstat (limited to 'gdb/block.c')
-rw-r--r-- | gdb/block.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/gdb/block.c b/gdb/block.c index 776ae53..c165bc2 100644 --- a/gdb/block.c +++ b/gdb/block.c @@ -25,6 +25,8 @@ #include "gdb_obstack.h" #include "cp-support.h" #include "addrmap.h" +#include "gdbtypes.h" +#include "exceptions.h" /* This is used by struct block to store namespace-related info for C++ files, namely using declarations and the current namespace in @@ -160,6 +162,38 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section, return 0; } +/* Return call_site for specified PC in GDBARCH. PC must match exactly, it + must be the next instruction after call (or after tail call jump). Throw + NO_ENTRY_VALUE_ERROR otherwise. This function never returns NULL. */ + +struct call_site * +call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + struct symtab *symtab; + void **slot = NULL; + + /* -1 as tail call PC can be already after the compilation unit range. */ + symtab = find_pc_symtab (pc - 1); + + if (symtab != NULL && symtab->call_site_htab != NULL) + slot = htab_find_slot (symtab->call_site_htab, &pc, NO_INSERT); + + if (slot == NULL) + { + struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (pc); + + /* DW_TAG_gnu_call_site will be missing just if GCC could not determine + the call target. */ + throw_error (NO_ENTRY_VALUE_ERROR, + _("DW_OP_GNU_entry_value resolving cannot find " + "DW_TAG_GNU_call_site %s in %s"), + paddress (gdbarch, pc), + msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); + } + + return *slot; +} + /* Return the blockvector immediately containing the innermost lexical block containing the specified pc value, or 0 if there is none. Backward compatibility, no section. */ |