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