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