1 /* Objective-C language support routines for GDB, the GNU debugger.
2 
3    Copyright (C) 2002-2024 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 "event-top.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 "cli/cli-cmds.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 *
lookup_struct_typedef(const char * name,const struct block * block,int noerr)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, SEARCH_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
lookup_objc_class(struct gdbarch * gdbarch,const char * classname)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
lookup_child_selector(struct gdbarch * gdbarch,const char * selname)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 *
value_nsstring(struct gdbarch * gdbarch,const char * ptr,int len)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   nsstringValue->deprecated_set_type (type);
216   return nsstringValue;
217 }
218 
219 /* Class representing the Objective-C language.  */
220 
221 class objc_language : public language_defn
222 {
223 public:
objc_language()224   objc_language ()
225     : language_defn (language_objc)
226   { /* Nothing.  */ }
227 
228   /* See language.h.  */
229 
name()230   const char *name () const override
231   { return "objective-c"; }
232 
233   /* See language.h.  */
234 
natural_name()235   const char *natural_name () const override
236   { return "Objective-C"; }
237 
238   /* See language.h.  */
239 
filename_extensions()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.  */
language_arch_info(struct gdbarch * gdbarch,struct language_arch_info * lai)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.  */
sniff_from_mangled_name(const char * mangled,gdb::unique_xmalloc_ptr<char> * demangled)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 
can_print_type_offsets()269   bool can_print_type_offsets () const override
270   {
271     return true;
272   }
273 
274   /* See language.h.  */
275 
print_type(struct type * type,const char * varstring,struct ui_file * stream,int show,int level,const struct type_print_options * flags)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 
skip_trampoline(const frame_info_ptr & frame,CORE_ADDR stop_pc)285   CORE_ADDR skip_trampoline (const 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 
name_of_this()319   const char *name_of_this () const override
320   { return "self"; }
321 
322   /* See language.h.  */
323 
macro_expansion()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>
demangle_symbol(const char * mangled,int options)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
start_msglist(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
add_msglist(struct stoken * str,int addcolon)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
end_msglist(struct parser_state * ps)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
specialcmp(const char * a,const char * b)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
compare_selectors(const void * a,const void * b)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
info_selectors_command(const char * regexp,int from_tty)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
compare_classes(const void * a,const void * b)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
info_classes_command(const char * regexp,int from_tty)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 *
parse_selector(char * method,char ** selector)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 *
parse_method(char * method,char * type,char ** theclass,char ** category,char ** selector)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
find_methods(char type,const char * theclass,const char * category,const char * selector,std::vector<const char * > * symbol_names)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
uniquify_strings(std::vector<const char * > * strings)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 *
find_imps(const char * method,std::vector<const char * > * symbol_names)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, SEARCH_VFT,
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
print_object_command(const char * args,int from_tty)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 = expr->evaluate (builtin_type (expr->gdbarch)->builtin_data_ptr);
1168   }
1169 
1170   /* Validate the address for sanity.  */
1171   object_addr = value_as_long (object);
1172   read_memory (object_addr, &c, 1);
1173 
1174   function = find_function_in_inferior ("_NSPrintForDebugger", NULL);
1175   if (function == NULL)
1176     error (_("Unable to locate _NSPrintForDebugger in child process"));
1177 
1178   description = call_function_by_hand (function, NULL, object);
1179 
1180   string_addr = value_as_long (description);
1181   if (string_addr == 0)
1182     error (_("object returns null description"));
1183 
1184   read_memory (string_addr + i++, &c, 1);
1185   if (c != 0)
1186     do
1187       { /* Read and print characters up to EOS.  */
1188           QUIT;
1189           gdb_printf ("%c", c);
1190           read_memory (string_addr + i++, &c, 1);
1191       } while (c != 0);
1192   else
1193     gdb_printf(_("<object returns empty description>"));
1194   gdb_printf ("\n");
1195 }
1196 
1197 /* The data structure 'methcalls' is used to detect method calls (thru
1198  * ObjC runtime lib functions objc_msgSend, objc_msgSendSuper, etc.),
1199  * and ultimately find the method being called.
1200  */
1201 
1202 struct objc_methcall {
1203   const char *name;
1204  /* Return instance method to be called.  */
1205   int (*stop_at) (CORE_ADDR, CORE_ADDR *);
1206   /* Start of pc range corresponding to method invocation.  */
1207   CORE_ADDR begin;
1208   /* End of pc range corresponding to method invocation.  */
1209   CORE_ADDR end;
1210 };
1211 
1212 static int resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc);
1213 static int resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1214 static int resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc);
1215 static int resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1216 
1217 static struct objc_methcall methcalls[] = {
1218   { "_objc_msgSend", resolve_msgsend, 0, 0},
1219   { "_objc_msgSend_stret", resolve_msgsend_stret, 0, 0},
1220   { "_objc_msgSendSuper", resolve_msgsend_super, 0, 0},
1221   { "_objc_msgSendSuper_stret", resolve_msgsend_super_stret, 0, 0},
1222   { "_objc_getClass", NULL, 0, 0},
1223   { "_objc_getMetaClass", NULL, 0, 0}
1224 };
1225 
1226 #define nmethcalls (sizeof (methcalls) / sizeof (methcalls[0]))
1227 
1228 /* The following function, "find_objc_msgsend", fills in the data
1229  * structure "objc_msgs" by finding the addresses of each of the
1230  * (currently four) functions that it holds (of which objc_msgSend is
1231  * the first).  This must be called each time symbols are loaded, in
1232  * case the functions have moved for some reason.
1233  */
1234 
1235 static void
find_objc_msgsend(void)1236 find_objc_msgsend (void)
1237 {
1238   unsigned int i;
1239 
1240   for (i = 0; i < nmethcalls; i++)
1241     {
1242       struct bound_minimal_symbol func;
1243 
1244       /* Try both with and without underscore.  */
1245       func = lookup_bound_minimal_symbol (methcalls[i].name);
1246       if ((func.minsym == NULL) && (methcalls[i].name[0] == '_'))
1247           {
1248             func = lookup_bound_minimal_symbol (methcalls[i].name + 1);
1249           }
1250       if (func.minsym == NULL)
1251           {
1252             methcalls[i].begin = 0;
1253             methcalls[i].end = 0;
1254             continue;
1255           }
1256 
1257       methcalls[i].begin = func.value_address ();
1258       methcalls[i].end = minimal_symbol_upper_bound (func);
1259     }
1260 }
1261 
1262 /* find_objc_msgcall (replaces pc_off_limits)
1263  *
1264  * ALL that this function now does is to determine whether the input
1265  * address ("pc") is the address of one of the Objective-C message
1266  * dispatch functions (mainly objc_msgSend or objc_msgSendSuper), and
1267  * if so, it returns the address of the method that will be called.
1268  *
1269  * The old function "pc_off_limits" used to do a lot of other things
1270  * in addition, such as detecting shared library jump stubs and
1271  * returning the address of the shlib function that would be called.
1272  * That functionality has been moved into the gdbarch_skip_trampoline_code and
1273  * IN_SOLIB_TRAMPOLINE macros, which are resolved in the target-
1274  * dependent modules.
1275  */
1276 
1277 static int
find_objc_msgcall_submethod(int (* f)(CORE_ADDR,CORE_ADDR *),CORE_ADDR pc,CORE_ADDR * new_pc)1278 find_objc_msgcall_submethod (int (*f) (CORE_ADDR, CORE_ADDR *),
1279                                    CORE_ADDR pc,
1280                                    CORE_ADDR *new_pc)
1281 {
1282   try
1283     {
1284       if (f (pc, new_pc) == 0)
1285           return 1;
1286     }
1287   catch (const gdb_exception_error &ex)
1288     {
1289       exception_fprintf (gdb_stderr, ex,
1290                                "Unable to determine target of "
1291                                "Objective-C method call (ignoring):\n");
1292     }
1293 
1294   return 0;
1295 }
1296 
1297 int
find_objc_msgcall(CORE_ADDR pc,CORE_ADDR * new_pc)1298 find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc)
1299 {
1300   unsigned int i;
1301 
1302   find_objc_msgsend ();
1303   if (new_pc != NULL)
1304     {
1305       *new_pc = 0;
1306     }
1307 
1308   for (i = 0; i < nmethcalls; i++)
1309     if ((pc >= methcalls[i].begin) && (pc < methcalls[i].end))
1310       {
1311           if (methcalls[i].stop_at != NULL)
1312             return find_objc_msgcall_submethod (methcalls[i].stop_at,
1313                                                         pc, new_pc);
1314           else
1315             return 0;
1316       }
1317 
1318   return 0;
1319 }
1320 
1321 void _initialize_objc_language ();
1322 void
_initialize_objc_language()1323 _initialize_objc_language ()
1324 {
1325   add_info ("selectors", info_selectors_command,
1326               _("All Objective-C selectors, or those matching REGEXP."));
1327   add_info ("classes", info_classes_command,
1328               _("All Objective-C classes, or those matching REGEXP."));
1329   cmd_list_element *print_object_cmd
1330     = add_com ("print-object", class_vars, print_object_command,
1331                  _("Ask an Objective-C object to print itself."));
1332   add_com_alias ("po", print_object_cmd, class_vars, 1);
1333 }
1334 
1335 static void
read_objc_method(struct gdbarch * gdbarch,CORE_ADDR addr,struct objc_method * method)1336 read_objc_method (struct gdbarch *gdbarch, CORE_ADDR addr,
1337                       struct objc_method *method)
1338 {
1339   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1340 
1341   method->name  = read_memory_unsigned_integer (addr + 0, 4, byte_order);
1342   method->types = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1343   method->imp   = read_memory_unsigned_integer (addr + 8, 4, byte_order);
1344 }
1345 
1346 static unsigned long
read_objc_methlist_nmethods(struct gdbarch * gdbarch,CORE_ADDR addr)1347 read_objc_methlist_nmethods (struct gdbarch *gdbarch, CORE_ADDR addr)
1348 {
1349   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1350 
1351   return read_memory_unsigned_integer (addr + 4, 4, byte_order);
1352 }
1353 
1354 static void
read_objc_methlist_method(struct gdbarch * gdbarch,CORE_ADDR addr,unsigned long num,struct objc_method * method)1355 read_objc_methlist_method (struct gdbarch *gdbarch, CORE_ADDR addr,
1356                                  unsigned long num, struct objc_method *method)
1357 {
1358   gdb_assert (num < read_objc_methlist_nmethods (gdbarch, addr));
1359   read_objc_method (gdbarch, addr + 8 + (12 * num), method);
1360 }
1361 
1362 static void
read_objc_object(struct gdbarch * gdbarch,CORE_ADDR addr,struct objc_object * object)1363 read_objc_object (struct gdbarch *gdbarch, CORE_ADDR addr,
1364                       struct objc_object *object)
1365 {
1366   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1367 
1368   object->isa = read_memory_unsigned_integer (addr, 4, byte_order);
1369 }
1370 
1371 static void
read_objc_super(struct gdbarch * gdbarch,CORE_ADDR addr,struct objc_super * super)1372 read_objc_super (struct gdbarch *gdbarch, CORE_ADDR addr,
1373                      struct objc_super *super)
1374 {
1375   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1376 
1377   super->receiver = read_memory_unsigned_integer (addr, 4, byte_order);
1378   super->theclass = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1379 };
1380 
1381 static void
read_objc_class(struct gdbarch * gdbarch,CORE_ADDR addr,struct objc_class * theclass)1382 read_objc_class (struct gdbarch *gdbarch, CORE_ADDR addr,
1383                      struct objc_class *theclass)
1384 {
1385   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1386 
1387   theclass->isa = read_memory_unsigned_integer (addr, 4, byte_order);
1388   theclass->super_class = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1389   theclass->name = read_memory_unsigned_integer (addr + 8, 4, byte_order);
1390   theclass->version = read_memory_unsigned_integer (addr + 12, 4, byte_order);
1391   theclass->info = read_memory_unsigned_integer (addr + 16, 4, byte_order);
1392   theclass->instance_size = read_memory_unsigned_integer (addr + 18, 4,
1393                                                                    byte_order);
1394   theclass->ivars = read_memory_unsigned_integer (addr + 24, 4, byte_order);
1395   theclass->methods = read_memory_unsigned_integer (addr + 28, 4, byte_order);
1396   theclass->cache = read_memory_unsigned_integer (addr + 32, 4, byte_order);
1397   theclass->protocols = read_memory_unsigned_integer (addr + 36, 4, byte_order);
1398 }
1399 
1400 static CORE_ADDR
find_implementation_from_class(struct gdbarch * gdbarch,CORE_ADDR theclass,CORE_ADDR sel)1401 find_implementation_from_class (struct gdbarch *gdbarch,
1402                                         CORE_ADDR theclass, CORE_ADDR sel)
1403 {
1404   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1405   CORE_ADDR subclass = theclass;
1406 
1407   while (subclass != 0)
1408     {
1409 
1410       struct objc_class class_str;
1411       unsigned mlistnum = 0;
1412 
1413       read_objc_class (gdbarch, subclass, &class_str);
1414 
1415       for (;;)
1416           {
1417             CORE_ADDR mlist;
1418             unsigned long nmethods;
1419             unsigned long i;
1420 
1421             mlist = read_memory_unsigned_integer (class_str.methods +
1422                                                             (4 * mlistnum),
1423                                                             4, byte_order);
1424             if (mlist == 0)
1425               break;
1426 
1427             nmethods = read_objc_methlist_nmethods (gdbarch, mlist);
1428 
1429             for (i = 0; i < nmethods; i++)
1430               {
1431                 struct objc_method meth_str;
1432 
1433                 read_objc_methlist_method (gdbarch, mlist, i, &meth_str);
1434 
1435                 if (meth_str.name == sel)
1436                     /* FIXME: hppa arch was doing a pointer dereference
1437                        here.  There needs to be a better way to do that.  */
1438                     return meth_str.imp;
1439               }
1440             mlistnum++;
1441           }
1442       subclass = class_str.super_class;
1443     }
1444 
1445   return 0;
1446 }
1447 
1448 static CORE_ADDR
find_implementation(struct gdbarch * gdbarch,CORE_ADDR object,CORE_ADDR sel)1449 find_implementation (struct gdbarch *gdbarch,
1450                          CORE_ADDR object, CORE_ADDR sel)
1451 {
1452   struct objc_object ostr;
1453 
1454   if (object == 0)
1455     return 0;
1456   read_objc_object (gdbarch, object, &ostr);
1457   if (ostr.isa == 0)
1458     return 0;
1459 
1460   return find_implementation_from_class (gdbarch, ostr.isa, sel);
1461 }
1462 
1463 static int
resolve_msgsend(CORE_ADDR pc,CORE_ADDR * new_pc)1464 resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc)
1465 {
1466   frame_info_ptr frame = get_current_frame ();
1467   struct gdbarch *gdbarch = get_frame_arch (frame);
1468   struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1469 
1470   CORE_ADDR object;
1471   CORE_ADDR sel;
1472   CORE_ADDR res;
1473 
1474   object = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
1475   sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1476 
1477   res = find_implementation (gdbarch, object, sel);
1478   if (new_pc != 0)
1479     *new_pc = res;
1480   if (res == 0)
1481     return 1;
1482   return 0;
1483 }
1484 
1485 static int
resolve_msgsend_stret(CORE_ADDR pc,CORE_ADDR * new_pc)1486 resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
1487 {
1488   frame_info_ptr frame = get_current_frame ();
1489   struct gdbarch *gdbarch = get_frame_arch (frame);
1490   struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1491 
1492   CORE_ADDR object;
1493   CORE_ADDR sel;
1494   CORE_ADDR res;
1495 
1496   object = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1497   sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);
1498 
1499   res = find_implementation (gdbarch, object, sel);
1500   if (new_pc != 0)
1501     *new_pc = res;
1502   if (res == 0)
1503     return 1;
1504   return 0;
1505 }
1506 
1507 static int
resolve_msgsend_super(CORE_ADDR pc,CORE_ADDR * new_pc)1508 resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc)
1509 {
1510   frame_info_ptr frame = get_current_frame ();
1511   struct gdbarch *gdbarch = get_frame_arch (frame);
1512   struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1513 
1514   struct objc_super sstr;
1515 
1516   CORE_ADDR super;
1517   CORE_ADDR sel;
1518   CORE_ADDR res;
1519 
1520   super = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
1521   sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1522 
1523   read_objc_super (gdbarch, super, &sstr);
1524   if (sstr.theclass == 0)
1525     return 0;
1526 
1527   res = find_implementation_from_class (gdbarch, sstr.theclass, sel);
1528   if (new_pc != 0)
1529     *new_pc = res;
1530   if (res == 0)
1531     return 1;
1532   return 0;
1533 }
1534 
1535 static int
resolve_msgsend_super_stret(CORE_ADDR pc,CORE_ADDR * new_pc)1536 resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
1537 {
1538   frame_info_ptr frame = get_current_frame ();
1539   struct gdbarch *gdbarch = get_frame_arch (frame);
1540   struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1541 
1542   struct objc_super sstr;
1543 
1544   CORE_ADDR super;
1545   CORE_ADDR sel;
1546   CORE_ADDR res;
1547 
1548   super = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1549   sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);
1550 
1551   read_objc_super (gdbarch, super, &sstr);
1552   if (sstr.theclass == 0)
1553     return 0;
1554 
1555   res = find_implementation_from_class (gdbarch, sstr.theclass, sel);
1556   if (new_pc != 0)
1557     *new_pc = res;
1558   if (res == 0)
1559     return 1;
1560   return 0;
1561 }
1562