* eval.c (evaluate_subexp_standard) [OP_OBJC_MSGCALL]: Support
authorUlrich Weigand <uweigand@de.ibm.com>
Tue, 29 Sep 2009 00:48:32 +0000 (00:48 +0000)
committerUlrich Weigand <uweigand@de.ibm.com>
Tue, 29 Sep 2009 00:48:32 +0000 (00:48 +0000)
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.

gdb/ChangeLog
gdb/eval.c
gdb/linespec.c
gdb/objc-lang.c
gdb/ppc-sysv-tdep.c

index b9e6b1ec66e39f120575635152847f87e6f4c999..2447062cb0ed9b2ebed358b09ffc5f40df0c8669 100644 (file)
@@ -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.
index 2926465c418797f5f381fee85088277901ca70ae..a1d6e124d5302b33ddfce6d20646b2f88aba6584 100644 (file)
@@ -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);
          }
 
index 70e27f7683c3c22a8306ee28b540f45db5b7f9ea..19df329f45ef375bbff44f025d6db945dd63d3b7 100644 (file)
@@ -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;
     }
index 0e4fb71965b2a9443e55ec5e343246363a1b5a63..f3a8b7308fb3701ce3054e641cb38f396a605e7d 100644 (file)
@@ -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);
index 703ca4db40a314450f5e395f650ea5a676fe950e..031ec52da0267cb272356addc4636deb780934ad 100644 (file)
@@ -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 =