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