ObjCLanguageRuntime.h revision d27e543e9c5f81ef1288afbc9e48de2da5976a8a
13019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm//===-- ObjCLanguageRuntime.h ---------------------------------------------------*- C++ -*-===// 25724bee8c27219ac277ea76d75dc70fa830eaac0hp.com!davidm// 33019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm// The LLVM Compiler Infrastructure 43019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm// 53019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm// This file is distributed under the University of Illinois Open Source 63019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm// License. See LICENSE.TXT for details. 73019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm// 83019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm//===----------------------------------------------------------------------===// 93019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm 103019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm#ifndef liblldb_ObjCLanguageRuntime_h_ 113019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm#define liblldb_ObjCLanguageRuntime_h_ 123019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm 133019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm// C Includes 143019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm// C++ Includes 153019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm#include <functional> 163019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm#include <map> 173019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm 183019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm// Other libraries and framework includes 193019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm// Project includes 203019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm#include "lldb/lldb-private.h" 213019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm#include "lldb/Core/PluginInterface.h" 223019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm#include "lldb/Symbol/Type.h" 233019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm#include "lldb/Symbol/TypeVendor.h" 243019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm#include "lldb/Target/LanguageRuntime.h" 253019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm 265724bee8c27219ac277ea76d75dc70fa830eaac0hp.com!davidmnamespace lldb_private { 273019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm 28aebba1f8a7dee9b9ae3e70128ad48de69ca90b15Tommi Rantalaclass ClangUtilityFunction; 293019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm 303019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidmclass ObjCLanguageRuntime : 313019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm public LanguageRuntime 323019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm{ 333019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidmpublic: 343019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm 353019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm typedef lldb::addr_t ObjCISA; 363019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm 373019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm class ClassDescriptor; 383019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm typedef STD_SHARED_PTR(ClassDescriptor) ClassDescriptorSP; 393019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm 403019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm // the information that we want to support retrieving from an ObjC class 413019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm // this needs to be pure virtual since there are at least 2 different implementations 423019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm // of the runtime, and more might come 433019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm class ClassDescriptor 443019e19bd70fa345c24eb1158676f4d066ee4f62hp.com!davidm { 45 public: 46 47 ClassDescriptor() : 48 m_is_kvo (eLazyBoolCalculate), 49 m_is_cf (eLazyBoolCalculate), 50 m_type_wp () 51 { 52 } 53 54 virtual 55 ~ClassDescriptor () 56 { 57 } 58 59 virtual ConstString 60 GetClassName () = 0; 61 62 virtual ClassDescriptorSP 63 GetSuperclass () = 0; 64 65 // virtual if any implementation has some other version-specific rules 66 // but for the known v1/v2 this is all that needs to be done 67 virtual bool 68 IsKVO () 69 { 70 if (m_is_kvo == eLazyBoolCalculate) 71 { 72 const char* class_name = GetClassName().AsCString(); 73 if (class_name && *class_name) 74 m_is_kvo = (LazyBool)(strstr(class_name,"NSKVONotifying_") == class_name); 75 } 76 return (m_is_kvo == eLazyBoolYes); 77 } 78 79 // virtual if any implementation has some other version-specific rules 80 // but for the known v1/v2 this is all that needs to be done 81 virtual bool 82 IsCFType () 83 { 84 if (m_is_cf == eLazyBoolCalculate) 85 { 86 const char* class_name = GetClassName().AsCString(); 87 if (class_name && *class_name) 88 m_is_cf = (LazyBool)(strcmp(class_name,"__NSCFType") == 0 || 89 strcmp(class_name,"NSCFType") == 0); 90 } 91 return (m_is_cf == eLazyBoolYes); 92 } 93 94 virtual bool 95 IsValid () = 0; 96 97 virtual bool 98 IsTagged () = 0; 99 100 virtual uint64_t 101 GetInstanceSize () = 0; 102 103 // use to implement version-specific additional constraints on pointers 104 virtual bool 105 CheckPointer (lldb::addr_t value, 106 uint32_t ptr_size) const 107 { 108 return true; 109 } 110 111 virtual ObjCISA 112 GetISA () = 0; 113 114 // This should return true iff the interface could be completed 115 virtual bool 116 Describe (std::function <void (ObjCISA)> const &superclass_func, 117 std::function <bool (const char*, const char*)> const &instance_method_func, 118 std::function <bool (const char*, const char*)> const &class_method_func, 119 std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func) 120 { 121 return false; 122 } 123 124 lldb::TypeSP 125 GetType () 126 { 127 return m_type_wp.lock(); 128 } 129 130 void 131 SetType (const lldb::TypeSP &type_sp) 132 { 133 m_type_wp = type_sp; 134 } 135 136 protected: 137 bool 138 IsPointerValid (lldb::addr_t value, 139 uint32_t ptr_size, 140 bool allow_NULLs = false, 141 bool allow_tagged = false, 142 bool check_version_specific = false) const; 143 144 private: 145 LazyBool m_is_kvo; 146 LazyBool m_is_cf; 147 lldb::TypeWP m_type_wp; 148 }; 149 150 // a convenience subclass of ClassDescriptor meant to represent invalid objects 151 class ClassDescriptor_Invalid : public ClassDescriptor 152 { 153 public: 154 ClassDescriptor_Invalid() {} 155 156 virtual 157 ~ClassDescriptor_Invalid () 158 {} 159 160 virtual ConstString 161 GetClassName () { return ConstString(""); } 162 163 virtual ClassDescriptorSP 164 GetSuperclass () { return ClassDescriptorSP(new ClassDescriptor_Invalid()); } 165 166 virtual bool 167 IsValid () { return false; } 168 169 virtual bool 170 IsTagged () { return false; } 171 172 virtual uint64_t 173 GetInstanceSize () { return 0; } 174 175 virtual ObjCISA 176 GetISA () { return 0; } 177 178 virtual bool 179 CheckPointer (lldb::addr_t value, uint32_t ptr_size) const 180 { 181 return false; 182 } 183 }; 184 185 virtual ClassDescriptorSP 186 GetClassDescriptor (ValueObject& in_value); 187 188 ClassDescriptorSP 189 GetNonKVOClassDescriptor (ValueObject& in_value); 190 191 virtual ClassDescriptorSP 192 GetClassDescriptor (const ConstString &class_name); 193 194 virtual ClassDescriptorSP 195 GetClassDescriptor (ObjCISA isa); 196 197 ClassDescriptorSP 198 GetNonKVOClassDescriptor (ObjCISA isa); 199 200 virtual 201 ~ObjCLanguageRuntime(); 202 203 virtual lldb::LanguageType 204 GetLanguageType () const 205 { 206 return lldb::eLanguageTypeObjC; 207 } 208 209 virtual bool 210 IsModuleObjCLibrary (const lldb::ModuleSP &module_sp) = 0; 211 212 virtual bool 213 ReadObjCLibrary (const lldb::ModuleSP &module_sp) = 0; 214 215 virtual bool 216 HasReadObjCLibrary () = 0; 217 218 virtual lldb::ThreadPlanSP 219 GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0; 220 221 lldb::addr_t 222 LookupInMethodCache (lldb::addr_t class_addr, lldb::addr_t sel); 223 224 void 225 AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t sel, lldb::addr_t impl_addr); 226 227 TypeAndOrName 228 LookupInClassNameCache (lldb::addr_t class_addr); 229 230 void 231 AddToClassNameCache (lldb::addr_t class_addr, const char *name, lldb::TypeSP type_sp); 232 233 void 234 AddToClassNameCache (lldb::addr_t class_addr, const TypeAndOrName &class_or_type_name); 235 236 lldb::TypeSP 237 LookupInCompleteClassCache (ConstString &name); 238 239 virtual ClangUtilityFunction * 240 CreateObjectChecker (const char *) = 0; 241 242 virtual ObjCRuntimeVersions 243 GetRuntimeVersion () 244 { 245 return eObjC_VersionUnknown; 246 } 247 248 bool 249 IsValidISA(ObjCISA isa) 250 { 251 UpdateISAToDescriptorMap(); 252 return m_isa_to_descriptor_cache.count(isa) > 0; 253 } 254 255 virtual void 256 UpdateISAToDescriptorMapIfNeeded() = 0; 257 258 void 259 UpdateISAToDescriptorMap() 260 { 261 if (m_process && m_process->GetStopID() != m_isa_to_descriptor_cache_stop_id) 262 { 263 UpdateISAToDescriptorMapIfNeeded (); 264 assert (m_process->GetStopID() == m_isa_to_descriptor_cache_stop_id); // REMOVE THIS PRIOR TO CHECKIN 265 } 266 } 267 268 virtual ObjCISA 269 GetISA(const ConstString &name); 270 271 virtual ConstString 272 GetActualTypeName(ObjCISA isa); 273 274 virtual ObjCISA 275 GetParentClass(ObjCISA isa); 276 277 virtual TypeVendor * 278 GetTypeVendor() 279 { 280 return NULL; 281 } 282 283 // Finds the byte offset of the child_type ivar in parent_type. If it can't find the 284 // offset, returns LLDB_INVALID_IVAR_OFFSET. 285 286 virtual size_t 287 GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name); 288 289 // Given the name of an Objective-C runtime symbol (e.g., ivar offset symbol), 290 // try to determine from the runtime what the value of that symbol would be. 291 // Useful when the underlying binary is stripped. 292 virtual lldb::addr_t 293 LookupRuntimeSymbol (const ConstString &name) 294 { 295 return LLDB_INVALID_ADDRESS; 296 } 297 298 //------------------------------------------------------------------ 299 /// Chop up an objective C function prototype. 300 /// 301 /// Chop up an objective C function fullname and optionally fill in 302 /// any non-NULL ConstString objects. If a ConstString * is NULL, 303 /// then this name doesn't get filled in 304 /// 305 /// @param[in] name 306 /// A fully specified objective C function name. The string might 307 /// contain a category and it includes the leading "+" or "-" and 308 /// the square brackets, no types for the arguments, just the plain 309 /// selector. A few examples: 310 /// "-[NSStringDrawingContext init]" 311 /// "-[NSStringDrawingContext addString:inRect:]" 312 /// "-[NSString(NSStringDrawing) sizeWithAttributes:]" 313 /// "+[NSString(NSStringDrawing) usesFontLeading]" 314 /// 315 /// @param[out] class_name 316 /// If non-NULL, this string will be filled in with the class 317 /// name including the category. The examples above would return: 318 /// "NSStringDrawingContext" 319 /// "NSStringDrawingContext" 320 /// "NSString(NSStringDrawing)" 321 /// "NSString(NSStringDrawing)" 322 /// 323 /// @param[out] selector_name 324 /// If non-NULL, this string will be filled in with the selector 325 /// name. The examples above would return: 326 /// "init" 327 /// "addString:inRect:" 328 /// "sizeWithAttributes:" 329 /// "usesFontLeading" 330 /// 331 /// @param[out] name_sans_category 332 /// If non-NULL, this string will be filled in with the class 333 /// name _without_ the category. If there is no category, and empty 334 /// string will be returned (as the result would be normally returned 335 /// in the "class_name" argument). The examples above would return: 336 /// <empty> 337 /// <empty> 338 /// "-[NSString sizeWithAttributes:]" 339 /// "+[NSString usesFontLeading]" 340 /// 341 /// @param[out] class_name_sans_category 342 /// If non-NULL, this string will be filled in with the prototype 343 /// name _without_ the category. If there is no category, and empty 344 /// string will be returned (as this is already the value that was 345 /// passed in). The examples above would return: 346 /// <empty> 347 /// <empty> 348 /// "NSString" 349 /// "NSString" 350 /// 351 /// @return 352 /// Returns the number of strings that were successfully filled 353 /// in. 354 //------------------------------------------------------------------ 355 static uint32_t 356 ParseMethodName (const char *name, 357 ConstString *class_name, // Class name (with category if there is one) 358 ConstString *selector_name, // selector only 359 ConstString *name_sans_category, // full function name with no category (empty if no category) 360 ConstString *class_name_sans_category);// Class name without category (empty if no category) 361 362 static bool 363 IsPossibleObjCMethodName (const char *name) 364 { 365 if (!name) 366 return false; 367 bool starts_right = (name[0] == '+' || name[0] == '-') && name[1] == '['; 368 bool ends_right = (name[strlen(name) - 1] == ']'); 369 return (starts_right && ends_right); 370 } 371 372 static bool 373 IsPossibleObjCSelector (const char *name) 374 { 375 if (!name) 376 return false; 377 378 if (strchr(name, ':') == NULL) 379 return true; 380 else if (name[strlen(name) - 1] == ':') 381 return true; 382 else 383 return false; 384 } 385 386 bool 387 HasNewLiteralsAndIndexing () 388 { 389 if (m_has_new_literals_and_indexing == eLazyBoolCalculate) 390 { 391 if (CalculateHasNewLiteralsAndIndexing()) 392 m_has_new_literals_and_indexing = eLazyBoolYes; 393 else 394 m_has_new_literals_and_indexing = eLazyBoolNo; 395 } 396 397 return (m_has_new_literals_and_indexing == eLazyBoolYes); 398 } 399 400protected: 401 //------------------------------------------------------------------ 402 // Classes that inherit from ObjCLanguageRuntime can see and modify these 403 //------------------------------------------------------------------ 404 ObjCLanguageRuntime(Process *process); 405 406 virtual bool CalculateHasNewLiteralsAndIndexing() 407 { 408 return false; 409 } 410private: 411 // We keep a map of <Class,Selector>->Implementation so we don't have to call the resolver 412 // function over and over. 413 414 // FIXME: We need to watch for the loading of Protocols, and flush the cache for any 415 // class that we see so changed. 416 417 struct ClassAndSel 418 { 419 ClassAndSel() 420 { 421 sel_addr = LLDB_INVALID_ADDRESS; 422 class_addr = LLDB_INVALID_ADDRESS; 423 } 424 ClassAndSel (lldb::addr_t in_sel_addr, lldb::addr_t in_class_addr) : 425 class_addr (in_class_addr), 426 sel_addr(in_sel_addr) 427 { 428 } 429 bool operator== (const ClassAndSel &rhs) 430 { 431 if (class_addr == rhs.class_addr 432 && sel_addr == rhs.sel_addr) 433 return true; 434 else 435 return false; 436 } 437 438 bool operator< (const ClassAndSel &rhs) const 439 { 440 if (class_addr < rhs.class_addr) 441 return true; 442 else if (class_addr > rhs.class_addr) 443 return false; 444 else 445 { 446 if (sel_addr < rhs.sel_addr) 447 return true; 448 else 449 return false; 450 } 451 } 452 453 lldb::addr_t class_addr; 454 lldb::addr_t sel_addr; 455 }; 456 457 typedef std::map<ClassAndSel,lldb::addr_t> MsgImplMap; 458 MsgImplMap m_impl_cache; 459 460 LazyBool m_has_new_literals_and_indexing; 461protected: 462 typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap; 463 typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator; 464 ISAToDescriptorMap m_isa_to_descriptor_cache; 465 uint32_t m_isa_to_descriptor_cache_stop_id; 466 typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap; 467 CompleteClassMap m_complete_class_cache; 468 469 DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime); 470}; 471 472} // namespace lldb_private 473 474#endif // liblldb_ObjCLanguageRuntime_h_ 475