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