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