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