aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2009-09-29 00:48:32 +0000
committerUlrich Weigand <uweigand@de.ibm.com>2009-09-29 00:48:32 +0000
commit69368a60a4878ec4ef1060732020e9eaf19b32b0 (patch)
treee42355f5c9bd92ed24f12457f1b50f24f1b216f8 /gdb
parent67f470de12c95c08410c46543072c22f857a0a3b (diff)
downloadgdb-69368a60a4878ec4ef1060732020e9eaf19b32b0.zip
gdb-69368a60a4878ec4ef1060732020e9eaf19b32b0.tar.gz
gdb-69368a60a4878ec4ef1060732020e9eaf19b32b0.tar.bz2
* 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.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog13
-rw-r--r--gdb/eval.c24
-rw-r--r--gdb/linespec.c18
-rw-r--r--gdb/objc-lang.c16
-rw-r--r--gdb/ppc-sysv-tdep.c10
5 files changed, 61 insertions, 20 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b9e6b1e..2447062 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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>
Fix ia64 breakpoints in the L-X slot.
diff --git a/gdb/eval.c b/gdb/eval.c
index 2926465..a1d6e12 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1161,8 +1161,13 @@ evaluate_subexp_standard (struct type *expect_type,
if (addr)
{
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,
+ &current_target);
+
+ /* Is it a high_level symbol? */
sym = find_pc_function (addr);
if (sym != NULL)
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)
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)
- 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
- set_value_address (method, value_as_address (msg_send));
- called_method = method;
+ called_method
+ = value_from_pointer (lookup_pointer_type (value_type (method)),
+ value_as_address (msg_send));
}
else
{
@@ -1275,7 +1289,7 @@ evaluate_subexp_standard (struct type *expect_type,
{
/* Function objc_msg_lookup returns a pointer. */
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);
}
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 70e27f76..19df329 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -1172,11 +1172,19 @@ decode_objc (char **argptr, int funfirstline, struct symtab *file_symtab,
}
else
{
- /* The only match was a non-debuggable symbol. */
- values.sals[0].symtab = NULL;
- values.sals[0].line = 0;
- values.sals[0].end = 0;
- values.sals[0].pc = SYMBOL_VALUE_ADDRESS (sym_arr[0]);
+ /* The only match was a non-debuggable symbol, which might point
+ to a function descriptor; resolve it to the actual code address
+ instead. */
+ struct minimal_symbol *msymbol = (struct minimal_symbol *)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,
+ &current_target);
+
+ init_sal (&values.sals[0]);
+ values.sals[0].pc = pc;
}
return values;
}
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index 0e4fb71..f3a8b73 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -1173,16 +1173,18 @@ find_methods (struct symtab *symtab, char type,
ALL_OBJFILE_MSYMBOLS (objfile, msymbol)
{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ CORE_ADDR pc = SYMBOL_VALUE_ADDRESS (msymbol);
+
QUIT;
- if ((MSYMBOL_TYPE (msymbol) != mst_text)
- && (MSYMBOL_TYPE (msymbol) != mst_file_text))
- /* Not a function or method. */
- continue;
+ /* 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, pc,
+ &current_target);
if (symtab)
- if ((SYMBOL_VALUE_ADDRESS (msymbol) < BLOCK_START (block)) ||
- (SYMBOL_VALUE_ADDRESS (msymbol) >= BLOCK_END (block)))
+ if (pc < BLOCK_START (block) || pc >= BLOCK_END (block))
/* Not in the specified symtab. */
continue;
@@ -1221,7 +1223,7 @@ find_methods (struct symtab *symtab, char type,
((nselector == NULL) || (strcmp (selector, nselector) != 0)))
continue;
- sym = find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol));
+ sym = find_pc_function (pc);
if (sym != NULL)
{
const char *newsymname = SYMBOL_NATURAL_NAME (sym);
diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c
index 703ca4d..031ec52 100644
--- a/gdb/ppc-sysv-tdep.c
+++ b/gdb/ppc-sysv-tdep.c
@@ -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);
/* 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;
- if (convert_code_addr_to_desc_addr (func_addr, &desc_addr))
+ struct type *ftype = check_typedef (value_type (function));
+ 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. */
CORE_ADDR toc =