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