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