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