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