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