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