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