[gdb/testsuite] Restore breakpoint command in ui-redirect.exp
[external/binutils.git] / gdb / objc-lang.c
1 /* Objective-C language support routines for GDB, the GNU debugger.
2
3    Copyright (C) 2002-2019 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_key<unsigned int> 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                                                            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, 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, NULL, stringValue[2]);
185     }
186   else if (lookup_minimal_symbol("istr", 0, 0).minsym)
187     {
188       function = find_function_in_inferior("istr", NULL);
189       nsstringValue = call_function_by_hand(function, NULL, stringValue[2]);
190     }
191   else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0).minsym)
192     {
193       function
194         = find_function_in_inferior("+[NSString stringWithCString:]", NULL);
195       type = builtin_type (gdbarch)->builtin_long;
196
197       stringValue[0] = value_from_longest 
198         (type, lookup_objc_class (gdbarch, "NSString"));
199       stringValue[1] = value_from_longest 
200         (type, lookup_child_selector (gdbarch, "stringWithCString:"));
201       nsstringValue = call_function_by_hand(function, NULL, stringValue);
202     }
203   else
204     error (_("NSString: internal error -- no way to create new NSString"));
205
206   sym = lookup_struct_typedef("NSString", 0, 1);
207   if (sym == NULL)
208     sym = lookup_struct_typedef("NXString", 0, 1);
209   if (sym == NULL)
210     type = builtin_type (gdbarch)->builtin_data_ptr;
211   else
212     type = lookup_pointer_type(SYMBOL_TYPE (sym));
213
214   deprecated_set_value_type (nsstringValue, type);
215   return nsstringValue;
216 }
217
218 /* Objective-C name demangling.  */
219
220 char *
221 objc_demangle (const char *mangled, int options)
222 {
223   char *demangled, *cp;
224
225   if (mangled[0] == '_' &&
226      (mangled[1] == 'i' || mangled[1] == 'c') &&
227       mangled[2] == '_')
228     {
229       cp = demangled = (char *) xmalloc (strlen (mangled) + 2);
230
231       if (mangled[1] == 'i')
232         *cp++ = '-';            /* for instance method */
233       else
234         *cp++ = '+';            /* for class    method */
235
236       *cp++ = '[';              /* opening left brace  */
237       strcpy(cp, mangled+3);    /* Tack on the rest of the mangled name.  */
238
239       while (*cp && *cp == '_')
240         cp++;                   /* Skip any initial underbars in class
241                                    name.  */
242
243       cp = strchr(cp, '_');
244       if (!cp)                  /* Find first non-initial underbar.  */
245         {
246           xfree(demangled);     /* not mangled name */
247           return NULL;
248         }
249       if (cp[1] == '_')         /* Easy case: no category name.    */
250         {
251           *cp++ = ' ';          /* Replace two '_' with one ' '.   */
252           strcpy(cp, mangled + (cp - demangled) + 2);
253         }
254       else
255         {
256           *cp++ = '(';          /* Less easy case: category name.  */
257           cp = strchr(cp, '_');
258           if (!cp)
259             {
260               xfree(demangled); /* not mangled name */
261               return NULL;
262             }
263           *cp++ = ')';
264           *cp++ = ' ';          /* Overwriting 1st char of method name...  */
265           strcpy(cp, mangled + (cp - demangled));       /* Get it back.  */
266         }
267
268       while (*cp && *cp == '_')
269         cp++;                   /* Skip any initial underbars in
270                                    method name.  */
271
272       for (; *cp; cp++)
273         if (*cp == '_')
274           *cp = ':';            /* Replace remaining '_' with ':'.  */
275
276       *cp++ = ']';              /* closing right brace */
277       *cp++ = 0;                /* string terminator */
278       return demangled;
279     }
280   else
281     return NULL;        /* Not an objc mangled name.  */
282 }
283
284 /* la_sniff_from_mangled_name for ObjC.  */
285
286 static int
287 objc_sniff_from_mangled_name (const char *mangled, char **demangled)
288 {
289   *demangled = objc_demangle (mangled, 0);
290   return *demangled != NULL;
291 }
292
293 /* Determine if we are currently in the Objective-C dispatch function.
294    If so, get the address of the method function that the dispatcher
295    would call and use that as the function to step into instead.  Also
296    skip over the trampoline for the function (if any).  This is better
297    for the user since they are only interested in stepping into the
298    method function anyway.  */
299 static CORE_ADDR 
300 objc_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
301 {
302   struct gdbarch *gdbarch = get_frame_arch (frame);
303   CORE_ADDR real_stop_pc;
304   CORE_ADDR method_stop_pc;
305   
306   real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
307
308   if (real_stop_pc != 0)
309     find_objc_msgcall (real_stop_pc, &method_stop_pc);
310   else
311     find_objc_msgcall (stop_pc, &method_stop_pc);
312
313   if (method_stop_pc)
314     {
315       real_stop_pc = gdbarch_skip_trampoline_code
316                        (gdbarch, frame, method_stop_pc);
317       if (real_stop_pc == 0)
318         real_stop_pc = method_stop_pc;
319     }
320
321   return real_stop_pc;
322 }
323
324
325 /* Table mapping opcodes into strings for printing operators
326    and precedences of the operators.  */
327
328 static const struct op_print objc_op_print_tab[] =
329   {
330     {",",  BINOP_COMMA, PREC_COMMA, 0},
331     {"=",  BINOP_ASSIGN, PREC_ASSIGN, 1},
332     {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
333     {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
334     {"|",  BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
335     {"^",  BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
336     {"&",  BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
337     {"==", BINOP_EQUAL, PREC_EQUAL, 0},
338     {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
339     {"<=", BINOP_LEQ, PREC_ORDER, 0},
340     {">=", BINOP_GEQ, PREC_ORDER, 0},
341     {">",  BINOP_GTR, PREC_ORDER, 0},
342     {"<",  BINOP_LESS, PREC_ORDER, 0},
343     {">>", BINOP_RSH, PREC_SHIFT, 0},
344     {"<<", BINOP_LSH, PREC_SHIFT, 0},
345     {"+",  BINOP_ADD, PREC_ADD, 0},
346     {"-",  BINOP_SUB, PREC_ADD, 0},
347     {"*",  BINOP_MUL, PREC_MUL, 0},
348     {"/",  BINOP_DIV, PREC_MUL, 0},
349     {"%",  BINOP_REM, PREC_MUL, 0},
350     {"@",  BINOP_REPEAT, PREC_REPEAT, 0},
351     {"-",  UNOP_NEG, PREC_PREFIX, 0},
352     {"!",  UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
353     {"~",  UNOP_COMPLEMENT, PREC_PREFIX, 0},
354     {"*",  UNOP_IND, PREC_PREFIX, 0},
355     {"&",  UNOP_ADDR, PREC_PREFIX, 0},
356     {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
357     {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
358     {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
359     {NULL, OP_NULL, PREC_NULL, 0}
360 };
361
362 static const char *objc_extensions[] =
363 {
364   ".m", NULL
365 };
366
367 extern const struct language_defn objc_language_defn = {
368   "objective-c",                /* Language name */
369   "Objective-C",
370   language_objc,
371   range_check_off,
372   case_sensitive_on,
373   array_row_major,
374   macro_expansion_c,
375   objc_extensions,
376   &exp_descriptor_standard,
377   c_parse,
378   null_post_parser,
379   c_printchar,                 /* Print a character constant */
380   c_printstr,                  /* Function to print string constant */
381   c_emit_char,
382   c_print_type,                 /* Print a type using appropriate syntax */
383   c_print_typedef,              /* Print a typedef using appropriate syntax */
384   c_val_print,                  /* Print a value using appropriate syntax */
385   c_value_print,                /* Print a top-level value */
386   default_read_var_value,       /* la_read_var_value */
387   objc_skip_trampoline,         /* Language specific skip_trampoline */
388   "self",                       /* name_of_this */
389   false,                        /* la_store_sym_names_in_linkage_form_p */
390   basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
391   basic_lookup_transparent_type,/* lookup_transparent_type */
392   objc_demangle,                /* Language specific symbol demangler */
393   objc_sniff_from_mangled_name,
394   NULL,                         /* Language specific
395                                    class_name_from_physname */
396   objc_op_print_tab,            /* Expression operators for printing */
397   1,                            /* C-style arrays */
398   0,                            /* String lower bound */
399   default_word_break_characters,
400   default_collect_symbol_completion_matches,
401   c_language_arch_info,
402   default_print_array_index,
403   default_pass_by_reference,
404   default_get_string,
405   c_watch_location_expression,
406   NULL,                         /* la_get_symbol_name_matcher */
407   iterate_over_symbols,
408   default_search_name_hash,
409   &default_varobj_ops,
410   NULL,
411   NULL,
412   c_is_string_type_p,
413   "{...}"                       /* la_struct_too_deep_ellipsis */
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 (ps->gdbarch (), 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   const char            *name;
567   char                  *val;
568   int                    matches = 0;
569   int                    maxlen  = 0;
570   int                    ix;
571   char                   myregexp[2048];
572   char                   asel[256];
573   struct symbol        **sym_arr;
574   int                    plusminus = 0;
575
576   if (regexp == NULL)
577     strcpy(myregexp, ".*]");    /* Null input, match all objc methods.  */
578   else
579     {
580       if (*regexp == '+' || *regexp == '-')
581         { /* User wants only class methods or only instance methods.  */
582           plusminus = *regexp++;
583           while (*regexp == ' ' || *regexp == '\t')
584             regexp++;
585         }
586       if (*regexp == '\0')
587         strcpy(myregexp, ".*]");
588       else
589         {
590           /* Allow a few extra bytes because of the strcat below.  */
591           if (sizeof (myregexp) < strlen (regexp) + 4)
592             error (_("Regexp is too long: %s"), regexp);
593           strcpy(myregexp, regexp);
594           if (myregexp[strlen(myregexp) - 1] == '$') /* end of selector */
595             myregexp[strlen(myregexp) - 1] = ']';    /* end of method name */
596           else
597             strcat(myregexp, ".*]");
598         }
599     }
600
601   if (regexp != NULL)
602     {
603       val = re_comp (myregexp);
604       if (val != 0)
605         error (_("Invalid regexp (%s): %s"), val, regexp);
606     }
607
608   /* First time thru is JUST to get max length and count.  */
609   for (objfile *objfile : current_program_space->objfiles ())
610     {
611       for (minimal_symbol *msymbol : objfile->msymbols ())
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     }
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       for (objfile *objfile : current_program_space->objfiles ())
650         {
651           for (minimal_symbol *msymbol : objfile->msymbols ())
652             {
653               QUIT;
654               name = MSYMBOL_NATURAL_NAME (msymbol);
655               if (name &&
656                   (name[0] == '-' || name[0] == '+') &&
657                   name[1] == '[')               /* Got a method name.  */
658                 {
659                   /* Filter for class/instance methods.  */
660                   if (plusminus && name[0] != plusminus)
661                     continue;
662                   /* Find selector part.  */
663                   name = (char *) strchr(name+2, ' ');
664                   if (regexp == NULL || re_exec(++name) != 0)
665                     sym_arr[matches++] = (struct symbol *) msymbol;
666                 }
667             }
668         }
669
670       qsort (sym_arr, matches, sizeof (struct minimal_symbol *), 
671              compare_selectors);
672       /* Prevent compare on first iteration.  */
673       asel[0] = 0;
674       for (ix = 0; ix < matches; ix++)  /* Now do the output.  */
675         {
676           char *p = asel;
677
678           QUIT;
679           name = SYMBOL_NATURAL_NAME (sym_arr[ix]);
680           name = strchr (name, ' ') + 1;
681           if (p[0] && specialcmp(name, p) == 0)
682             continue;           /* Seen this one already (not unique).  */
683
684           /* Copy selector part.  */
685           while (*name && *name != ']')
686             *p++ = *name++;
687           *p++ = '\0';
688           /* Print in columns.  */
689           puts_filtered_tabular(asel, maxlen + 1, 0);
690         }
691       begin_line();
692     }
693   else
694     printf_filtered (_("No selectors matching \"%s\"\n"),
695                      regexp ? regexp : "*");
696 }
697
698 /*
699  * Function: compare_classes (const void *, const void *)
700  *
701  * Comparison function for use with qsort.  Arguments are symbols or
702  * msymbols Compares class part of objc method name alphabetically. 
703  */
704
705 static int
706 compare_classes (const void *a, const void *b)
707 {
708   const char *aname, *bname;
709
710   aname = SYMBOL_PRINT_NAME (*(struct symbol **) a);
711   bname = SYMBOL_PRINT_NAME (*(struct symbol **) b);
712   if (aname == NULL || bname == NULL)
713     error (_("internal: compare_classes(1)"));
714
715   return specialcmp (aname+1, bname+1);
716 }
717
718 /*
719  * Function: classes_info(regexp, from_tty)
720  *
721  * Implements the "info classes" command for objective c classes.
722  * Lists all objective c classes that match the optional regexp.
723  * Works by grepping thru the list of objective c methods.  List will
724  * be sorted and uniqued (since one class may have many methods).
725  * BUGS: will not list a class that has no methods. 
726  */
727
728 static void
729 info_classes_command (const char *regexp, int from_tty)
730 {
731   const char            *name;
732   char                  *val;
733   int                    matches = 0;
734   int                    maxlen  = 0;
735   int                    ix;
736   char                   myregexp[2048];
737   char                   aclass[256];
738   struct symbol        **sym_arr;
739
740   if (regexp == NULL)
741     strcpy(myregexp, ".* ");    /* Null input: match all objc classes.  */
742   else
743     {
744       /* Allow a few extra bytes because of the strcat below.  */
745       if (sizeof (myregexp) < strlen (regexp) + 4)
746         error (_("Regexp is too long: %s"), regexp);
747       strcpy(myregexp, regexp);
748       if (myregexp[strlen(myregexp) - 1] == '$')
749         /* In the method name, the end of the class name is marked by ' '.  */
750         myregexp[strlen(myregexp) - 1] = ' ';
751       else
752         strcat(myregexp, ".* ");
753     }
754
755   if (regexp != NULL)
756     {
757       val = re_comp (myregexp);
758       if (val != 0)
759         error (_("Invalid regexp (%s): %s"), val, regexp);
760     }
761
762   /* First time thru is JUST to get max length and count.  */
763   for (objfile *objfile : current_program_space->objfiles ())
764     {
765       for (minimal_symbol *msymbol : objfile->msymbols ())
766         {
767           QUIT;
768           name = MSYMBOL_NATURAL_NAME (msymbol);
769           if (name &&
770               (name[0] == '-' || name[0] == '+') &&
771               name[1] == '[')                   /* Got a method name.  */
772             if (regexp == NULL || re_exec(name+2) != 0)
773               { 
774                 /* Compute length of classname part.  */
775                 const char *mystart = name + 2;
776                 const char *myend   = strchr (mystart, ' ');
777             
778                 if (myend && (myend - mystart > maxlen))
779                   maxlen = myend - mystart;
780                 matches++;
781               }
782         }
783     }
784   if (matches)
785     {
786       printf_filtered (_("Classes matching \"%s\":\n\n"), 
787                        regexp ? regexp : "*");
788       sym_arr = XALLOCAVEC (struct symbol *, matches);
789       matches = 0;
790       for (objfile *objfile : current_program_space->objfiles ())
791         {
792           for (minimal_symbol *msymbol : objfile->msymbols ())
793             {
794               QUIT;
795               name = MSYMBOL_NATURAL_NAME (msymbol);
796               if (name &&
797                   (name[0] == '-' || name[0] == '+') &&
798                   name[1] == '[') /* Got a method name.  */
799                 if (regexp == NULL || re_exec(name+2) != 0)
800                   sym_arr[matches++] = (struct symbol *) msymbol;
801             }
802         }
803
804       qsort (sym_arr, matches, sizeof (struct minimal_symbol *), 
805              compare_classes);
806       /* Prevent compare on first iteration.  */
807       aclass[0] = 0;
808       for (ix = 0; ix < matches; ix++)  /* Now do the output.  */
809         {
810           char *p = aclass;
811
812           QUIT;
813           name = SYMBOL_NATURAL_NAME (sym_arr[ix]);
814           name += 2;
815           if (p[0] && specialcmp(name, p) == 0)
816             continue;   /* Seen this one already (not unique).  */
817
818           /* Copy class part of method name.  */
819           while (*name && *name != ' ')
820             *p++ = *name++;
821           *p++ = '\0';
822           /* Print in columns.  */
823           puts_filtered_tabular(aclass, maxlen + 1, 0);
824         }
825       begin_line();
826     }
827   else
828     printf_filtered (_("No classes matching \"%s\"\n"), regexp ? regexp : "*");
829 }
830
831 static char * 
832 parse_selector (char *method, char **selector)
833 {
834   char *s1 = NULL;
835   char *s2 = NULL;
836   int found_quote = 0;
837
838   char *nselector = NULL;
839
840   gdb_assert (selector != NULL);
841
842   s1 = method;
843
844   s1 = skip_spaces (s1);
845   if (*s1 == '\'') 
846     {
847       found_quote = 1;
848       s1++;
849     }
850   s1 = skip_spaces (s1);
851    
852   nselector = s1;
853   s2 = s1;
854
855   for (;;)
856     {
857       if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
858         *s1++ = *s2;
859       else if (isspace (*s2))
860         ;
861       else if ((*s2 == '\0') || (*s2 == '\''))
862         break;
863       else
864         return NULL;
865       s2++;
866     }
867   *s1++ = '\0';
868
869   s2 = skip_spaces (s2);
870   if (found_quote)
871     {
872       if (*s2 == '\'') 
873         s2++;
874       s2 = skip_spaces (s2);
875     }
876
877   if (selector != NULL)
878     *selector = nselector;
879
880   return s2;
881 }
882
883 static char * 
884 parse_method (char *method, char *type, char **theclass,
885               char **category, char **selector)
886 {
887   char *s1 = NULL;
888   char *s2 = NULL;
889   int found_quote = 0;
890
891   char ntype = '\0';
892   char *nclass = NULL;
893   char *ncategory = NULL;
894   char *nselector = NULL;
895
896   gdb_assert (type != NULL);
897   gdb_assert (theclass != NULL);
898   gdb_assert (category != NULL);
899   gdb_assert (selector != NULL);
900   
901   s1 = method;
902
903   s1 = skip_spaces (s1);
904   if (*s1 == '\'') 
905     {
906       found_quote = 1;
907       s1++;
908     }
909   s1 = skip_spaces (s1);
910   
911   if ((s1[0] == '+') || (s1[0] == '-'))
912     ntype = *s1++;
913
914   s1 = skip_spaces (s1);
915
916   if (*s1 != '[')
917     return NULL;
918   s1++;
919
920   nclass = s1;
921   while (isalnum (*s1) || (*s1 == '_'))
922     s1++;
923   
924   s2 = s1;
925   s2 = skip_spaces (s2);
926   
927   if (*s2 == '(')
928     {
929       s2++;
930       s2 = skip_spaces (s2);
931       ncategory = s2;
932       while (isalnum (*s2) || (*s2 == '_'))
933         s2++;
934       *s2++ = '\0';
935     }
936
937   /* Truncate the class name now that we're not using the open paren.  */
938   *s1++ = '\0';
939
940   nselector = s2;
941   s1 = s2;
942
943   for (;;)
944     {
945       if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
946         *s1++ = *s2;
947       else if (isspace (*s2))
948         ;
949       else if (*s2 == ']')
950         break;
951       else
952         return NULL;
953       s2++;
954     }
955   *s1++ = '\0';
956   s2++;
957
958   s2 = skip_spaces (s2);
959   if (found_quote)
960     {
961       if (*s2 != '\'') 
962         return NULL;
963       s2++;
964       s2 = skip_spaces (s2);
965     }
966
967   if (type != NULL)
968     *type = ntype;
969   if (theclass != NULL)
970     *theclass = nclass;
971   if (category != NULL)
972     *category = ncategory;
973   if (selector != NULL)
974     *selector = nselector;
975
976   return s2;
977 }
978
979 static void
980 find_methods (char type, const char *theclass, const char *category, 
981               const char *selector,
982               std::vector<const char *> *symbol_names)
983 {
984   const char *symname = NULL;
985
986   char ntype = '\0';
987   char *nclass = NULL;
988   char *ncategory = NULL;
989   char *nselector = NULL;
990
991   static char *tmp = NULL;
992   static unsigned int tmplen = 0;
993
994   gdb_assert (symbol_names != NULL);
995
996   for (objfile *objfile : current_program_space->objfiles ())
997     {
998       unsigned int *objc_csym;
999
1000       /* The objfile_csym variable counts the number of ObjC methods
1001          that this objfile defines.  We save that count as a private
1002          objfile data.  If we have already determined that this objfile
1003          provides no ObjC methods, we can skip it entirely.  */
1004
1005       unsigned int objfile_csym = 0;
1006
1007       objc_csym = objc_objfile_data.get (objfile);
1008       if (objc_csym != NULL && *objc_csym == 0)
1009         /* There are no ObjC symbols in this objfile.  Skip it entirely.  */
1010         continue;
1011
1012       for (minimal_symbol *msymbol : objfile->msymbols ())
1013         {
1014           QUIT;
1015
1016           /* Check the symbol name first as this can be done entirely without
1017              sending any query to the target.  */
1018           symname = MSYMBOL_NATURAL_NAME (msymbol);
1019           if (symname == NULL)
1020             continue;
1021
1022           if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '['))
1023             /* Not a method name.  */
1024             continue;
1025
1026           objfile_csym++;
1027
1028           /* Now that thinks are a bit sane, clean up the symname.  */
1029           while ((strlen (symname) + 1) >= tmplen)
1030             {
1031               tmplen = (tmplen == 0) ? 1024 : tmplen * 2;
1032               tmp = (char *) xrealloc (tmp, tmplen);
1033             }
1034           strcpy (tmp, symname);
1035
1036           if (parse_method (tmp, &ntype, &nclass,
1037                             &ncategory, &nselector) == NULL)
1038             continue;
1039
1040           if ((type != '\0') && (ntype != type))
1041             continue;
1042
1043           if ((theclass != NULL)
1044               && ((nclass == NULL) || (strcmp (theclass, nclass) != 0)))
1045             continue;
1046
1047           if ((category != NULL) && 
1048               ((ncategory == NULL) || (strcmp (category, ncategory) != 0)))
1049             continue;
1050
1051           if ((selector != NULL) && 
1052               ((nselector == NULL) || (strcmp (selector, nselector) != 0)))
1053             continue;
1054
1055           symbol_names->push_back (symname);
1056         }
1057
1058       if (objc_csym == NULL)
1059         objc_csym = objc_objfile_data.emplace (objfile, objfile_csym);
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, 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 (const gdb_exception &ex)
1303     {
1304       exception_fprintf (gdb_stderr, ex,
1305                          "Unable to determine target of "
1306                          "Objective-C method call (ignoring):\n");
1307     }
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 }