1 /* GNU Objective C Runtime selector related functions 2 Copyright (C) 1993-2018 Free Software Foundation, Inc. 3 Contributed by Kresten Krab Thorup 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it under the 8 terms of the GNU General Public License as published by the Free Software 9 Foundation; either version 3, or (at your option) any later version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 14 details. 15 16 Under Section 7 of GPL version 3, you are granted additional 17 permissions described in the GCC Runtime Library Exception, version 18 3.1, as published by the Free Software Foundation. 19 20 You should have received a copy of the GNU General Public License and 21 a copy of the GCC Runtime Library Exception along with this program; 22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 <http://www.gnu.org/licenses/>. */ 24 25 #include "objc-private/common.h" 26 #include "objc/runtime.h" 27 #include "objc/thr.h" 28 #include "objc-private/hash.h" 29 #include "objc-private/objc-list.h" 30 #include "objc-private/module-abi-8.h" 31 #include "objc-private/runtime.h" 32 #include "objc-private/sarray.h" 33 #include "objc-private/selector.h" 34 #include <stdlib.h> /* For malloc. */ 35 36 /* Initial selector hash table size. Value doesn't matter much. */ 37 #define SELECTOR_HASH_SIZE 128 38 39 /* Tables mapping selector names to uid and opposite. */ 40 static struct sarray *__objc_selector_array = 0; /* uid -> sel !T:MUTEX */ 41 static struct sarray *__objc_selector_names = 0; /* uid -> name !T:MUTEX */ 42 static cache_ptr __objc_selector_hash = 0; /* name -> uid !T:MUTEX */ 43 44 /* Number of selectors stored in each of the above tables. */ 45 unsigned int __objc_selector_max_index = 0; /* !T:MUTEX */ 46 47 /* Forward-declare an internal function. */ 48 static SEL 49 __sel_register_typed_name (const char *name, const char *types, 50 struct objc_selector *orig, BOOL is_const); 51 52 void __objc_init_selector_tables (void) 53 { 54 __objc_selector_array = sarray_new (SELECTOR_HASH_SIZE, 0); 55 __objc_selector_names = sarray_new (SELECTOR_HASH_SIZE, 0); 56 __objc_selector_hash 57 = objc_hash_new (SELECTOR_HASH_SIZE, 58 (hash_func_type) objc_hash_string, 59 (compare_func_type) objc_compare_strings); 60 } 61 62 /* Register a bunch of selectors from the table of selectors in a 63 module. 'selectors' should not be NULL. The list is terminated by 64 a selectors with a NULL sel_id. The selectors are assumed to 65 contain the 'name' in the sel_id field; this is replaced with the 66 final selector id after they are registered. */ 67 void 68 __objc_register_selectors_from_module (struct objc_selector *selectors) 69 { 70 int i; 71 72 for (i = 0; selectors[i].sel_id; ++i) 73 { 74 const char *name, *type; 75 name = (char *) selectors[i].sel_id; 76 type = (char *) selectors[i].sel_types; 77 /* Constructors are constant static data and we can safely store 78 pointers to them in the runtime structures, so we set 79 is_const == YES. */ 80 __sel_register_typed_name (name, type, (struct objc_selector *) &(selectors[i]), 81 /* is_const */ YES); 82 } 83 } 84 85 /* This routine is given a class and records all of the methods in its 86 class structure in the record table. */ 87 void 88 __objc_register_selectors_from_class (Class class) 89 { 90 struct objc_method_list * method_list; 91 92 method_list = class->methods; 93 while (method_list) 94 { 95 __objc_register_selectors_from_list (method_list); 96 method_list = method_list->method_next; 97 } 98 } 99 100 101 /* This routine is given a list of methods and records each of the 102 methods in the record table. This is the routine that does the 103 actual recording work. 104 105 The name and type pointers in the method list must be permanent and 106 immutable. */ 107 void 108 __objc_register_selectors_from_list (struct objc_method_list *method_list) 109 { 110 int i = 0; 111 112 objc_mutex_lock (__objc_runtime_mutex); 113 while (i < method_list->method_count) 114 { 115 Method method = &method_list->method_list[i]; 116 if (method->method_name) 117 { 118 method->method_name 119 = __sel_register_typed_name ((const char *) method->method_name, 120 method->method_types, 0, YES); 121 } 122 i += 1; 123 } 124 objc_mutex_unlock (__objc_runtime_mutex); 125 } 126 127 /* The same as __objc_register_selectors_from_list, but works on a 128 struct objc_method_description_list* instead of a struct 129 objc_method_list*. This is only used for protocols, which have 130 lists of method descriptions, not methods. */ 131 void 132 __objc_register_selectors_from_description_list 133 (struct objc_method_description_list *method_list) 134 { 135 int i = 0; 136 137 objc_mutex_lock (__objc_runtime_mutex); 138 while (i < method_list->count) 139 { 140 struct objc_method_description *method = &method_list->list[i]; 141 if (method->name) 142 { 143 method->name 144 = __sel_register_typed_name ((const char *) method->name, 145 method->types, 0, YES); 146 } 147 i += 1; 148 } 149 objc_mutex_unlock (__objc_runtime_mutex); 150 } 151 152 /* Register instance methods as class methods for root classes. */ 153 void __objc_register_instance_methods_to_class (Class class) 154 { 155 struct objc_method_list *method_list; 156 struct objc_method_list *class_method_list; 157 int max_methods_no = 16; 158 struct objc_method_list *new_list; 159 Method curr_method; 160 161 /* Only if a root class. */ 162 if (class->super_class) 163 return; 164 165 /* Allocate a method list to hold the new class methods. */ 166 new_list = objc_calloc (sizeof (struct objc_method_list) 167 + sizeof (struct objc_method[max_methods_no]), 1); 168 method_list = class->methods; 169 class_method_list = class->class_pointer->methods; 170 curr_method = &new_list->method_list[0]; 171 172 /* Iterate through the method lists for the class. */ 173 while (method_list) 174 { 175 int i; 176 177 /* Iterate through the methods from this method list. */ 178 for (i = 0; i < method_list->method_count; i++) 179 { 180 Method mth = &method_list->method_list[i]; 181 if (mth->method_name 182 && ! search_for_method_in_list (class_method_list, 183 mth->method_name)) 184 { 185 /* This instance method isn't a class method. Add it 186 into the new_list. */ 187 *curr_method = *mth; 188 189 /* Reallocate the method list if necessary. */ 190 if (++new_list->method_count == max_methods_no) 191 new_list = 192 objc_realloc (new_list, sizeof (struct objc_method_list) 193 + sizeof (struct 194 objc_method[max_methods_no += 16])); 195 curr_method = &new_list->method_list[new_list->method_count]; 196 } 197 } 198 199 method_list = method_list->method_next; 200 } 201 202 /* If we created any new class methods then attach the method list 203 to the class. */ 204 if (new_list->method_count) 205 { 206 new_list = 207 objc_realloc (new_list, sizeof (struct objc_method_list) 208 + sizeof (struct objc_method[new_list->method_count])); 209 new_list->method_next = class->class_pointer->methods; 210 class->class_pointer->methods = new_list; 211 } 212 else 213 objc_free(new_list); 214 215 __objc_update_dispatch_table_for_class (class->class_pointer); 216 } 217 218 BOOL 219 sel_isEqual (SEL s1, SEL s2) 220 { 221 if (s1 == 0 || s2 == 0) 222 return s1 == s2; 223 else 224 return s1->sel_id == s2->sel_id; 225 } 226 227 /* Return YES iff t1 and t2 have same method types. Ignore the 228 argframe layout. */ 229 static BOOL 230 sel_types_match (const char *t1, const char *t2) 231 { 232 if (! t1 || ! t2) 233 return NO; 234 while (*t1 && *t2) 235 { 236 if (*t1 == '+') t1++; 237 if (*t2 == '+') t2++; 238 while (isdigit ((unsigned char) *t1)) t1++; 239 while (isdigit ((unsigned char) *t2)) t2++; 240 /* xxx Remove these next two lines when qualifiers are put in 241 all selectors, not just Protocol selectors. */ 242 t1 = objc_skip_type_qualifiers (t1); 243 t2 = objc_skip_type_qualifiers (t2); 244 if (! *t1 && ! *t2) 245 return YES; 246 if (*t1 != *t2) 247 return NO; 248 t1++; 249 t2++; 250 } 251 return NO; 252 } 253 254 /* Return selector representing name. */ 255 SEL 256 sel_get_any_uid (const char *name) 257 { 258 struct objc_list *l; 259 sidx i; 260 261 objc_mutex_lock (__objc_runtime_mutex); 262 263 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name); 264 if (soffset_decode (i) == 0) 265 { 266 objc_mutex_unlock (__objc_runtime_mutex); 267 return 0; 268 } 269 270 l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i); 271 objc_mutex_unlock (__objc_runtime_mutex); 272 273 if (l == 0) 274 return 0; 275 276 return (SEL) l->head; 277 } 278 279 SEL 280 sel_getTypedSelector (const char *name) 281 { 282 sidx i; 283 284 if (name == NULL) 285 return NULL; 286 287 objc_mutex_lock (__objc_runtime_mutex); 288 289 /* Look for a typed selector. */ 290 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name); 291 if (i != 0) 292 { 293 struct objc_list *l; 294 SEL returnValue = NULL; 295 296 for (l = (struct objc_list *) sarray_get_safe (__objc_selector_array, i); 297 l; l = l->tail) 298 { 299 SEL s = (SEL) l->head; 300 if (s->sel_types) 301 { 302 if (returnValue == NULL) 303 { 304 /* First typed selector that we find. Keep it in 305 returnValue, but keep checking as we want to 306 detect conflicts. */ 307 returnValue = s; 308 } 309 else 310 { 311 /* We had already found a typed selectors, so we 312 have multiple ones. Double-check that they have 313 different types, just in case for some reason we 314 got duplicates with the same types. If so, it's 315 OK, we'll ignore the duplicate. */ 316 if (returnValue->sel_types == s->sel_types) 317 continue; 318 else if (sel_types_match (returnValue->sel_types, s->sel_types)) 319 continue; 320 else 321 { 322 /* The types of the two selectors are different; 323 it's a conflict. Too bad. Return NULL. */ 324 objc_mutex_unlock (__objc_runtime_mutex); 325 return NULL; 326 } 327 } 328 } 329 } 330 331 if (returnValue != NULL) 332 { 333 objc_mutex_unlock (__objc_runtime_mutex); 334 return returnValue; 335 } 336 } 337 338 /* No typed selector found. Return NULL. */ 339 objc_mutex_unlock (__objc_runtime_mutex); 340 return 0; 341 } 342 343 SEL * 344 sel_copyTypedSelectorList (const char *name, unsigned int *numberOfReturnedSelectors) 345 { 346 unsigned int count = 0; 347 SEL *returnValue = NULL; 348 sidx i; 349 350 if (name == NULL) 351 { 352 if (numberOfReturnedSelectors) 353 *numberOfReturnedSelectors = 0; 354 return NULL; 355 } 356 357 objc_mutex_lock (__objc_runtime_mutex); 358 359 /* Count how many selectors we have. */ 360 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name); 361 if (i != 0) 362 { 363 struct objc_list *selector_list = NULL; 364 selector_list = (struct objc_list *) sarray_get_safe (__objc_selector_array, i); 365 366 /* Count how many selectors we have. */ 367 { 368 struct objc_list *l; 369 for (l = selector_list; l; l = l->tail) 370 count++; 371 } 372 373 if (count != 0) 374 { 375 /* Allocate enough memory to hold them. */ 376 returnValue = (SEL *)(malloc (sizeof (SEL) * (count + 1))); 377 378 /* Copy the selectors. */ 379 { 380 unsigned int j; 381 for (j = 0; j < count; j++) 382 { 383 returnValue[j] = (SEL)(selector_list->head); 384 selector_list = selector_list->tail; 385 } 386 returnValue[j] = NULL; 387 } 388 } 389 } 390 391 objc_mutex_unlock (__objc_runtime_mutex); 392 393 if (numberOfReturnedSelectors) 394 *numberOfReturnedSelectors = count; 395 396 return returnValue; 397 } 398 399 /* Get the name of a selector. If the selector is unknown, the empty 400 string "" is returned. */ 401 const char *sel_getName (SEL selector) 402 { 403 const char *ret; 404 405 if (selector == NULL) 406 return "<null selector>"; 407 408 objc_mutex_lock (__objc_runtime_mutex); 409 if ((soffset_decode ((sidx)selector->sel_id) > 0) 410 && (soffset_decode ((sidx)selector->sel_id) <= __objc_selector_max_index)) 411 ret = sarray_get_safe (__objc_selector_names, (sidx) selector->sel_id); 412 else 413 ret = 0; 414 objc_mutex_unlock (__objc_runtime_mutex); 415 return ret; 416 } 417 418 BOOL 419 sel_is_mapped (SEL selector) 420 { 421 unsigned int idx = soffset_decode ((sidx)selector->sel_id); 422 return ((idx > 0) && (idx <= __objc_selector_max_index)); 423 } 424 425 const char *sel_getTypeEncoding (SEL selector) 426 { 427 if (selector) 428 return selector->sel_types; 429 else 430 return 0; 431 } 432 433 /* The uninstalled dispatch table. */ 434 extern struct sarray *__objc_uninstalled_dtable; 435 436 /* __sel_register_typed_name allocates lots of struct objc_selector:s 437 of 8 (16, if pointers are 64 bits) bytes at startup. To reduce the 438 number of malloc calls and memory lost to malloc overhead, we 439 allocate objc_selector:s in blocks here. This is only called from 440 __sel_register_typed_name, and __sel_register_typed_name may only 441 be called when __objc_runtime_mutex is locked. 442 443 Note that the objc_selector:s allocated from 444 __sel_register_typed_name are never freed. 445 446 62 because 62 * sizeof (struct objc_selector) = 496 (992). This 447 should let malloc add some overhead and use a nice, round 512 448 (1024) byte chunk. */ 449 #define SELECTOR_POOL_SIZE 62 450 static struct objc_selector *selector_pool; 451 static int selector_pool_left; 452 453 static struct objc_selector * 454 pool_alloc_selector(void) 455 { 456 if (!selector_pool_left) 457 { 458 selector_pool = objc_malloc (sizeof (struct objc_selector) 459 * SELECTOR_POOL_SIZE); 460 selector_pool_left = SELECTOR_POOL_SIZE; 461 } 462 return &selector_pool[--selector_pool_left]; 463 } 464 465 /* Store the passed selector name in the selector record and return 466 its selector value (value returned by sel_get_uid). Assume that 467 the calling function has locked down __objc_runtime_mutex. The 468 'is_const' parameter tells us if the name and types parameters are 469 really constant or not. If YES then they are constant and we can 470 just store the pointers. If NO then we need to copy name and types 471 because the pointers may disappear later on. If the 'orig' 472 parameter is not NULL, then we are registering a selector from a 473 module, and 'orig' is that selector. In this case, we can put the 474 selector in the tables if needed, and orig->sel_id is updated with 475 the selector ID of the registered selector, and 'orig' is 476 returned. */ 477 static SEL 478 __sel_register_typed_name (const char *name, const char *types, 479 struct objc_selector *orig, BOOL is_const) 480 { 481 struct objc_selector *j; 482 sidx i; 483 struct objc_list *l; 484 485 i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name); 486 if (soffset_decode (i) != 0) 487 { 488 /* There are already selectors with that name. Examine them to 489 see if the one we're registering already exists. */ 490 for (l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i); 491 l; l = l->tail) 492 { 493 SEL s = (SEL)l->head; 494 if (types == 0 || s->sel_types == 0) 495 { 496 if (s->sel_types == types) 497 { 498 if (orig) 499 { 500 orig->sel_id = (void *)i; 501 return orig; 502 } 503 else 504 return s; 505 } 506 } 507 else if (sel_types_match (s->sel_types, types)) 508 { 509 if (orig) 510 { 511 orig->sel_id = (void *)i; 512 return orig; 513 } 514 else 515 return s; 516 } 517 } 518 /* A selector with this specific name/type combination does not 519 exist yet. We need to register it. */ 520 if (orig) 521 j = orig; 522 else 523 j = pool_alloc_selector (); 524 525 j->sel_id = (void *)i; 526 /* Can we use the pointer or must we copy types ? Don't copy if 527 NULL. */ 528 if ((is_const) || (types == 0)) 529 j->sel_types = types; 530 else 531 { 532 j->sel_types = (char *)objc_malloc (strlen (types) + 1); 533 strcpy ((char *)j->sel_types, types); 534 } 535 l = (struct objc_list *)sarray_get_safe (__objc_selector_array, i); 536 } 537 else 538 { 539 /* There are no other selectors with this name registered in the 540 runtime tables. */ 541 const char *new_name; 542 543 /* Determine i. */ 544 __objc_selector_max_index += 1; 545 i = soffset_encode (__objc_selector_max_index); 546 547 /* Prepare the selector. */ 548 if (orig) 549 j = orig; 550 else 551 j = pool_alloc_selector (); 552 553 j->sel_id = (void *)i; 554 /* Can we use the pointer or must we copy types ? Don't copy if 555 NULL. */ 556 if (is_const || (types == 0)) 557 j->sel_types = types; 558 else 559 { 560 j->sel_types = (char *)objc_malloc (strlen (types) + 1); 561 strcpy ((char *)j->sel_types, types); 562 } 563 564 /* Since this is the first selector with this name, we need to 565 register the correspondence between 'i' (the sel_id) and 566 'name' (the actual string) in __objc_selector_names and 567 __objc_selector_hash. */ 568 569 /* Can we use the pointer or must we copy name ? Don't copy if 570 NULL. (FIXME: Can the name really be NULL here ?) */ 571 if (is_const || (name == 0)) 572 new_name = name; 573 else 574 { 575 new_name = (char *)objc_malloc (strlen (name) + 1); 576 strcpy ((char *)new_name, name); 577 } 578 579 /* This maps the sel_id to the name. */ 580 sarray_at_put_safe (__objc_selector_names, i, (void *)new_name); 581 582 /* This maps the name to the sel_id. */ 583 objc_hash_add (&__objc_selector_hash, (void *)new_name, (void *)i); 584 585 l = 0; 586 } 587 588 DEBUG_PRINTF ("Record selector %s[%s] as: %ld\n", name, types, 589 (long)soffset_decode (i)); 590 591 /* Now add the selector to the list of selectors with that id. */ 592 l = list_cons ((void *)j, l); 593 sarray_at_put_safe (__objc_selector_array, i, (void *)l); 594 595 sarray_realloc (__objc_uninstalled_dtable, __objc_selector_max_index + 1); 596 597 return (SEL)j; 598 } 599 600 SEL 601 sel_registerName (const char *name) 602 { 603 SEL ret; 604 605 if (name == NULL) 606 return NULL; 607 608 objc_mutex_lock (__objc_runtime_mutex); 609 /* Assume that name is not constant static memory and needs to be 610 copied before put into a runtime structure. is_const == NO. */ 611 ret = __sel_register_typed_name (name, 0, 0, NO); 612 objc_mutex_unlock (__objc_runtime_mutex); 613 614 return ret; 615 } 616 617 SEL 618 sel_registerTypedName (const char *name, const char *type) 619 { 620 SEL ret; 621 622 if (name == NULL) 623 return NULL; 624 625 objc_mutex_lock (__objc_runtime_mutex); 626 /* Assume that name and type are not constant static memory and need 627 to be copied before put into a runtime structure. is_const == 628 NO. */ 629 ret = __sel_register_typed_name (name, type, 0, NO); 630 objc_mutex_unlock (__objc_runtime_mutex); 631 632 return ret; 633 } 634 635 /* Return the selector representing name. */ 636 SEL 637 sel_getUid (const char *name) 638 { 639 return sel_registerTypedName (name, 0); 640 } 641