* eval.c (evaluate_subexp_standard) [OP_OBJC_MSGCALL]: Support
platforms that use function descriptors. Prefer to use function pointer types instead of function types. * linespec.c (decode_objc): Support function descriptors. Fully initialize SAL result. * objc-lang.c (find_methods): Support function descriptors. Do not require function symbol to point to text section. * ppc-sysv-tdep.c (ppc64_sysv_abi_push_dummy_call): When calling via a function pointer, use the descriptor it points to.
This commit is contained in:
parent
67f470de12
commit
69368a60a4
5 changed files with 61 additions and 20 deletions
|
@ -1,3 +1,16 @@
|
||||||
|
2009-09-28 Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
|
* eval.c (evaluate_subexp_standard) [OP_OBJC_MSGCALL]: Support
|
||||||
|
platforms that use function descriptors. Prefer to use function
|
||||||
|
pointer types instead of function types.
|
||||||
|
* linespec.c (decode_objc): Support function descriptors. Fully
|
||||||
|
initialize SAL result.
|
||||||
|
* objc-lang.c (find_methods): Support function descriptors.
|
||||||
|
Do not require function symbol to point to text section.
|
||||||
|
|
||||||
|
* ppc-sysv-tdep.c (ppc64_sysv_abi_push_dummy_call): When calling
|
||||||
|
via a function pointer, use the descriptor it points to.
|
||||||
|
|
||||||
2009-09-28 Jan Kratochvil <jan.kratochvil@redhat.com>
|
2009-09-28 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
Fix ia64 breakpoints in the L-X slot.
|
Fix ia64 breakpoints in the L-X slot.
|
||||||
|
|
24
gdb/eval.c
24
gdb/eval.c
|
@ -1161,8 +1161,13 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||||
if (addr)
|
if (addr)
|
||||||
{
|
{
|
||||||
struct symbol *sym = NULL;
|
struct symbol *sym = NULL;
|
||||||
/* Is it a high_level symbol? */
|
|
||||||
|
|
||||||
|
/* The address might point to a function descriptor;
|
||||||
|
resolve it to the actual code address instead. */
|
||||||
|
addr = gdbarch_convert_from_func_ptr_addr (exp->gdbarch, addr,
|
||||||
|
¤t_target);
|
||||||
|
|
||||||
|
/* Is it a high_level symbol? */
|
||||||
sym = find_pc_function (addr);
|
sym = find_pc_function (addr);
|
||||||
if (sym != NULL)
|
if (sym != NULL)
|
||||||
method = value_of_variable (sym, 0);
|
method = value_of_variable (sym, 0);
|
||||||
|
@ -1216,11 +1221,20 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||||
{
|
{
|
||||||
if (TYPE_CODE (value_type (method)) != TYPE_CODE_FUNC)
|
if (TYPE_CODE (value_type (method)) != TYPE_CODE_FUNC)
|
||||||
error (_("method address has symbol information with non-function type; skipping"));
|
error (_("method address has symbol information with non-function type; skipping"));
|
||||||
|
|
||||||
|
/* Create a function pointer of the appropriate type, and replace
|
||||||
|
its value with the value of msg_send or msg_send_stret. We must
|
||||||
|
use a pointer here, as msg_send and msg_send_stret are of pointer
|
||||||
|
type, and the representation may be different on systems that use
|
||||||
|
function descriptors. */
|
||||||
if (struct_return)
|
if (struct_return)
|
||||||
set_value_address (method, value_as_address (msg_send_stret));
|
called_method
|
||||||
|
= value_from_pointer (lookup_pointer_type (value_type (method)),
|
||||||
|
value_as_address (msg_send_stret));
|
||||||
else
|
else
|
||||||
set_value_address (method, value_as_address (msg_send));
|
called_method
|
||||||
called_method = method;
|
= value_from_pointer (lookup_pointer_type (value_type (method)),
|
||||||
|
value_as_address (msg_send));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1275,7 +1289,7 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||||
{
|
{
|
||||||
/* Function objc_msg_lookup returns a pointer. */
|
/* Function objc_msg_lookup returns a pointer. */
|
||||||
deprecated_set_value_type (argvec[0],
|
deprecated_set_value_type (argvec[0],
|
||||||
lookup_function_type (lookup_pointer_type (value_type (argvec[0]))));
|
lookup_pointer_type (lookup_function_type (value_type (argvec[0]))));
|
||||||
argvec[0] = call_function_by_hand (argvec[0], nargs + 2, argvec + 1);
|
argvec[0] = call_function_by_hand (argvec[0], nargs + 2, argvec + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1172,11 +1172,19 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The only match was a non-debuggable symbol. */
|
/* The only match was a non-debuggable symbol, which might point
|
||||||
values.sals[0].symtab = NULL;
|
to a function descriptor; resolve it to the actual code address
|
||||||
values.sals[0].line = 0;
|
instead. */
|
||||||
values.sals[0].end = 0;
|
struct minimal_symbol *msymbol = (struct minimal_symbol *)sym_arr[0];
|
||||||
values.sals[0].pc = SYMBOL_VALUE_ADDRESS (sym_arr[0]);
|
struct objfile *objfile = msymbol_objfile (msymbol);
|
||||||
|
struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
||||||
|
CORE_ADDR pc = SYMBOL_VALUE_ADDRESS (msymbol);
|
||||||
|
|
||||||
|
pc = gdbarch_convert_from_func_ptr_addr (gdbarch, pc,
|
||||||
|
¤t_target);
|
||||||
|
|
||||||
|
init_sal (&values.sals[0]);
|
||||||
|
values.sals[0].pc = pc;
|
||||||
}
|
}
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1173,16 +1173,18 @@ find_methods (struct symtab *symtab, char type,
|
||||||
|
|
||||||
ALL_OBJFILE_MSYMBOLS (objfile, msymbol)
|
ALL_OBJFILE_MSYMBOLS (objfile, msymbol)
|
||||||
{
|
{
|
||||||
|
struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
||||||
|
CORE_ADDR pc = SYMBOL_VALUE_ADDRESS (msymbol);
|
||||||
|
|
||||||
QUIT;
|
QUIT;
|
||||||
|
|
||||||
if ((MSYMBOL_TYPE (msymbol) != mst_text)
|
/* The minimal symbol might point to a function descriptor;
|
||||||
&& (MSYMBOL_TYPE (msymbol) != mst_file_text))
|
resolve it to the actual code address instead. */
|
||||||
/* Not a function or method. */
|
pc = gdbarch_convert_from_func_ptr_addr (gdbarch, pc,
|
||||||
continue;
|
¤t_target);
|
||||||
|
|
||||||
if (symtab)
|
if (symtab)
|
||||||
if ((SYMBOL_VALUE_ADDRESS (msymbol) < BLOCK_START (block)) ||
|
if (pc < BLOCK_START (block) || pc >= BLOCK_END (block))
|
||||||
(SYMBOL_VALUE_ADDRESS (msymbol) >= BLOCK_END (block)))
|
|
||||||
/* Not in the specified symtab. */
|
/* Not in the specified symtab. */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1221,7 +1223,7 @@ find_methods (struct symtab *symtab, char type,
|
||||||
((nselector == NULL) || (strcmp (selector, nselector) != 0)))
|
((nselector == NULL) || (strcmp (selector, nselector) != 0)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sym = find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol));
|
sym = find_pc_function (pc);
|
||||||
if (sym != NULL)
|
if (sym != NULL)
|
||||||
{
|
{
|
||||||
const char *newsymname = SYMBOL_NATURAL_NAME (sym);
|
const char *newsymname = SYMBOL_NATURAL_NAME (sym);
|
||||||
|
|
|
@ -1326,10 +1326,14 @@ ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
|
||||||
regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);
|
regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);
|
||||||
|
|
||||||
/* Use the func_addr to find the descriptor, and use that to find
|
/* Use the func_addr to find the descriptor, and use that to find
|
||||||
the TOC. */
|
the TOC. If we're calling via a function pointer, the pointer
|
||||||
|
itself identifies the descriptor. */
|
||||||
{
|
{
|
||||||
CORE_ADDR desc_addr;
|
struct type *ftype = check_typedef (value_type (function));
|
||||||
if (convert_code_addr_to_desc_addr (func_addr, &desc_addr))
|
CORE_ADDR desc_addr = value_as_address (function);
|
||||||
|
|
||||||
|
if (TYPE_CODE (ftype) == TYPE_CODE_PTR
|
||||||
|
|| convert_code_addr_to_desc_addr (func_addr, &desc_addr))
|
||||||
{
|
{
|
||||||
/* The TOC is the second double word in the descriptor. */
|
/* The TOC is the second double word in the descriptor. */
|
||||||
CORE_ADDR toc =
|
CORE_ADDR toc =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue