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