ObjCLanguageRuntime.h revision 102b2c2681c9a830afe25bfea35557421905e42c
1//===-- ObjCLanguageRuntime.h ---------------------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef liblldb_ObjCLanguageRuntime_h_ 11#define liblldb_ObjCLanguageRuntime_h_ 12 13// C Includes 14// C++ Includes 15#include <functional> 16#include <map> 17#include <unordered_set> 18 19// Other libraries and framework includes 20// Project includes 21#include "lldb/lldb-private.h" 22#include "lldb/Core/PluginInterface.h" 23#include "lldb/Symbol/Type.h" 24#include "lldb/Symbol/TypeVendor.h" 25#include "lldb/Target/LanguageRuntime.h" 26 27namespace lldb_private { 28 29class ClangUtilityFunction; 30 31class ObjCLanguageRuntime : 32 public LanguageRuntime 33{ 34public: 35 class MethodName 36 { 37 public: 38 enum Type 39 { 40 eTypeUnspecified, 41 eTypeClassMethod, 42 eTypeInstanceMethod 43 }; 44 45 MethodName () : 46 m_full(), 47 m_class(), 48 m_category(), 49 m_selector(), 50 m_type (eTypeUnspecified), 51 m_category_is_valid (false) 52 { 53 } 54 55 MethodName (const char *name, bool strict) : 56 m_full(), 57 m_class(), 58 m_category(), 59 m_selector(), 60 m_type (eTypeUnspecified), 61 m_category_is_valid (false) 62 { 63 SetName (name, strict); 64 } 65 66 void 67 Clear(); 68 69 bool 70 IsValid (bool strict) const 71 { 72 // If "strict" is true, the name must have everything specified including 73 // the leading "+" or "-" on the method name 74 if (strict && m_type == eTypeUnspecified) 75 return false; 76 // Other than that, m_full will only be filled in if the objective C 77 // name is valid. 78 return (bool)m_full; 79 } 80 81 bool 82 HasCategory() 83 { 84 return (bool)GetCategory(); 85 } 86 87 Type 88 GetType () const 89 { 90 return m_type; 91 } 92 93 const ConstString & 94 GetFullName () const 95 { 96 return m_full; 97 } 98 99 ConstString 100 GetFullNameWithoutCategory (bool empty_if_no_category); 101 102 bool 103 SetName (const char *name, bool strict); 104 105 const ConstString & 106 GetClassName (); 107 108 const ConstString & 109 GetClassNameWithCategory (); 110 111 const ConstString & 112 GetCategory (); 113 114 const ConstString & 115 GetSelector (); 116 117 // Get all possible names for a method. Examples: 118 // If name is "+[NSString(my_additions) myStringWithCString:]" 119 // names[0] => "+[NSString(my_additions) myStringWithCString:]" 120 // names[1] => "+[NSString myStringWithCString:]" 121 // If name is specified without the leading '+' or '-' like "[NSString(my_additions) myStringWithCString:]" 122 // names[0] => "+[NSString(my_additions) myStringWithCString:]" 123 // names[1] => "-[NSString(my_additions) myStringWithCString:]" 124 // names[2] => "+[NSString myStringWithCString:]" 125 // names[3] => "-[NSString myStringWithCString:]" 126 size_t 127 GetFullNames (std::vector<ConstString> &names, bool append); 128 protected: 129 ConstString m_full; // Full name: "+[NSString(my_additions) myStringWithCString:]" 130 ConstString m_class; // Class name: "NSString" 131 ConstString m_class_category; // Class with category: "NSString(my_additions)" 132 ConstString m_category; // Category: "my_additions" 133 ConstString m_selector; // Selector: "myStringWithCString:" 134 Type m_type; 135 bool m_category_is_valid; 136 137 }; 138 typedef lldb::addr_t ObjCISA; 139 140 class ClassDescriptor; 141 typedef std::shared_ptr<ClassDescriptor> ClassDescriptorSP; 142 143 // the information that we want to support retrieving from an ObjC class 144 // this needs to be pure virtual since there are at least 2 different implementations 145 // of the runtime, and more might come 146 class ClassDescriptor 147 { 148 public: 149 150 ClassDescriptor() : 151 m_is_kvo (eLazyBoolCalculate), 152 m_is_cf (eLazyBoolCalculate), 153 m_type_wp () 154 { 155 } 156 157 virtual 158 ~ClassDescriptor () 159 { 160 } 161 162 virtual ConstString 163 GetClassName () = 0; 164 165 virtual ClassDescriptorSP 166 GetSuperclass () = 0; 167 168 // virtual if any implementation has some other version-specific rules 169 // but for the known v1/v2 this is all that needs to be done 170 virtual bool 171 IsKVO () 172 { 173 if (m_is_kvo == eLazyBoolCalculate) 174 { 175 const char* class_name = GetClassName().AsCString(); 176 if (class_name && *class_name) 177 m_is_kvo = (LazyBool)(strstr(class_name,"NSKVONotifying_") == class_name); 178 } 179 return (m_is_kvo == eLazyBoolYes); 180 } 181 182 // virtual if any implementation has some other version-specific rules 183 // but for the known v1/v2 this is all that needs to be done 184 virtual bool 185 IsCFType () 186 { 187 if (m_is_cf == eLazyBoolCalculate) 188 { 189 const char* class_name = GetClassName().AsCString(); 190 if (class_name && *class_name) 191 m_is_cf = (LazyBool)(strcmp(class_name,"__NSCFType") == 0 || 192 strcmp(class_name,"NSCFType") == 0); 193 } 194 return (m_is_cf == eLazyBoolYes); 195 } 196 197 virtual bool 198 IsValid () = 0; 199 200 virtual bool 201 GetTaggedPointerInfo (uint64_t* info_bits = NULL, 202 uint64_t* value_bits = NULL) = 0; 203 204 virtual uint64_t 205 GetInstanceSize () = 0; 206 207 // use to implement version-specific additional constraints on pointers 208 virtual bool 209 CheckPointer (lldb::addr_t value, 210 uint32_t ptr_size) const 211 { 212 return true; 213 } 214 215 virtual ObjCISA 216 GetISA () = 0; 217 218 // This should return true iff the interface could be completed 219 virtual bool 220 Describe (std::function <void (ObjCISA)> const &superclass_func, 221 std::function <bool (const char*, const char*)> const &instance_method_func, 222 std::function <bool (const char*, const char*)> const &class_method_func, 223 std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func) 224 { 225 return false; 226 } 227 228 lldb::TypeSP 229 GetType () 230 { 231 return m_type_wp.lock(); 232 } 233 234 void 235 SetType (const lldb::TypeSP &type_sp) 236 { 237 m_type_wp = type_sp; 238 } 239 240 protected: 241 bool 242 IsPointerValid (lldb::addr_t value, 243 uint32_t ptr_size, 244 bool allow_NULLs = false, 245 bool allow_tagged = false, 246 bool check_version_specific = false) const; 247 248 private: 249 LazyBool m_is_kvo; 250 LazyBool m_is_cf; 251 lldb::TypeWP m_type_wp; 252 }; 253 254 virtual ClassDescriptorSP 255 GetClassDescriptor (ValueObject& in_value); 256 257 ClassDescriptorSP 258 GetNonKVOClassDescriptor (ValueObject& in_value); 259 260 virtual ClassDescriptorSP 261 GetClassDescriptor (const ConstString &class_name); 262 263 virtual ClassDescriptorSP 264 GetClassDescriptor (ObjCISA isa); 265 266 ClassDescriptorSP 267 GetNonKVOClassDescriptor (ObjCISA isa); 268 269 virtual 270 ~ObjCLanguageRuntime(); 271 272 virtual lldb::LanguageType 273 GetLanguageType () const 274 { 275 return lldb::eLanguageTypeObjC; 276 } 277 278 virtual bool 279 IsModuleObjCLibrary (const lldb::ModuleSP &module_sp) = 0; 280 281 virtual bool 282 ReadObjCLibrary (const lldb::ModuleSP &module_sp) = 0; 283 284 virtual bool 285 HasReadObjCLibrary () = 0; 286 287 virtual lldb::ThreadPlanSP 288 GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0; 289 290 lldb::addr_t 291 LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t sel); 292 293 void 294 AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr); 295 296 TypeAndOrName 297 LookupInClassNameCache (lldb::addr_t class_addr); 298 299 void 300 AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp); 301 302 void 303 AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_or_type_name); 304 305 lldb::TypeSP 306 LookupInCompleteClassCache (ConstString &name); 307 308 virtual ClangUtilityFunction * 309 CreateObjectChecker (const char *) = 0; 310 311 virtual ObjCRuntimeVersions 312 GetRuntimeVersion () 313 { 314 return eObjC_VersionUnknown; 315 } 316 317 bool 318 IsValidISA(ObjCISA isa) 319 { 320 UpdateISAToDescriptorMap(); 321 return m_isa_to_descriptor.count(isa) > 0; 322 } 323 324 virtual void 325 UpdateISAToDescriptorMapIfNeeded() = 0; 326 327 void 328 UpdateISAToDescriptorMap() 329 { 330 if (m_process && m_process->GetStopID() != m_isa_to_descriptor_stop_id) 331 { 332 UpdateISAToDescriptorMapIfNeeded (); 333 } 334 } 335 336 virtual ObjCISA 337 GetISA(const ConstString &name); 338 339 virtual ConstString 340 GetActualTypeName(ObjCISA isa); 341 342 virtual ObjCISA 343 GetParentClass(ObjCISA isa); 344 345 virtual TypeVendor * 346 GetTypeVendor() 347 { 348 return NULL; 349 } 350 351 // Finds the byte offset of the child_type ivar in parent_type. If it can't find the 352 // offset, returns LLDB_INVALID_IVAR_OFFSET. 353 354 virtual size_t 355 GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name); 356 357 // Given the name of an Objective-C runtime symbol (e.g., ivar offset symbol), 358 // try to determine from the runtime what the value of that symbol would be. 359 // Useful when the underlying binary is stripped. 360 virtual lldb::addr_t 361 LookupRuntimeSymbol (const ConstString &name) 362 { 363 return LLDB_INVALID_ADDRESS; 364 } 365 366 //------------------------------------------------------------------ 367 /// Chop up an objective C function prototype. 368 /// 369 /// Chop up an objective C function fullname and optionally fill in 370 /// any non-NULL ConstString objects. If a ConstString * is NULL, 371 /// then this name doesn't get filled in 372 /// 373 /// @param[in] name 374 /// A fully specified objective C function name. The string might 375 /// contain a category and it includes the leading "+" or "-" and 376 /// the square brackets, no types for the arguments, just the plain 377 /// selector. A few examples: 378 /// "-[NSStringDrawingContext init]" 379 /// "-[NSStringDrawingContext addString:inRect:]" 380 /// "-[NSString(NSStringDrawing) sizeWithAttributes:]" 381 /// "+[NSString(NSStringDrawing) usesFontLeading]" 382 /// 383 /// @param[out] class_name 384 /// If non-NULL, this string will be filled in with the class 385 /// name including the category. The examples above would return: 386 /// "NSStringDrawingContext" 387 /// "NSStringDrawingContext" 388 /// "NSString(NSStringDrawing)" 389 /// "NSString(NSStringDrawing)" 390 /// 391 /// @param[out] selector_name 392 /// If non-NULL, this string will be filled in with the selector 393 /// name. The examples above would return: 394 /// "init" 395 /// "addString:inRect:" 396 /// "sizeWithAttributes:" 397 /// "usesFontLeading" 398 /// 399 /// @param[out] name_sans_category 400 /// If non-NULL, this string will be filled in with the class 401 /// name _without_ the category. If there is no category, and empty 402 /// string will be returned (as the result would be normally returned 403 /// in the "class_name" argument). The examples above would return: 404 /// <empty> 405 /// <empty> 406 /// "-[NSString sizeWithAttributes:]" 407 /// "+[NSString usesFontLeading]" 408 /// 409 /// @param[out] class_name_sans_category 410 /// If non-NULL, this string will be filled in with the prototype 411 /// name _without_ the category. If there is no category, and empty 412 /// string will be returned (as this is already the value that was 413 /// passed in). The examples above would return: 414 /// <empty> 415 /// <empty> 416 /// "NSString" 417 /// "NSString" 418 /// 419 /// @return 420 /// Returns the number of strings that were successfully filled 421 /// in. 422 //------------------------------------------------------------------ 423// static uint32_t 424// ParseMethodName (const char *name, 425// ConstString *class_name, // Class name (with category if there is one) 426// ConstString *selector_name, // selector only 427// ConstString *name_sans_category, // full function name with no category (empty if no category) 428// ConstString *class_name_sans_category);// Class name without category (empty if no category) 429 430 static bool 431 IsPossibleObjCMethodName (const char *name) 432 { 433 if (!name) 434 return false; 435 bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '['; 436 bool ends_right = (name[strlen(name) - 1] == ']'); 437 return (starts_right && ends_right); 438 } 439 440 static bool 441 IsPossibleObjCSelector (const char *name) 442 { 443 if (!name) 444 return false; 445 446 if (strchr(name, ':') == NULL) 447 return true; 448 else if (name[strlen(name) - 1] == ':') 449 return true; 450 else 451 return false; 452 } 453 454 bool 455 HasNewLiteralsAndIndexing () 456 { 457 if (m_has_new_literals_and_indexing == eLazyBoolCalculate) 458 { 459 if (CalculateHasNewLiteralsAndIndexing()) 460 m_has_new_literals_and_indexing = eLazyBoolYes; 461 else 462 m_has_new_literals_and_indexing = eLazyBoolNo; 463 } 464 465 return (m_has_new_literals_and_indexing == eLazyBoolYes); 466 } 467 468 virtual void 469 SymbolsDidLoad (const ModuleList& module_list) 470 { 471 m_negative_complete_class_cache.clear(); 472 } 473 474protected: 475 //------------------------------------------------------------------ 476 // Classes that inherit from ObjCLanguageRuntime can see and modify these 477 //------------------------------------------------------------------ 478 ObjCLanguageRuntime(Process *process); 479 480 virtual bool CalculateHasNewLiteralsAndIndexing() 481 { 482 return false; 483 } 484 485 486 bool 487 ISAIsCached (ObjCISA isa) const 488 { 489 return m_isa_to_descriptor.find(isa) != m_isa_to_descriptor.end(); 490 } 491 492 bool 493 AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp) 494 { 495 if (isa != 0) 496 { 497 m_isa_to_descriptor[isa] = descriptor_sp; 498 return true; 499 } 500 return false; 501 } 502 503 bool 504 AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name); 505 506 bool 507 AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, uint32_t class_name_hash) 508 { 509 if (isa != 0) 510 { 511 m_isa_to_descriptor[isa] = descriptor_sp; 512 m_hash_to_isa_map.insert(std::make_pair(class_name_hash, isa)); 513 return true; 514 } 515 return false; 516 } 517 518private: 519 // We keep a map of <Class,Selector>->Implementation so we don't have to call the resolver 520 // function over and over. 521 522 // FIXME: We need to watch for the loading of Protocols, and flush the cache for any 523 // class that we see so changed. 524 525 struct ClassAndSel 526 { 527 ClassAndSel() 528 { 529 sel_addr = LLDB_INVALID_ADDRESS; 530 class_addr = LLDB_INVALID_ADDRESS; 531 } 532 ClassAndSel (lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr) : 533 class_addr (in_class_addr), 534 sel_addr(in_sel_addr) 535 { 536 } 537 bool operator== (const ClassAndSel &rhs) 538 { 539 if (class_addr == rhs.class_addr 540 && sel_addr == rhs.sel_addr) 541 return true; 542 else 543 return false; 544 } 545 546 bool operator< (const ClassAndSel &rhs) const 547 { 548 if (class_addr < rhs.class_addr) 549 return true; 550 else if (class_addr > rhs.class_addr) 551 return false; 552 else 553 { 554 if (sel_addr < rhs.sel_addr) 555 return true; 556 else 557 return false; 558 } 559 } 560 561 lldb::addr_t class_addr; 562 lldb::addr_t sel_addr; 563 }; 564 565 typedef std::map<ClassAndSel,lldb::addr_t> MsgImplMap; 566 typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap; 567 typedef std::multimap<uint32_t, ObjCISA> HashToISAMap; 568 typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator; 569 typedef HashToISAMap::iterator HashToISAIterator; 570 571 MsgImplMap m_impl_cache; 572 LazyBool m_has_new_literals_and_indexing; 573 ISAToDescriptorMap m_isa_to_descriptor; 574 HashToISAMap m_hash_to_isa_map; 575 576protected: 577 uint32_t m_isa_to_descriptor_stop_id; 578 579 typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap; 580 CompleteClassMap m_complete_class_cache; 581 582 struct ConstStringSetHelpers { 583 size_t operator () (const ConstString& arg) const // for hashing 584 { 585 return (size_t)arg.GetCString(); 586 } 587 bool operator () (const ConstString& arg1, const ConstString& arg2) const // for equality 588 { 589 return arg1.operator==(arg2); 590 } 591 }; 592 typedef std::unordered_set<ConstString, ConstStringSetHelpers, ConstStringSetHelpers> CompleteClassSet; 593 CompleteClassSet m_negative_complete_class_cache; 594 595 ISAToDescriptorIterator 596 GetDescriptorIterator (const ConstString &name); 597 598 DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime); 599}; 600 601} // namespace lldb_private 602 603#endif // liblldb_ObjCLanguageRuntime_h_ 604