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