gdb: Convert language la_word_break_characters field to a method
[binutils-gdb.git] / gdb / objc-lang.c
1 /* Objective-C language support routines for GDB, the GNU debugger.
2
3 Copyright (C) 2002-2020 Free Software Foundation, Inc.
4
5 Contributed by Apple Computer, Inc.
6 Written by Michael Snyder.
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22
23 #include "defs.h"
24 #include "symtab.h"
25 #include "gdbtypes.h"
26 #include "expression.h"
27 #include "parser-defs.h"
28 #include "language.h"
29 #include "varobj.h"
30 #include "c-lang.h"
31 #include "objc-lang.h"
32 #include "complaints.h"
33 #include "value.h"
34 #include "symfile.h"
35 #include "objfiles.h"
36 #include "target.h" /* for target_has_execution */
37 #include "gdbcore.h"
38 #include "gdbcmd.h"
39 #include "frame.h"
40 #include "gdb_regex.h"
41 #include "regcache.h"
42 #include "block.h"
43 #include "infcall.h"
44 #include "valprint.h"
45 #include "cli/cli-utils.h"
46
47 #include <ctype.h>
48 #include <algorithm>
49
50 struct objc_object {
51 CORE_ADDR isa;
52 };
53
54 struct objc_class {
55 CORE_ADDR isa;
56 CORE_ADDR super_class;
57 CORE_ADDR name;
58 long version;
59 long info;
60 long instance_size;
61 CORE_ADDR ivars;
62 CORE_ADDR methods;
63 CORE_ADDR cache;
64 CORE_ADDR protocols;
65 };
66
67 struct objc_super {
68 CORE_ADDR receiver;
69 CORE_ADDR theclass;
70 };
71
72 struct objc_method {
73 CORE_ADDR name;
74 CORE_ADDR types;
75 CORE_ADDR imp;
76 };
77
78 static const struct objfile_key<unsigned int> objc_objfile_data;
79
80 /* Lookup a structure type named "struct NAME", visible in lexical
81 block BLOCK. If NOERR is nonzero, return zero if NAME is not
82 suitably defined. */
83
84 struct symbol *
85 lookup_struct_typedef (const char *name, const struct block *block, int noerr)
86 {
87 struct symbol *sym;
88
89 sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0).symbol;
90
91 if (sym == NULL)
92 {
93 if (noerr)
94 return 0;
95 else
96 error (_("No struct type named %s."), name);
97 }
98 if (SYMBOL_TYPE (sym)->code () != TYPE_CODE_STRUCT)
99 {
100 if (noerr)
101 return 0;
102 else
103 error (_("This context has class, union or enum %s, not a struct."),
104 name);
105 }
106 return sym;
107 }
108
109 CORE_ADDR
110 lookup_objc_class (struct gdbarch *gdbarch, const char *classname)
111 {
112 struct type *char_type = builtin_type (gdbarch)->builtin_char;
113 struct value * function, *classval;
114
115 if (! target_has_execution)
116 {
117 /* Can't call into inferior to lookup class. */
118 return 0;
119 }
120
121 if (lookup_minimal_symbol("objc_lookUpClass", 0, 0).minsym)
122 function = find_function_in_inferior("objc_lookUpClass", NULL);
123 else if (lookup_minimal_symbol ("objc_lookup_class", 0, 0).minsym)
124 function = find_function_in_inferior("objc_lookup_class", NULL);
125 else
126 {
127 complaint (_("no way to lookup Objective-C classes"));
128 return 0;
129 }
130
131 classval = value_string (classname, strlen (classname) + 1, char_type);
132 classval = value_coerce_array (classval);
133 return (CORE_ADDR) value_as_long (call_function_by_hand (function,
134 NULL,
135 classval));
136 }
137
138 CORE_ADDR
139 lookup_child_selector (struct gdbarch *gdbarch, const char *selname)
140 {
141 struct type *char_type = builtin_type (gdbarch)->builtin_char;
142 struct value * function, *selstring;
143
144 if (! target_has_execution)
145 {
146 /* Can't call into inferior to lookup selector. */
147 return 0;
148 }
149
150 if (lookup_minimal_symbol("sel_getUid", 0, 0).minsym)
151 function = find_function_in_inferior("sel_getUid", NULL);
152 else if (lookup_minimal_symbol ("sel_get_any_uid", 0, 0).minsym)
153 function = find_function_in_inferior("sel_get_any_uid", NULL);
154 else
155 {
156 complaint (_("no way to lookup Objective-C selectors"));
157 return 0;
158 }
159
160 selstring = value_coerce_array (value_string (selname,
161 strlen (selname) + 1,
162 char_type));
163 return value_as_long (call_function_by_hand (function, NULL, selstring));
164 }
165
166 struct value *
167 value_nsstring (struct gdbarch *gdbarch, char *ptr, int len)
168 {
169 struct type *char_type = builtin_type (gdbarch)->builtin_char;
170 struct value *stringValue[3];
171 struct value *function, *nsstringValue;
172 struct symbol *sym;
173 struct type *type;
174
175 if (!target_has_execution)
176 return 0; /* Can't call into inferior to create NSString. */
177
178 stringValue[2] = value_string(ptr, len, char_type);
179 stringValue[2] = value_coerce_array(stringValue[2]);
180 /* _NSNewStringFromCString replaces "istr" after Lantern2A. */
181 if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0).minsym)
182 {
183 function = find_function_in_inferior("_NSNewStringFromCString", NULL);
184 nsstringValue = call_function_by_hand(function, NULL, stringValue[2]);
185 }
186 else if (lookup_minimal_symbol("istr", 0, 0).minsym)
187 {
188 function = find_function_in_inferior("istr", NULL);
189 nsstringValue = call_function_by_hand(function, NULL, stringValue[2]);
190 }
191 else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0).minsym)
192 {
193 function
194 = find_function_in_inferior("+[NSString stringWithCString:]", NULL);
195 type = builtin_type (gdbarch)->builtin_long;
196
197 stringValue[0] = value_from_longest
198 (type, lookup_objc_class (gdbarch, "NSString"));
199 stringValue[1] = value_from_longest
200 (type, lookup_child_selector (gdbarch, "stringWithCString:"));
201 nsstringValue = call_function_by_hand(function, NULL, stringValue);
202 }
203 else
204 error (_("NSString: internal error -- no way to create new NSString"));
205
206 sym = lookup_struct_typedef("NSString", 0, 1);
207 if (sym == NULL)
208 sym = lookup_struct_typedef("NXString", 0, 1);
209 if (sym == NULL)
210 type = builtin_type (gdbarch)->builtin_data_ptr;
211 else
212 type = lookup_pointer_type(SYMBOL_TYPE (sym));
213
214 deprecated_set_value_type (nsstringValue, type);
215 return nsstringValue;
216 }
217
218 /* Objective-C name demangling. */
219
220 char *
221 objc_demangle (const char *mangled, int options)
222 {
223 char *demangled, *cp;
224
225 if (mangled[0] == '_' &&
226 (mangled[1] == 'i' || mangled[1] == 'c') &&
227 mangled[2] == '_')
228 {
229 cp = demangled = (char *) xmalloc (strlen (mangled) + 2);
230
231 if (mangled[1] == 'i')
232 *cp++ = '-'; /* for instance method */
233 else
234 *cp++ = '+'; /* for class method */
235
236 *cp++ = '['; /* opening left brace */
237 strcpy(cp, mangled+3); /* Tack on the rest of the mangled name. */
238
239 while (*cp && *cp == '_')
240 cp++; /* Skip any initial underbars in class
241 name. */
242
243 cp = strchr(cp, '_');
244 if (!cp) /* Find first non-initial underbar. */
245 {
246 xfree(demangled); /* not mangled name */
247 return NULL;
248 }
249 if (cp[1] == '_') /* Easy case: no category name. */
250 {
251 *cp++ = ' '; /* Replace two '_' with one ' '. */
252 strcpy(cp, mangled + (cp - demangled) + 2);
253 }
254 else
255 {
256 *cp++ = '('; /* Less easy case: category name. */
257 cp = strchr(cp, '_');
258 if (!cp)
259 {
260 xfree(demangled); /* not mangled name */
261 return NULL;
262 }
263 *cp++ = ')';
264 *cp++ = ' '; /* Overwriting 1st char of method name... */
265 strcpy(cp, mangled + (cp - demangled)); /* Get it back. */
266 }
267
268 while (*cp && *cp == '_')
269 cp++; /* Skip any initial underbars in
270 method name. */
271
272 for (; *cp; cp++)
273 if (*cp == '_')
274 *cp = ':'; /* Replace remaining '_' with ':'. */
275
276 *cp++ = ']'; /* closing right brace */
277 *cp++ = 0; /* string terminator */
278 return demangled;
279 }
280 else
281 return NULL; /* Not an objc mangled name. */
282 }
283
284
285 /* Table mapping opcodes into strings for printing operators
286 and precedences of the operators. */
287
288 static const struct op_print objc_op_print_tab[] =
289 {
290 {",", BINOP_COMMA, PREC_COMMA, 0},
291 {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
292 {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
293 {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
294 {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
295 {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
296 {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
297 {"==", BINOP_EQUAL, PREC_EQUAL, 0},
298 {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
299 {"<=", BINOP_LEQ, PREC_ORDER, 0},
300 {">=", BINOP_GEQ, PREC_ORDER, 0},
301 {">", BINOP_GTR, PREC_ORDER, 0},
302 {"<", BINOP_LESS, PREC_ORDER, 0},
303 {">>", BINOP_RSH, PREC_SHIFT, 0},
304 {"<<", BINOP_LSH, PREC_SHIFT, 0},
305 {"+", BINOP_ADD, PREC_ADD, 0},
306 {"-", BINOP_SUB, PREC_ADD, 0},
307 {"*", BINOP_MUL, PREC_MUL, 0},
308 {"/", BINOP_DIV, PREC_MUL, 0},
309 {"%", BINOP_REM, PREC_MUL, 0},
310 {"@", BINOP_REPEAT, PREC_REPEAT, 0},
311 {"-", UNOP_NEG, PREC_PREFIX, 0},
312 {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
313 {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
314 {"*", UNOP_IND, PREC_PREFIX, 0},
315 {"&", UNOP_ADDR, PREC_PREFIX, 0},
316 {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
317 {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
318 {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
319 {NULL, OP_NULL, PREC_NULL, 0}
320 };
321
322 static const char *objc_extensions[] =
323 {
324 ".m", NULL
325 };
326
327 /* Constant data representing the Objective-C language. */
328
329 extern const struct language_data objc_language_data =
330 {
331 "objective-c", /* Language name */
332 "Objective-C",
333 language_objc,
334 range_check_off,
335 case_sensitive_on,
336 array_row_major,
337 macro_expansion_c,
338 objc_extensions,
339 &exp_descriptor_standard,
340 c_parse,
341 null_post_parser,
342 c_printchar, /* Print a character constant */
343 c_printstr, /* Function to print string constant */
344 c_emit_char,
345 c_print_typedef, /* Print a typedef using appropriate syntax */
346 c_value_print_inner, /* la_value_print_inner */
347 c_value_print, /* Print a top-level value */
348 "self", /* name_of_this */
349 false, /* la_store_sym_names_in_linkage_form_p */
350 basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
351 objc_op_print_tab, /* Expression operators for printing */
352 1, /* C-style arrays */
353 0, /* String lower bound */
354 default_collect_symbol_completion_matches,
355 c_watch_location_expression,
356 &default_varobj_ops,
357 c_is_string_type_p,
358 "{...}" /* la_struct_too_deep_ellipsis */
359 };
360
361 /* Class representing the Objective-C language. */
362
363 class objc_language : public language_defn
364 {
365 public:
366 objc_language ()
367 : language_defn (language_objc, objc_language_data)
368 { /* Nothing. */ }
369
370 /* See language.h. */
371 void language_arch_info (struct gdbarch *gdbarch,
372 struct language_arch_info *lai) const override
373 {
374 c_language_arch_info (gdbarch, lai);
375 }
376
377 /* See language.h. */
378 bool sniff_from_mangled_name (const char *mangled,
379 char **demangled) const override
380 {
381 *demangled = objc_demangle (mangled, 0);
382 return *demangled != NULL;
383 }
384
385 /* See language.h. */
386
387 char *demangle (const char *mangled, int options) const override
388 {
389 return objc_demangle (mangled, options);
390 }
391
392 /* See language.h. */
393
394 void print_type (struct type *type, const char *varstring,
395 struct ui_file *stream, int show, int level,
396 const struct type_print_options *flags) const override
397 {
398 c_print_type (type, varstring, stream, show, level, flags);
399 }
400
401 /* See language.h. */
402
403 CORE_ADDR skip_trampoline (struct frame_info *frame,
404 CORE_ADDR stop_pc) const override
405 {
406 struct gdbarch *gdbarch = get_frame_arch (frame);
407 CORE_ADDR real_stop_pc;
408 CORE_ADDR method_stop_pc;
409
410 /* Determine if we are currently in the Objective-C dispatch function.
411 If so, get the address of the method function that the dispatcher
412 would call and use that as the function to step into instead. Also
413 skip over the trampoline for the function (if any). This is better
414 for the user since they are only interested in stepping into the
415 method function anyway. */
416
417 real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
418
419 if (real_stop_pc != 0)
420 find_objc_msgcall (real_stop_pc, &method_stop_pc);
421 else
422 find_objc_msgcall (stop_pc, &method_stop_pc);
423
424 if (method_stop_pc)
425 {
426 real_stop_pc = gdbarch_skip_trampoline_code
427 (gdbarch, frame, method_stop_pc);
428 if (real_stop_pc == 0)
429 real_stop_pc = method_stop_pc;
430 }
431
432 return real_stop_pc;
433 }
434 };
435
436 /* Single instance of the class representing the Objective-C language. */
437
438 static objc_language objc_language_defn;
439
440 /*
441 * ObjC:
442 * Following functions help construct Objective-C message calls.
443 */
444
445 struct selname /* For parsing Objective-C. */
446 {
447 struct selname *next;
448 char *msglist_sel;
449 int msglist_len;
450 };
451
452 static int msglist_len;
453 static struct selname *selname_chain;
454 static char *msglist_sel;
455
456 void
457 start_msglist(void)
458 {
459 struct selname *newobj = XNEW (struct selname);
460
461 newobj->next = selname_chain;
462 newobj->msglist_len = msglist_len;
463 newobj->msglist_sel = msglist_sel;
464 msglist_len = 0;
465 msglist_sel = (char *)xmalloc(1);
466 *msglist_sel = 0;
467 selname_chain = newobj;
468 }
469
470 void
471 add_msglist(struct stoken *str, int addcolon)
472 {
473 char *s;
474 const char *p;
475 int len, plen;
476
477 if (str == 0) /* Unnamed arg, or... */
478 {
479 if (addcolon == 0) /* variable number of args. */
480 {
481 msglist_len++;
482 return;
483 }
484 p = "";
485 plen = 0;
486 }
487 else
488 {
489 p = str->ptr;
490 plen = str->length;
491 }
492 len = plen + strlen(msglist_sel) + 2;
493 s = (char *)xmalloc(len);
494 strcpy(s, msglist_sel);
495 strncat(s, p, plen);
496 xfree(msglist_sel);
497 msglist_sel = s;
498 if (addcolon)
499 {
500 s[len-2] = ':';
501 s[len-1] = 0;
502 msglist_len++;
503 }
504 else
505 s[len-2] = '\0';
506 }
507
508 int
509 end_msglist (struct parser_state *ps)
510 {
511 int val = msglist_len;
512 struct selname *sel = selname_chain;
513 char *p = msglist_sel;
514 CORE_ADDR selid;
515
516 selname_chain = sel->next;
517 msglist_len = sel->msglist_len;
518 msglist_sel = sel->msglist_sel;
519 selid = lookup_child_selector (ps->gdbarch (), p);
520 if (!selid)
521 error (_("Can't find selector \"%s\""), p);
522 write_exp_elt_longcst (ps, selid);
523 xfree(p);
524 write_exp_elt_longcst (ps, val); /* Number of args */
525 xfree(sel);
526
527 return val;
528 }
529
530 /*
531 * Function: specialcmp (const char *a, const char *b)
532 *
533 * Special strcmp: treats ']' and ' ' as end-of-string.
534 * Used for qsorting lists of objc methods (either by class or selector).
535 */
536
537 static int
538 specialcmp (const char *a, const char *b)
539 {
540 while (*a && *a != ' ' && *a != ']' && *b && *b != ' ' && *b != ']')
541 {
542 if (*a != *b)
543 return *a - *b;
544 a++, b++;
545 }
546 if (*a && *a != ' ' && *a != ']')
547 return 1; /* a is longer therefore greater. */
548 if (*b && *b != ' ' && *b != ']')
549 return -1; /* a is shorter therefore lesser. */
550 return 0; /* a and b are identical. */
551 }
552
553 /*
554 * Function: compare_selectors (const void *, const void *)
555 *
556 * Comparison function for use with qsort. Arguments are symbols or
557 * msymbols Compares selector part of objc method name alphabetically.
558 */
559
560 static int
561 compare_selectors (const void *a, const void *b)
562 {
563 const char *aname, *bname;
564
565 aname = (*(struct symbol **) a)->print_name ();
566 bname = (*(struct symbol **) b)->print_name ();
567 if (aname == NULL || bname == NULL)
568 error (_("internal: compare_selectors(1)"));
569
570 aname = strchr(aname, ' ');
571 bname = strchr(bname, ' ');
572 if (aname == NULL || bname == NULL)
573 error (_("internal: compare_selectors(2)"));
574
575 return specialcmp (aname+1, bname+1);
576 }
577
578 /*
579 * Function: selectors_info (regexp, from_tty)
580 *
581 * Implements the "Info selectors" command. Takes an optional regexp
582 * arg. Lists all objective c selectors that match the regexp. Works
583 * by grepping thru all symbols for objective c methods. Output list
584 * is sorted and uniqued.
585 */
586
587 static void
588 info_selectors_command (const char *regexp, int from_tty)
589 {
590 const char *name;
591 char *val;
592 int matches = 0;
593 int maxlen = 0;
594 int ix;
595 char myregexp[2048];
596 char asel[256];
597 struct symbol **sym_arr;
598 int plusminus = 0;
599
600 if (regexp == NULL)
601 strcpy(myregexp, ".*]"); /* Null input, match all objc methods. */
602 else
603 {
604 if (*regexp == '+' || *regexp == '-')
605 { /* User wants only class methods or only instance methods. */
606 plusminus = *regexp++;
607 while (*regexp == ' ' || *regexp == '\t')
608 regexp++;
609 }
610 if (*regexp == '\0')
611 strcpy(myregexp, ".*]");
612 else
613 {
614 /* Allow a few extra bytes because of the strcat below. */
615 if (sizeof (myregexp) < strlen (regexp) + 4)
616 error (_("Regexp is too long: %s"), regexp);
617 strcpy(myregexp, regexp);
618 if (myregexp[strlen(myregexp) - 1] == '$') /* end of selector */
619 myregexp[strlen(myregexp) - 1] = ']'; /* end of method name */
620 else
621 strcat(myregexp, ".*]");
622 }
623 }
624
625 if (regexp != NULL)
626 {
627 val = re_comp (myregexp);
628 if (val != 0)
629 error (_("Invalid regexp (%s): %s"), val, regexp);
630 }
631
632 /* First time thru is JUST to get max length and count. */
633 for (objfile *objfile : current_program_space->objfiles ())
634 {
635 for (minimal_symbol *msymbol : objfile->msymbols ())
636 {
637 QUIT;
638 name = msymbol->natural_name ();
639 if (name
640 && (name[0] == '-' || name[0] == '+')
641 && name[1] == '[') /* Got a method name. */
642 {
643 /* Filter for class/instance methods. */
644 if (plusminus && name[0] != plusminus)
645 continue;
646 /* Find selector part. */
647 name = (char *) strchr (name+2, ' ');
648 if (name == NULL)
649 {
650 complaint (_("Bad method name '%s'"),
651 msymbol->natural_name ());
652 continue;
653 }
654 if (regexp == NULL || re_exec(++name) != 0)
655 {
656 const char *mystart = name;
657 const char *myend = strchr (mystart, ']');
658
659 if (myend && (myend - mystart > maxlen))
660 maxlen = myend - mystart; /* Get longest selector. */
661 matches++;
662 }
663 }
664 }
665 }
666 if (matches)
667 {
668 printf_filtered (_("Selectors matching \"%s\":\n\n"),
669 regexp ? regexp : "*");
670
671 sym_arr = XALLOCAVEC (struct symbol *, matches);
672 matches = 0;
673 for (objfile *objfile : current_program_space->objfiles ())
674 {
675 for (minimal_symbol *msymbol : objfile->msymbols ())
676 {
677 QUIT;
678 name = msymbol->natural_name ();
679 if (name &&
680 (name[0] == '-' || name[0] == '+') &&
681 name[1] == '[') /* Got a method name. */
682 {
683 /* Filter for class/instance methods. */
684 if (plusminus && name[0] != plusminus)
685 continue;
686 /* Find selector part. */
687 name = (char *) strchr(name+2, ' ');
688 if (regexp == NULL || re_exec(++name) != 0)
689 sym_arr[matches++] = (struct symbol *) msymbol;
690 }
691 }
692 }
693
694 qsort (sym_arr, matches, sizeof (struct minimal_symbol *),
695 compare_selectors);
696 /* Prevent compare on first iteration. */
697 asel[0] = 0;
698 for (ix = 0; ix < matches; ix++) /* Now do the output. */
699 {
700 char *p = asel;
701
702 QUIT;
703 name = sym_arr[ix]->natural_name ();
704 name = strchr (name, ' ') + 1;
705 if (p[0] && specialcmp(name, p) == 0)
706 continue; /* Seen this one already (not unique). */
707
708 /* Copy selector part. */
709 while (*name && *name != ']')
710 *p++ = *name++;
711 *p++ = '\0';
712 /* Print in columns. */
713 puts_filtered_tabular(asel, maxlen + 1, 0);
714 }
715 begin_line();
716 }
717 else
718 printf_filtered (_("No selectors matching \"%s\"\n"),
719 regexp ? regexp : "*");
720 }
721
722 /*
723 * Function: compare_classes (const void *, const void *)
724 *
725 * Comparison function for use with qsort. Arguments are symbols or
726 * msymbols Compares class part of objc method name alphabetically.
727 */
728
729 static int
730 compare_classes (const void *a, const void *b)
731 {
732 const char *aname, *bname;
733
734 aname = (*(struct symbol **) a)->print_name ();
735 bname = (*(struct symbol **) b)->print_name ();
736 if (aname == NULL || bname == NULL)
737 error (_("internal: compare_classes(1)"));
738
739 return specialcmp (aname+1, bname+1);
740 }
741
742 /*
743 * Function: classes_info(regexp, from_tty)
744 *
745 * Implements the "info classes" command for objective c classes.
746 * Lists all objective c classes that match the optional regexp.
747 * Works by grepping thru the list of objective c methods. List will
748 * be sorted and uniqued (since one class may have many methods).
749 * BUGS: will not list a class that has no methods.
750 */
751
752 static void
753 info_classes_command (const char *regexp, int from_tty)
754 {
755 const char *name;
756 char *val;
757 int matches = 0;
758 int maxlen = 0;
759 int ix;
760 char myregexp[2048];
761 char aclass[256];
762 struct symbol **sym_arr;
763
764 if (regexp == NULL)
765 strcpy(myregexp, ".* "); /* Null input: match all objc classes. */
766 else
767 {
768 /* Allow a few extra bytes because of the strcat below. */
769 if (sizeof (myregexp) < strlen (regexp) + 4)
770 error (_("Regexp is too long: %s"), regexp);
771 strcpy(myregexp, regexp);
772 if (myregexp[strlen(myregexp) - 1] == '$')
773 /* In the method name, the end of the class name is marked by ' '. */
774 myregexp[strlen(myregexp) - 1] = ' ';
775 else
776 strcat(myregexp, ".* ");
777 }
778
779 if (regexp != NULL)
780 {
781 val = re_comp (myregexp);
782 if (val != 0)
783 error (_("Invalid regexp (%s): %s"), val, regexp);
784 }
785
786 /* First time thru is JUST to get max length and count. */
787 for (objfile *objfile : current_program_space->objfiles ())
788 {
789 for (minimal_symbol *msymbol : objfile->msymbols ())
790 {
791 QUIT;
792 name = msymbol->natural_name ();
793 if (name &&
794 (name[0] == '-' || name[0] == '+') &&
795 name[1] == '[') /* Got a method name. */
796 if (regexp == NULL || re_exec(name+2) != 0)
797 {
798 /* Compute length of classname part. */
799 const char *mystart = name + 2;
800 const char *myend = strchr (mystart, ' ');
801
802 if (myend && (myend - mystart > maxlen))
803 maxlen = myend - mystart;
804 matches++;
805 }
806 }
807 }
808 if (matches)
809 {
810 printf_filtered (_("Classes matching \"%s\":\n\n"),
811 regexp ? regexp : "*");
812 sym_arr = XALLOCAVEC (struct symbol *, matches);
813 matches = 0;
814 for (objfile *objfile : current_program_space->objfiles ())
815 {
816 for (minimal_symbol *msymbol : objfile->msymbols ())
817 {
818 QUIT;
819 name = msymbol->natural_name ();
820 if (name &&
821 (name[0] == '-' || name[0] == '+') &&
822 name[1] == '[') /* Got a method name. */
823 if (regexp == NULL || re_exec(name+2) != 0)
824 sym_arr[matches++] = (struct symbol *) msymbol;
825 }
826 }
827
828 qsort (sym_arr, matches, sizeof (struct minimal_symbol *),
829 compare_classes);
830 /* Prevent compare on first iteration. */
831 aclass[0] = 0;
832 for (ix = 0; ix < matches; ix++) /* Now do the output. */
833 {
834 char *p = aclass;
835
836 QUIT;
837 name = sym_arr[ix]->natural_name ();
838 name += 2;
839 if (p[0] && specialcmp(name, p) == 0)
840 continue; /* Seen this one already (not unique). */
841
842 /* Copy class part of method name. */
843 while (*name && *name != ' ')
844 *p++ = *name++;
845 *p++ = '\0';
846 /* Print in columns. */
847 puts_filtered_tabular(aclass, maxlen + 1, 0);
848 }
849 begin_line();
850 }
851 else
852 printf_filtered (_("No classes matching \"%s\"\n"), regexp ? regexp : "*");
853 }
854
855 static char *
856 parse_selector (char *method, char **selector)
857 {
858 char *s1 = NULL;
859 char *s2 = NULL;
860 int found_quote = 0;
861
862 char *nselector = NULL;
863
864 gdb_assert (selector != NULL);
865
866 s1 = method;
867
868 s1 = skip_spaces (s1);
869 if (*s1 == '\'')
870 {
871 found_quote = 1;
872 s1++;
873 }
874 s1 = skip_spaces (s1);
875
876 nselector = s1;
877 s2 = s1;
878
879 for (;;)
880 {
881 if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
882 *s1++ = *s2;
883 else if (isspace (*s2))
884 ;
885 else if ((*s2 == '\0') || (*s2 == '\''))
886 break;
887 else
888 return NULL;
889 s2++;
890 }
891 *s1++ = '\0';
892
893 s2 = skip_spaces (s2);
894 if (found_quote)
895 {
896 if (*s2 == '\'')
897 s2++;
898 s2 = skip_spaces (s2);
899 }
900
901 if (selector != NULL)
902 *selector = nselector;
903
904 return s2;
905 }
906
907 static char *
908 parse_method (char *method, char *type, char **theclass,
909 char **category, char **selector)
910 {
911 char *s1 = NULL;
912 char *s2 = NULL;
913 int found_quote = 0;
914
915 char ntype = '\0';
916 char *nclass = NULL;
917 char *ncategory = NULL;
918 char *nselector = NULL;
919
920 gdb_assert (type != NULL);
921 gdb_assert (theclass != NULL);
922 gdb_assert (category != NULL);
923 gdb_assert (selector != NULL);
924
925 s1 = method;
926
927 s1 = skip_spaces (s1);
928 if (*s1 == '\'')
929 {
930 found_quote = 1;
931 s1++;
932 }
933 s1 = skip_spaces (s1);
934
935 if ((s1[0] == '+') || (s1[0] == '-'))
936 ntype = *s1++;
937
938 s1 = skip_spaces (s1);
939
940 if (*s1 != '[')
941 return NULL;
942 s1++;
943
944 nclass = s1;
945 while (isalnum (*s1) || (*s1 == '_'))
946 s1++;
947
948 s2 = s1;
949 s2 = skip_spaces (s2);
950
951 if (*s2 == '(')
952 {
953 s2++;
954 s2 = skip_spaces (s2);
955 ncategory = s2;
956 while (isalnum (*s2) || (*s2 == '_'))
957 s2++;
958 *s2++ = '\0';
959 }
960
961 /* Truncate the class name now that we're not using the open paren. */
962 *s1++ = '\0';
963
964 nselector = s2;
965 s1 = s2;
966
967 for (;;)
968 {
969 if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
970 *s1++ = *s2;
971 else if (isspace (*s2))
972 ;
973 else if (*s2 == ']')
974 break;
975 else
976 return NULL;
977 s2++;
978 }
979 *s1++ = '\0';
980 s2++;
981
982 s2 = skip_spaces (s2);
983 if (found_quote)
984 {
985 if (*s2 != '\'')
986 return NULL;
987 s2++;
988 s2 = skip_spaces (s2);
989 }
990
991 if (type != NULL)
992 *type = ntype;
993 if (theclass != NULL)
994 *theclass = nclass;
995 if (category != NULL)
996 *category = ncategory;
997 if (selector != NULL)
998 *selector = nselector;
999
1000 return s2;
1001 }
1002
1003 static void
1004 find_methods (char type, const char *theclass, const char *category,
1005 const char *selector,
1006 std::vector<const char *> *symbol_names)
1007 {
1008 const char *symname = NULL;
1009
1010 char ntype = '\0';
1011 char *nclass = NULL;
1012 char *ncategory = NULL;
1013 char *nselector = NULL;
1014
1015 static char *tmp = NULL;
1016 static unsigned int tmplen = 0;
1017
1018 gdb_assert (symbol_names != NULL);
1019
1020 for (objfile *objfile : current_program_space->objfiles ())
1021 {
1022 unsigned int *objc_csym;
1023
1024 /* The objfile_csym variable counts the number of ObjC methods
1025 that this objfile defines. We save that count as a private
1026 objfile data. If we have already determined that this objfile
1027 provides no ObjC methods, we can skip it entirely. */
1028
1029 unsigned int objfile_csym = 0;
1030
1031 objc_csym = objc_objfile_data.get (objfile);
1032 if (objc_csym != NULL && *objc_csym == 0)
1033 /* There are no ObjC symbols in this objfile. Skip it entirely. */
1034 continue;
1035
1036 for (minimal_symbol *msymbol : objfile->msymbols ())
1037 {
1038 QUIT;
1039
1040 /* Check the symbol name first as this can be done entirely without
1041 sending any query to the target. */
1042 symname = msymbol->natural_name ();
1043 if (symname == NULL)
1044 continue;
1045
1046 if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '['))
1047 /* Not a method name. */
1048 continue;
1049
1050 objfile_csym++;
1051
1052 /* Now that thinks are a bit sane, clean up the symname. */
1053 while ((strlen (symname) + 1) >= tmplen)
1054 {
1055 tmplen = (tmplen == 0) ? 1024 : tmplen * 2;
1056 tmp = (char *) xrealloc (tmp, tmplen);
1057 }
1058 strcpy (tmp, symname);
1059
1060 if (parse_method (tmp, &ntype, &nclass,
1061 &ncategory, &nselector) == NULL)
1062 continue;
1063
1064 if ((type != '\0') && (ntype != type))
1065 continue;
1066
1067 if ((theclass != NULL)
1068 && ((nclass == NULL) || (strcmp (theclass, nclass) != 0)))
1069 continue;
1070
1071 if ((category != NULL) &&
1072 ((ncategory == NULL) || (strcmp (category, ncategory) != 0)))
1073 continue;
1074
1075 if ((selector != NULL) &&
1076 ((nselector == NULL) || (strcmp (selector, nselector) != 0)))
1077 continue;
1078
1079 symbol_names->push_back (symname);
1080 }
1081
1082 if (objc_csym == NULL)
1083 objc_csym = objc_objfile_data.emplace (objfile, objfile_csym);
1084 else
1085 /* Count of ObjC methods in this objfile should be constant. */
1086 gdb_assert (*objc_csym == objfile_csym);
1087 }
1088 }
1089
1090 /* Uniquify a vector of strings. */
1091
1092 static void
1093 uniquify_strings (std::vector<const char *> *strings)
1094 {
1095 if (strings->empty ())
1096 return;
1097
1098 std::sort (strings->begin (), strings->end (), compare_cstrings);
1099 strings->erase (std::unique (strings->begin (), strings->end (), streq),
1100 strings->end ());
1101 }
1102
1103 /*
1104 * Function: find_imps (const char *selector, struct symbol **sym_arr)
1105 *
1106 * Input: a string representing a selector
1107 * a pointer to an array of symbol pointers
1108 * possibly a pointer to a symbol found by the caller.
1109 *
1110 * Output: number of methods that implement that selector. Side
1111 * effects: The array of symbol pointers is filled with matching syms.
1112 *
1113 * By analogy with function "find_methods" (symtab.c), builds a list
1114 * of symbols matching the ambiguous input, so that "decode_line_2"
1115 * (symtab.c) can list them and ask the user to choose one or more.
1116 * In this case the matches are objective c methods
1117 * ("implementations") matching an objective c selector.
1118 *
1119 * Note that it is possible for a normal (c-style) function to have
1120 * the same name as an objective c selector. To prevent the selector
1121 * from eclipsing the function, we allow the caller (decode_line_1) to
1122 * search for such a function first, and if it finds one, pass it in
1123 * to us. We will then integrate it into the list. We also search
1124 * for one here, among the minsyms.
1125 *
1126 * NOTE: if NUM_DEBUGGABLE is non-zero, the sym_arr will be divided
1127 * into two parts: debuggable (struct symbol) syms, and
1128 * non_debuggable (struct minimal_symbol) syms. The debuggable
1129 * ones will come first, before NUM_DEBUGGABLE (which will thus
1130 * be the index of the first non-debuggable one).
1131 */
1132
1133 const char *
1134 find_imps (const char *method, std::vector<const char *> *symbol_names)
1135 {
1136 char type = '\0';
1137 char *theclass = NULL;
1138 char *category = NULL;
1139 char *selector = NULL;
1140
1141 char *buf = NULL;
1142 char *tmp = NULL;
1143
1144 int selector_case = 0;
1145
1146 gdb_assert (symbol_names != NULL);
1147
1148 buf = (char *) alloca (strlen (method) + 1);
1149 strcpy (buf, method);
1150 tmp = parse_method (buf, &type, &theclass, &category, &selector);
1151
1152 if (tmp == NULL)
1153 {
1154 strcpy (buf, method);
1155 tmp = parse_selector (buf, &selector);
1156
1157 if (tmp == NULL)
1158 return NULL;
1159
1160 selector_case = 1;
1161 }
1162
1163 find_methods (type, theclass, category, selector, symbol_names);
1164
1165 /* If we hit the "selector" case, and we found some methods, then
1166 add the selector itself as a symbol, if it exists. */
1167 if (selector_case && !symbol_names->empty ())
1168 {
1169 struct symbol *sym = lookup_symbol (selector, NULL, VAR_DOMAIN,
1170 0).symbol;
1171
1172 if (sym != NULL)
1173 symbol_names->push_back (sym->natural_name ());
1174 else
1175 {
1176 struct bound_minimal_symbol msym
1177 = lookup_minimal_symbol (selector, 0, 0);
1178
1179 if (msym.minsym != NULL)
1180 symbol_names->push_back (msym.minsym->natural_name ());
1181 }
1182 }
1183
1184 uniquify_strings (symbol_names);
1185
1186 return method + (tmp - buf);
1187 }
1188
1189 static void
1190 print_object_command (const char *args, int from_tty)
1191 {
1192 struct value *object, *function, *description;
1193 CORE_ADDR string_addr, object_addr;
1194 int i = 0;
1195 gdb_byte c = 0;
1196
1197 if (!args || !*args)
1198 error (
1199 "The 'print-object' command requires an argument (an Objective-C object)");
1200
1201 {
1202 expression_up expr = parse_expression (args);
1203 int pc = 0;
1204
1205 object = evaluate_subexp (builtin_type (expr->gdbarch)->builtin_data_ptr,
1206 expr.get (), &pc, EVAL_NORMAL);
1207 }
1208
1209 /* Validate the address for sanity. */
1210 object_addr = value_as_long (object);
1211 read_memory (object_addr, &c, 1);
1212
1213 function = find_function_in_inferior ("_NSPrintForDebugger", NULL);
1214 if (function == NULL)
1215 error (_("Unable to locate _NSPrintForDebugger in child process"));
1216
1217 description = call_function_by_hand (function, NULL, object);
1218
1219 string_addr = value_as_long (description);
1220 if (string_addr == 0)
1221 error (_("object returns null description"));
1222
1223 read_memory (string_addr + i++, &c, 1);
1224 if (c != 0)
1225 do
1226 { /* Read and print characters up to EOS. */
1227 QUIT;
1228 printf_filtered ("%c", c);
1229 read_memory (string_addr + i++, &c, 1);
1230 } while (c != 0);
1231 else
1232 printf_filtered(_("<object returns empty description>"));
1233 printf_filtered ("\n");
1234 }
1235
1236 /* The data structure 'methcalls' is used to detect method calls (thru
1237 * ObjC runtime lib functions objc_msgSend, objc_msgSendSuper, etc.),
1238 * and ultimately find the method being called.
1239 */
1240
1241 struct objc_methcall {
1242 const char *name;
1243 /* Return instance method to be called. */
1244 int (*stop_at) (CORE_ADDR, CORE_ADDR *);
1245 /* Start of pc range corresponding to method invocation. */
1246 CORE_ADDR begin;
1247 /* End of pc range corresponding to method invocation. */
1248 CORE_ADDR end;
1249 };
1250
1251 static int resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc);
1252 static int resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1253 static int resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc);
1254 static int resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1255
1256 static struct objc_methcall methcalls[] = {
1257 { "_objc_msgSend", resolve_msgsend, 0, 0},
1258 { "_objc_msgSend_stret", resolve_msgsend_stret, 0, 0},
1259 { "_objc_msgSendSuper", resolve_msgsend_super, 0, 0},
1260 { "_objc_msgSendSuper_stret", resolve_msgsend_super_stret, 0, 0},
1261 { "_objc_getClass", NULL, 0, 0},
1262 { "_objc_getMetaClass", NULL, 0, 0}
1263 };
1264
1265 #define nmethcalls (sizeof (methcalls) / sizeof (methcalls[0]))
1266
1267 /* The following function, "find_objc_msgsend", fills in the data
1268 * structure "objc_msgs" by finding the addresses of each of the
1269 * (currently four) functions that it holds (of which objc_msgSend is
1270 * the first). This must be called each time symbols are loaded, in
1271 * case the functions have moved for some reason.
1272 */
1273
1274 static void
1275 find_objc_msgsend (void)
1276 {
1277 unsigned int i;
1278
1279 for (i = 0; i < nmethcalls; i++)
1280 {
1281 struct bound_minimal_symbol func;
1282
1283 /* Try both with and without underscore. */
1284 func = lookup_bound_minimal_symbol (methcalls[i].name);
1285 if ((func.minsym == NULL) && (methcalls[i].name[0] == '_'))
1286 {
1287 func = lookup_bound_minimal_symbol (methcalls[i].name + 1);
1288 }
1289 if (func.minsym == NULL)
1290 {
1291 methcalls[i].begin = 0;
1292 methcalls[i].end = 0;
1293 continue;
1294 }
1295
1296 methcalls[i].begin = BMSYMBOL_VALUE_ADDRESS (func);
1297 methcalls[i].end = minimal_symbol_upper_bound (func);
1298 }
1299 }
1300
1301 /* find_objc_msgcall (replaces pc_off_limits)
1302 *
1303 * ALL that this function now does is to determine whether the input
1304 * address ("pc") is the address of one of the Objective-C message
1305 * dispatch functions (mainly objc_msgSend or objc_msgSendSuper), and
1306 * if so, it returns the address of the method that will be called.
1307 *
1308 * The old function "pc_off_limits" used to do a lot of other things
1309 * in addition, such as detecting shared library jump stubs and
1310 * returning the address of the shlib function that would be called.
1311 * That functionality has been moved into the gdbarch_skip_trampoline_code and
1312 * IN_SOLIB_TRAMPOLINE macros, which are resolved in the target-
1313 * dependent modules.
1314 */
1315
1316 static int
1317 find_objc_msgcall_submethod (int (*f) (CORE_ADDR, CORE_ADDR *),
1318 CORE_ADDR pc,
1319 CORE_ADDR *new_pc)
1320 {
1321 try
1322 {
1323 if (f (pc, new_pc) == 0)
1324 return 1;
1325 }
1326 catch (const gdb_exception &ex)
1327 {
1328 exception_fprintf (gdb_stderr, ex,
1329 "Unable to determine target of "
1330 "Objective-C method call (ignoring):\n");
1331 }
1332
1333 return 0;
1334 }
1335
1336 int
1337 find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc)
1338 {
1339 unsigned int i;
1340
1341 find_objc_msgsend ();
1342 if (new_pc != NULL)
1343 {
1344 *new_pc = 0;
1345 }
1346
1347 for (i = 0; i < nmethcalls; i++)
1348 if ((pc >= methcalls[i].begin) && (pc < methcalls[i].end))
1349 {
1350 if (methcalls[i].stop_at != NULL)
1351 return find_objc_msgcall_submethod (methcalls[i].stop_at,
1352 pc, new_pc);
1353 else
1354 return 0;
1355 }
1356
1357 return 0;
1358 }
1359
1360 void _initialize_objc_language ();
1361 void
1362 _initialize_objc_language ()
1363 {
1364 add_info ("selectors", info_selectors_command,
1365 _("All Objective-C selectors, or those matching REGEXP."));
1366 add_info ("classes", info_classes_command,
1367 _("All Objective-C classes, or those matching REGEXP."));
1368 add_com ("print-object", class_vars, print_object_command,
1369 _("Ask an Objective-C object to print itself."));
1370 add_com_alias ("po", "print-object", class_vars, 1);
1371 }
1372
1373 static void
1374 read_objc_method (struct gdbarch *gdbarch, CORE_ADDR addr,
1375 struct objc_method *method)
1376 {
1377 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1378
1379 method->name = read_memory_unsigned_integer (addr + 0, 4, byte_order);
1380 method->types = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1381 method->imp = read_memory_unsigned_integer (addr + 8, 4, byte_order);
1382 }
1383
1384 static unsigned long
1385 read_objc_methlist_nmethods (struct gdbarch *gdbarch, CORE_ADDR addr)
1386 {
1387 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1388
1389 return read_memory_unsigned_integer (addr + 4, 4, byte_order);
1390 }
1391
1392 static void
1393 read_objc_methlist_method (struct gdbarch *gdbarch, CORE_ADDR addr,
1394 unsigned long num, struct objc_method *method)
1395 {
1396 gdb_assert (num < read_objc_methlist_nmethods (gdbarch, addr));
1397 read_objc_method (gdbarch, addr + 8 + (12 * num), method);
1398 }
1399
1400 static void
1401 read_objc_object (struct gdbarch *gdbarch, CORE_ADDR addr,
1402 struct objc_object *object)
1403 {
1404 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1405
1406 object->isa = read_memory_unsigned_integer (addr, 4, byte_order);
1407 }
1408
1409 static void
1410 read_objc_super (struct gdbarch *gdbarch, CORE_ADDR addr,
1411 struct objc_super *super)
1412 {
1413 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1414
1415 super->receiver = read_memory_unsigned_integer (addr, 4, byte_order);
1416 super->theclass = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1417 };
1418
1419 static void
1420 read_objc_class (struct gdbarch *gdbarch, CORE_ADDR addr,
1421 struct objc_class *theclass)
1422 {
1423 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1424
1425 theclass->isa = read_memory_unsigned_integer (addr, 4, byte_order);
1426 theclass->super_class = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1427 theclass->name = read_memory_unsigned_integer (addr + 8, 4, byte_order);
1428 theclass->version = read_memory_unsigned_integer (addr + 12, 4, byte_order);
1429 theclass->info = read_memory_unsigned_integer (addr + 16, 4, byte_order);
1430 theclass->instance_size = read_memory_unsigned_integer (addr + 18, 4,
1431 byte_order);
1432 theclass->ivars = read_memory_unsigned_integer (addr + 24, 4, byte_order);
1433 theclass->methods = read_memory_unsigned_integer (addr + 28, 4, byte_order);
1434 theclass->cache = read_memory_unsigned_integer (addr + 32, 4, byte_order);
1435 theclass->protocols = read_memory_unsigned_integer (addr + 36, 4, byte_order);
1436 }
1437
1438 static CORE_ADDR
1439 find_implementation_from_class (struct gdbarch *gdbarch,
1440 CORE_ADDR theclass, CORE_ADDR sel)
1441 {
1442 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1443 CORE_ADDR subclass = theclass;
1444
1445 while (subclass != 0)
1446 {
1447
1448 struct objc_class class_str;
1449 unsigned mlistnum = 0;
1450
1451 read_objc_class (gdbarch, subclass, &class_str);
1452
1453 for (;;)
1454 {
1455 CORE_ADDR mlist;
1456 unsigned long nmethods;
1457 unsigned long i;
1458
1459 mlist = read_memory_unsigned_integer (class_str.methods +
1460 (4 * mlistnum),
1461 4, byte_order);
1462 if (mlist == 0)
1463 break;
1464
1465 nmethods = read_objc_methlist_nmethods (gdbarch, mlist);
1466
1467 for (i = 0; i < nmethods; i++)
1468 {
1469 struct objc_method meth_str;
1470
1471 read_objc_methlist_method (gdbarch, mlist, i, &meth_str);
1472
1473 if (meth_str.name == sel)
1474 /* FIXME: hppa arch was doing a pointer dereference
1475 here. There needs to be a better way to do that. */
1476 return meth_str.imp;
1477 }
1478 mlistnum++;
1479 }
1480 subclass = class_str.super_class;
1481 }
1482
1483 return 0;
1484 }
1485
1486 static CORE_ADDR
1487 find_implementation (struct gdbarch *gdbarch,
1488 CORE_ADDR object, CORE_ADDR sel)
1489 {
1490 struct objc_object ostr;
1491
1492 if (object == 0)
1493 return 0;
1494 read_objc_object (gdbarch, object, &ostr);
1495 if (ostr.isa == 0)
1496 return 0;
1497
1498 return find_implementation_from_class (gdbarch, ostr.isa, sel);
1499 }
1500
1501 static int
1502 resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc)
1503 {
1504 struct frame_info *frame = get_current_frame ();
1505 struct gdbarch *gdbarch = get_frame_arch (frame);
1506 struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1507
1508 CORE_ADDR object;
1509 CORE_ADDR sel;
1510 CORE_ADDR res;
1511
1512 object = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
1513 sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1514
1515 res = find_implementation (gdbarch, object, sel);
1516 if (new_pc != 0)
1517 *new_pc = res;
1518 if (res == 0)
1519 return 1;
1520 return 0;
1521 }
1522
1523 static int
1524 resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
1525 {
1526 struct frame_info *frame = get_current_frame ();
1527 struct gdbarch *gdbarch = get_frame_arch (frame);
1528 struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1529
1530 CORE_ADDR object;
1531 CORE_ADDR sel;
1532 CORE_ADDR res;
1533
1534 object = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1535 sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);
1536
1537 res = find_implementation (gdbarch, object, sel);
1538 if (new_pc != 0)
1539 *new_pc = res;
1540 if (res == 0)
1541 return 1;
1542 return 0;
1543 }
1544
1545 static int
1546 resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc)
1547 {
1548 struct frame_info *frame = get_current_frame ();
1549 struct gdbarch *gdbarch = get_frame_arch (frame);
1550 struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1551
1552 struct objc_super sstr;
1553
1554 CORE_ADDR super;
1555 CORE_ADDR sel;
1556 CORE_ADDR res;
1557
1558 super = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
1559 sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1560
1561 read_objc_super (gdbarch, super, &sstr);
1562 if (sstr.theclass == 0)
1563 return 0;
1564
1565 res = find_implementation_from_class (gdbarch, sstr.theclass, sel);
1566 if (new_pc != 0)
1567 *new_pc = res;
1568 if (res == 0)
1569 return 1;
1570 return 0;
1571 }
1572
1573 static int
1574 resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
1575 {
1576 struct frame_info *frame = get_current_frame ();
1577 struct gdbarch *gdbarch = get_frame_arch (frame);
1578 struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1579
1580 struct objc_super sstr;
1581
1582 CORE_ADDR super;
1583 CORE_ADDR sel;
1584 CORE_ADDR res;
1585
1586 super = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1587 sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);
1588
1589 read_objc_super (gdbarch, super, &sstr);
1590 if (sstr.theclass == 0)
1591 return 0;
1592
1593 res = find_implementation_from_class (gdbarch, sstr.theclass, sel);
1594 if (new_pc != 0)
1595 *new_pc = res;
1596 if (res == 0)
1597 return 1;
1598 return 0;
1599 }