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