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