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