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