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