1 //===-- ModuleSpec.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_ModuleSpec_h_ 11 #define liblldb_ModuleSpec_h_ 12 13 #include "lldb/Core/ArchSpec.h" 14 #include "lldb/Core/Stream.h" 15 #include "lldb/Core/UUID.h" 16 #include "lldb/Host/FileSpec.h" 17 #include "lldb/Host/Mutex.h" 18 #include "lldb/Target/PathMappingList.h" 19 20 namespace lldb_private { 21 22 class ModuleSpec 23 { 24 public: ModuleSpec()25 ModuleSpec () : 26 m_file (), 27 m_platform_file (), 28 m_symbol_file (), 29 m_arch (), 30 m_uuid (), 31 m_object_name (), 32 m_object_offset (0), 33 m_object_size (0), 34 m_object_mod_time (), 35 m_source_mappings () 36 { 37 } 38 ModuleSpec(const FileSpec & file_spec)39 ModuleSpec (const FileSpec &file_spec) : 40 m_file (file_spec), 41 m_platform_file (), 42 m_symbol_file (), 43 m_arch (), 44 m_uuid (), 45 m_object_name (), 46 m_object_offset (0), 47 m_object_size (file_spec.GetByteSize ()), 48 m_object_mod_time (), 49 m_source_mappings () 50 { 51 } 52 ModuleSpec(const FileSpec & file_spec,const ArchSpec & arch)53 ModuleSpec (const FileSpec &file_spec, const ArchSpec &arch) : 54 m_file (file_spec), 55 m_platform_file (), 56 m_symbol_file (), 57 m_arch (arch), 58 m_uuid (), 59 m_object_name (), 60 m_object_offset (0), 61 m_object_size (file_spec.GetByteSize ()), 62 m_object_mod_time (), 63 m_source_mappings () 64 { 65 } 66 ModuleSpec(const ModuleSpec & rhs)67 ModuleSpec (const ModuleSpec &rhs) : 68 m_file (rhs.m_file), 69 m_platform_file (rhs.m_platform_file), 70 m_symbol_file (rhs.m_symbol_file), 71 m_arch (rhs.m_arch), 72 m_uuid (rhs.m_uuid), 73 m_object_name (rhs.m_object_name), 74 m_object_offset (rhs.m_object_offset), 75 m_object_size (rhs.m_object_size), 76 m_object_mod_time (rhs.m_object_mod_time), 77 m_source_mappings (rhs.m_source_mappings) 78 { 79 } 80 81 ModuleSpec & 82 operator = (const ModuleSpec &rhs) 83 { 84 if (this != &rhs) 85 { 86 m_file = rhs.m_file; 87 m_platform_file = rhs.m_platform_file; 88 m_symbol_file = rhs.m_symbol_file; 89 m_arch = rhs.m_arch; 90 m_uuid = rhs.m_uuid; 91 m_object_name = rhs.m_object_name; 92 m_object_offset = rhs.m_object_offset; 93 m_object_size = rhs.m_object_size; 94 m_object_mod_time = rhs.m_object_mod_time; 95 m_source_mappings = rhs.m_source_mappings; 96 } 97 return *this; 98 } 99 100 FileSpec * GetFileSpecPtr()101 GetFileSpecPtr () 102 { 103 if (m_file) 104 return &m_file; 105 return NULL; 106 } 107 108 const FileSpec * GetFileSpecPtr()109 GetFileSpecPtr () const 110 { 111 if (m_file) 112 return &m_file; 113 return NULL; 114 } 115 116 FileSpec & GetFileSpec()117 GetFileSpec () 118 { 119 return m_file; 120 } 121 const FileSpec & GetFileSpec()122 GetFileSpec () const 123 { 124 return m_file; 125 } 126 127 FileSpec * GetPlatformFileSpecPtr()128 GetPlatformFileSpecPtr () 129 { 130 if (m_platform_file) 131 return &m_platform_file; 132 return NULL; 133 } 134 135 const FileSpec * GetPlatformFileSpecPtr()136 GetPlatformFileSpecPtr () const 137 { 138 if (m_platform_file) 139 return &m_platform_file; 140 return NULL; 141 } 142 143 FileSpec & GetPlatformFileSpec()144 GetPlatformFileSpec () 145 { 146 return m_platform_file; 147 } 148 149 const FileSpec & GetPlatformFileSpec()150 GetPlatformFileSpec () const 151 { 152 return m_platform_file; 153 } 154 155 FileSpec * GetSymbolFileSpecPtr()156 GetSymbolFileSpecPtr () 157 { 158 if (m_symbol_file) 159 return &m_symbol_file; 160 return NULL; 161 } 162 163 const FileSpec * GetSymbolFileSpecPtr()164 GetSymbolFileSpecPtr () const 165 { 166 if (m_symbol_file) 167 return &m_symbol_file; 168 return NULL; 169 } 170 171 FileSpec & GetSymbolFileSpec()172 GetSymbolFileSpec () 173 { 174 return m_symbol_file; 175 } 176 177 const FileSpec & GetSymbolFileSpec()178 GetSymbolFileSpec () const 179 { 180 return m_symbol_file; 181 } 182 183 184 ArchSpec * GetArchitecturePtr()185 GetArchitecturePtr () 186 { 187 if (m_arch.IsValid()) 188 return &m_arch; 189 return NULL; 190 } 191 192 const ArchSpec * GetArchitecturePtr()193 GetArchitecturePtr () const 194 { 195 if (m_arch.IsValid()) 196 return &m_arch; 197 return NULL; 198 } 199 200 ArchSpec & GetArchitecture()201 GetArchitecture () 202 { 203 return m_arch; 204 } 205 206 const ArchSpec & GetArchitecture()207 GetArchitecture () const 208 { 209 return m_arch; 210 } 211 212 UUID * GetUUIDPtr()213 GetUUIDPtr () 214 { 215 if (m_uuid.IsValid()) 216 return &m_uuid; 217 return NULL; 218 } 219 220 const UUID * GetUUIDPtr()221 GetUUIDPtr () const 222 { 223 if (m_uuid.IsValid()) 224 return &m_uuid; 225 return NULL; 226 } 227 228 UUID & GetUUID()229 GetUUID () 230 { 231 return m_uuid; 232 } 233 234 const UUID & GetUUID()235 GetUUID () const 236 { 237 return m_uuid; 238 } 239 240 ConstString & GetObjectName()241 GetObjectName () 242 { 243 return m_object_name; 244 } 245 246 const ConstString & GetObjectName()247 GetObjectName () const 248 { 249 return m_object_name; 250 } 251 252 uint64_t GetObjectOffset()253 GetObjectOffset () const 254 { 255 return m_object_offset; 256 } 257 258 void SetObjectOffset(uint64_t object_offset)259 SetObjectOffset (uint64_t object_offset) 260 { 261 m_object_offset = object_offset; 262 } 263 264 uint64_t GetObjectSize()265 GetObjectSize () const 266 { 267 return m_object_size; 268 } 269 270 void SetObjectSize(uint64_t object_size)271 SetObjectSize (uint64_t object_size) 272 { 273 m_object_size = object_size; 274 } 275 276 TimeValue & GetObjectModificationTime()277 GetObjectModificationTime () 278 { 279 return m_object_mod_time; 280 } 281 282 const TimeValue & GetObjectModificationTime()283 GetObjectModificationTime () const 284 { 285 return m_object_mod_time; 286 } 287 288 PathMappingList & GetSourceMappingList()289 GetSourceMappingList () const 290 { 291 return m_source_mappings; 292 } 293 294 void Clear()295 Clear () 296 { 297 m_file.Clear(); 298 m_platform_file.Clear(); 299 m_symbol_file.Clear(); 300 m_arch.Clear(); 301 m_uuid.Clear(); 302 m_object_name.Clear(); 303 m_object_offset = 0; 304 m_object_size = 0; 305 m_source_mappings.Clear(false); 306 m_object_mod_time.Clear(); 307 } 308 309 310 explicit operator bool () const 311 { 312 if (m_file) 313 return true; 314 if (m_platform_file) 315 return true; 316 if (m_symbol_file) 317 return true; 318 if (m_arch.IsValid()) 319 return true; 320 if (m_uuid.IsValid()) 321 return true; 322 if (m_object_name) 323 return true; 324 if (m_object_size) 325 return true; 326 if (m_object_mod_time.IsValid()) 327 return true; 328 return false; 329 } 330 331 void Dump(Stream & strm)332 Dump (Stream &strm) 333 { 334 bool dumped_something = false; 335 if (m_file) 336 { 337 strm.PutCString("file = '"); 338 strm << m_file; 339 strm.PutCString("'"); 340 dumped_something = true; 341 } 342 if (m_platform_file) 343 { 344 if (dumped_something) 345 strm.PutCString(", "); 346 strm.PutCString("platform_file = '"); 347 strm << m_platform_file; 348 strm.PutCString("'"); 349 dumped_something = true; 350 } 351 if (m_symbol_file) 352 { 353 if (dumped_something) 354 strm.PutCString(", "); 355 strm.PutCString("symbol_file = '"); 356 strm << m_symbol_file; 357 strm.PutCString("'"); 358 dumped_something = true; 359 } 360 if (m_arch.IsValid()) 361 { 362 if (dumped_something) 363 strm.PutCString(", "); 364 strm.Printf("arch = %s", m_arch.GetTriple().str().c_str()); 365 dumped_something = true; 366 } 367 if (m_uuid.IsValid()) 368 { 369 if (dumped_something) 370 strm.PutCString(", "); 371 strm.PutCString("uuid = "); 372 m_uuid.Dump(&strm); 373 dumped_something = true; 374 } 375 if (m_object_name) 376 { 377 if (dumped_something) 378 strm.PutCString(", "); 379 strm.Printf("object_name = %s", m_object_name.GetCString()); 380 dumped_something = true; 381 } 382 if (m_object_offset > 0) 383 { 384 if (dumped_something) 385 strm.PutCString(", "); 386 strm.Printf("object_offset = %" PRIu64, m_object_offset); 387 dumped_something = true; 388 } 389 if (m_object_size > 0) 390 { 391 if (dumped_something) 392 strm.PutCString(", "); 393 strm.Printf("object size = %" PRIu64, m_object_size); 394 dumped_something = true; 395 } 396 if (m_object_mod_time.IsValid()) 397 { 398 if (dumped_something) 399 strm.PutCString(", "); 400 strm.Printf("object_mod_time = 0x%" PRIx64, m_object_mod_time.GetAsSecondsSinceJan1_1970()); 401 } 402 } 403 404 bool Matches(const ModuleSpec & match_module_spec,bool exact_arch_match)405 Matches (const ModuleSpec &match_module_spec, bool exact_arch_match) const 406 { 407 if (match_module_spec.GetUUIDPtr() && match_module_spec.GetUUID() != GetUUID()) 408 return false; 409 if (match_module_spec.GetObjectName() && match_module_spec.GetObjectName() != GetObjectName()) 410 return false; 411 if (match_module_spec.GetFileSpecPtr()) 412 { 413 const FileSpec &fspec = match_module_spec.GetFileSpec(); 414 if (!FileSpec::Equal(fspec, GetFileSpec(), fspec.GetDirectory().IsEmpty() == false)) 415 return false; 416 } 417 if (GetPlatformFileSpec() && match_module_spec.GetPlatformFileSpecPtr()) 418 { 419 const FileSpec &fspec = match_module_spec.GetPlatformFileSpec(); 420 if (!FileSpec::Equal(fspec, GetPlatformFileSpec(), fspec.GetDirectory().IsEmpty() == false)) 421 return false; 422 423 } 424 // Only match the symbol file spec if there is one in this ModuleSpec 425 if (GetSymbolFileSpec() && match_module_spec.GetSymbolFileSpecPtr()) 426 { 427 const FileSpec &fspec = match_module_spec.GetSymbolFileSpec(); 428 if (!FileSpec::Equal(fspec, GetSymbolFileSpec(), fspec.GetDirectory().IsEmpty() == false)) 429 return false; 430 431 } 432 if (match_module_spec.GetArchitecturePtr()) 433 { 434 if (exact_arch_match) 435 { 436 if (!GetArchitecture().IsExactMatch(match_module_spec.GetArchitecture())) 437 return false; 438 } 439 else 440 { 441 if (!GetArchitecture().IsCompatibleMatch(match_module_spec.GetArchitecture())) 442 return false; 443 } 444 } 445 return true; 446 } 447 448 protected: 449 FileSpec m_file; 450 FileSpec m_platform_file; 451 FileSpec m_symbol_file; 452 ArchSpec m_arch; 453 UUID m_uuid; 454 ConstString m_object_name; 455 uint64_t m_object_offset; 456 uint64_t m_object_size; 457 TimeValue m_object_mod_time; 458 mutable PathMappingList m_source_mappings; 459 }; 460 461 class ModuleSpecList 462 { 463 public: ModuleSpecList()464 ModuleSpecList () : 465 m_specs(), 466 m_mutex(Mutex::eMutexTypeRecursive) 467 { 468 } 469 ModuleSpecList(const ModuleSpecList & rhs)470 ModuleSpecList (const ModuleSpecList &rhs) : 471 m_specs(), 472 m_mutex(Mutex::eMutexTypeRecursive) 473 { 474 Mutex::Locker lhs_locker(m_mutex); 475 Mutex::Locker rhs_locker(rhs.m_mutex); 476 m_specs = rhs.m_specs; 477 } 478 ~ModuleSpecList()479 ~ModuleSpecList () 480 { 481 } 482 483 ModuleSpecList & 484 operator = (const ModuleSpecList &rhs) 485 { 486 if (this != &rhs) 487 { 488 Mutex::Locker lhs_locker(m_mutex); 489 Mutex::Locker rhs_locker(rhs.m_mutex); 490 m_specs = rhs.m_specs; 491 } 492 return *this; 493 } 494 495 size_t GetSize()496 GetSize() const 497 { 498 Mutex::Locker locker(m_mutex); 499 return m_specs.size(); 500 } 501 502 void Clear()503 Clear () 504 { 505 Mutex::Locker locker(m_mutex); 506 m_specs.clear(); 507 } 508 509 void Append(const ModuleSpec & spec)510 Append (const ModuleSpec &spec) 511 { 512 Mutex::Locker locker(m_mutex); 513 m_specs.push_back (spec); 514 } 515 516 void Append(const ModuleSpecList & rhs)517 Append (const ModuleSpecList &rhs) 518 { 519 Mutex::Locker lhs_locker(m_mutex); 520 Mutex::Locker rhs_locker(rhs.m_mutex); 521 m_specs.insert(m_specs.end(), rhs.m_specs.begin(), rhs.m_specs.end()); 522 } 523 524 // The index "i" must be valid and this can't be used in 525 // multi-threaded code as no mutex lock is taken. 526 ModuleSpec & GetModuleSpecRefAtIndex(size_t i)527 GetModuleSpecRefAtIndex (size_t i) 528 { 529 return m_specs[i]; 530 } 531 bool GetModuleSpecAtIndex(size_t i,ModuleSpec & module_spec)532 GetModuleSpecAtIndex (size_t i, ModuleSpec &module_spec) const 533 { 534 Mutex::Locker locker(m_mutex); 535 if (i < m_specs.size()) 536 { 537 module_spec = m_specs[i]; 538 return true; 539 } 540 module_spec.Clear(); 541 return false; 542 } 543 544 545 bool FindMatchingModuleSpec(const ModuleSpec & module_spec,ModuleSpec & match_module_spec)546 FindMatchingModuleSpec (const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const 547 { 548 Mutex::Locker locker(m_mutex); 549 bool exact_arch_match = true; 550 for (auto spec: m_specs) 551 { 552 if (spec.Matches(module_spec, exact_arch_match)) 553 { 554 match_module_spec = spec; 555 return true; 556 } 557 } 558 559 // If there was an architecture, retry with a compatible arch 560 if (module_spec.GetArchitecturePtr()) 561 { 562 exact_arch_match = false; 563 for (auto spec: m_specs) 564 { 565 if (spec.Matches(module_spec, exact_arch_match)) 566 { 567 match_module_spec = spec; 568 return true; 569 } 570 } 571 } 572 match_module_spec.Clear(); 573 return false; 574 } 575 576 size_t FindMatchingModuleSpecs(const ModuleSpec & module_spec,ModuleSpecList & matching_list)577 FindMatchingModuleSpecs (const ModuleSpec &module_spec, ModuleSpecList &matching_list) const 578 { 579 Mutex::Locker locker(m_mutex); 580 bool exact_arch_match = true; 581 const size_t initial_match_count = matching_list.GetSize(); 582 for (auto spec: m_specs) 583 { 584 if (spec.Matches(module_spec, exact_arch_match)) 585 matching_list.Append (spec); 586 } 587 588 // If there was an architecture, retry with a compatible arch if no matches were found 589 if (module_spec.GetArchitecturePtr() && (initial_match_count == matching_list.GetSize())) 590 { 591 exact_arch_match = false; 592 for (auto spec: m_specs) 593 { 594 if (spec.Matches(module_spec, exact_arch_match)) 595 matching_list.Append (spec); 596 } 597 } 598 return matching_list.GetSize() - initial_match_count; 599 } 600 601 void Dump(Stream & strm)602 Dump (Stream &strm) 603 { 604 Mutex::Locker locker(m_mutex); 605 uint32_t idx = 0; 606 for (auto spec: m_specs) 607 { 608 strm.Printf("[%u] ", idx); 609 spec.Dump (strm); 610 strm.EOL(); 611 ++idx; 612 } 613 } 614 615 protected: 616 typedef std::vector<ModuleSpec> collection; ///< The module collection type. 617 collection m_specs; ///< The collection of modules. 618 mutable Mutex m_mutex; 619 }; 620 621 } // namespace lldb_private 622 623 #endif // liblldb_ModuleSpec_h_ 624