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