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