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