1 /* Objective C language support routines for GDB, the GNU debugger.
2 Copyright 1996 NeXT Software, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "expression.h"
24 #include "parser-defs.h"
26 #include "objc-lang.h"
27 #include "complaints.h"
31 #include "string.h" /* for strchr */
32 #include "target.h" /* for target_has_execution */
36 #include "gdb_regex.h"
47 CORE_ADDR super_class
;
69 /* Complaints about ObjC classes, selectors, etc. */
71 static struct complaint noclass_lookup_complaint
=
72 {"no way to lookup Objective-C classes", 0, 0};
74 static struct complaint nosel_lookup_complaint
=
75 {"no way to lookup Objective-C selectors", 0, 0};
78 #if (!defined __GNUC__ || __GNUC__ < 2 || __GNUC_MINOR__ < (defined __cplusplus ? 6 : 4))
79 #define __CHECK_FUNCTION ((__const char *) 0)
81 #define __CHECK_FUNCTION __PRETTY_FUNCTION__
84 #define CHECK(expression) \
85 ((void) ((expression) ? 0 : gdb_check (#expression, __FILE__, __LINE__, \
88 #define CHECK_FATAL(expression) \
89 ((void) ((expression) ? 0 : gdb_check_fatal (#expression, __FILE__, \
90 __LINE__, __CHECK_FUNCTION)))
93 gdb_check (const char *str
, const char *file
, unsigned int line
,
96 error ("assertion failure on line %u of \"%s\" in function \"%s\": %s\n",
97 line
, file
, func
, str
);
101 gdb_check_fatal (const char *str
, const char *file
, unsigned int line
,
104 internal_error (file
, line
,
105 "assertion failure in function \"%s\": %s\n", func
, str
);
108 /* Lookup a structure type named "struct NAME",
109 visible in lexical block BLOCK.
110 If NOERR is nonzero, return zero if NAME is not suitably defined. */
113 lookup_struct_typedef (char *name
, struct block
*block
, int noerr
)
115 register struct symbol
*sym
;
117 sym
= lookup_symbol (name
, block
, STRUCT_NAMESPACE
, 0, (struct symtab
**) NULL
);
124 error ("No struct type named %s.", name
);
126 if (TYPE_CODE (SYMBOL_TYPE (sym
)) != TYPE_CODE_STRUCT
)
131 error ("This context has class, union or enum %s, not a struct.", name
);
137 lookup_objc_class (char *classname
)
139 struct value
* function
, *classval
;
141 if (! target_has_execution
)
143 /* can't call into inferior to lookup class */
147 if (lookup_minimal_symbol("objc_lookUpClass", 0, 0))
148 function
= find_function_in_inferior("objc_lookUpClass");
149 else if (lookup_minimal_symbol ("objc_lookup_class", 0, 0))
150 function
= find_function_in_inferior("objc_lookup_class");
153 complain (&noclass_lookup_complaint
, 0);
157 classval
= value_string (classname
, strlen (classname
) + 1);
158 classval
= value_coerce_array (classval
);
159 return (CORE_ADDR
) value_as_long (call_function_by_hand (function
,
164 lookup_child_selector (char *selname
)
166 struct value
* function
, *selstring
;
168 if (! target_has_execution
)
170 /* can't call into inferior to lookup selector */
174 if (lookup_minimal_symbol("sel_getUid", 0, 0))
175 function
= find_function_in_inferior("sel_getUid");
176 else if (lookup_minimal_symbol ("sel_get_any_uid", 0, 0))
177 function
= find_function_in_inferior("sel_get_any_uid");
180 complain (&nosel_lookup_complaint
, 0);
184 selstring
= value_coerce_array (value_string (selname
, strlen (selname
) + 1));
185 return value_as_long (call_function_by_hand (function
, 1, &selstring
));
189 value_nsstring (char *ptr
, int len
)
191 struct value
*stringValue
[3];
192 struct value
*function
, *nsstringValue
;
196 if (!target_has_execution
)
197 return 0; /* can't call into inferior to create NSString */
199 if (!(sym
= lookup_struct_typedef("NSString", 0, 1)) &&
200 !(sym
= lookup_struct_typedef("NXString", 0, 1)))
201 type
= lookup_pointer_type(builtin_type_void
);
203 type
= lookup_pointer_type(SYMBOL_TYPE (sym
));
205 stringValue
[2] = value_string(ptr
, len
);
206 stringValue
[2] = value_coerce_array(stringValue
[2]);
207 /* _NSNewStringFromCString replaces "istr" after Lantern2A */
208 if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0))
210 function
= find_function_in_inferior("_NSNewStringFromCString");
211 nsstringValue
= call_function_by_hand(function
, 1, &stringValue
[2]);
213 else if (lookup_minimal_symbol("istr", 0, 0))
215 function
= find_function_in_inferior("istr");
216 nsstringValue
= call_function_by_hand(function
, 1, &stringValue
[2]);
218 else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0))
220 function
= find_function_in_inferior("+[NSString stringWithCString:]");
221 stringValue
[0] = value_from_longest
222 (builtin_type_long
, lookup_objc_class ("NSString"));
223 stringValue
[1] = value_from_longest
224 (builtin_type_long
, lookup_child_selector ("stringWithCString:"));
225 nsstringValue
= call_function_by_hand(function
, 3, &stringValue
[0]);
228 error ("NSString: internal error -- no way to create new NSString");
230 VALUE_TYPE(nsstringValue
) = type
;
231 return nsstringValue
;
234 /* Objective C name demangling */
237 objc_demangle (const char *mangled
)
239 char *demangled
, *cp
;
241 if (mangled
[0] == '_' &&
242 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
245 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
247 if (mangled
[1] == 'i')
248 *cp
++ = '-'; /* for instance method */
250 *cp
++ = '+'; /* for class method */
252 *cp
++ = '['; /* opening left brace */
253 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
255 while (*cp
&& *cp
== '_')
256 cp
++; /* skip any initial underbars in class name */
258 if (!(cp
= strchr(cp
, '_'))) /* find first non-initial underbar */
260 free(demangled
); /* not mangled name */
263 if (cp
[1] == '_') { /* easy case: no category name */
264 *cp
++ = ' '; /* replace two '_' with one ' ' */
265 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
268 *cp
++ = '('; /* less easy case: category name */
269 if (!(cp
= strchr(cp
, '_')))
271 free(demangled
); /* not mangled name */
275 *cp
++ = ' '; /* overwriting 1st char of method name... */
276 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
279 while (*cp
&& *cp
== '_')
280 cp
++; /* skip any initial underbars in method name */
284 *cp
= ':'; /* replace remaining '_' with ':' */
286 *cp
++ = ']'; /* closing right brace */
287 *cp
++ = 0; /* string terminator */
291 return NULL
; /* not an objc mangled name */
294 /* Print the character C on STREAM as part of the contents of a literal
295 string whose delimiter is QUOTER. Note that that format for printing
296 characters and strings is language specific. */
299 objc_emit_char (register int c
, struct ui_file
*stream
, int quoter
)
302 c
&= 0xFF; /* Avoid sign bit follies */
304 if (PRINT_LITERAL_FORM (c
))
306 if (c
== '\\' || c
== quoter
)
308 fputs_filtered ("\\", stream
);
310 fprintf_filtered (stream
, "%c", c
);
317 fputs_filtered ("\\n", stream
);
320 fputs_filtered ("\\b", stream
);
323 fputs_filtered ("\\t", stream
);
326 fputs_filtered ("\\f", stream
);
329 fputs_filtered ("\\r", stream
);
332 fputs_filtered ("\\e", stream
);
335 fputs_filtered ("\\a", stream
);
338 fprintf_filtered (stream
, "\\%.3o", (unsigned int) c
);
345 objc_printchar (int c
, struct ui_file
*stream
)
347 fputs_filtered ("'", stream
);
348 objc_emit_char (c
, stream
, '\'');
349 fputs_filtered ("'", stream
);
352 /* Print the character string STRING, printing at most LENGTH characters.
353 Printing stops early if the number hits print_max; repeat counts
354 are printed as appropriate. Print ellipses at the end if we
355 had to stop before printing LENGTH characters, or if FORCE_ELLIPSES. */
358 objc_printstr (struct ui_file
*stream
, char *string
, unsigned int length
,
361 register unsigned int i
;
362 unsigned int things_printed
= 0;
365 extern int inspect_it
;
366 extern int repeat_count_threshold
;
367 extern int print_max
;
369 /* If the string was not truncated due to `set print elements', and
370 the last byte of it is a null, we don't print that, in traditional C
372 if ((!force_ellipses
) && length
> 0 && string
[length
-1] == '\0')
377 fputs_filtered ("\"\"", stream
);
381 for (i
= 0; i
< length
&& things_printed
< print_max
; ++i
)
383 /* Position of the character we are examining
384 to see whether it is repeated. */
386 /* Number of repetitions we have detected so far. */
393 fputs_filtered (", ", stream
);
399 while (rep1
< length
&& string
[rep1
] == string
[i
])
405 if (reps
> repeat_count_threshold
)
410 fputs_filtered ("\\\", ", stream
);
412 fputs_filtered ("\", ", stream
);
415 objc_printchar (string
[i
], stream
);
416 fprintf_filtered (stream
, " <repeats %u times>", reps
);
418 things_printed
+= repeat_count_threshold
;
426 fputs_filtered ("\\\"", stream
);
428 fputs_filtered ("\"", stream
);
431 objc_emit_char (string
[i
], stream
, '"');
436 /* Terminate the quotes if necessary. */
440 fputs_filtered ("\\\"", stream
);
442 fputs_filtered ("\"", stream
);
445 if (force_ellipses
|| i
< length
)
446 fputs_filtered ("...", stream
);
449 /* Create a fundamental C type using default reasonable for the current
452 Some object/debugging file formats (DWARF version 1, COFF, etc) do not
453 define fundamental types such as "int" or "double". Others (stabs or
454 DWARF version 2, etc) do define fundamental types. For the formats which
455 don't provide fundamental types, gdb can create such types using this
458 FIXME: Some compilers distinguish explicitly signed integral types
459 (signed short, signed int, signed long) from "regular" integral types
460 (short, int, long) in the debugging information. There is some dis-
461 agreement as to how useful this feature is. In particular, gcc does
462 not support this. Also, only some debugging formats allow the
463 distinction to be passed on to a debugger. For now, we always just
464 use "short", "int", or "long" as the type name, for both the implicit
465 and explicitly signed types. This also makes life easier for the
466 gdb test suite since we don't have to account for the differences
467 in output depending upon what the compiler and debugging format
468 support. We will probably have to re-examine the issue when gdb
469 starts taking it's fundamental type information directly from the
470 debugging information supplied by the compiler. fnf@cygnus.com */
473 objc_create_fundamental_type (struct objfile
*objfile
, int typeid)
475 register struct type
*type
= NULL
;
480 /* FIXME: For now, if we are asked to produce a type not in this
481 language, create the equivalent of a C integer type with the
482 name "<?type?>". When all the dust settles from the type
483 reconstruction work, this should probably become an error. */
484 type
= init_type (TYPE_CODE_INT
,
485 TARGET_INT_BIT
/ TARGET_CHAR_BIT
,
486 0, "<?type?>", objfile
);
487 warning ("internal error: no C/C++ fundamental type %d", typeid);
490 type
= init_type (TYPE_CODE_VOID
,
491 TARGET_CHAR_BIT
/ TARGET_CHAR_BIT
,
495 type
= init_type (TYPE_CODE_INT
,
496 TARGET_CHAR_BIT
/ TARGET_CHAR_BIT
,
500 type
= init_type (TYPE_CODE_INT
,
501 TARGET_CHAR_BIT
/ TARGET_CHAR_BIT
,
502 0, "signed char", objfile
);
504 case FT_UNSIGNED_CHAR
:
505 type
= init_type (TYPE_CODE_INT
,
506 TARGET_CHAR_BIT
/ TARGET_CHAR_BIT
,
507 TYPE_FLAG_UNSIGNED
, "unsigned char", objfile
);
510 type
= init_type (TYPE_CODE_INT
,
511 TARGET_SHORT_BIT
/ TARGET_CHAR_BIT
,
512 0, "short", objfile
);
514 case FT_SIGNED_SHORT
:
515 type
= init_type (TYPE_CODE_INT
,
516 TARGET_SHORT_BIT
/ TARGET_CHAR_BIT
,
517 0, "short", objfile
); /* FIXME-fnf */
519 case FT_UNSIGNED_SHORT
:
520 type
= init_type (TYPE_CODE_INT
,
521 TARGET_SHORT_BIT
/ TARGET_CHAR_BIT
,
522 TYPE_FLAG_UNSIGNED
, "unsigned short", objfile
);
525 type
= init_type (TYPE_CODE_INT
,
526 TARGET_INT_BIT
/ TARGET_CHAR_BIT
,
529 case FT_SIGNED_INTEGER
:
530 type
= init_type (TYPE_CODE_INT
,
531 TARGET_INT_BIT
/ TARGET_CHAR_BIT
,
532 0, "int", objfile
); /* FIXME -fnf */
534 case FT_UNSIGNED_INTEGER
:
535 type
= init_type (TYPE_CODE_INT
,
536 TARGET_INT_BIT
/ TARGET_CHAR_BIT
,
537 TYPE_FLAG_UNSIGNED
, "unsigned int", objfile
);
540 type
= init_type (TYPE_CODE_INT
,
541 TARGET_LONG_BIT
/ TARGET_CHAR_BIT
,
545 type
= init_type (TYPE_CODE_INT
,
546 TARGET_LONG_BIT
/ TARGET_CHAR_BIT
,
547 0, "long", objfile
); /* FIXME -fnf */
549 case FT_UNSIGNED_LONG
:
550 type
= init_type (TYPE_CODE_INT
,
551 TARGET_LONG_BIT
/ TARGET_CHAR_BIT
,
552 TYPE_FLAG_UNSIGNED
, "unsigned long", objfile
);
555 type
= init_type (TYPE_CODE_INT
,
556 TARGET_LONG_LONG_BIT
/ TARGET_CHAR_BIT
,
557 0, "long long", objfile
);
559 case FT_SIGNED_LONG_LONG
:
560 type
= init_type (TYPE_CODE_INT
,
561 TARGET_LONG_LONG_BIT
/ TARGET_CHAR_BIT
,
562 0, "signed long long", objfile
);
564 case FT_UNSIGNED_LONG_LONG
:
565 type
= init_type (TYPE_CODE_INT
,
566 TARGET_LONG_LONG_BIT
/ TARGET_CHAR_BIT
,
567 TYPE_FLAG_UNSIGNED
, "unsigned long long", objfile
);
570 type
= init_type (TYPE_CODE_FLT
,
571 TARGET_FLOAT_BIT
/ TARGET_CHAR_BIT
,
572 0, "float", objfile
);
574 case FT_DBL_PREC_FLOAT
:
575 type
= init_type (TYPE_CODE_FLT
,
576 TARGET_DOUBLE_BIT
/ TARGET_CHAR_BIT
,
577 0, "double", objfile
);
579 case FT_EXT_PREC_FLOAT
:
580 type
= init_type (TYPE_CODE_FLT
,
581 TARGET_LONG_DOUBLE_BIT
/ TARGET_CHAR_BIT
,
582 0, "long double", objfile
);
589 /* Table mapping opcodes into strings for printing operators
590 and precedences of the operators. */
592 static const struct op_print objc_op_print_tab
[] =
594 {",", BINOP_COMMA
, PREC_COMMA
, 0},
595 {"=", BINOP_ASSIGN
, PREC_ASSIGN
, 1},
596 {"||", BINOP_LOGICAL_OR
, PREC_LOGICAL_OR
, 0},
597 {"&&", BINOP_LOGICAL_AND
, PREC_LOGICAL_AND
, 0},
598 {"|", BINOP_BITWISE_IOR
, PREC_BITWISE_IOR
, 0},
599 {"^", BINOP_BITWISE_XOR
, PREC_BITWISE_XOR
, 0},
600 {"&", BINOP_BITWISE_AND
, PREC_BITWISE_AND
, 0},
601 {"==", BINOP_EQUAL
, PREC_EQUAL
, 0},
602 {"!=", BINOP_NOTEQUAL
, PREC_EQUAL
, 0},
603 {"<=", BINOP_LEQ
, PREC_ORDER
, 0},
604 {">=", BINOP_GEQ
, PREC_ORDER
, 0},
605 {">", BINOP_GTR
, PREC_ORDER
, 0},
606 {"<", BINOP_LESS
, PREC_ORDER
, 0},
607 {">>", BINOP_RSH
, PREC_SHIFT
, 0},
608 {"<<", BINOP_LSH
, PREC_SHIFT
, 0},
609 {"+", BINOP_ADD
, PREC_ADD
, 0},
610 {"-", BINOP_SUB
, PREC_ADD
, 0},
611 {"*", BINOP_MUL
, PREC_MUL
, 0},
612 {"/", BINOP_DIV
, PREC_MUL
, 0},
613 {"%", BINOP_REM
, PREC_MUL
, 0},
614 {"@", BINOP_REPEAT
, PREC_REPEAT
, 0},
615 {"-", UNOP_NEG
, PREC_PREFIX
, 0},
616 {"!", UNOP_LOGICAL_NOT
, PREC_PREFIX
, 0},
617 {"~", UNOP_COMPLEMENT
, PREC_PREFIX
, 0},
618 {"*", UNOP_IND
, PREC_PREFIX
, 0},
619 {"&", UNOP_ADDR
, PREC_PREFIX
, 0},
620 {"sizeof ", UNOP_SIZEOF
, PREC_PREFIX
, 0},
621 {"++", UNOP_PREINCREMENT
, PREC_PREFIX
, 0},
622 {"--", UNOP_PREDECREMENT
, PREC_PREFIX
, 0},
626 struct type
** const (objc_builtin_types
[]) =
633 &builtin_type_double
,
635 &builtin_type_long_long
,
636 &builtin_type_signed_char
,
637 &builtin_type_unsigned_char
,
638 &builtin_type_unsigned_short
,
639 &builtin_type_unsigned_int
,
640 &builtin_type_unsigned_long
,
641 &builtin_type_unsigned_long_long
,
642 &builtin_type_long_double
,
643 &builtin_type_complex
,
644 &builtin_type_double_complex
,
648 const struct language_defn objc_language_defn
= {
649 "objective-c", /* Language name */
657 evaluate_subexp_standard
,
658 objc_printchar
, /* Print a character constant */
659 objc_printstr
, /* Function to print string constant */
661 objc_create_fundamental_type
, /* Create fundamental type in this language */
662 c_print_type
, /* Print a type using appropriate syntax */
663 c_val_print
, /* Print a value using appropriate syntax */
664 c_value_print
, /* Print a top-level value */
665 {"", "", "", ""}, /* Binary format info */
666 {"0%lo", "0", "o", ""}, /* Octal format info */
667 {"%ld", "", "d", ""}, /* Decimal format info */
668 {"0x%lx", "0x", "x", ""}, /* Hex format info */
669 objc_op_print_tab
, /* expression operators for printing */
670 1, /* c-style arrays */
671 0, /* String lower bound */
672 &builtin_type_char
, /* Type of string elements */
678 * Following functions help construct Objective C message calls
681 struct selname
/* for parsing Objective C */
683 struct selname
*next
;
688 static int msglist_len
;
689 static struct selname
*selname_chain
;
690 static char *msglist_sel
;
695 register struct selname
*new =
696 (struct selname
*) xmalloc (sizeof (struct selname
));
698 new->next
= selname_chain
;
699 new->msglist_len
= msglist_len
;
700 new->msglist_sel
= msglist_sel
;
702 msglist_sel
= (char *)xmalloc(1);
708 add_msglist(struct stoken
*str
, int addcolon
)
713 if (str
== 0) { /* unnamed arg, or... */
714 if (addcolon
== 0) { /* variable number of args */
724 len
= plen
+ strlen(msglist_sel
) + 2;
725 s
= (char *)xmalloc(len
);
726 strcpy(s
, msglist_sel
);
741 register int val
= msglist_len
;
742 register struct selname
*sel
= selname_chain
;
743 register char *p
= msglist_sel
;
746 selname_chain
= sel
->next
;
747 msglist_len
= sel
->msglist_len
;
748 msglist_sel
= sel
->msglist_sel
;
749 selid
= lookup_child_selector(p
);
751 error("Can't find selector \"%s\"", p
);
752 write_exp_elt_longcst (selid
);
754 write_exp_elt_longcst (val
);/* Number of args */
761 * Function: specialcmp (char *a, char *b)
763 * Special strcmp: treats ']' and ' ' as end-of-string.
764 * Used for qsorting lists of objc methods (either by class or selector)
767 int specialcmp(char *a
, char *b
)
769 while (*a
&& *a
!= ' ' && *a
!= ']' && *b
&& *b
!= ' ' && *b
!= ']')
775 if (*a
&& *a
!= ' ' && *a
!= ']')
776 return 1; /* a is longer therefore greater */
777 if (*b
&& *b
!= ' ' && *b
!= ']')
778 return -1; /* a is shorter therefore lesser */
779 return 0; /* a and b are identical */
783 * Function: compare_selectors (void *, void *)
785 * Comparison function for use with qsort. Arguments are symbols or msymbols
786 * Compares selector part of objc method name alphabetically.
790 compare_selectors (a
, b
)
796 if ((aname
= SYMBOL_SOURCE_NAME (*(struct symbol
**) a
)) == NULL
||
797 (bname
= SYMBOL_SOURCE_NAME (*(struct symbol
**) b
)) == NULL
)
798 error ("internal: compare_selectors(1)");
800 if ((aname
= strchr(aname
, ' ')) == NULL
||
801 (bname
= strchr(bname
, ' ')) == NULL
)
802 error ("internal: compare_selectors(2)");
804 return specialcmp (aname
+1, bname
+1);
808 * Function: selectors_info (regexp, from_tty)
810 * Implements the "Info selectors" command. Takes an optional regexp arg.
811 * Lists all objective c selectors that match the regexp. Works by
812 * grepping thru all symbols for objective c methods. Output list is
813 * sorted and uniqued.
817 selectors_info (char *regexp
, int from_tty
)
819 struct objfile
*objfile
;
820 struct minimal_symbol
*msymbol
;
828 struct symbol
**sym_arr
;
832 strcpy(myregexp
, ".*]"); /* null input, match all objc methods */
835 if (*regexp
== '+' || *regexp
== '-') /* if regexp starts with +/- */
836 { /* user wants only class methods or only instance methods */
837 plusminus
= *regexp
++;
838 while (*regexp
== ' ' || *regexp
== '\t')
842 strcpy(myregexp
, ".*]");
845 strcpy(myregexp
, regexp
);
846 if (myregexp
[strlen(myregexp
) - 1] == '$') /* end of selector */
847 myregexp
[strlen(myregexp
) - 1] = ']'; /* end of method name */
849 strcat(myregexp
, ".*]");
854 if (0 != (val
= re_comp (myregexp
)))
855 error ("Invalid regexp (%s): %s", val
, regexp
);
857 /* first time thru is JUST to get max length and count */
858 ALL_MSYMBOLS (objfile
, msymbol
)
861 if ((name
= SYMBOL_DEMANGLED_NAME (msymbol
)) == NULL
)
862 name
= SYMBOL_NAME (msymbol
);
864 (name
[0] == '-' || name
[0] == '+') &&
865 name
[1] == '[') /* got a method name */
867 if (plusminus
&& name
[0] != plusminus
)
868 continue; /* filter for class/instance methods */
869 name
= (char *) strchr(name
+2, ' '); /* find selector part */
870 if (regexp
== NULL
|| re_exec(++name
) != 0)
872 char *mystart
= name
;
873 char *myend
= (char *) strchr(mystart
, ']');
875 if (myend
&& (myend
- mystart
> maxlen
))
876 maxlen
= myend
- mystart
; /* get longest selector */
883 printf_filtered ("Selectors matching \"%s\":\n\n",
884 regexp
? regexp
: "*");
886 sym_arr
= alloca (matches
* sizeof (struct symbol
*));
888 ALL_MSYMBOLS (objfile
, msymbol
)
891 if ((name
= SYMBOL_DEMANGLED_NAME (msymbol
)) == NULL
)
892 name
= SYMBOL_NAME (msymbol
);
894 (name
[0] == '-' || name
[0] == '+') &&
895 name
[1] == '[') /* got a method name */
897 if (plusminus
&& name
[0] != plusminus
)
898 continue; /* filter for class/instance methods */
899 name
= (char *) strchr(name
+2, ' '); /* find selector part */
900 if (regexp
== NULL
|| re_exec(++name
) != 0)
901 sym_arr
[matches
++] = (struct symbol
*) msymbol
;
905 qsort (sym_arr
, matches
, sizeof (struct minimal_symbol
*),
907 asel
[0] = 0; /* to prevent compare on first iteration */
908 for (ix
= 0; ix
< matches
; ix
++) /* now do the output */
913 if ((name
= SYMBOL_DEMANGLED_NAME (sym_arr
[ix
])) == NULL
)
914 name
= SYMBOL_NAME (sym_arr
[ix
]);
915 name
= strchr (name
, ' ') + 1;
916 if (p
[0] && specialcmp(name
, p
) == 0)
917 continue; /* seen this one already (not unique) */
919 while (*name
&& *name
!= ']') /* copy selector part */
922 puts_filtered_tabular(asel
, maxlen
+ 1, 0); /* print in columns */
927 printf_filtered ("No selectors matching \"%s\"\n", regexp
? regexp
: "*");
931 * Function: compare_classes (void *, void *)
933 * Comparison function for use with qsort. Arguments are symbols or msymbols
934 * Compares class part of objc method name alphabetically.
938 compare_classes (a
, b
)
944 if ((aname
= SYMBOL_SOURCE_NAME (*(struct symbol
**) a
)) == NULL
||
945 (bname
= SYMBOL_SOURCE_NAME (*(struct symbol
**) b
)) == NULL
)
946 error ("internal: compare_classes(1)");
948 return specialcmp (aname
+1, bname
+1);
952 * Function: classes_info(regexp, from_tty)
954 * Implements the "info classes" command for objective c classes.
955 * Lists all objective c classes that match the optional regexp.
956 * Works by grepping thru the list of objective c methods.
957 * List will be sorted and uniqued (since one class may have many methods).
958 * BUGS: will not list a class that has no methods.
962 classes_info (char *regexp
, int from_tty
)
964 struct objfile
*objfile
;
965 struct minimal_symbol
*msymbol
;
973 struct symbol
**sym_arr
;
976 strcpy(myregexp
, ".* "); /* null input: match all objc classes */
979 strcpy(myregexp
, regexp
);
980 if (myregexp
[strlen(myregexp
) - 1] == '$')
981 /* in the method name, the end of the class name is marked by ' ' */
982 myregexp
[strlen(myregexp
) - 1] = ' ';
984 strcat(myregexp
, ".* ");
988 if (0 != (val
= re_comp (myregexp
)))
989 error ("Invalid regexp (%s): %s", val
, regexp
);
991 /* first time thru is JUST to get max length and count */
992 ALL_MSYMBOLS (objfile
, msymbol
)
995 if ((name
= SYMBOL_DEMANGLED_NAME (msymbol
)) == NULL
)
996 name
= SYMBOL_NAME (msymbol
);
998 (name
[0] == '-' || name
[0] == '+') &&
999 name
[1] == '[') /* got a method name */
1000 if (regexp
== NULL
|| re_exec(name
+2) != 0)
1002 char *mystart
= name
+ 2; /* compute length of classname part */
1003 char *myend
= (char *) strchr(mystart
, ' ');
1005 if (myend
&& (myend
- mystart
> maxlen
))
1006 maxlen
= myend
- mystart
;
1012 printf_filtered ("Classes matching \"%s\":\n\n",
1013 regexp
? regexp
: "*");
1014 sym_arr
= alloca (matches
* sizeof (struct symbol
*));
1016 ALL_MSYMBOLS (objfile
, msymbol
)
1019 if ((name
= SYMBOL_DEMANGLED_NAME (msymbol
)) == NULL
)
1020 name
= SYMBOL_NAME (msymbol
);
1022 (name
[0] == '-' || name
[0] == '+') &&
1023 name
[1] == '[') /* got a method name */
1024 if (regexp
== NULL
|| re_exec(name
+2) != 0)
1025 sym_arr
[matches
++] = (struct symbol
*) msymbol
;
1028 qsort (sym_arr
, matches
, sizeof (struct minimal_symbol
*),
1030 aclass
[0] = 0; /* to prevent compare on first iteration */
1031 for (ix
= 0; ix
< matches
; ix
++) /* now do the output */
1036 if ((name
= SYMBOL_DEMANGLED_NAME (sym_arr
[ix
])) == NULL
)
1037 name
= SYMBOL_NAME (sym_arr
[ix
]);
1039 if (p
[0] && specialcmp(name
, p
) == 0)
1040 continue; /* seen this one already (not unique) */
1042 while (*name
&& *name
!= ' ') /* copy class part of method name */
1045 puts_filtered_tabular(aclass
, maxlen
+ 1, 0); /* print in columns */
1050 printf_filtered ("No classes matching \"%s\"\n", regexp
? regexp
: "*");
1054 * Function: find_imps (char *selector, struct symbol **sym_arr)
1056 * Input: a string representing a selector
1057 * a pointer to an array of symbol pointers
1058 * possibly a pointer to a symbol found by the caller.
1060 * Output: number of methods that implement that selector.
1061 * Side effects: The array of symbol pointers is filled with matching syms.
1063 * By analogy with function "find_methods" (symtab.c), builds a list of
1064 * symbols matching the ambiguous input, so that "decode_line_2" (symtab.c)
1065 * can list them and ask the user to choose one or more. In this case the
1066 * matches are objective c methods ("implementations") matching an objective
1069 * Note that it is possible for a normal (c-style) function to have the
1070 * same name as an objective c selector. To prevent the selector from
1071 * eclipsing the function, we allow the caller (decode_line_1) to search
1072 * for such a function first, and if it finds one, pass it in to us. We
1073 * will then integrate it into the list. We also search for one here,
1074 * among the minsyms.
1076 * NOTE: if NUM_DEBUGGABLE is non-zero, the sym_arr will be
1077 * divided into two parts: debuggable (struct symbol) syms,
1078 * and non_debuggable (struct minimal_symbol) syms.
1079 * The debuggable ones will come first, before NUM_DEBUGGABLE
1080 * (which will thus be the index of the first non-debuggable one).
1084 * Function: total_number_of_imps (char *selector);
1086 * Input: a string representing a selector
1087 * Output: number of methods that implement that selector.
1089 * By analogy with function "total_number_of_methods", this allows
1090 * decode_line_1 (symtab.c) to detect if there are objective c methods
1091 * matching the input, and to allocate an array of pointers to them
1092 * which can be manipulated by "decode_line_2" (also in symtab.c)
1096 parse_selector (char *method
, char **selector
)
1100 int found_quote
= 0;
1102 char *nselector
= NULL
;
1104 CHECK (selector
!= NULL
);
1108 while (isspace (*s1
))
1115 while (isspace (*s1
))
1122 if (isalnum (*s2
) || (*s2
== '_') || (*s2
== ':'))
1124 else if (isspace (*s2
))
1126 else if ((*s2
== '\0') || (*s2
== '\''))
1134 while (isspace (*s2
))
1140 while (isspace (*s2
))
1144 if (selector
!= NULL
)
1145 *selector
= nselector
;
1151 parse_method (char *method
, char *type
, char **class, char **category
,
1156 int found_quote
= 0;
1159 char *nclass
= NULL
;
1160 char *ncategory
= NULL
;
1161 char *nselector
= NULL
;
1163 CHECK (type
!= NULL
);
1164 CHECK (class != NULL
);
1165 CHECK (category
!= NULL
);
1166 CHECK (selector
!= NULL
);
1170 while (isspace (*s1
))
1177 while (isspace (*s1
))
1180 if ((s1
[0] == '+') || (s1
[0] == '-'))
1183 while (isspace (*s1
))
1191 while (isalnum (*s1
) || (*s1
== '_'))
1195 while (isspace (*s2
))
1201 while (isspace (*s2
))
1204 while (isalnum (*s2
) || (*s2
== '_'))
1209 /* truncate the class name now that we're not using the open paren */
1216 if (isalnum (*s2
) || (*s2
== '_') || (*s2
== ':'))
1218 else if (isspace (*s2
))
1220 else if (*s2
== ']')
1229 while (isspace (*s2
))
1236 while (isspace (*s2
))
1244 if (category
!= NULL
)
1245 *category
= ncategory
;
1246 if (selector
!= NULL
)
1247 *selector
= nselector
;
1253 find_methods (struct symtab
*symtab
,
1254 char type
, const char *class, const char *category
,
1255 const char *selector
,
1256 struct symbol
**syms
, unsigned int *nsym
, unsigned int *ndebug
)
1258 struct objfile
*objfile
= NULL
;
1259 struct minimal_symbol
*msymbol
= NULL
;
1260 struct block
*block
= NULL
;
1261 struct symbol
*sym
= NULL
;
1263 char *symname
= NULL
;
1266 char *nclass
= NULL
;
1267 char *ncategory
= NULL
;
1268 char *nselector
= NULL
;
1270 unsigned int csym
= 0;
1271 unsigned int cdebug
= 0;
1273 static char *tmp
= NULL
;
1274 static unsigned int tmplen
= 0;
1276 CHECK (nsym
!= NULL
);
1277 CHECK (ndebug
!= NULL
);
1280 block
= BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab
), STATIC_BLOCK
);
1282 ALL_MSYMBOLS (objfile
, msymbol
)
1286 if ((msymbol
->type
!= mst_text
) && (msymbol
->type
!= mst_file_text
))
1287 /* not a function or method */
1291 if ((SYMBOL_VALUE_ADDRESS (msymbol
) < block
->startaddr
) ||
1292 (SYMBOL_VALUE_ADDRESS (msymbol
) >= block
->endaddr
))
1293 /* not in the specified symtab */
1296 symname
= SYMBOL_DEMANGLED_NAME (msymbol
);
1297 if (symname
== NULL
)
1298 symname
= SYMBOL_NAME (msymbol
);
1299 if (symname
== NULL
)
1302 if ((symname
[0] != '-' && symname
[0] != '+') || (symname
[1] != '['))
1303 /* not a method name */
1306 while ((strlen (symname
) + 1) >= tmplen
)
1308 tmplen
= (tmplen
== 0) ? 1024 : tmplen
* 2;
1309 tmp
= xrealloc (tmp
, tmplen
);
1311 strcpy (tmp
, symname
);
1313 if (parse_method (tmp
, &ntype
, &nclass
, &ncategory
, &nselector
) == NULL
)
1316 if ((type
!= '\0') && (ntype
!= type
))
1319 if ((class != NULL
) && ((nclass
== NULL
) || (strcmp (class, nclass
) != 0)))
1322 if ((category
!= NULL
) && ((ncategory
== NULL
) || (strcmp (category
, ncategory
) != 0)))
1325 if ((selector
!= NULL
) && ((nselector
== NULL
) || (strcmp (selector
, nselector
) != 0)))
1328 sym
= find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol
));
1331 const char *newsymname
= SYMBOL_DEMANGLED_NAME (sym
);
1333 if (newsymname
== NULL
)
1334 newsymname
= SYMBOL_NAME (sym
);
1335 if (strcmp (symname
, newsymname
) == 0)
1337 /* found a high-level method sym: swap it into the
1338 lower part of sym_arr (below num_debuggable) */
1341 syms
[csym
] = syms
[cdebug
];
1349 warning ("debugging symbol \"%s\" does not match minimal symbol (\"%s\"); ignoring",
1350 newsymname
, symname
);
1352 syms
[csym
] = (struct symbol
*) msymbol
;
1358 /* found a non-debuggable method symbol */
1360 syms
[csym
] = (struct symbol
*) msymbol
;
1371 char *find_imps (struct symtab
*symtab
, struct block
*block
,
1372 char *method
, struct symbol
**syms
, unsigned int *nsym
,
1373 unsigned int *ndebug
)
1377 char *category
= NULL
;
1378 char *selector
= NULL
;
1380 unsigned int csym
= 0;
1381 unsigned int cdebug
= 0;
1383 unsigned int ncsym
= 0;
1384 unsigned int ncdebug
= 0;
1389 CHECK (nsym
!= NULL
);
1390 CHECK (ndebug
!= NULL
);
1397 buf
= (char *) alloca (strlen (method
) + 1);
1398 strcpy (buf
, method
);
1399 tmp
= parse_method (buf
, &type
, &class, &category
, &selector
);
1403 struct symtab
*sym_symtab
= NULL
;
1404 struct symbol
*sym
= NULL
;
1405 struct minimal_symbol
*msym
= NULL
;
1407 strcpy (buf
, method
);
1408 tmp
= parse_selector (buf
, &selector
);
1413 sym
= lookup_symbol (selector
, block
, VAR_NAMESPACE
, 0, &sym_symtab
);
1423 msym
= lookup_minimal_symbol (selector
, 0, 0);
1434 find_methods (symtab
, type
, class, category
, selector
, syms
+ csym
, &ncsym
, &ncdebug
);
1436 find_methods (symtab
, type
, class, category
, selector
, NULL
, &ncsym
, &ncdebug
);
1438 /* If we didn't find any methods, just return. */
1439 if (ncsym
== 0 && ncdebug
== 0)
1442 /* Take debug symbols from the second batch of symbols and swap them
1443 * with debug symbols from the first batch. Repeat until either the
1444 * second section is out of debug symbols or the first section is
1445 * full of debug symbols. Either way we have all debug symbols
1446 * packed to the beginning of the buffer. */
1450 while ((cdebug
< csym
) && (ncdebug
> 0))
1452 struct symbol
*s
= NULL
;
1454 unsigned int i
= cdebug
; /* first non-debugging symbol */
1455 unsigned int j
= csym
+ ncdebug
-1; /* last of second batch of debug symbols */
1461 /* We've moved a symbol from the second debug section to the first one. */
1476 return method
+ (tmp
- buf
);
1480 /* sort debuggable symbols */
1482 qsort (syms
, cdebug
, sizeof (struct minimal_symbol
*), compare_classes
);
1484 /* sort minimal_symbols */
1485 if ((csym
- cdebug
) > 1)
1486 qsort (&syms
[cdebug
], csym
- cdebug
, sizeof (struct minimal_symbol
*), compare_classes
);
1488 syms
[csym
] = 0; /* terminate the sym_arr list */
1490 return method
+ (tmp
- buf
);
1494 print_object_command (char *args
, int from_tty
)
1496 struct value
*object
, *function
, *description
;
1497 CORE_ADDR string_addr
;
1501 if (!args
|| !*args
)
1502 error ("The 'print-object' command requires an argument (an Objective-C object)");
1505 struct expression
*expr
= parse_expression (args
);
1506 register struct cleanup
*old_chain
= make_cleanup (free_current_contents
, &expr
);
1510 object
= expr
->language_defn
->evaluate_exp (builtin_type_void_data_ptr
,
1511 expr
, &pc
, EVAL_NORMAL
);
1513 object
= evaluate_subexp (builtin_type_void_data_ptr
, expr
, &pc
, EVAL_NORMAL
);
1515 do_cleanups (old_chain
);
1518 if (!(function
= find_function_in_inferior ("_NSPrintForDebugger")))
1519 error ("Unable to locate _NSPrintForDebugger in child process");
1521 description
= call_function_by_hand (function
, 1, &object
);
1523 if ((string_addr
= value_as_long (description
)) == 0)
1524 error ("object returns null description");
1526 read_memory (string_addr
+ i
++, &c
, 1);
1529 { /* read and print characters up to EOS */
1531 printf_filtered ("%c", c
);
1532 read_memory (string_addr
+ i
++, &c
, 1);
1535 printf_filtered("<object returns empty description>");
1536 printf_filtered ("\n");
1539 /* The data structure 'methcalls' is used to detect method calls
1540 * (thru ObjC runtime lib functions objc_msgSend, objc_msgSendSuper, etc.),
1541 * and ultimately find the method being called.
1544 struct objc_methcall
{
1546 CORE_ADDR (*stop_at
) (CORE_ADDR
); /* should return instance method to be called */
1547 CORE_ADDR begin
; /* start of pc range corresponding to method invocation */
1548 CORE_ADDR end
; /* end of pc range corresponding to method invocation */
1551 static int resolve_msgsend
PARAMS ((CORE_ADDR pc
, CORE_ADDR
*new_pc
));
1552 static int resolve_msgsend_stret
PARAMS ((CORE_ADDR pc
, CORE_ADDR
*new_pc
));
1553 static int resolve_msgsend_super
PARAMS ((CORE_ADDR pc
, CORE_ADDR
*new_pc
));
1554 static int resolve_msgsend_super_stret
PARAMS ((CORE_ADDR pc
, CORE_ADDR
*new_pc
));
1556 static struct objc_methcall methcalls
[] = {
1557 { "_objc_msgSend", resolve_msgsend
, 0, 0},
1558 { "_objc_msgSend_stret", resolve_msgsend_stret
, 0, 0},
1559 { "_objc_msgSendSuper", resolve_msgsend_super
, 0, 0},
1560 { "_objc_msgSendSuper_stret", resolve_msgsend_super_stret
, 0, 0},
1561 { "_objc_getClass", NULL
, 0, 0},
1562 { "_objc_getMetaClass", NULL
, 0, 0}
1565 #define nmethcalls (sizeof (methcalls) / sizeof (methcalls[0]))
1567 /* The following function, "find_objc_msgsend", fills in the data structure
1568 * "objc_msgs" by finding the addresses of each of the (currently four)
1569 * functions that it holds (of which objc_msgSend is the first). This
1570 * must be called each time symbols are loaded, in case the functions
1571 * have moved for some reason.
1575 find_objc_msgsend (void)
1578 for (i
= 0; i
< nmethcalls
; i
++) {
1580 struct minimal_symbol
*func
;
1582 /* try both with and without underscore */
1583 func
= lookup_minimal_symbol (methcalls
[i
].name
, NULL
, NULL
);
1584 if ((func
== NULL
) && (methcalls
[i
].name
[0] == '_')) {
1585 func
= lookup_minimal_symbol (methcalls
[i
].name
+ 1, NULL
, NULL
);
1588 methcalls
[i
].begin
= 0;
1589 methcalls
[i
].end
= 0;
1593 methcalls
[i
].begin
= SYMBOL_VALUE_ADDRESS (func
);
1595 methcalls
[i
].end
= SYMBOL_VALUE_ADDRESS (++func
);
1596 } while (methcalls
[i
].begin
== methcalls
[i
].end
);
1600 /* find_objc_msgcall (replaces pc_off_limits)
1602 * ALL that this function now does is to determine whether the input
1603 * address ("pc") is the address of one of the Objective C message
1604 * dispatch functions (mainly objc_msgSend or objc_msgSendSuper), and
1605 * if so, it returns the address of the method that will be called.
1607 * The old function "pc_off_limits" used to do a lot of other things
1608 * in addition, such as detecting shared library jump stubs and
1609 * returning the address of the shlib function that would be called.
1610 * That functionality has been moved into the SKIP_TRAMPOLINE_CODE
1611 * and IN_SOLIB_TRAMPOLINE macros, which are resolved in the target-
1612 * dependent modules.
1615 struct objc_submethod_helper_data
{
1616 CORE_ADDR (*f
) (CORE_ADDR
, CORE_ADDR
*);
1622 find_objc_msgcall_submethod_helper (PTR arg
)
1624 struct objc_submethod_helper_data
*s
= (struct objc_submethod_helper_data
*) arg
;
1625 if (s
->f (s
->pc
, s
->new_pc
) == 0) {
1633 find_objc_msgcall_submethod (f
, pc
, new_pc
)
1634 CORE_ADDR (*f
) (CORE_ADDR
, CORE_ADDR
*);
1638 struct objc_submethod_helper_data s
;
1644 if (catch_errors (find_objc_msgcall_submethod_helper
,
1646 "Unable to determine target of Objective-C method call (ignoring):\n",
1647 RETURN_MASK_ALL
) == 0) {
1655 find_objc_msgcall (CORE_ADDR pc
, CORE_ADDR
*new_pc
)
1659 find_objc_msgsend ();
1660 if (new_pc
!= NULL
) { *new_pc
= 0; }
1662 for (i
= 0; i
< nmethcalls
; i
++) {
1663 if ((pc
>= methcalls
[i
].begin
) && (pc
< methcalls
[i
].end
)) {
1664 if (methcalls
[i
].stop_at
!= NULL
) {
1665 return find_objc_msgcall_submethod (methcalls
[i
].stop_at
, pc
, new_pc
);
1675 _initialize_objc_language (void)
1677 add_language (&objc_language_defn
);
1678 add_info ("selectors", selectors_info
, /* INFO SELECTORS command */
1679 "All Objective C selectors, or those matching REGEXP.");
1680 add_info ("classes", classes_info
, /* INFO CLASSES command */
1681 "All Objective C classes, or those matching REGEXP.");
1682 add_com ("print-object", class_vars
, print_object_command
,
1683 "Ask an Objective-C object to print itself.\n");
1684 add_com_alias ("po", "print-object", class_vars
, 1);
1687 #if defined (__powerpc__) || defined (__ppc__)
1688 static unsigned long FETCH_ARGUMENT (int i
)
1690 return read_register (3 + i
);
1692 #elif defined (__i386__)
1693 static unsigned long FETCH_ARGUMENT (int i
)
1695 CORE_ADDR stack
= read_register (SP_REGNUM
);
1696 return read_memory_unsigned_integer (stack
+ (4 * (i
+ 1)), 4);
1698 #elif defined (__sparc__)
1699 static unsigned long FETCH_ARGUMENT (int i
)
1701 return read_register (O0_REGNUM
+ i
);
1703 #elif defined (__hppa__) || defined (__hppa)
1704 static unsigned long FETCH_ARGUMENT (int i
)
1706 return read_register (R0_REGNUM
+ 26 - i
);
1709 #error unknown architecture
1712 #if defined (__hppa__) || defined (__hppa)
1713 static CORE_ADDR
CONVERT_FUNCPTR (CORE_ADDR pc
)
1716 pc
= (CORE_ADDR
) read_memory_integer (pc
& ~0x3, 4);
1721 static CORE_ADDR
CONVERT_FUNCPTR (CORE_ADDR pc
)
1728 read_objc_method (CORE_ADDR addr
, struct objc_method
*method
)
1730 method
->name
= read_memory_unsigned_integer (addr
, 4);
1731 method
->types
= read_memory_unsigned_integer (addr
+ 4, 4);
1732 method
->imp
= read_memory_unsigned_integer (addr
+ 8, 4);
1736 unsigned long read_objc_methlist_nmethods (CORE_ADDR addr
)
1738 return read_memory_unsigned_integer (addr
+ 4, 4);
1742 read_objc_methlist_method (CORE_ADDR addr
, unsigned long num
,
1743 struct objc_method
*method
)
1745 CHECK_FATAL (num
< read_objc_methlist_nmethods (addr
));
1746 read_objc_method (addr
+ 8 + (12 * num
), method
);
1750 read_objc_object (CORE_ADDR addr
, struct objc_object
*object
)
1752 object
->isa
= read_memory_unsigned_integer (addr
, 4);
1756 read_objc_super (CORE_ADDR addr
, struct objc_super
*super
)
1758 super
->receiver
= read_memory_unsigned_integer (addr
, 4);
1759 super
->class = read_memory_unsigned_integer (addr
+ 4, 4);
1763 read_objc_class (CORE_ADDR addr
, struct objc_class
*class)
1765 class->isa
= read_memory_unsigned_integer (addr
, 4);
1766 class->super_class
= read_memory_unsigned_integer (addr
+ 4, 4);
1767 class->name
= read_memory_unsigned_integer (addr
+ 8, 4);
1768 class->version
= read_memory_unsigned_integer (addr
+ 12, 4);
1769 class->info
= read_memory_unsigned_integer (addr
+ 16, 4);
1770 class->instance_size
= read_memory_unsigned_integer (addr
+ 18, 4);
1771 class->ivars
= read_memory_unsigned_integer (addr
+ 24, 4);
1772 class->methods
= read_memory_unsigned_integer (addr
+ 28, 4);
1773 class->cache
= read_memory_unsigned_integer (addr
+ 32, 4);
1774 class->protocols
= read_memory_unsigned_integer (addr
+ 36, 4);
1778 find_implementation_from_class (CORE_ADDR
class, CORE_ADDR sel
)
1780 CORE_ADDR subclass
= class;
1782 while (subclass
!= 0) {
1784 struct objc_class class_str
;
1785 unsigned mlistnum
= 0;
1787 read_objc_class (subclass
, &class_str
);
1791 unsigned long nmethods
;
1794 mlist
= read_memory_unsigned_integer (class_str
.methods
+ (4 * mlistnum
), 4);
1795 if (mlist
== 0) { break; }
1797 nmethods
= read_objc_methlist_nmethods (mlist
);
1799 for (i
= 0; i
< nmethods
; i
++) {
1800 struct objc_method meth_str
;
1801 read_objc_methlist_method (mlist
, i
, &meth_str
);
1804 fprintf (stderr
, "checking method 0x%lx against selector 0x%lx\n", meth_str
.name
, sel
);
1807 if (meth_str
.name
== sel
) {
1808 return CONVERT_FUNCPTR (meth_str
.imp
);
1815 subclass
= class_str
.super_class
;
1822 find_implementation (CORE_ADDR object
, CORE_ADDR sel
)
1824 struct objc_object ostr
;
1826 if (object
== 0) { return 0; }
1827 read_objc_object (object
, &ostr
);
1828 if (ostr
.isa
== 0) { return 0; }
1830 return find_implementation_from_class (ostr
.isa
, sel
);
1834 resolve_msgsend (CORE_ADDR pc
, CORE_ADDR
*new_pc
)
1840 object
= FETCH_ARGUMENT (0);
1841 sel
= FETCH_ARGUMENT (1);
1843 res
= find_implementation (object
, sel
);
1844 if (new_pc
!= 0) { *new_pc
= res
; }
1845 if (res
== 0) { return 1; }
1850 resolve_msgsend_stret (CORE_ADDR pc
, CORE_ADDR
*new_pc
)
1856 object
= FETCH_ARGUMENT (1);
1857 sel
= FETCH_ARGUMENT (2);
1859 res
= find_implementation (object
, sel
);
1860 if (new_pc
!= 0) { *new_pc
= res
; }
1861 if (res
== 0) { return 1; }
1866 resolve_msgsend_super (CORE_ADDR pc
, CORE_ADDR
*new_pc
)
1868 struct objc_super sstr
;
1874 super
= FETCH_ARGUMENT (0);
1875 sel
= FETCH_ARGUMENT (1);
1877 read_objc_super (super
, &sstr
);
1878 if (sstr
.class == 0) { return 0; }
1880 res
= find_implementation_from_class (sstr
.class, sel
);
1881 if (new_pc
!= 0) { *new_pc
= res
; }
1882 if (res
== 0) { return 1; }
1887 resolve_msgsend_super_stret (CORE_ADDR pc
, CORE_ADDR
*new_pc
)
1889 struct objc_super sstr
;
1895 super
= FETCH_ARGUMENT (1);
1896 sel
= FETCH_ARGUMENT (2);
1898 read_objc_super (super
, &sstr
);
1899 if (sstr
.class == 0) { return 0; }
1901 res
= find_implementation_from_class (sstr
.class, sel
);
1902 if (new_pc
!= 0) { *new_pc
= res
; }
1903 if (res
== 0) { return 1; }