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