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