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