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