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