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