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