Automatic date update in version.in
[deliverable/binutils-gdb.git] / gdb / objc-lang.c
1 /* Objective-C language support routines for GDB, the GNU debugger.
2
3 Copyright (C) 2002-2021 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"
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 #include "c-exp.h"
47
48 #include <ctype.h>
49 #include <algorithm>
50
51 struct objc_object {
52 CORE_ADDR isa;
53 };
54
55 struct objc_class {
56 CORE_ADDR isa;
57 CORE_ADDR super_class;
58 CORE_ADDR name;
59 long version;
60 long info;
61 long instance_size;
62 CORE_ADDR ivars;
63 CORE_ADDR methods;
64 CORE_ADDR cache;
65 CORE_ADDR protocols;
66 };
67
68 struct objc_super {
69 CORE_ADDR receiver;
70 CORE_ADDR theclass;
71 };
72
73 struct objc_method {
74 CORE_ADDR name;
75 CORE_ADDR types;
76 CORE_ADDR imp;
77 };
78
79 static const struct objfile_key<unsigned int> objc_objfile_data;
80
81 /* Lookup a structure type named "struct NAME", visible in lexical
82 block BLOCK. If NOERR is nonzero, return zero if NAME is not
83 suitably defined. */
84
85 struct symbol *
86 lookup_struct_typedef (const char *name, const struct block *block, int noerr)
87 {
88 struct symbol *sym;
89
90 sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0).symbol;
91
92 if (sym == NULL)
93 {
94 if (noerr)
95 return 0;
96 else
97 error (_("No struct type named %s."), name);
98 }
99 if (SYMBOL_TYPE (sym)->code () != TYPE_CODE_STRUCT)
100 {
101 if (noerr)
102 return 0;
103 else
104 error (_("This context has class, union or enum %s, not a struct."),
105 name);
106 }
107 return sym;
108 }
109
110 CORE_ADDR
111 lookup_objc_class (struct gdbarch *gdbarch, const char *classname)
112 {
113 struct type *char_type = builtin_type (gdbarch)->builtin_char;
114 struct value * function, *classval;
115
116 if (! target_has_execution ())
117 {
118 /* Can't call into inferior to lookup class. */
119 return 0;
120 }
121
122 if (lookup_minimal_symbol("objc_lookUpClass", 0, 0).minsym)
123 function = find_function_in_inferior("objc_lookUpClass", NULL);
124 else if (lookup_minimal_symbol ("objc_lookup_class", 0, 0).minsym)
125 function = find_function_in_inferior("objc_lookup_class", NULL);
126 else
127 {
128 complaint (_("no way to lookup Objective-C classes"));
129 return 0;
130 }
131
132 classval = value_string (classname, strlen (classname) + 1, char_type);
133 classval = value_coerce_array (classval);
134 return (CORE_ADDR) value_as_long (call_function_by_hand (function,
135 NULL,
136 classval));
137 }
138
139 CORE_ADDR
140 lookup_child_selector (struct gdbarch *gdbarch, const char *selname)
141 {
142 struct type *char_type = builtin_type (gdbarch)->builtin_char;
143 struct value * function, *selstring;
144
145 if (! target_has_execution ())
146 {
147 /* Can't call into inferior to lookup selector. */
148 return 0;
149 }
150
151 if (lookup_minimal_symbol("sel_getUid", 0, 0).minsym)
152 function = find_function_in_inferior("sel_getUid", NULL);
153 else if (lookup_minimal_symbol ("sel_get_any_uid", 0, 0).minsym)
154 function = find_function_in_inferior("sel_get_any_uid", NULL);
155 else
156 {
157 complaint (_("no way to lookup Objective-C selectors"));
158 return 0;
159 }
160
161 selstring = value_coerce_array (value_string (selname,
162 strlen (selname) + 1,
163 char_type));
164 return value_as_long (call_function_by_hand (function, NULL, selstring));
165 }
166
167 struct value *
168 value_nsstring (struct gdbarch *gdbarch, const char *ptr, int len)
169 {
170 struct type *char_type = builtin_type (gdbarch)->builtin_char;
171 struct value *stringValue[3];
172 struct value *function, *nsstringValue;
173 struct symbol *sym;
174 struct type *type;
175
176 if (!target_has_execution ())
177 return 0; /* Can't call into inferior to create NSString. */
178
179 stringValue[2] = value_string(ptr, len, char_type);
180 stringValue[2] = value_coerce_array(stringValue[2]);
181 /* _NSNewStringFromCString replaces "istr" after Lantern2A. */
182 if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0).minsym)
183 {
184 function = find_function_in_inferior("_NSNewStringFromCString", NULL);
185 nsstringValue = call_function_by_hand(function, NULL, stringValue[2]);
186 }
187 else if (lookup_minimal_symbol("istr", 0, 0).minsym)
188 {
189 function = find_function_in_inferior("istr", NULL);
190 nsstringValue = call_function_by_hand(function, NULL, stringValue[2]);
191 }
192 else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0).minsym)
193 {
194 function
195 = find_function_in_inferior("+[NSString stringWithCString:]", NULL);
196 type = builtin_type (gdbarch)->builtin_long;
197
198 stringValue[0] = value_from_longest
199 (type, lookup_objc_class (gdbarch, "NSString"));
200 stringValue[1] = value_from_longest
201 (type, lookup_child_selector (gdbarch, "stringWithCString:"));
202 nsstringValue = call_function_by_hand(function, NULL, stringValue);
203 }
204 else
205 error (_("NSString: internal error -- no way to create new NSString"));
206
207 sym = lookup_struct_typedef("NSString", 0, 1);
208 if (sym == NULL)
209 sym = lookup_struct_typedef("NXString", 0, 1);
210 if (sym == NULL)
211 type = builtin_type (gdbarch)->builtin_data_ptr;
212 else
213 type = lookup_pointer_type(SYMBOL_TYPE (sym));
214
215 deprecated_set_value_type (nsstringValue, type);
216 return nsstringValue;
217 }
218
219 /* Class representing the Objective-C language. */
220
221 class objc_language : public language_defn
222 {
223 public:
224 objc_language ()
225 : language_defn (language_objc)
226 { /* Nothing. */ }
227
228 /* See language.h. */
229
230 const char *name () const override
231 { return "objective-c"; }
232
233 /* See language.h. */
234
235 const char *natural_name () const override
236 { return "Objective-C"; }
237
238 /* See language.h. */
239
240 const std::vector<const char *> &filename_extensions () const override
241 {
242 static const std::vector<const char *> extensions = { ".m" };
243 return extensions;
244 }
245
246 /* See language.h. */
247 void language_arch_info (struct gdbarch *gdbarch,
248 struct language_arch_info *lai) const override
249 {
250 c_language_arch_info (gdbarch, lai);
251 }
252
253 /* See language.h. */
254 bool sniff_from_mangled_name (const char *mangled,
255 char **demangled) const override
256 {
257 *demangled = demangle_symbol (mangled, 0);
258 return *demangled != NULL;
259 }
260
261 /* See language.h. */
262
263 char *demangle_symbol (const char *mangled, int options) const override;
264
265 /* See language.h. */
266
267 void print_type (struct type *type, const char *varstring,
268 struct ui_file *stream, int show, int level,
269 const struct type_print_options *flags) const override
270 {
271 c_print_type (type, varstring, stream, show, level, flags);
272 }
273
274 /* See language.h. */
275
276 CORE_ADDR skip_trampoline (struct frame_info *frame,
277 CORE_ADDR stop_pc) const override
278 {
279 struct gdbarch *gdbarch = get_frame_arch (frame);
280 CORE_ADDR real_stop_pc;
281 CORE_ADDR method_stop_pc;
282
283 /* Determine if we are currently in the Objective-C dispatch function.
284 If so, get the address of the method function that the dispatcher
285 would call and use that as the function to step into instead. Also
286 skip over the trampoline for the function (if any). This is better
287 for the user since they are only interested in stepping into the
288 method function anyway. */
289
290 real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
291
292 if (real_stop_pc != 0)
293 find_objc_msgcall (real_stop_pc, &method_stop_pc);
294 else
295 find_objc_msgcall (stop_pc, &method_stop_pc);
296
297 if (method_stop_pc)
298 {
299 real_stop_pc = gdbarch_skip_trampoline_code
300 (gdbarch, frame, method_stop_pc);
301 if (real_stop_pc == 0)
302 real_stop_pc = method_stop_pc;
303 }
304
305 return real_stop_pc;
306 }
307
308 /* See language.h. */
309
310 const char *name_of_this () const override
311 { return "self"; }
312
313 /* See language.h. */
314
315 enum macro_expansion macro_expansion () const override
316 { return macro_expansion_c; }
317 };
318
319 /* See declaration of objc_language::demangle_symbol above. */
320
321 char *
322 objc_language::demangle_symbol (const char *mangled, int options) const
323 {
324 char *demangled, *cp;
325
326 if (mangled[0] == '_'
327 && (mangled[1] == 'i' || mangled[1] == 'c')
328 && mangled[2] == '_')
329 {
330 cp = demangled = (char *) xmalloc (strlen (mangled) + 2);
331
332 if (mangled[1] == 'i')
333 *cp++ = '-'; /* for instance method */
334 else
335 *cp++ = '+'; /* for class method */
336
337 *cp++ = '['; /* opening left brace */
338 strcpy(cp, mangled+3); /* Tack on the rest of the mangled name. */
339
340 while (*cp != '\0' && *cp == '_')
341 cp++; /* Skip any initial underbars in class
342 name. */
343
344 cp = strchr(cp, '_');
345 if (cp == nullptr) /* Find first non-initial underbar. */
346 {
347 xfree(demangled); /* not mangled name */
348 return nullptr;
349 }
350 if (cp[1] == '_') /* Easy case: no category name. */
351 {
352 *cp++ = ' '; /* Replace two '_' with one ' '. */
353 strcpy(cp, mangled + (cp - demangled) + 2);
354 }
355 else
356 {
357 *cp++ = '('; /* Less easy case: category name. */
358 cp = strchr(cp, '_');
359 if (cp == nullptr)
360 {
361 xfree(demangled); /* not mangled name */
362 return nullptr;
363 }
364 *cp++ = ')';
365 *cp++ = ' '; /* Overwriting 1st char of method name... */
366 strcpy(cp, mangled + (cp - demangled)); /* Get it back. */
367 }
368
369 while (*cp != '\0' && *cp == '_')
370 cp++; /* Skip any initial underbars in
371 method name. */
372
373 for (; *cp != '\0'; cp++)
374 if (*cp == '_')
375 *cp = ':'; /* Replace remaining '_' with ':'. */
376
377 *cp++ = ']'; /* closing right brace */
378 *cp++ = 0; /* string terminator */
379 return demangled;
380 }
381 else
382 return nullptr; /* Not an objc mangled name. */
383 }
384
385 /* Single instance of the class representing the Objective-C language. */
386
387 static objc_language objc_language_defn;
388
389 /*
390 * ObjC:
391 * Following functions help construct Objective-C message calls.
392 */
393
394 struct selname /* For parsing Objective-C. */
395 {
396 struct selname *next;
397 char *msglist_sel;
398 int msglist_len;
399 };
400
401 static int msglist_len;
402 static struct selname *selname_chain;
403 static char *msglist_sel;
404
405 void
406 start_msglist(void)
407 {
408 struct selname *newobj = XNEW (struct selname);
409
410 newobj->next = selname_chain;
411 newobj->msglist_len = msglist_len;
412 newobj->msglist_sel = msglist_sel;
413 msglist_len = 0;
414 msglist_sel = (char *)xmalloc(1);
415 *msglist_sel = 0;
416 selname_chain = newobj;
417 }
418
419 void
420 add_msglist(struct stoken *str, int addcolon)
421 {
422 char *s;
423 const char *p;
424 int len, plen;
425
426 if (str == 0) /* Unnamed arg, or... */
427 {
428 if (addcolon == 0) /* variable number of args. */
429 {
430 msglist_len++;
431 return;
432 }
433 p = "";
434 plen = 0;
435 }
436 else
437 {
438 p = str->ptr;
439 plen = str->length;
440 }
441 len = plen + strlen(msglist_sel) + 2;
442 s = (char *)xmalloc(len);
443 strcpy(s, msglist_sel);
444 strncat(s, p, plen);
445 xfree(msglist_sel);
446 msglist_sel = s;
447 if (addcolon)
448 {
449 s[len-2] = ':';
450 s[len-1] = 0;
451 msglist_len++;
452 }
453 else
454 s[len-2] = '\0';
455 }
456
457 int
458 end_msglist (struct parser_state *ps)
459 {
460 int val = msglist_len;
461 struct selname *sel = selname_chain;
462 char *p = msglist_sel;
463 CORE_ADDR selid;
464
465 std::vector<expr::operation_up> args = ps->pop_vector (val);
466 expr::operation_up target = ps->pop ();
467
468 selname_chain = sel->next;
469 msglist_len = sel->msglist_len;
470 msglist_sel = sel->msglist_sel;
471 selid = lookup_child_selector (ps->gdbarch (), p);
472 if (!selid)
473 error (_("Can't find selector \"%s\""), p);
474
475 ps->push_new<expr::objc_msgcall_operation> (selid, std::move (target),
476 std::move (args));
477
478 xfree(p);
479 xfree(sel);
480
481 return val;
482 }
483
484 /*
485 * Function: specialcmp (const char *a, const char *b)
486 *
487 * Special strcmp: treats ']' and ' ' as end-of-string.
488 * Used for qsorting lists of objc methods (either by class or selector).
489 */
490
491 static int
492 specialcmp (const char *a, const char *b)
493 {
494 while (*a && *a != ' ' && *a != ']' && *b && *b != ' ' && *b != ']')
495 {
496 if (*a != *b)
497 return *a - *b;
498 a++, b++;
499 }
500 if (*a && *a != ' ' && *a != ']')
501 return 1; /* a is longer therefore greater. */
502 if (*b && *b != ' ' && *b != ']')
503 return -1; /* a is shorter therefore lesser. */
504 return 0; /* a and b are identical. */
505 }
506
507 /*
508 * Function: compare_selectors (const void *, const void *)
509 *
510 * Comparison function for use with qsort. Arguments are symbols or
511 * msymbols Compares selector part of objc method name alphabetically.
512 */
513
514 static int
515 compare_selectors (const void *a, const void *b)
516 {
517 const char *aname, *bname;
518
519 aname = (*(struct symbol **) a)->print_name ();
520 bname = (*(struct symbol **) b)->print_name ();
521 if (aname == NULL || bname == NULL)
522 error (_("internal: compare_selectors(1)"));
523
524 aname = strchr(aname, ' ');
525 bname = strchr(bname, ' ');
526 if (aname == NULL || bname == NULL)
527 error (_("internal: compare_selectors(2)"));
528
529 return specialcmp (aname+1, bname+1);
530 }
531
532 /*
533 * Function: selectors_info (regexp, from_tty)
534 *
535 * Implements the "Info selectors" command. Takes an optional regexp
536 * arg. Lists all objective c selectors that match the regexp. Works
537 * by grepping thru all symbols for objective c methods. Output list
538 * is sorted and uniqued.
539 */
540
541 static void
542 info_selectors_command (const char *regexp, int from_tty)
543 {
544 const char *name;
545 char *val;
546 int matches = 0;
547 int maxlen = 0;
548 int ix;
549 char myregexp[2048];
550 char asel[256];
551 struct symbol **sym_arr;
552 int plusminus = 0;
553
554 if (regexp == NULL)
555 strcpy(myregexp, ".*]"); /* Null input, match all objc methods. */
556 else
557 {
558 if (*regexp == '+' || *regexp == '-')
559 { /* User wants only class methods or only instance methods. */
560 plusminus = *regexp++;
561 while (*regexp == ' ' || *regexp == '\t')
562 regexp++;
563 }
564 if (*regexp == '\0')
565 strcpy(myregexp, ".*]");
566 else
567 {
568 /* Allow a few extra bytes because of the strcat below. */
569 if (sizeof (myregexp) < strlen (regexp) + 4)
570 error (_("Regexp is too long: %s"), regexp);
571 strcpy(myregexp, regexp);
572 if (myregexp[strlen(myregexp) - 1] == '$') /* end of selector */
573 myregexp[strlen(myregexp) - 1] = ']'; /* end of method name */
574 else
575 strcat(myregexp, ".*]");
576 }
577 }
578
579 if (regexp != NULL)
580 {
581 val = re_comp (myregexp);
582 if (val != 0)
583 error (_("Invalid regexp (%s): %s"), val, regexp);
584 }
585
586 /* First time thru is JUST to get max length and count. */
587 for (objfile *objfile : current_program_space->objfiles ())
588 {
589 for (minimal_symbol *msymbol : objfile->msymbols ())
590 {
591 QUIT;
592 name = msymbol->natural_name ();
593 if (name
594 && (name[0] == '-' || name[0] == '+')
595 && name[1] == '[') /* Got a method name. */
596 {
597 /* Filter for class/instance methods. */
598 if (plusminus && name[0] != plusminus)
599 continue;
600 /* Find selector part. */
601 name = (char *) strchr (name+2, ' ');
602 if (name == NULL)
603 {
604 complaint (_("Bad method name '%s'"),
605 msymbol->natural_name ());
606 continue;
607 }
608 if (regexp == NULL || re_exec(++name) != 0)
609 {
610 const char *mystart = name;
611 const char *myend = strchr (mystart, ']');
612
613 if (myend && (myend - mystart > maxlen))
614 maxlen = myend - mystart; /* Get longest selector. */
615 matches++;
616 }
617 }
618 }
619 }
620 if (matches)
621 {
622 printf_filtered (_("Selectors matching \"%s\":\n\n"),
623 regexp ? regexp : "*");
624
625 sym_arr = XALLOCAVEC (struct symbol *, matches);
626 matches = 0;
627 for (objfile *objfile : current_program_space->objfiles ())
628 {
629 for (minimal_symbol *msymbol : objfile->msymbols ())
630 {
631 QUIT;
632 name = msymbol->natural_name ();
633 if (name &&
634 (name[0] == '-' || name[0] == '+') &&
635 name[1] == '[') /* Got a method name. */
636 {
637 /* Filter for class/instance methods. */
638 if (plusminus && name[0] != plusminus)
639 continue;
640 /* Find selector part. */
641 name = (char *) strchr(name+2, ' ');
642 if (regexp == NULL || re_exec(++name) != 0)
643 sym_arr[matches++] = (struct symbol *) msymbol;
644 }
645 }
646 }
647
648 qsort (sym_arr, matches, sizeof (struct minimal_symbol *),
649 compare_selectors);
650 /* Prevent compare on first iteration. */
651 asel[0] = 0;
652 for (ix = 0; ix < matches; ix++) /* Now do the output. */
653 {
654 char *p = asel;
655
656 QUIT;
657 name = sym_arr[ix]->natural_name ();
658 name = strchr (name, ' ') + 1;
659 if (p[0] && specialcmp(name, p) == 0)
660 continue; /* Seen this one already (not unique). */
661
662 /* Copy selector part. */
663 while (*name && *name != ']')
664 *p++ = *name++;
665 *p++ = '\0';
666 /* Print in columns. */
667 puts_filtered_tabular(asel, maxlen + 1, 0);
668 }
669 begin_line();
670 }
671 else
672 printf_filtered (_("No selectors matching \"%s\"\n"),
673 regexp ? regexp : "*");
674 }
675
676 /*
677 * Function: compare_classes (const void *, const void *)
678 *
679 * Comparison function for use with qsort. Arguments are symbols or
680 * msymbols Compares class part of objc method name alphabetically.
681 */
682
683 static int
684 compare_classes (const void *a, const void *b)
685 {
686 const char *aname, *bname;
687
688 aname = (*(struct symbol **) a)->print_name ();
689 bname = (*(struct symbol **) b)->print_name ();
690 if (aname == NULL || bname == NULL)
691 error (_("internal: compare_classes(1)"));
692
693 return specialcmp (aname+1, bname+1);
694 }
695
696 /*
697 * Function: classes_info(regexp, from_tty)
698 *
699 * Implements the "info classes" command for objective c classes.
700 * Lists all objective c classes that match the optional regexp.
701 * Works by grepping thru the list of objective c methods. List will
702 * be sorted and uniqued (since one class may have many methods).
703 * BUGS: will not list a class that has no methods.
704 */
705
706 static void
707 info_classes_command (const char *regexp, int from_tty)
708 {
709 const char *name;
710 char *val;
711 int matches = 0;
712 int maxlen = 0;
713 int ix;
714 char myregexp[2048];
715 char aclass[256];
716 struct symbol **sym_arr;
717
718 if (regexp == NULL)
719 strcpy(myregexp, ".* "); /* Null input: match all objc classes. */
720 else
721 {
722 /* Allow a few extra bytes because of the strcat below. */
723 if (sizeof (myregexp) < strlen (regexp) + 4)
724 error (_("Regexp is too long: %s"), regexp);
725 strcpy(myregexp, regexp);
726 if (myregexp[strlen(myregexp) - 1] == '$')
727 /* In the method name, the end of the class name is marked by ' '. */
728 myregexp[strlen(myregexp) - 1] = ' ';
729 else
730 strcat(myregexp, ".* ");
731 }
732
733 if (regexp != NULL)
734 {
735 val = re_comp (myregexp);
736 if (val != 0)
737 error (_("Invalid regexp (%s): %s"), val, regexp);
738 }
739
740 /* First time thru is JUST to get max length and count. */
741 for (objfile *objfile : current_program_space->objfiles ())
742 {
743 for (minimal_symbol *msymbol : objfile->msymbols ())
744 {
745 QUIT;
746 name = msymbol->natural_name ();
747 if (name &&
748 (name[0] == '-' || name[0] == '+') &&
749 name[1] == '[') /* Got a method name. */
750 if (regexp == NULL || re_exec(name+2) != 0)
751 {
752 /* Compute length of classname part. */
753 const char *mystart = name + 2;
754 const char *myend = strchr (mystart, ' ');
755
756 if (myend && (myend - mystart > maxlen))
757 maxlen = myend - mystart;
758 matches++;
759 }
760 }
761 }
762 if (matches)
763 {
764 printf_filtered (_("Classes matching \"%s\":\n\n"),
765 regexp ? regexp : "*");
766 sym_arr = XALLOCAVEC (struct symbol *, matches);
767 matches = 0;
768 for (objfile *objfile : current_program_space->objfiles ())
769 {
770 for (minimal_symbol *msymbol : objfile->msymbols ())
771 {
772 QUIT;
773 name = msymbol->natural_name ();
774 if (name &&
775 (name[0] == '-' || name[0] == '+') &&
776 name[1] == '[') /* Got a method name. */
777 if (regexp == NULL || re_exec(name+2) != 0)
778 sym_arr[matches++] = (struct symbol *) msymbol;
779 }
780 }
781
782 qsort (sym_arr, matches, sizeof (struct minimal_symbol *),
783 compare_classes);
784 /* Prevent compare on first iteration. */
785 aclass[0] = 0;
786 for (ix = 0; ix < matches; ix++) /* Now do the output. */
787 {
788 char *p = aclass;
789
790 QUIT;
791 name = sym_arr[ix]->natural_name ();
792 name += 2;
793 if (p[0] && specialcmp(name, p) == 0)
794 continue; /* Seen this one already (not unique). */
795
796 /* Copy class part of method name. */
797 while (*name && *name != ' ')
798 *p++ = *name++;
799 *p++ = '\0';
800 /* Print in columns. */
801 puts_filtered_tabular(aclass, maxlen + 1, 0);
802 }
803 begin_line();
804 }
805 else
806 printf_filtered (_("No classes matching \"%s\"\n"), regexp ? regexp : "*");
807 }
808
809 static char *
810 parse_selector (char *method, char **selector)
811 {
812 char *s1 = NULL;
813 char *s2 = NULL;
814 int found_quote = 0;
815
816 char *nselector = NULL;
817
818 gdb_assert (selector != NULL);
819
820 s1 = method;
821
822 s1 = skip_spaces (s1);
823 if (*s1 == '\'')
824 {
825 found_quote = 1;
826 s1++;
827 }
828 s1 = skip_spaces (s1);
829
830 nselector = s1;
831 s2 = s1;
832
833 for (;;)
834 {
835 if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
836 *s1++ = *s2;
837 else if (isspace (*s2))
838 ;
839 else if ((*s2 == '\0') || (*s2 == '\''))
840 break;
841 else
842 return NULL;
843 s2++;
844 }
845 *s1++ = '\0';
846
847 s2 = skip_spaces (s2);
848 if (found_quote)
849 {
850 if (*s2 == '\'')
851 s2++;
852 s2 = skip_spaces (s2);
853 }
854
855 if (selector != NULL)
856 *selector = nselector;
857
858 return s2;
859 }
860
861 static char *
862 parse_method (char *method, char *type, char **theclass,
863 char **category, char **selector)
864 {
865 char *s1 = NULL;
866 char *s2 = NULL;
867 int found_quote = 0;
868
869 char ntype = '\0';
870 char *nclass = NULL;
871 char *ncategory = NULL;
872 char *nselector = NULL;
873
874 gdb_assert (type != NULL);
875 gdb_assert (theclass != NULL);
876 gdb_assert (category != NULL);
877 gdb_assert (selector != NULL);
878
879 s1 = method;
880
881 s1 = skip_spaces (s1);
882 if (*s1 == '\'')
883 {
884 found_quote = 1;
885 s1++;
886 }
887 s1 = skip_spaces (s1);
888
889 if ((s1[0] == '+') || (s1[0] == '-'))
890 ntype = *s1++;
891
892 s1 = skip_spaces (s1);
893
894 if (*s1 != '[')
895 return NULL;
896 s1++;
897
898 nclass = s1;
899 while (isalnum (*s1) || (*s1 == '_'))
900 s1++;
901
902 s2 = s1;
903 s2 = skip_spaces (s2);
904
905 if (*s2 == '(')
906 {
907 s2++;
908 s2 = skip_spaces (s2);
909 ncategory = s2;
910 while (isalnum (*s2) || (*s2 == '_'))
911 s2++;
912 *s2++ = '\0';
913 }
914
915 /* Truncate the class name now that we're not using the open paren. */
916 *s1++ = '\0';
917
918 nselector = s2;
919 s1 = s2;
920
921 for (;;)
922 {
923 if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
924 *s1++ = *s2;
925 else if (isspace (*s2))
926 ;
927 else if (*s2 == ']')
928 break;
929 else
930 return NULL;
931 s2++;
932 }
933 *s1++ = '\0';
934 s2++;
935
936 s2 = skip_spaces (s2);
937 if (found_quote)
938 {
939 if (*s2 != '\'')
940 return NULL;
941 s2++;
942 s2 = skip_spaces (s2);
943 }
944
945 if (type != NULL)
946 *type = ntype;
947 if (theclass != NULL)
948 *theclass = nclass;
949 if (category != NULL)
950 *category = ncategory;
951 if (selector != NULL)
952 *selector = nselector;
953
954 return s2;
955 }
956
957 static void
958 find_methods (char type, const char *theclass, const char *category,
959 const char *selector,
960 std::vector<const char *> *symbol_names)
961 {
962 const char *symname = NULL;
963
964 char ntype = '\0';
965 char *nclass = NULL;
966 char *ncategory = NULL;
967 char *nselector = NULL;
968
969 static char *tmp = NULL;
970 static unsigned int tmplen = 0;
971
972 gdb_assert (symbol_names != NULL);
973
974 for (objfile *objfile : current_program_space->objfiles ())
975 {
976 unsigned int *objc_csym;
977
978 /* The objfile_csym variable counts the number of ObjC methods
979 that this objfile defines. We save that count as a private
980 objfile data. If we have already determined that this objfile
981 provides no ObjC methods, we can skip it entirely. */
982
983 unsigned int objfile_csym = 0;
984
985 objc_csym = objc_objfile_data.get (objfile);
986 if (objc_csym != NULL && *objc_csym == 0)
987 /* There are no ObjC symbols in this objfile. Skip it entirely. */
988 continue;
989
990 for (minimal_symbol *msymbol : objfile->msymbols ())
991 {
992 QUIT;
993
994 /* Check the symbol name first as this can be done entirely without
995 sending any query to the target. */
996 symname = msymbol->natural_name ();
997 if (symname == NULL)
998 continue;
999
1000 if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '['))
1001 /* Not a method name. */
1002 continue;
1003
1004 objfile_csym++;
1005
1006 /* Now that thinks are a bit sane, clean up the symname. */
1007 while ((strlen (symname) + 1) >= tmplen)
1008 {
1009 tmplen = (tmplen == 0) ? 1024 : tmplen * 2;
1010 tmp = (char *) xrealloc (tmp, tmplen);
1011 }
1012 strcpy (tmp, symname);
1013
1014 if (parse_method (tmp, &ntype, &nclass,
1015 &ncategory, &nselector) == NULL)
1016 continue;
1017
1018 if ((type != '\0') && (ntype != type))
1019 continue;
1020
1021 if ((theclass != NULL)
1022 && ((nclass == NULL) || (strcmp (theclass, nclass) != 0)))
1023 continue;
1024
1025 if ((category != NULL) &&
1026 ((ncategory == NULL) || (strcmp (category, ncategory) != 0)))
1027 continue;
1028
1029 if ((selector != NULL) &&
1030 ((nselector == NULL) || (strcmp (selector, nselector) != 0)))
1031 continue;
1032
1033 symbol_names->push_back (symname);
1034 }
1035
1036 if (objc_csym == NULL)
1037 objc_csym = objc_objfile_data.emplace (objfile, objfile_csym);
1038 else
1039 /* Count of ObjC methods in this objfile should be constant. */
1040 gdb_assert (*objc_csym == objfile_csym);
1041 }
1042 }
1043
1044 /* Uniquify a vector of strings. */
1045
1046 static void
1047 uniquify_strings (std::vector<const char *> *strings)
1048 {
1049 if (strings->empty ())
1050 return;
1051
1052 std::sort (strings->begin (), strings->end (), compare_cstrings);
1053 strings->erase (std::unique (strings->begin (), strings->end (), streq),
1054 strings->end ());
1055 }
1056
1057 /*
1058 * Function: find_imps (const char *selector, struct symbol **sym_arr)
1059 *
1060 * Input: a string representing a selector
1061 * a pointer to an array of symbol pointers
1062 * possibly a pointer to a symbol found by the caller.
1063 *
1064 * Output: number of methods that implement that selector. Side
1065 * effects: The array of symbol pointers is filled with matching syms.
1066 *
1067 * By analogy with function "find_methods" (symtab.c), builds a list
1068 * of symbols matching the ambiguous input, so that "decode_line_2"
1069 * (symtab.c) can list them and ask the user to choose one or more.
1070 * In this case the matches are objective c methods
1071 * ("implementations") matching an objective c selector.
1072 *
1073 * Note that it is possible for a normal (c-style) function to have
1074 * the same name as an objective c selector. To prevent the selector
1075 * from eclipsing the function, we allow the caller (decode_line_1) to
1076 * search for such a function first, and if it finds one, pass it in
1077 * to us. We will then integrate it into the list. We also search
1078 * for one here, among the minsyms.
1079 *
1080 * NOTE: if NUM_DEBUGGABLE is non-zero, the sym_arr will be divided
1081 * into two parts: debuggable (struct symbol) syms, and
1082 * non_debuggable (struct minimal_symbol) syms. The debuggable
1083 * ones will come first, before NUM_DEBUGGABLE (which will thus
1084 * be the index of the first non-debuggable one).
1085 */
1086
1087 const char *
1088 find_imps (const char *method, std::vector<const char *> *symbol_names)
1089 {
1090 char type = '\0';
1091 char *theclass = NULL;
1092 char *category = NULL;
1093 char *selector = NULL;
1094
1095 char *buf = NULL;
1096 char *tmp = NULL;
1097
1098 int selector_case = 0;
1099
1100 gdb_assert (symbol_names != NULL);
1101
1102 buf = (char *) alloca (strlen (method) + 1);
1103 strcpy (buf, method);
1104 tmp = parse_method (buf, &type, &theclass, &category, &selector);
1105
1106 if (tmp == NULL)
1107 {
1108 strcpy (buf, method);
1109 tmp = parse_selector (buf, &selector);
1110
1111 if (tmp == NULL)
1112 return NULL;
1113
1114 selector_case = 1;
1115 }
1116
1117 find_methods (type, theclass, category, selector, symbol_names);
1118
1119 /* If we hit the "selector" case, and we found some methods, then
1120 add the selector itself as a symbol, if it exists. */
1121 if (selector_case && !symbol_names->empty ())
1122 {
1123 struct symbol *sym = lookup_symbol (selector, NULL, VAR_DOMAIN,
1124 0).symbol;
1125
1126 if (sym != NULL)
1127 symbol_names->push_back (sym->natural_name ());
1128 else
1129 {
1130 struct bound_minimal_symbol msym
1131 = lookup_minimal_symbol (selector, 0, 0);
1132
1133 if (msym.minsym != NULL)
1134 symbol_names->push_back (msym.minsym->natural_name ());
1135 }
1136 }
1137
1138 uniquify_strings (symbol_names);
1139
1140 return method + (tmp - buf);
1141 }
1142
1143 static void
1144 print_object_command (const char *args, int from_tty)
1145 {
1146 struct value *object, *function, *description;
1147 CORE_ADDR string_addr, object_addr;
1148 int i = 0;
1149 gdb_byte c = 0;
1150
1151 if (!args || !*args)
1152 error (
1153 "The 'print-object' command requires an argument (an Objective-C object)");
1154
1155 {
1156 expression_up expr = parse_expression (args);
1157
1158 object
1159 = evaluate_expression (expr.get (),
1160 builtin_type (expr->gdbarch)->builtin_data_ptr);
1161 }
1162
1163 /* Validate the address for sanity. */
1164 object_addr = value_as_long (object);
1165 read_memory (object_addr, &c, 1);
1166
1167 function = find_function_in_inferior ("_NSPrintForDebugger", NULL);
1168 if (function == NULL)
1169 error (_("Unable to locate _NSPrintForDebugger in child process"));
1170
1171 description = call_function_by_hand (function, NULL, object);
1172
1173 string_addr = value_as_long (description);
1174 if (string_addr == 0)
1175 error (_("object returns null description"));
1176
1177 read_memory (string_addr + i++, &c, 1);
1178 if (c != 0)
1179 do
1180 { /* Read and print characters up to EOS. */
1181 QUIT;
1182 printf_filtered ("%c", c);
1183 read_memory (string_addr + i++, &c, 1);
1184 } while (c != 0);
1185 else
1186 printf_filtered(_("<object returns empty description>"));
1187 printf_filtered ("\n");
1188 }
1189
1190 /* The data structure 'methcalls' is used to detect method calls (thru
1191 * ObjC runtime lib functions objc_msgSend, objc_msgSendSuper, etc.),
1192 * and ultimately find the method being called.
1193 */
1194
1195 struct objc_methcall {
1196 const char *name;
1197 /* Return instance method to be called. */
1198 int (*stop_at) (CORE_ADDR, CORE_ADDR *);
1199 /* Start of pc range corresponding to method invocation. */
1200 CORE_ADDR begin;
1201 /* End of pc range corresponding to method invocation. */
1202 CORE_ADDR end;
1203 };
1204
1205 static int resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc);
1206 static int resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1207 static int resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc);
1208 static int resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1209
1210 static struct objc_methcall methcalls[] = {
1211 { "_objc_msgSend", resolve_msgsend, 0, 0},
1212 { "_objc_msgSend_stret", resolve_msgsend_stret, 0, 0},
1213 { "_objc_msgSendSuper", resolve_msgsend_super, 0, 0},
1214 { "_objc_msgSendSuper_stret", resolve_msgsend_super_stret, 0, 0},
1215 { "_objc_getClass", NULL, 0, 0},
1216 { "_objc_getMetaClass", NULL, 0, 0}
1217 };
1218
1219 #define nmethcalls (sizeof (methcalls) / sizeof (methcalls[0]))
1220
1221 /* The following function, "find_objc_msgsend", fills in the data
1222 * structure "objc_msgs" by finding the addresses of each of the
1223 * (currently four) functions that it holds (of which objc_msgSend is
1224 * the first). This must be called each time symbols are loaded, in
1225 * case the functions have moved for some reason.
1226 */
1227
1228 static void
1229 find_objc_msgsend (void)
1230 {
1231 unsigned int i;
1232
1233 for (i = 0; i < nmethcalls; i++)
1234 {
1235 struct bound_minimal_symbol func;
1236
1237 /* Try both with and without underscore. */
1238 func = lookup_bound_minimal_symbol (methcalls[i].name);
1239 if ((func.minsym == NULL) && (methcalls[i].name[0] == '_'))
1240 {
1241 func = lookup_bound_minimal_symbol (methcalls[i].name + 1);
1242 }
1243 if (func.minsym == NULL)
1244 {
1245 methcalls[i].begin = 0;
1246 methcalls[i].end = 0;
1247 continue;
1248 }
1249
1250 methcalls[i].begin = BMSYMBOL_VALUE_ADDRESS (func);
1251 methcalls[i].end = minimal_symbol_upper_bound (func);
1252 }
1253 }
1254
1255 /* find_objc_msgcall (replaces pc_off_limits)
1256 *
1257 * ALL that this function now does is to determine whether the input
1258 * address ("pc") is the address of one of the Objective-C message
1259 * dispatch functions (mainly objc_msgSend or objc_msgSendSuper), and
1260 * if so, it returns the address of the method that will be called.
1261 *
1262 * The old function "pc_off_limits" used to do a lot of other things
1263 * in addition, such as detecting shared library jump stubs and
1264 * returning the address of the shlib function that would be called.
1265 * That functionality has been moved into the gdbarch_skip_trampoline_code and
1266 * IN_SOLIB_TRAMPOLINE macros, which are resolved in the target-
1267 * dependent modules.
1268 */
1269
1270 static int
1271 find_objc_msgcall_submethod (int (*f) (CORE_ADDR, CORE_ADDR *),
1272 CORE_ADDR pc,
1273 CORE_ADDR *new_pc)
1274 {
1275 try
1276 {
1277 if (f (pc, new_pc) == 0)
1278 return 1;
1279 }
1280 catch (const gdb_exception &ex)
1281 {
1282 exception_fprintf (gdb_stderr, ex,
1283 "Unable to determine target of "
1284 "Objective-C method call (ignoring):\n");
1285 }
1286
1287 return 0;
1288 }
1289
1290 int
1291 find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc)
1292 {
1293 unsigned int i;
1294
1295 find_objc_msgsend ();
1296 if (new_pc != NULL)
1297 {
1298 *new_pc = 0;
1299 }
1300
1301 for (i = 0; i < nmethcalls; i++)
1302 if ((pc >= methcalls[i].begin) && (pc < methcalls[i].end))
1303 {
1304 if (methcalls[i].stop_at != NULL)
1305 return find_objc_msgcall_submethod (methcalls[i].stop_at,
1306 pc, new_pc);
1307 else
1308 return 0;
1309 }
1310
1311 return 0;
1312 }
1313
1314 void _initialize_objc_language ();
1315 void
1316 _initialize_objc_language ()
1317 {
1318 add_info ("selectors", info_selectors_command,
1319 _("All Objective-C selectors, or those matching REGEXP."));
1320 add_info ("classes", info_classes_command,
1321 _("All Objective-C classes, or those matching REGEXP."));
1322 cmd_list_element *print_object_cmd
1323 = add_com ("print-object", class_vars, print_object_command,
1324 _("Ask an Objective-C object to print itself."));
1325 add_com_alias ("po", print_object_cmd, class_vars, 1);
1326 }
1327
1328 static void
1329 read_objc_method (struct gdbarch *gdbarch, CORE_ADDR addr,
1330 struct objc_method *method)
1331 {
1332 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1333
1334 method->name = read_memory_unsigned_integer (addr + 0, 4, byte_order);
1335 method->types = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1336 method->imp = read_memory_unsigned_integer (addr + 8, 4, byte_order);
1337 }
1338
1339 static unsigned long
1340 read_objc_methlist_nmethods (struct gdbarch *gdbarch, CORE_ADDR addr)
1341 {
1342 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1343
1344 return read_memory_unsigned_integer (addr + 4, 4, byte_order);
1345 }
1346
1347 static void
1348 read_objc_methlist_method (struct gdbarch *gdbarch, CORE_ADDR addr,
1349 unsigned long num, struct objc_method *method)
1350 {
1351 gdb_assert (num < read_objc_methlist_nmethods (gdbarch, addr));
1352 read_objc_method (gdbarch, addr + 8 + (12 * num), method);
1353 }
1354
1355 static void
1356 read_objc_object (struct gdbarch *gdbarch, CORE_ADDR addr,
1357 struct objc_object *object)
1358 {
1359 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1360
1361 object->isa = read_memory_unsigned_integer (addr, 4, byte_order);
1362 }
1363
1364 static void
1365 read_objc_super (struct gdbarch *gdbarch, CORE_ADDR addr,
1366 struct objc_super *super)
1367 {
1368 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1369
1370 super->receiver = read_memory_unsigned_integer (addr, 4, byte_order);
1371 super->theclass = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1372 };
1373
1374 static void
1375 read_objc_class (struct gdbarch *gdbarch, CORE_ADDR addr,
1376 struct objc_class *theclass)
1377 {
1378 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1379
1380 theclass->isa = read_memory_unsigned_integer (addr, 4, byte_order);
1381 theclass->super_class = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1382 theclass->name = read_memory_unsigned_integer (addr + 8, 4, byte_order);
1383 theclass->version = read_memory_unsigned_integer (addr + 12, 4, byte_order);
1384 theclass->info = read_memory_unsigned_integer (addr + 16, 4, byte_order);
1385 theclass->instance_size = read_memory_unsigned_integer (addr + 18, 4,
1386 byte_order);
1387 theclass->ivars = read_memory_unsigned_integer (addr + 24, 4, byte_order);
1388 theclass->methods = read_memory_unsigned_integer (addr + 28, 4, byte_order);
1389 theclass->cache = read_memory_unsigned_integer (addr + 32, 4, byte_order);
1390 theclass->protocols = read_memory_unsigned_integer (addr + 36, 4, byte_order);
1391 }
1392
1393 static CORE_ADDR
1394 find_implementation_from_class (struct gdbarch *gdbarch,
1395 CORE_ADDR theclass, CORE_ADDR sel)
1396 {
1397 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1398 CORE_ADDR subclass = theclass;
1399
1400 while (subclass != 0)
1401 {
1402
1403 struct objc_class class_str;
1404 unsigned mlistnum = 0;
1405
1406 read_objc_class (gdbarch, subclass, &class_str);
1407
1408 for (;;)
1409 {
1410 CORE_ADDR mlist;
1411 unsigned long nmethods;
1412 unsigned long i;
1413
1414 mlist = read_memory_unsigned_integer (class_str.methods +
1415 (4 * mlistnum),
1416 4, byte_order);
1417 if (mlist == 0)
1418 break;
1419
1420 nmethods = read_objc_methlist_nmethods (gdbarch, mlist);
1421
1422 for (i = 0; i < nmethods; i++)
1423 {
1424 struct objc_method meth_str;
1425
1426 read_objc_methlist_method (gdbarch, mlist, i, &meth_str);
1427
1428 if (meth_str.name == sel)
1429 /* FIXME: hppa arch was doing a pointer dereference
1430 here. There needs to be a better way to do that. */
1431 return meth_str.imp;
1432 }
1433 mlistnum++;
1434 }
1435 subclass = class_str.super_class;
1436 }
1437
1438 return 0;
1439 }
1440
1441 static CORE_ADDR
1442 find_implementation (struct gdbarch *gdbarch,
1443 CORE_ADDR object, CORE_ADDR sel)
1444 {
1445 struct objc_object ostr;
1446
1447 if (object == 0)
1448 return 0;
1449 read_objc_object (gdbarch, object, &ostr);
1450 if (ostr.isa == 0)
1451 return 0;
1452
1453 return find_implementation_from_class (gdbarch, ostr.isa, sel);
1454 }
1455
1456 static int
1457 resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc)
1458 {
1459 struct frame_info *frame = get_current_frame ();
1460 struct gdbarch *gdbarch = get_frame_arch (frame);
1461 struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1462
1463 CORE_ADDR object;
1464 CORE_ADDR sel;
1465 CORE_ADDR res;
1466
1467 object = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
1468 sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1469
1470 res = find_implementation (gdbarch, object, sel);
1471 if (new_pc != 0)
1472 *new_pc = res;
1473 if (res == 0)
1474 return 1;
1475 return 0;
1476 }
1477
1478 static int
1479 resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
1480 {
1481 struct frame_info *frame = get_current_frame ();
1482 struct gdbarch *gdbarch = get_frame_arch (frame);
1483 struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1484
1485 CORE_ADDR object;
1486 CORE_ADDR sel;
1487 CORE_ADDR res;
1488
1489 object = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1490 sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);
1491
1492 res = find_implementation (gdbarch, object, sel);
1493 if (new_pc != 0)
1494 *new_pc = res;
1495 if (res == 0)
1496 return 1;
1497 return 0;
1498 }
1499
1500 static int
1501 resolve_msgsend_super (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 struct objc_super sstr;
1508
1509 CORE_ADDR super;
1510 CORE_ADDR sel;
1511 CORE_ADDR res;
1512
1513 super = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
1514 sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1515
1516 read_objc_super (gdbarch, super, &sstr);
1517 if (sstr.theclass == 0)
1518 return 0;
1519
1520 res = find_implementation_from_class (gdbarch, sstr.theclass, sel);
1521 if (new_pc != 0)
1522 *new_pc = res;
1523 if (res == 0)
1524 return 1;
1525 return 0;
1526 }
1527
1528 static int
1529 resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
1530 {
1531 struct frame_info *frame = get_current_frame ();
1532 struct gdbarch *gdbarch = get_frame_arch (frame);
1533 struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1534
1535 struct objc_super sstr;
1536
1537 CORE_ADDR super;
1538 CORE_ADDR sel;
1539 CORE_ADDR res;
1540
1541 super = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1542 sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);
1543
1544 read_objc_super (gdbarch, super, &sstr);
1545 if (sstr.theclass == 0)
1546 return 0;
1547
1548 res = find_implementation_from_class (gdbarch, sstr.theclass, sel);
1549 if (new_pc != 0)
1550 *new_pc = res;
1551 if (res == 0)
1552 return 1;
1553 return 0;
1554 }
This page took 0.064195 seconds and 4 git commands to generate.