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