* linespec.c: Include "target.h".
(minsym_found): Handle minimal symbols pointing to function descriptors. Use find_function_start_pc. * minsyms.c (msymbol_objfile): New function. * parse.c (write_exp_msymbol): Handle minimal symbols pointing to function descriptors. * symtab.c (fixup_section): Only use minimal symbol at the same address to determine section of a symbol. (find_function_start_pc): New function. (find_function_start_sal): Use it. * symtab.h (msymbol_objfile): Add prototype. (find_function_start_pc): Likewise. * value.c: Include "objfiles.h". (value_fn_field): Handle minimal symbols pointing to function descriptors. * Makefile.in (linespec.o): Update dependencies. (value.o): Likewise.
This commit is contained in:
parent
0315afbc1d
commit
bccdca4a5f
@ -1,3 +1,23 @@
|
||||
2008-05-02 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* linespec.c: Include "target.h".
|
||||
(minsym_found): Handle minimal symbols pointing to function
|
||||
descriptors. Use find_function_start_pc.
|
||||
* minsyms.c (msymbol_objfile): New function.
|
||||
* parse.c (write_exp_msymbol): Handle minimal symbols pointing
|
||||
to function descriptors.
|
||||
* symtab.c (fixup_section): Only use minimal symbol at the same
|
||||
address to determine section of a symbol.
|
||||
(find_function_start_pc): New function.
|
||||
(find_function_start_sal): Use it.
|
||||
* symtab.h (msymbol_objfile): Add prototype.
|
||||
(find_function_start_pc): Likewise.
|
||||
* value.c: Include "objfiles.h".
|
||||
(value_fn_field): Handle minimal symbols pointing to function
|
||||
descriptors.
|
||||
* Makefile.in (linespec.o): Update dependencies.
|
||||
(value.o): Likewise.
|
||||
|
||||
2008-05-02 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* ada-lang.c (unwrap_value): Handle the case where the "F" field
|
||||
|
@ -2373,7 +2373,8 @@ libunwind-frame.o: libunwind-frame.c $(defs_h) $(inferior_h) $(frame_h) \
|
||||
linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \
|
||||
$(symfile_h) $(objfiles_h) $(source_h) $(demangle_h) $(value_h) \
|
||||
$(completer_h) $(cp_abi_h) $(parser_defs_h) $(block_h) $(interps_h) \
|
||||
$(objc_lang_h) $(linespec_h) $(exceptions_h) $(language_h) $(mi_cmds_h)
|
||||
$(objc_lang_h) $(linespec_h) $(exceptions_h) $(language_h) \
|
||||
$(mi_cmds_h) $(target_h)
|
||||
linux-fork.o: linux-fork.c $(defs_h) $(inferior_h) $(regcache_h) $(gdbcmd_h) \
|
||||
$(infcall_h) $(gdb_assert_h) $(gdb_string_h) $(linux_fork_h) \
|
||||
$(linux_nat_h) $(gdb_wait_h) $(gdb_dirent_h)
|
||||
@ -2967,7 +2968,7 @@ valprint.o: valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
|
||||
value.o: value.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
|
||||
$(value_h) $(gdbcore_h) $(command_h) $(gdbcmd_h) $(target_h) \
|
||||
$(language_h) $(demangle_h) $(doublest_h) \
|
||||
$(gdb_assert_h) $(regcache_h) $(block_h) $(dfp_h)
|
||||
$(gdb_assert_h) $(regcache_h) $(block_h) $(dfp_h) $(objfiles_h)
|
||||
varobj.o: varobj.c $(defs_h) $(exceptions_h) $(value_h) $(expression_h) \
|
||||
$(frame_h) $(language_h) $(wrapper_h) $(gdbcmd_h) $(block_h) \
|
||||
$(gdb_assert_h) $(gdb_string_h) $(varobj_h) $(vec_h) $(gdbthread_h) \
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "language.h"
|
||||
#include "interps.h"
|
||||
#include "mi/mi-cmds.h"
|
||||
#include "target.h"
|
||||
|
||||
/* We share this one with symtab.c, but it is not exported widely. */
|
||||
|
||||
@ -1846,21 +1847,32 @@ symbol_found (int funfirstline, char ***canonical, char *copy,
|
||||
static struct symtabs_and_lines
|
||||
minsym_found (int funfirstline, struct minimal_symbol *msymbol)
|
||||
{
|
||||
struct objfile *objfile = msymbol_objfile (msymbol);
|
||||
struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
||||
struct symtabs_and_lines values;
|
||||
CORE_ADDR pc;
|
||||
|
||||
values.sals = (struct symtab_and_line *)
|
||||
xmalloc (sizeof (struct symtab_and_line));
|
||||
values.sals[0] = find_pc_sect_line (SYMBOL_VALUE_ADDRESS (msymbol),
|
||||
(struct bfd_section *) 0, 0);
|
||||
values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
|
||||
|
||||
/* The minimal symbol might point to a function descriptor;
|
||||
resolve it to the actual code address instead. */
|
||||
pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
|
||||
values.sals[0].pc,
|
||||
¤t_target);
|
||||
if (pc != values.sals[0].pc)
|
||||
values.sals[0] = find_pc_sect_line (pc, NULL, 0);
|
||||
|
||||
if (funfirstline)
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
|
||||
values.sals[0].pc
|
||||
+= gdbarch_deprecated_function_start_offset (current_gdbarch);
|
||||
values.sals[0].pc = gdbarch_skip_prologue
|
||||
(current_gdbarch, values.sals[0].pc);
|
||||
values.sals[0].pc = find_function_start_pc (gdbarch,
|
||||
values.sals[0].pc,
|
||||
values.sals[0].section);
|
||||
|
||||
sal = find_pc_sect_line (values.sals[0].pc, values.sals[0].section, 0);
|
||||
|
||||
|
@ -132,6 +132,26 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
|
||||
}
|
||||
|
||||
|
||||
/* Return OBJFILE where minimal symbol SYM is defined. */
|
||||
struct objfile *
|
||||
msymbol_objfile (struct minimal_symbol *sym)
|
||||
{
|
||||
struct objfile *objf;
|
||||
struct minimal_symbol *tsym;
|
||||
|
||||
unsigned int hash
|
||||
= msymbol_hash (SYMBOL_LINKAGE_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
|
||||
|
||||
for (objf = object_files; objf; objf = objf->next)
|
||||
for (tsym = objf->msymbol_hash[hash]; tsym; tsym = tsym->hash_next)
|
||||
if (tsym == sym)
|
||||
return objf;
|
||||
|
||||
/* We should always be able to find the objfile ... */
|
||||
internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
|
||||
}
|
||||
|
||||
|
||||
/* Look through all the current minimal symbol tables and find the
|
||||
first minimal symbol that matches NAME. If OBJF is non-NULL, limit
|
||||
the search to that objfile. If SFILE is non-NULL, the only file-scope
|
||||
|
43
gdb/parse.c
43
gdb/parse.c
@ -400,39 +400,46 @@ write_exp_msymbol (struct minimal_symbol *msymbol,
|
||||
struct type *text_symbol_type,
|
||||
struct type *data_symbol_type)
|
||||
{
|
||||
struct gdbarch *gdbarch = current_gdbarch;
|
||||
CORE_ADDR addr;
|
||||
struct objfile *objfile = msymbol_objfile (msymbol);
|
||||
struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
||||
|
||||
CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (msymbol);
|
||||
asection *bfd_section = SYMBOL_BFD_SECTION (msymbol);
|
||||
enum minimal_symbol_type type = msymbol->type;
|
||||
CORE_ADDR pc;
|
||||
|
||||
/* The minimal symbol might point to a function descriptor;
|
||||
resolve it to the actual code address instead. */
|
||||
pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, ¤t_target);
|
||||
if (pc != addr)
|
||||
{
|
||||
/* In this case, assume we have a code symbol instead of
|
||||
a data symbol. */
|
||||
type = mst_text;
|
||||
bfd_section = NULL;
|
||||
addr = pc;
|
||||
}
|
||||
|
||||
if (overlay_debugging)
|
||||
addr = symbol_overlayed_address (addr, bfd_section);
|
||||
|
||||
write_exp_elt_opcode (OP_LONG);
|
||||
/* Let's make the type big enough to hold a 64-bit address. */
|
||||
write_exp_elt_type (builtin_type_CORE_ADDR);
|
||||
|
||||
addr = SYMBOL_VALUE_ADDRESS (msymbol);
|
||||
if (overlay_debugging)
|
||||
addr = symbol_overlayed_address (addr, SYMBOL_BFD_SECTION (msymbol));
|
||||
write_exp_elt_longcst ((LONGEST) addr);
|
||||
|
||||
write_exp_elt_opcode (OP_LONG);
|
||||
|
||||
if (SYMBOL_BFD_SECTION (msymbol)
|
||||
&& SYMBOL_BFD_SECTION (msymbol)->flags & SEC_THREAD_LOCAL)
|
||||
if (bfd_section && bfd_section->flags & SEC_THREAD_LOCAL)
|
||||
{
|
||||
bfd *bfd = SYMBOL_BFD_SECTION (msymbol)->owner;
|
||||
struct objfile *ofp;
|
||||
|
||||
ALL_OBJFILES (ofp)
|
||||
if (ofp->obfd == bfd)
|
||||
break;
|
||||
|
||||
write_exp_elt_opcode (UNOP_MEMVAL_TLS);
|
||||
write_exp_elt_objfile (ofp);
|
||||
write_exp_elt_objfile (objfile);
|
||||
write_exp_elt_type (builtin_type (gdbarch)->nodebug_tls_symbol);
|
||||
write_exp_elt_opcode (UNOP_MEMVAL_TLS);
|
||||
return;
|
||||
}
|
||||
|
||||
write_exp_elt_opcode (UNOP_MEMVAL);
|
||||
switch (msymbol->type)
|
||||
switch (type)
|
||||
{
|
||||
case mst_text:
|
||||
case mst_file_text:
|
||||
|
57
gdb/symtab.c
57
gdb/symtab.c
@ -998,7 +998,13 @@ fixup_section (struct general_symbol_info *ginfo, struct objfile *objfile)
|
||||
struct minimal_symbol *msym;
|
||||
msym = lookup_minimal_symbol (ginfo->name, NULL, objfile);
|
||||
|
||||
if (msym)
|
||||
/* First, check whether a minimal symbol with the same name exists
|
||||
and points to the same address. The address check is required
|
||||
e.g. on PowerPC64, where the minimal symbol for a function will
|
||||
point to the function descriptor, while the debug symbol will
|
||||
point to the actual function code. */
|
||||
if (msym
|
||||
&& SYMBOL_VALUE_ADDRESS (msym) == ginfo->value.address)
|
||||
{
|
||||
ginfo->bfd_section = SYMBOL_BFD_SECTION (msym);
|
||||
ginfo->section = SYMBOL_SECTION (msym);
|
||||
@ -2530,6 +2536,26 @@ find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
|
||||
return sal.symtab != 0;
|
||||
}
|
||||
|
||||
/* Given a function start address PC and SECTION, find the first
|
||||
address after the function prologue. */
|
||||
CORE_ADDR
|
||||
find_function_start_pc (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc, asection *section)
|
||||
{
|
||||
/* If the function is in an unmapped overlay, use its unmapped LMA address,
|
||||
so that gdbarch_skip_prologue has something unique to work on. */
|
||||
if (section_is_overlay (section) && !section_is_mapped (section))
|
||||
pc = overlay_unmapped_address (pc, section);
|
||||
|
||||
pc += gdbarch_deprecated_function_start_offset (gdbarch);
|
||||
pc = gdbarch_skip_prologue (gdbarch, pc);
|
||||
|
||||
/* For overlays, map pc back into its mapped VMA range. */
|
||||
pc = overlay_mapped_address (pc, section);
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
/* 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
|
||||
@ -2538,34 +2564,27 @@ find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
|
||||
struct symtab_and_line
|
||||
find_function_start_sal (struct symbol *sym, int funfirstline)
|
||||
{
|
||||
struct block *block = SYMBOL_BLOCK_VALUE (sym);
|
||||
struct objfile *objfile = lookup_objfile_from_block (block);
|
||||
struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
||||
|
||||
CORE_ADDR pc;
|
||||
struct symtab_and_line sal;
|
||||
|
||||
pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
|
||||
fixup_symbol_section (sym, NULL);
|
||||
pc = BLOCK_START (block);
|
||||
fixup_symbol_section (sym, objfile);
|
||||
if (funfirstline)
|
||||
{ /* skip "first line" of function (which is actually its prologue) */
|
||||
asection *section = SYMBOL_BFD_SECTION (sym);
|
||||
/* If function is in an unmapped overlay, use its unmapped LMA
|
||||
address, so that gdbarch_skip_prologue has something unique to work
|
||||
on */
|
||||
if (section_is_overlay (section) &&
|
||||
!section_is_mapped (section))
|
||||
pc = overlay_unmapped_address (pc, section);
|
||||
|
||||
pc += gdbarch_deprecated_function_start_offset (current_gdbarch);
|
||||
pc = gdbarch_skip_prologue (current_gdbarch, pc);
|
||||
|
||||
/* For overlays, map pc back into its mapped VMA range */
|
||||
pc = overlay_mapped_address (pc, section);
|
||||
{
|
||||
/* Skip "first line" of function (which is actually its prologue). */
|
||||
pc = find_function_start_pc (gdbarch, pc, SYMBOL_BFD_SECTION (sym));
|
||||
}
|
||||
sal = find_pc_sect_line (pc, SYMBOL_BFD_SECTION (sym), 0);
|
||||
|
||||
/* Check if gdbarch_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)))
|
||||
&& BLOCK_START (block) <= sal.end
|
||||
&& sal.end < BLOCK_END (block))
|
||||
{
|
||||
/* First pc of next line */
|
||||
pc = sal.end;
|
||||
|
@ -1168,6 +1168,8 @@ extern unsigned int msymbol_hash_iw (const char *);
|
||||
|
||||
extern unsigned int msymbol_hash (const char *);
|
||||
|
||||
extern struct objfile * msymbol_objfile (struct minimal_symbol *sym);
|
||||
|
||||
extern void
|
||||
add_minsym_to_hash_table (struct minimal_symbol *sym,
|
||||
struct minimal_symbol **table);
|
||||
@ -1342,6 +1344,9 @@ extern struct partial_symtab *find_main_psymtab (void);
|
||||
|
||||
extern struct symtab *find_line_symtab (struct symtab *, int, int *, int *);
|
||||
|
||||
extern CORE_ADDR find_function_start_pc (struct gdbarch *,
|
||||
CORE_ADDR, asection *);
|
||||
|
||||
extern struct symtab_and_line find_function_start_sal (struct symbol *sym,
|
||||
int);
|
||||
|
||||
|
10
gdb/value.c
10
gdb/value.c
@ -35,6 +35,7 @@
|
||||
#include "regcache.h"
|
||||
#include "block.h"
|
||||
#include "dfp.h"
|
||||
#include "objfiles.h"
|
||||
|
||||
/* Prototypes for exported functions. */
|
||||
|
||||
@ -1433,7 +1434,14 @@ value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *ty
|
||||
}
|
||||
else
|
||||
{
|
||||
VALUE_ADDRESS (v) = SYMBOL_VALUE_ADDRESS (msym);
|
||||
/* The minimal symbol might point to a function descriptor;
|
||||
resolve it to the actual code address instead. */
|
||||
struct objfile *objfile = msymbol_objfile (msym);
|
||||
struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
||||
|
||||
VALUE_ADDRESS (v)
|
||||
= gdbarch_convert_from_func_ptr_addr
|
||||
(gdbarch, SYMBOL_VALUE_ADDRESS (msym), ¤t_target);
|
||||
}
|
||||
|
||||
if (arg1p)
|
||||
|
Loading…
x
Reference in New Issue
Block a user