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