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