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
51struct objc_object {
52  CORE_ADDR isa;
53};
54
55struct 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
68struct objc_super {
69  CORE_ADDR receiver;
70  CORE_ADDR theclass;
71};
72
73struct objc_method {
74  CORE_ADDR name;
75  CORE_ADDR types;
76  CORE_ADDR imp;
77};
78
79static 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
85struct symbol *
86lookup_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
110CORE_ADDR
111lookup_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
139CORE_ADDR
140lookup_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
167struct value *
168value_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
221class objc_language : public language_defn
222{
223public:
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
330gdb::unique_xmalloc_ptr<char>
331objc_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
396static objc_language objc_language_defn;
397
398/*
399 * ObjC:
400 * Following functions help construct Objective-C message calls.
401 */
402
403struct selname		/* For parsing Objective-C.  */
404  {
405    struct selname *next;
406    char *msglist_sel;
407    int msglist_len;
408  };
409
410static int msglist_len;
411static struct selname *selname_chain;
412static char *msglist_sel;
413
414void
415start_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
428void
429add_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
466int
467end_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
500static int
501specialcmp (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
523static int
524compare_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
550static void
551info_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
692static int
693compare_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
715static void
716info_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
818static char *
819parse_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
870static char *
871parse_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
966static void
967find_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
1055static void
1056uniquify_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
1096const char *
1097find_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
1152static void
1153print_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
1204struct 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
1214static int resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc);
1215static int resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1216static int resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc);
1217static int resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1218
1219static 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
1237static void
1238find_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
1279static int
1280find_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
1299int
1300find_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
1323void _initialize_objc_language ();
1324void
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
1337static void
1338read_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
1348static unsigned long
1349read_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
1356static void
1357read_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
1364static void
1365read_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
1373static void
1374read_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
1383static void
1384read_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
1402static CORE_ADDR
1403find_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
1450static CORE_ADDR
1451find_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
1465static int
1466resolve_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
1487static int
1488resolve_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
1509static int
1510resolve_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
1537static int
1538resolve_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