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