problem looking up some symbols when they have a linkage name
[deliverable/binutils-gdb.git] / gdb / objc-lang.c
CommitLineData
d2e6263c 1/* Objective-C language support routines for GDB, the GNU debugger.
b81654f1 2
e2882c85 3 Copyright (C) 2002-2018 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 */
59cc4834 392 false, /* la_store_sym_names_in_linkage_form_p */
5f9a71c3 393 basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
b368761e 394 basic_lookup_transparent_type,/* lookup_transparent_type */
9a3d7dfd 395 objc_demangle, /* Language specific symbol demangler */
8b302db8 396 objc_sniff_from_mangled_name,
0df8b418
MS
397 NULL, /* Language specific
398 class_name_from_physname */
d2e6263c
MS
399 objc_op_print_tab, /* Expression operators for printing */
400 1, /* C-style arrays */
b81654f1 401 0, /* String lower bound */
6084f43a 402 default_word_break_characters,
eb3ff9a5 403 default_collect_symbol_completion_matches,
cad351d1 404 c_language_arch_info,
e79af960 405 default_print_array_index,
41f1b697 406 default_pass_by_reference,
ae6a3a4c 407 default_get_string,
43cc5389 408 c_watch_location_expression,
b5ec771e 409 NULL, /* la_get_symbol_name_matcher */
f8eba3c6 410 iterate_over_symbols,
5ffa0793 411 default_search_name_hash,
a53b64ea 412 &default_varobj_ops,
bb2ec1b3
TT
413 NULL,
414 NULL,
b81654f1
MS
415 LANG_MAGIC
416};
417
418/*
419 * ObjC:
0df8b418 420 * Following functions help construct Objective-C message calls.
b81654f1
MS
421 */
422
d2e6263c 423struct selname /* For parsing Objective-C. */
b81654f1
MS
424 {
425 struct selname *next;
426 char *msglist_sel;
427 int msglist_len;
428 };
429
430static int msglist_len;
431static struct selname *selname_chain;
432static char *msglist_sel;
433
434void
435start_msglist(void)
436{
8d749320 437 struct selname *newobj = XNEW (struct selname);
b81654f1 438
fe978cb0
PA
439 newobj->next = selname_chain;
440 newobj->msglist_len = msglist_len;
441 newobj->msglist_sel = msglist_sel;
b81654f1
MS
442 msglist_len = 0;
443 msglist_sel = (char *)xmalloc(1);
444 *msglist_sel = 0;
fe978cb0 445 selname_chain = newobj;
b81654f1
MS
446}
447
448void
449add_msglist(struct stoken *str, int addcolon)
450{
d7561cbb
KS
451 char *s;
452 const char *p;
b81654f1
MS
453 int len, plen;
454
5cc80db3
MS
455 if (str == 0) /* Unnamed arg, or... */
456 {
457 if (addcolon == 0) /* variable number of args. */
458 {
459 msglist_len++;
460 return;
461 }
462 p = "";
463 plen = 0;
464 }
465 else
466 {
467 p = str->ptr;
468 plen = str->length;
b81654f1 469 }
b81654f1
MS
470 len = plen + strlen(msglist_sel) + 2;
471 s = (char *)xmalloc(len);
472 strcpy(s, msglist_sel);
473 strncat(s, p, plen);
7248f48e 474 xfree(msglist_sel);
b81654f1 475 msglist_sel = s;
5cc80db3
MS
476 if (addcolon)
477 {
478 s[len-2] = ':';
479 s[len-1] = 0;
480 msglist_len++;
481 }
482 else
b81654f1
MS
483 s[len-2] = '\0';
484}
485
486int
410a0ff2 487end_msglist (struct parser_state *ps)
b81654f1 488{
f86f5ca3
PH
489 int val = msglist_len;
490 struct selname *sel = selname_chain;
491 char *p = msglist_sel;
c253954e 492 CORE_ADDR selid;
b81654f1
MS
493
494 selname_chain = sel->next;
495 msglist_len = sel->msglist_len;
496 msglist_sel = sel->msglist_sel;
410a0ff2 497 selid = lookup_child_selector (parse_gdbarch (ps), p);
b81654f1 498 if (!selid)
8a3fe4f8 499 error (_("Can't find selector \"%s\""), p);
410a0ff2 500 write_exp_elt_longcst (ps, selid);
7248f48e 501 xfree(p);
410a0ff2 502 write_exp_elt_longcst (ps, val); /* Number of args */
7248f48e 503 xfree(sel);
b81654f1
MS
504
505 return val;
506}
507
508/*
0d5cff50 509 * Function: specialcmp (const char *a, const char *b)
b81654f1
MS
510 *
511 * Special strcmp: treats ']' and ' ' as end-of-string.
d2e6263c 512 * Used for qsorting lists of objc methods (either by class or selector).
b81654f1
MS
513 */
514
b9362cc7 515static int
0d5cff50 516specialcmp (const char *a, const char *b)
b81654f1
MS
517{
518 while (*a && *a != ' ' && *a != ']' && *b && *b != ' ' && *b != ']')
519 {
520 if (*a != *b)
521 return *a - *b;
522 a++, b++;
523 }
524 if (*a && *a != ' ' && *a != ']')
0df8b418 525 return 1; /* a is longer therefore greater. */
b81654f1 526 if (*b && *b != ' ' && *b != ']')
0df8b418
MS
527 return -1; /* a is shorter therefore lesser. */
528 return 0; /* a and b are identical. */
b81654f1
MS
529}
530
531/*
36e53c63 532 * Function: compare_selectors (const void *, const void *)
b81654f1 533 *
d2e6263c
MS
534 * Comparison function for use with qsort. Arguments are symbols or
535 * msymbols Compares selector part of objc method name alphabetically.
b81654f1
MS
536 */
537
538static int
36e53c63 539compare_selectors (const void *a, const void *b)
b81654f1 540{
0d5cff50 541 const char *aname, *bname;
b81654f1 542
de5ad195
DC
543 aname = SYMBOL_PRINT_NAME (*(struct symbol **) a);
544 bname = SYMBOL_PRINT_NAME (*(struct symbol **) b);
7248f48e 545 if (aname == NULL || bname == NULL)
8a3fe4f8 546 error (_("internal: compare_selectors(1)"));
b81654f1 547
7248f48e
AF
548 aname = strchr(aname, ' ');
549 bname = strchr(bname, ' ');
550 if (aname == NULL || bname == NULL)
8a3fe4f8 551 error (_("internal: compare_selectors(2)"));
b81654f1
MS
552
553 return specialcmp (aname+1, bname+1);
554}
555
556/*
557 * Function: selectors_info (regexp, from_tty)
558 *
d2e6263c
MS
559 * Implements the "Info selectors" command. Takes an optional regexp
560 * arg. Lists all objective c selectors that match the regexp. Works
561 * by grepping thru all symbols for objective c methods. Output list
562 * is sorted and uniqued.
b81654f1
MS
563 */
564
565static void
1d12d88f 566info_selectors_command (const char *regexp, int from_tty)
b81654f1
MS
567{
568 struct objfile *objfile;
569 struct minimal_symbol *msymbol;
0d5cff50 570 const char *name;
b81654f1
MS
571 char *val;
572 int matches = 0;
573 int maxlen = 0;
574 int ix;
575 char myregexp[2048];
576 char asel[256];
577 struct symbol **sym_arr;
578 int plusminus = 0;
579
580 if (regexp == NULL)
d2e6263c 581 strcpy(myregexp, ".*]"); /* Null input, match all objc methods. */
b81654f1
MS
582 else
583 {
d2e6263c
MS
584 if (*regexp == '+' || *regexp == '-')
585 { /* User wants only class methods or only instance methods. */
b81654f1
MS
586 plusminus = *regexp++;
587 while (*regexp == ' ' || *regexp == '\t')
588 regexp++;
589 }
590 if (*regexp == '\0')
591 strcpy(myregexp, ".*]");
592 else
593 {
a9dc8dcc 594 /* Allow a few extra bytes because of the strcat below. */
28288541 595 if (sizeof (myregexp) < strlen (regexp) + 4)
20937029
JK
596 error (_("Regexp is too long: %s"), regexp);
597 strcpy(myregexp, regexp);
b81654f1
MS
598 if (myregexp[strlen(myregexp) - 1] == '$') /* end of selector */
599 myregexp[strlen(myregexp) - 1] = ']'; /* end of method name */
600 else
601 strcat(myregexp, ".*]");
602 }
603 }
604
605 if (regexp != NULL)
5e488a7b
AC
606 {
607 val = re_comp (myregexp);
608 if (val != 0)
8a3fe4f8 609 error (_("Invalid regexp (%s): %s"), val, regexp);
5e488a7b 610 }
b81654f1 611
d2e6263c 612 /* First time thru is JUST to get max length and count. */
b81654f1
MS
613 ALL_MSYMBOLS (objfile, msymbol)
614 {
615 QUIT;
efd66ac6 616 name = MSYMBOL_NATURAL_NAME (msymbol);
3e6ef9e4
JB
617 if (name
618 && (name[0] == '-' || name[0] == '+')
619 && name[1] == '[') /* Got a method name. */
b81654f1 620 {
d2e6263c 621 /* Filter for class/instance methods. */
b81654f1 622 if (plusminus && name[0] != plusminus)
d2e6263c
MS
623 continue;
624 /* Find selector part. */
3e6ef9e4 625 name = (char *) strchr (name+2, ' ');
50412521
MS
626 if (name == NULL)
627 {
628 complaint (&symfile_complaints,
629 _("Bad method name '%s'"),
efd66ac6 630 MSYMBOL_NATURAL_NAME (msymbol));
50412521
MS
631 continue;
632 }
b81654f1
MS
633 if (regexp == NULL || re_exec(++name) != 0)
634 {
0d5cff50
DE
635 const char *mystart = name;
636 const char *myend = strchr (mystart, ']');
b81654f1
MS
637
638 if (myend && (myend - mystart > maxlen))
d2e6263c 639 maxlen = myend - mystart; /* Get longest selector. */
b81654f1
MS
640 matches++;
641 }
642 }
643 }
644 if (matches)
645 {
a3f17187 646 printf_filtered (_("Selectors matching \"%s\":\n\n"),
b81654f1
MS
647 regexp ? regexp : "*");
648
8d749320 649 sym_arr = XALLOCAVEC (struct symbol *, matches);
b81654f1
MS
650 matches = 0;
651 ALL_MSYMBOLS (objfile, msymbol)
652 {
653 QUIT;
efd66ac6 654 name = MSYMBOL_NATURAL_NAME (msymbol);
b81654f1
MS
655 if (name &&
656 (name[0] == '-' || name[0] == '+') &&
d2e6263c 657 name[1] == '[') /* Got a method name. */
b81654f1 658 {
d2e6263c 659 /* Filter for class/instance methods. */
b81654f1 660 if (plusminus && name[0] != plusminus)
d2e6263c
MS
661 continue;
662 /* Find selector part. */
663 name = (char *) strchr(name+2, ' ');
b81654f1
MS
664 if (regexp == NULL || re_exec(++name) != 0)
665 sym_arr[matches++] = (struct symbol *) msymbol;
666 }
667 }
668
669 qsort (sym_arr, matches, sizeof (struct minimal_symbol *),
670 compare_selectors);
d2e6263c
MS
671 /* Prevent compare on first iteration. */
672 asel[0] = 0;
673 for (ix = 0; ix < matches; ix++) /* Now do the output. */
b81654f1
MS
674 {
675 char *p = asel;
676
677 QUIT;
36018d2e 678 name = SYMBOL_NATURAL_NAME (sym_arr[ix]);
b81654f1
MS
679 name = strchr (name, ' ') + 1;
680 if (p[0] && specialcmp(name, p) == 0)
d2e6263c 681 continue; /* Seen this one already (not unique). */
b81654f1 682
d2e6263c
MS
683 /* Copy selector part. */
684 while (*name && *name != ']')
b81654f1
MS
685 *p++ = *name++;
686 *p++ = '\0';
d2e6263c
MS
687 /* Print in columns. */
688 puts_filtered_tabular(asel, maxlen + 1, 0);
b81654f1
MS
689 }
690 begin_line();
691 }
692 else
0df8b418
MS
693 printf_filtered (_("No selectors matching \"%s\"\n"),
694 regexp ? regexp : "*");
b81654f1
MS
695}
696
697/*
36e53c63 698 * Function: compare_classes (const void *, const void *)
b81654f1 699 *
d2e6263c
MS
700 * Comparison function for use with qsort. Arguments are symbols or
701 * msymbols Compares class part of objc method name alphabetically.
b81654f1
MS
702 */
703
704static int
36e53c63 705compare_classes (const void *a, const void *b)
b81654f1 706{
0d5cff50 707 const char *aname, *bname;
b81654f1 708
de5ad195
DC
709 aname = SYMBOL_PRINT_NAME (*(struct symbol **) a);
710 bname = SYMBOL_PRINT_NAME (*(struct symbol **) b);
7248f48e 711 if (aname == NULL || bname == NULL)
8a3fe4f8 712 error (_("internal: compare_classes(1)"));
b81654f1
MS
713
714 return specialcmp (aname+1, bname+1);
715}
716
717/*
718 * Function: classes_info(regexp, from_tty)
719 *
720 * Implements the "info classes" command for objective c classes.
721 * Lists all objective c classes that match the optional regexp.
d2e6263c
MS
722 * Works by grepping thru the list of objective c methods. List will
723 * be sorted and uniqued (since one class may have many methods).
724 * BUGS: will not list a class that has no methods.
b81654f1
MS
725 */
726
727static void
1d12d88f 728info_classes_command (const char *regexp, int from_tty)
b81654f1
MS
729{
730 struct objfile *objfile;
731 struct minimal_symbol *msymbol;
0d5cff50 732 const char *name;
b81654f1
MS
733 char *val;
734 int matches = 0;
735 int maxlen = 0;
736 int ix;
737 char myregexp[2048];
738 char aclass[256];
739 struct symbol **sym_arr;
740
741 if (regexp == NULL)
d2e6263c 742 strcpy(myregexp, ".* "); /* Null input: match all objc classes. */
b81654f1
MS
743 else
744 {
a9dc8dcc 745 /* Allow a few extra bytes because of the strcat below. */
28288541
MS
746 if (sizeof (myregexp) < strlen (regexp) + 4)
747 error (_("Regexp is too long: %s"), regexp);
b81654f1
MS
748 strcpy(myregexp, regexp);
749 if (myregexp[strlen(myregexp) - 1] == '$')
d2e6263c 750 /* In the method name, the end of the class name is marked by ' '. */
b81654f1
MS
751 myregexp[strlen(myregexp) - 1] = ' ';
752 else
753 strcat(myregexp, ".* ");
754 }
755
756 if (regexp != NULL)
5e488a7b
AC
757 {
758 val = re_comp (myregexp);
759 if (val != 0)
8a3fe4f8 760 error (_("Invalid regexp (%s): %s"), val, regexp);
5e488a7b 761 }
b81654f1 762
d2e6263c 763 /* First time thru is JUST to get max length and count. */
b81654f1
MS
764 ALL_MSYMBOLS (objfile, msymbol)
765 {
766 QUIT;
efd66ac6 767 name = MSYMBOL_NATURAL_NAME (msymbol);
b81654f1
MS
768 if (name &&
769 (name[0] == '-' || name[0] == '+') &&
d2e6263c 770 name[1] == '[') /* Got a method name. */
b81654f1
MS
771 if (regexp == NULL || re_exec(name+2) != 0)
772 {
d2e6263c 773 /* Compute length of classname part. */
0d5cff50
DE
774 const char *mystart = name + 2;
775 const char *myend = strchr (mystart, ' ');
b81654f1
MS
776
777 if (myend && (myend - mystart > maxlen))
778 maxlen = myend - mystart;
779 matches++;
780 }
781 }
782 if (matches)
783 {
a3f17187 784 printf_filtered (_("Classes matching \"%s\":\n\n"),
b81654f1 785 regexp ? regexp : "*");
8d749320 786 sym_arr = XALLOCAVEC (struct symbol *, matches);
b81654f1
MS
787 matches = 0;
788 ALL_MSYMBOLS (objfile, msymbol)
789 {
790 QUIT;
efd66ac6 791 name = MSYMBOL_NATURAL_NAME (msymbol);
b81654f1
MS
792 if (name &&
793 (name[0] == '-' || name[0] == '+') &&
d2e6263c 794 name[1] == '[') /* Got a method name. */
b81654f1
MS
795 if (regexp == NULL || re_exec(name+2) != 0)
796 sym_arr[matches++] = (struct symbol *) msymbol;
797 }
798
799 qsort (sym_arr, matches, sizeof (struct minimal_symbol *),
800 compare_classes);
d2e6263c
MS
801 /* Prevent compare on first iteration. */
802 aclass[0] = 0;
803 for (ix = 0; ix < matches; ix++) /* Now do the output. */
b81654f1
MS
804 {
805 char *p = aclass;
806
807 QUIT;
36018d2e 808 name = SYMBOL_NATURAL_NAME (sym_arr[ix]);
b81654f1
MS
809 name += 2;
810 if (p[0] && specialcmp(name, p) == 0)
d2e6263c 811 continue; /* Seen this one already (not unique). */
b81654f1 812
d2e6263c
MS
813 /* Copy class part of method name. */
814 while (*name && *name != ' ')
b81654f1
MS
815 *p++ = *name++;
816 *p++ = '\0';
d2e6263c
MS
817 /* Print in columns. */
818 puts_filtered_tabular(aclass, maxlen + 1, 0);
b81654f1
MS
819 }
820 begin_line();
821 }
822 else
a3f17187 823 printf_filtered (_("No classes matching \"%s\"\n"), regexp ? regexp : "*");
b81654f1
MS
824}
825
f8eba3c6 826static char *
b81654f1
MS
827parse_selector (char *method, char **selector)
828{
829 char *s1 = NULL;
830 char *s2 = NULL;
831 int found_quote = 0;
832
833 char *nselector = NULL;
834
e8f3fcdd 835 gdb_assert (selector != NULL);
b81654f1
MS
836
837 s1 = method;
838
529480d0 839 s1 = skip_spaces (s1);
b81654f1
MS
840 if (*s1 == '\'')
841 {
842 found_quote = 1;
843 s1++;
844 }
529480d0 845 s1 = skip_spaces (s1);
b81654f1
MS
846
847 nselector = s1;
848 s2 = s1;
849
5cc80db3
MS
850 for (;;)
851 {
852 if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
853 *s1++ = *s2;
854 else if (isspace (*s2))
855 ;
856 else if ((*s2 == '\0') || (*s2 == '\''))
857 break;
858 else
859 return NULL;
860 s2++;
861 }
b81654f1
MS
862 *s1++ = '\0';
863
529480d0 864 s2 = skip_spaces (s2);
b81654f1
MS
865 if (found_quote)
866 {
867 if (*s2 == '\'')
868 s2++;
529480d0 869 s2 = skip_spaces (s2);
b81654f1
MS
870 }
871
872 if (selector != NULL)
873 *selector = nselector;
874
875 return s2;
876}
877
f8eba3c6 878static char *
fe978cb0 879parse_method (char *method, char *type, char **theclass,
d2e6263c 880 char **category, char **selector)
b81654f1
MS
881{
882 char *s1 = NULL;
883 char *s2 = NULL;
884 int found_quote = 0;
885
886 char ntype = '\0';
887 char *nclass = NULL;
888 char *ncategory = NULL;
889 char *nselector = NULL;
890
e8f3fcdd 891 gdb_assert (type != NULL);
fe978cb0 892 gdb_assert (theclass != NULL);
e8f3fcdd
AC
893 gdb_assert (category != NULL);
894 gdb_assert (selector != NULL);
b81654f1
MS
895
896 s1 = method;
897
529480d0 898 s1 = skip_spaces (s1);
b81654f1
MS
899 if (*s1 == '\'')
900 {
901 found_quote = 1;
902 s1++;
903 }
529480d0 904 s1 = skip_spaces (s1);
b81654f1
MS
905
906 if ((s1[0] == '+') || (s1[0] == '-'))
907 ntype = *s1++;
908
529480d0 909 s1 = skip_spaces (s1);
b81654f1
MS
910
911 if (*s1 != '[')
912 return NULL;
913 s1++;
914
915 nclass = s1;
916 while (isalnum (*s1) || (*s1 == '_'))
917 s1++;
918
919 s2 = s1;
529480d0 920 s2 = skip_spaces (s2);
b81654f1
MS
921
922 if (*s2 == '(')
923 {
924 s2++;
529480d0 925 s2 = skip_spaces (s2);
b81654f1
MS
926 ncategory = s2;
927 while (isalnum (*s2) || (*s2 == '_'))
928 s2++;
929 *s2++ = '\0';
930 }
931
d2e6263c 932 /* Truncate the class name now that we're not using the open paren. */
b81654f1
MS
933 *s1++ = '\0';
934
935 nselector = s2;
936 s1 = s2;
937
5cc80db3
MS
938 for (;;)
939 {
940 if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
941 *s1++ = *s2;
942 else if (isspace (*s2))
943 ;
944 else if (*s2 == ']')
945 break;
946 else
947 return NULL;
948 s2++;
949 }
b81654f1
MS
950 *s1++ = '\0';
951 s2++;
952
529480d0 953 s2 = skip_spaces (s2);
b81654f1
MS
954 if (found_quote)
955 {
956 if (*s2 != '\'')
957 return NULL;
958 s2++;
529480d0 959 s2 = skip_spaces (s2);
b81654f1
MS
960 }
961
962 if (type != NULL)
963 *type = ntype;
fe978cb0
PA
964 if (theclass != NULL)
965 *theclass = nclass;
b81654f1
MS
966 if (category != NULL)
967 *category = ncategory;
968 if (selector != NULL)
969 *selector = nselector;
970
971 return s2;
972}
973
2f9a90b4 974static void
fe978cb0 975find_methods (char type, const char *theclass, const char *category,
f8eba3c6
TT
976 const char *selector,
977 VEC (const_char_ptr) **symbol_names)
b81654f1
MS
978{
979 struct objfile *objfile = NULL;
b81654f1 980
0d5cff50 981 const char *symname = NULL;
b81654f1
MS
982
983 char ntype = '\0';
984 char *nclass = NULL;
985 char *ncategory = NULL;
986 char *nselector = NULL;
987
b81654f1
MS
988 static char *tmp = NULL;
989 static unsigned int tmplen = 0;
990
f8eba3c6 991 gdb_assert (symbol_names != NULL);
b81654f1 992
57a9e6af 993 ALL_OBJFILES (objfile)
b81654f1 994 {
57a9e6af 995 unsigned int *objc_csym;
f8eba3c6 996 struct minimal_symbol *msymbol = NULL;
b81654f1 997
57a9e6af
PP
998 /* The objfile_csym variable counts the number of ObjC methods
999 that this objfile defines. We save that count as a private
1000 objfile data. If we have already determined that this objfile
1001 provides no ObjC methods, we can skip it entirely. */
b81654f1 1002
57a9e6af 1003 unsigned int objfile_csym = 0;
b81654f1 1004
19ba03f4 1005 objc_csym = (unsigned int *) objfile_data (objfile, objc_objfile_data);
57a9e6af
PP
1006 if (objc_csym != NULL && *objc_csym == 0)
1007 /* There are no ObjC symbols in this objfile. Skip it entirely. */
b81654f1
MS
1008 continue;
1009
57a9e6af 1010 ALL_OBJFILE_MSYMBOLS (objfile, msymbol)
b81654f1 1011 {
57a9e6af 1012 QUIT;
b81654f1 1013
0c4b2e63
MF
1014 /* Check the symbol name first as this can be done entirely without
1015 sending any query to the target. */
efd66ac6 1016 symname = MSYMBOL_NATURAL_NAME (msymbol);
0c4b2e63
MF
1017 if (symname == NULL)
1018 continue;
1019
1020 if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '['))
1021 /* Not a method name. */
1022 continue;
1023
8dfd1e6d
KS
1024 objfile_csym++;
1025
0c4b2e63 1026 /* Now that thinks are a bit sane, clean up the symname. */
57a9e6af
PP
1027 while ((strlen (symname) + 1) >= tmplen)
1028 {
1029 tmplen = (tmplen == 0) ? 1024 : tmplen * 2;
224c3ddb 1030 tmp = (char *) xrealloc (tmp, tmplen);
57a9e6af
PP
1031 }
1032 strcpy (tmp, symname);
b81654f1 1033
0df8b418
MS
1034 if (parse_method (tmp, &ntype, &nclass,
1035 &ncategory, &nselector) == NULL)
57a9e6af 1036 continue;
b81654f1 1037
57a9e6af
PP
1038 if ((type != '\0') && (ntype != type))
1039 continue;
b81654f1 1040
fe978cb0
PA
1041 if ((theclass != NULL)
1042 && ((nclass == NULL) || (strcmp (theclass, nclass) != 0)))
57a9e6af
PP
1043 continue;
1044
1045 if ((category != NULL) &&
1046 ((ncategory == NULL) || (strcmp (category, ncategory) != 0)))
1047 continue;
b81654f1 1048
57a9e6af
PP
1049 if ((selector != NULL) &&
1050 ((nselector == NULL) || (strcmp (selector, nselector) != 0)))
1051 continue;
1052
f8eba3c6 1053 VEC_safe_push (const_char_ptr, *symbol_names, symname);
57a9e6af 1054 }
f8eba3c6 1055
57a9e6af 1056 if (objc_csym == NULL)
b81654f1 1057 {
8d749320 1058 objc_csym = XOBNEW (&objfile->objfile_obstack, unsigned int);
57a9e6af
PP
1059 *objc_csym = objfile_csym;
1060 set_objfile_data (objfile, objc_objfile_data, objc_csym);
b81654f1 1061 }
57a9e6af
PP
1062 else
1063 /* Count of ObjC methods in this objfile should be constant. */
1064 gdb_assert (*objc_csym == objfile_csym);
b81654f1 1065 }
f8eba3c6 1066}
b81654f1 1067
f8eba3c6
TT
1068/* Uniquify a VEC of strings. */
1069
1070static void
1071uniquify_strings (VEC (const_char_ptr) **strings)
1072{
1073 int ix;
1074 const char *elem, *last = NULL;
1075 int out;
1076
ee7615e1
AA
1077 /* If the vector is empty, there's nothing to do. This explicit
1078 check is needed to avoid invoking qsort with NULL. */
1079 if (VEC_empty (const_char_ptr, *strings))
1080 return;
1081
f8eba3c6
TT
1082 qsort (VEC_address (const_char_ptr, *strings),
1083 VEC_length (const_char_ptr, *strings),
1084 sizeof (const_char_ptr),
1085 compare_strings);
1086 out = 0;
1087 for (ix = 0; VEC_iterate (const_char_ptr, *strings, ix, elem); ++ix)
1088 {
1089 if (last == NULL || strcmp (last, elem) != 0)
1090 {
1091 /* Keep ELEM. */
1092 VEC_replace (const_char_ptr, *strings, out, elem);
1093 ++out;
1094 }
1095 last = elem;
1096 }
1097 VEC_truncate (const_char_ptr, *strings, out);
b81654f1
MS
1098}
1099
f8eba3c6 1100/*
d7561cbb 1101 * Function: find_imps (const char *selector, struct symbol **sym_arr)
f8eba3c6
TT
1102 *
1103 * Input: a string representing a selector
1104 * a pointer to an array of symbol pointers
1105 * possibly a pointer to a symbol found by the caller.
1106 *
1107 * Output: number of methods that implement that selector. Side
1108 * effects: The array of symbol pointers is filled with matching syms.
1109 *
1110 * By analogy with function "find_methods" (symtab.c), builds a list
1111 * of symbols matching the ambiguous input, so that "decode_line_2"
1112 * (symtab.c) can list them and ask the user to choose one or more.
1113 * In this case the matches are objective c methods
1114 * ("implementations") matching an objective c selector.
1115 *
1116 * Note that it is possible for a normal (c-style) function to have
1117 * the same name as an objective c selector. To prevent the selector
1118 * from eclipsing the function, we allow the caller (decode_line_1) to
1119 * search for such a function first, and if it finds one, pass it in
1120 * to us. We will then integrate it into the list. We also search
1121 * for one here, among the minsyms.
1122 *
1123 * NOTE: if NUM_DEBUGGABLE is non-zero, the sym_arr will be divided
1124 * into two parts: debuggable (struct symbol) syms, and
1125 * non_debuggable (struct minimal_symbol) syms. The debuggable
1126 * ones will come first, before NUM_DEBUGGABLE (which will thus
1127 * be the index of the first non-debuggable one).
1128 */
1129
d7561cbb
KS
1130const char *
1131find_imps (const char *method, VEC (const_char_ptr) **symbol_names)
b81654f1
MS
1132{
1133 char type = '\0';
fe978cb0 1134 char *theclass = NULL;
b81654f1
MS
1135 char *category = NULL;
1136 char *selector = NULL;
1137
b81654f1
MS
1138 char *buf = NULL;
1139 char *tmp = NULL;
1140
f8eba3c6 1141 int selector_case = 0;
b81654f1 1142
f8eba3c6 1143 gdb_assert (symbol_names != NULL);
b81654f1
MS
1144
1145 buf = (char *) alloca (strlen (method) + 1);
1146 strcpy (buf, method);
fe978cb0 1147 tmp = parse_method (buf, &type, &theclass, &category, &selector);
b81654f1 1148
5cc80db3
MS
1149 if (tmp == NULL)
1150 {
5cc80db3
MS
1151 strcpy (buf, method);
1152 tmp = parse_selector (buf, &selector);
b81654f1 1153
5cc80db3
MS
1154 if (tmp == NULL)
1155 return NULL;
1156
f8eba3c6 1157 selector_case = 1;
5cc80db3 1158 }
b81654f1 1159
fe978cb0 1160 find_methods (type, theclass, category, selector, symbol_names);
b81654f1 1161
f8eba3c6
TT
1162 /* If we hit the "selector" case, and we found some methods, then
1163 add the selector itself as a symbol, if it exists. */
1164 if (selector_case && !VEC_empty (const_char_ptr, *symbol_names))
b81654f1 1165 {
d12307c1
PMR
1166 struct symbol *sym = lookup_symbol (selector, NULL, VAR_DOMAIN,
1167 0).symbol;
f8eba3c6
TT
1168
1169 if (sym != NULL)
1170 VEC_safe_push (const_char_ptr, *symbol_names,
1171 SYMBOL_NATURAL_NAME (sym));
1172 else
b81654f1 1173 {
3b7344d5
TT
1174 struct bound_minimal_symbol msym
1175 = lookup_minimal_symbol (selector, 0, 0);
f8eba3c6 1176
3b7344d5 1177 if (msym.minsym != NULL)
f8eba3c6 1178 VEC_safe_push (const_char_ptr, *symbol_names,
3b7344d5 1179 MSYMBOL_NATURAL_NAME (msym.minsym));
b81654f1
MS
1180 }
1181 }
1182
f8eba3c6 1183 uniquify_strings (symbol_names);
b81654f1
MS
1184
1185 return method + (tmp - buf);
1186}
1187
b9362cc7 1188static void
0b39b52e 1189print_object_command (const char *args, int from_tty)
b81654f1
MS
1190{
1191 struct value *object, *function, *description;
36e53c63 1192 CORE_ADDR string_addr, object_addr;
b81654f1 1193 int i = 0;
22a44745 1194 gdb_byte c = 0;
b81654f1
MS
1195
1196 if (!args || !*args)
d2e6263c
MS
1197 error (
1198"The 'print-object' command requires an argument (an Objective-C object)");
b81654f1
MS
1199
1200 {
4d01a485 1201 expression_up expr = parse_expression (args);
b81654f1
MS
1202 int pc = 0;
1203
4b27a620 1204 object = evaluate_subexp (builtin_type (expr->gdbarch)->builtin_data_ptr,
4d01a485 1205 expr.get (), &pc, EVAL_NORMAL);
b81654f1
MS
1206 }
1207
36e53c63
AF
1208 /* Validate the address for sanity. */
1209 object_addr = value_as_long (object);
1210 read_memory (object_addr, &c, 1);
1211
3e3b026f 1212 function = find_function_in_inferior ("_NSPrintForDebugger", NULL);
36e53c63 1213 if (function == NULL)
8a3fe4f8 1214 error (_("Unable to locate _NSPrintForDebugger in child process"));
b81654f1 1215
7022349d 1216 description = call_function_by_hand (function, NULL, 1, &object);
b81654f1 1217
7248f48e
AF
1218 string_addr = value_as_long (description);
1219 if (string_addr == 0)
8a3fe4f8 1220 error (_("object returns null description"));
b81654f1
MS
1221
1222 read_memory (string_addr + i++, &c, 1);
22a44745 1223 if (c != 0)
b81654f1 1224 do
d2e6263c 1225 { /* Read and print characters up to EOS. */
b81654f1
MS
1226 QUIT;
1227 printf_filtered ("%c", c);
1228 read_memory (string_addr + i++, &c, 1);
1229 } while (c != 0);
1230 else
a3f17187 1231 printf_filtered(_("<object returns empty description>"));
b81654f1
MS
1232 printf_filtered ("\n");
1233}
1234
d2e6263c
MS
1235/* The data structure 'methcalls' is used to detect method calls (thru
1236 * ObjC runtime lib functions objc_msgSend, objc_msgSendSuper, etc.),
0df8b418 1237 * and ultimately find the method being called.
b81654f1
MS
1238 */
1239
1240struct objc_methcall {
a121b7c1 1241 const char *name;
d2e6263c 1242 /* Return instance method to be called. */
36e53c63 1243 int (*stop_at) (CORE_ADDR, CORE_ADDR *);
d2e6263c
MS
1244 /* Start of pc range corresponding to method invocation. */
1245 CORE_ADDR begin;
1246 /* End of pc range corresponding to method invocation. */
1247 CORE_ADDR end;
b81654f1
MS
1248};
1249
d2e6263c
MS
1250static int resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc);
1251static int resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1252static int resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc);
1253static int resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
b81654f1
MS
1254
1255static struct objc_methcall methcalls[] = {
1256 { "_objc_msgSend", resolve_msgsend, 0, 0},
1257 { "_objc_msgSend_stret", resolve_msgsend_stret, 0, 0},
1258 { "_objc_msgSendSuper", resolve_msgsend_super, 0, 0},
1259 { "_objc_msgSendSuper_stret", resolve_msgsend_super_stret, 0, 0},
1260 { "_objc_getClass", NULL, 0, 0},
1261 { "_objc_getMetaClass", NULL, 0, 0}
1262};
1263
1264#define nmethcalls (sizeof (methcalls) / sizeof (methcalls[0]))
1265
d2e6263c
MS
1266/* The following function, "find_objc_msgsend", fills in the data
1267 * structure "objc_msgs" by finding the addresses of each of the
1268 * (currently four) functions that it holds (of which objc_msgSend is
1269 * the first). This must be called each time symbols are loaded, in
0df8b418 1270 * case the functions have moved for some reason.
b81654f1
MS
1271 */
1272
b9362cc7 1273static void
b81654f1
MS
1274find_objc_msgsend (void)
1275{
1276 unsigned int i;
b81654f1 1277
5cc80db3
MS
1278 for (i = 0; i < nmethcalls; i++)
1279 {
50e65b17 1280 struct bound_minimal_symbol func;
b81654f1 1281
5cc80db3 1282 /* Try both with and without underscore. */
50e65b17
TT
1283 func = lookup_bound_minimal_symbol (methcalls[i].name);
1284 if ((func.minsym == NULL) && (methcalls[i].name[0] == '_'))
5cc80db3 1285 {
50e65b17 1286 func = lookup_bound_minimal_symbol (methcalls[i].name + 1);
5cc80db3 1287 }
50e65b17 1288 if (func.minsym == NULL)
5cc80db3
MS
1289 {
1290 methcalls[i].begin = 0;
1291 methcalls[i].end = 0;
1292 continue;
1293 }
1294
77e371c0 1295 methcalls[i].begin = BMSYMBOL_VALUE_ADDRESS (func);
50e65b17 1296 methcalls[i].end = minimal_symbol_upper_bound (func);
b81654f1 1297 }
b81654f1
MS
1298}
1299
1300/* find_objc_msgcall (replaces pc_off_limits)
1301 *
d2e6263c
MS
1302 * ALL that this function now does is to determine whether the input
1303 * address ("pc") is the address of one of the Objective-C message
b81654f1
MS
1304 * dispatch functions (mainly objc_msgSend or objc_msgSendSuper), and
1305 * if so, it returns the address of the method that will be called.
1306 *
1307 * The old function "pc_off_limits" used to do a lot of other things
d2e6263c 1308 * in addition, such as detecting shared library jump stubs and
b81654f1 1309 * returning the address of the shlib function that would be called.
e76f05fa 1310 * That functionality has been moved into the gdbarch_skip_trampoline_code and
d2e6263c 1311 * IN_SOLIB_TRAMPOLINE macros, which are resolved in the target-
0df8b418 1312 * dependent modules.
b81654f1
MS
1313 */
1314
b9362cc7 1315static int
36e53c63 1316find_objc_msgcall_submethod (int (*f) (CORE_ADDR, CORE_ADDR *),
d2e6263c
MS
1317 CORE_ADDR pc,
1318 CORE_ADDR *new_pc)
b81654f1 1319{
bf469271
PA
1320 TRY
1321 {
1322 if (f (pc, new_pc) == 0)
1323 return 1;
1324 }
1325 CATCH (ex, RETURN_MASK_ALL)
1326 {
1327 exception_fprintf (gdb_stderr, ex,
1328 "Unable to determine target of "
1329 "Objective-C method call (ignoring):\n");
1330 }
1331 END_CATCH
1332
1333 return 0;
b81654f1
MS
1334}
1335
1336int
1337find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc)
1338{
1339 unsigned int i;
1340
1341 find_objc_msgsend ();
5e488a7b
AC
1342 if (new_pc != NULL)
1343 {
1344 *new_pc = 0;
1345 }
b81654f1 1346
d2e6263c
MS
1347 for (i = 0; i < nmethcalls; i++)
1348 if ((pc >= methcalls[i].begin) && (pc < methcalls[i].end))
1349 {
1350 if (methcalls[i].stop_at != NULL)
1351 return find_objc_msgcall_submethod (methcalls[i].stop_at,
1352 pc, new_pc);
1353 else
1354 return 0;
b81654f1 1355 }
d2e6263c 1356
b81654f1
MS
1357 return 0;
1358}
1359
1360void
1361_initialize_objc_language (void)
1362{
11db9430 1363 add_info ("selectors", info_selectors_command,
1bedd215 1364 _("All Objective-C selectors, or those matching REGEXP."));
11db9430 1365 add_info ("classes", info_classes_command,
1bedd215 1366 _("All Objective-C classes, or those matching REGEXP."));
b81654f1 1367 add_com ("print-object", class_vars, print_object_command,
1bedd215 1368 _("Ask an Objective-C object to print itself."));
b81654f1
MS
1369 add_com_alias ("po", "print-object", class_vars, 1);
1370}
1371
b81654f1 1372static void
e17a4113
UW
1373read_objc_method (struct gdbarch *gdbarch, CORE_ADDR addr,
1374 struct objc_method *method)
b81654f1 1375{
e17a4113 1376 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
5cc80db3 1377
e17a4113
UW
1378 method->name = read_memory_unsigned_integer (addr + 0, 4, byte_order);
1379 method->types = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1380 method->imp = read_memory_unsigned_integer (addr + 8, 4, byte_order);
b81654f1
MS
1381}
1382
e17a4113
UW
1383static unsigned long
1384read_objc_methlist_nmethods (struct gdbarch *gdbarch, CORE_ADDR addr)
b81654f1 1385{
e17a4113 1386 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
5cc80db3 1387
e17a4113 1388 return read_memory_unsigned_integer (addr + 4, 4, byte_order);
b81654f1
MS
1389}
1390
1391static void
e17a4113
UW
1392read_objc_methlist_method (struct gdbarch *gdbarch, CORE_ADDR addr,
1393 unsigned long num, struct objc_method *method)
b81654f1 1394{
e17a4113
UW
1395 gdb_assert (num < read_objc_methlist_nmethods (gdbarch, addr));
1396 read_objc_method (gdbarch, addr + 8 + (12 * num), method);
b81654f1
MS
1397}
1398
1399static void
e17a4113
UW
1400read_objc_object (struct gdbarch *gdbarch, CORE_ADDR addr,
1401 struct objc_object *object)
b81654f1 1402{
e17a4113 1403 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
5cc80db3 1404
e17a4113 1405 object->isa = read_memory_unsigned_integer (addr, 4, byte_order);
b81654f1
MS
1406}
1407
1408static void
e17a4113
UW
1409read_objc_super (struct gdbarch *gdbarch, CORE_ADDR addr,
1410 struct objc_super *super)
b81654f1 1411{
e17a4113 1412 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
5cc80db3 1413
e17a4113 1414 super->receiver = read_memory_unsigned_integer (addr, 4, byte_order);
fe978cb0 1415 super->theclass = read_memory_unsigned_integer (addr + 4, 4, byte_order);
b81654f1
MS
1416};
1417
1418static void
e17a4113 1419read_objc_class (struct gdbarch *gdbarch, CORE_ADDR addr,
fe978cb0 1420 struct objc_class *theclass)
b81654f1 1421{
e17a4113 1422 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
5cc80db3 1423
fe978cb0
PA
1424 theclass->isa = read_memory_unsigned_integer (addr, 4, byte_order);
1425 theclass->super_class = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1426 theclass->name = read_memory_unsigned_integer (addr + 8, 4, byte_order);
1427 theclass->version = read_memory_unsigned_integer (addr + 12, 4, byte_order);
1428 theclass->info = read_memory_unsigned_integer (addr + 16, 4, byte_order);
1429 theclass->instance_size = read_memory_unsigned_integer (addr + 18, 4,
0df8b418 1430 byte_order);
fe978cb0
PA
1431 theclass->ivars = read_memory_unsigned_integer (addr + 24, 4, byte_order);
1432 theclass->methods = read_memory_unsigned_integer (addr + 28, 4, byte_order);
1433 theclass->cache = read_memory_unsigned_integer (addr + 32, 4, byte_order);
1434 theclass->protocols = read_memory_unsigned_integer (addr + 36, 4, byte_order);
b81654f1
MS
1435}
1436
b9362cc7 1437static CORE_ADDR
e17a4113 1438find_implementation_from_class (struct gdbarch *gdbarch,
fe978cb0 1439 CORE_ADDR theclass, CORE_ADDR sel)
b81654f1 1440{
e17a4113 1441 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
fe978cb0 1442 CORE_ADDR subclass = theclass;
b81654f1 1443
d2e6263c
MS
1444 while (subclass != 0)
1445 {
b81654f1 1446
d2e6263c
MS
1447 struct objc_class class_str;
1448 unsigned mlistnum = 0;
b81654f1 1449
e17a4113 1450 read_objc_class (gdbarch, subclass, &class_str);
b81654f1 1451
d2e6263c
MS
1452 for (;;)
1453 {
1454 CORE_ADDR mlist;
1455 unsigned long nmethods;
1456 unsigned long i;
b81654f1 1457
d2e6263c 1458 mlist = read_memory_unsigned_integer (class_str.methods +
e17a4113
UW
1459 (4 * mlistnum),
1460 4, byte_order);
d2e6263c
MS
1461 if (mlist == 0)
1462 break;
b81654f1 1463
e17a4113 1464 nmethods = read_objc_methlist_nmethods (gdbarch, mlist);
b81654f1 1465
d2e6263c
MS
1466 for (i = 0; i < nmethods; i++)
1467 {
1468 struct objc_method meth_str;
b81654f1 1469
5cc80db3 1470 read_objc_methlist_method (gdbarch, mlist, i, &meth_str);
b81654f1 1471
d2e6263c 1472 if (meth_str.name == sel)
1abf022c 1473 /* FIXME: hppa arch was doing a pointer dereference
0df8b418 1474 here. There needs to be a better way to do that. */
1abf022c 1475 return meth_str.imp;
d2e6263c
MS
1476 }
1477 mlistnum++;
b81654f1 1478 }
d2e6263c 1479 subclass = class_str.super_class;
b81654f1 1480 }
b81654f1
MS
1481
1482 return 0;
1483}
1484
b9362cc7 1485static CORE_ADDR
e17a4113
UW
1486find_implementation (struct gdbarch *gdbarch,
1487 CORE_ADDR object, CORE_ADDR sel)
b81654f1
MS
1488{
1489 struct objc_object ostr;
1490
d2e6263c
MS
1491 if (object == 0)
1492 return 0;
e17a4113 1493 read_objc_object (gdbarch, object, &ostr);
d2e6263c
MS
1494 if (ostr.isa == 0)
1495 return 0;
b81654f1 1496
e17a4113 1497 return find_implementation_from_class (gdbarch, ostr.isa, sel);
b81654f1
MS
1498}
1499
1500static int
1501resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc)
1502{
5ed92fa8
UW
1503 struct frame_info *frame = get_current_frame ();
1504 struct gdbarch *gdbarch = get_frame_arch (frame);
1505 struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1506
b81654f1
MS
1507 CORE_ADDR object;
1508 CORE_ADDR sel;
1509 CORE_ADDR res;
1510
5ed92fa8
UW
1511 object = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
1512 sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
b81654f1 1513
e17a4113 1514 res = find_implementation (gdbarch, object, sel);
d2e6263c
MS
1515 if (new_pc != 0)
1516 *new_pc = res;
1517 if (res == 0)
1518 return 1;
b81654f1
MS
1519 return 0;
1520}
1521
1522static int
1523resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
1524{
5ed92fa8
UW
1525 struct frame_info *frame = get_current_frame ();
1526 struct gdbarch *gdbarch = get_frame_arch (frame);
1527 struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1528
b81654f1
MS
1529 CORE_ADDR object;
1530 CORE_ADDR sel;
1531 CORE_ADDR res;
1532
5ed92fa8
UW
1533 object = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1534 sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);
b81654f1 1535
e17a4113 1536 res = find_implementation (gdbarch, object, sel);
d2e6263c
MS
1537 if (new_pc != 0)
1538 *new_pc = res;
1539 if (res == 0)
1540 return 1;
b81654f1
MS
1541 return 0;
1542}
1543
1544static int
1545resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc)
1546{
5ed92fa8
UW
1547 struct frame_info *frame = get_current_frame ();
1548 struct gdbarch *gdbarch = get_frame_arch (frame);
1549 struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1550
b81654f1
MS
1551 struct objc_super sstr;
1552
1553 CORE_ADDR super;
1554 CORE_ADDR sel;
1555 CORE_ADDR res;
1556
5ed92fa8
UW
1557 super = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
1558 sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
b81654f1 1559
e17a4113 1560 read_objc_super (gdbarch, super, &sstr);
fe978cb0 1561 if (sstr.theclass == 0)
d2e6263c 1562 return 0;
b81654f1 1563
fe978cb0 1564 res = find_implementation_from_class (gdbarch, sstr.theclass, sel);
d2e6263c
MS
1565 if (new_pc != 0)
1566 *new_pc = res;
1567 if (res == 0)
1568 return 1;
b81654f1
MS
1569 return 0;
1570}
1571
1572static int
1573resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
1574{
5ed92fa8
UW
1575 struct frame_info *frame = get_current_frame ();
1576 struct gdbarch *gdbarch = get_frame_arch (frame);
1577 struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1578
b81654f1
MS
1579 struct objc_super sstr;
1580
1581 CORE_ADDR super;
1582 CORE_ADDR sel;
1583 CORE_ADDR res;
1584
5ed92fa8
UW
1585 super = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1586 sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);
b81654f1 1587
e17a4113 1588 read_objc_super (gdbarch, super, &sstr);
fe978cb0 1589 if (sstr.theclass == 0)
d2e6263c 1590 return 0;
b81654f1 1591
fe978cb0 1592 res = find_implementation_from_class (gdbarch, sstr.theclass, sel);
d2e6263c
MS
1593 if (new_pc != 0)
1594 *new_pc = res;
1595 if (res == 0)
1596 return 1;
b81654f1
MS
1597 return 0;
1598}
57a9e6af
PP
1599
1600void
1601_initialize_objc_lang (void)
1602{
1603 objc_objfile_data = register_objfile_data ();
1604}
This page took 1.545605 seconds and 4 git commands to generate.