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