ModuleSpec.h revision f9215bae3f7f76ad98bace0097821a12415690c5
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 19namespace lldb_private { 20 21class ModuleSpec 22{ 23public: 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 } 355 if (m_object_name) 356 { 357 if (dumped_something) 358 strm.PutCString(", "); 359 strm.Printf("object_name = %s", m_object_name.GetCString()); 360 dumped_something = true; 361 } 362 } 363 364 bool 365 Matches (const ModuleSpec &match_module_spec, bool exact_arch_match) const 366 { 367 if (match_module_spec.GetUUIDPtr() && match_module_spec.GetUUID() != GetUUID()) 368 return false; 369 if (match_module_spec.GetObjectName() && match_module_spec.GetObjectName() != GetObjectName()) 370 return false; 371 if (match_module_spec.GetFileSpecPtr()) 372 { 373 const FileSpec &fspec = match_module_spec.GetFileSpec(); 374 if (!FileSpec::Equal(fspec, GetFileSpec(), fspec.GetDirectory().IsEmpty() == false)) 375 return false; 376 } 377 if (match_module_spec.GetPlatformFileSpecPtr()) 378 { 379 const FileSpec &fspec = match_module_spec.GetPlatformFileSpec(); 380 if (!FileSpec::Equal(fspec, GetPlatformFileSpec(), fspec.GetDirectory().IsEmpty() == false)) 381 return false; 382 383 } 384 if (match_module_spec.GetSymbolFileSpecPtr()) 385 { 386 const FileSpec &fspec = match_module_spec.GetSymbolFileSpec(); 387 if (!FileSpec::Equal(fspec, GetSymbolFileSpec(), fspec.GetDirectory().IsEmpty() == false)) 388 return false; 389 390 } 391 if (match_module_spec.GetArchitecturePtr()) 392 { 393 if (exact_arch_match) 394 { 395 if (!GetArchitecture().IsExactMatch(match_module_spec.GetArchitecture())) 396 return false; 397 } 398 else 399 { 400 if (!GetArchitecture().IsCompatibleMatch(match_module_spec.GetArchitecture())) 401 return false; 402 } 403 } 404 return true; 405 } 406 407protected: 408 FileSpec m_file; 409 FileSpec m_platform_file; 410 FileSpec m_symbol_file; 411 ArchSpec m_arch; 412 UUID m_uuid; 413 ConstString m_object_name; 414 uint64_t m_object_offset; 415 TimeValue m_object_mod_time; 416 mutable PathMappingList m_source_mappings; 417}; 418 419class ModuleSpecList 420{ 421public: 422 ModuleSpecList () : 423 m_specs(), 424 m_mutex(Mutex::eMutexTypeRecursive) 425 { 426 } 427 428 ModuleSpecList (const ModuleSpecList &rhs) : 429 m_specs(), 430 m_mutex(Mutex::eMutexTypeRecursive) 431 { 432 Mutex::Locker lhs_locker(m_mutex); 433 Mutex::Locker rhs_locker(rhs.m_mutex); 434 m_specs = rhs.m_specs; 435 } 436 437 ~ModuleSpecList () 438 { 439 } 440 441 ModuleSpecList & 442 operator = (const ModuleSpecList &rhs) 443 { 444 if (this != &rhs) 445 { 446 Mutex::Locker lhs_locker(m_mutex); 447 Mutex::Locker rhs_locker(rhs.m_mutex); 448 m_specs = rhs.m_specs; 449 } 450 return *this; 451 } 452 453 size_t 454 GetSize() const 455 { 456 Mutex::Locker locker(m_mutex); 457 return m_specs.size(); 458 } 459 460 void 461 Clear () 462 { 463 Mutex::Locker locker(m_mutex); 464 m_specs.clear(); 465 } 466 467 void 468 Append (const ModuleSpec &spec) 469 { 470 Mutex::Locker locker(m_mutex); 471 m_specs.push_back (spec); 472 } 473 474 void 475 Append (const ModuleSpecList &rhs) 476 { 477 Mutex::Locker lhs_locker(m_mutex); 478 Mutex::Locker rhs_locker(rhs.m_mutex); 479 m_specs.insert(m_specs.end(), rhs.m_specs.begin(), rhs.m_specs.end()); 480 } 481 482 bool 483 GetModuleSpecAtIndex (size_t i, ModuleSpec &module_spec) const 484 { 485 Mutex::Locker locker(m_mutex); 486 if (i < m_specs.size()) 487 { 488 module_spec = m_specs[i]; 489 return true; 490 } 491 module_spec.Clear(); 492 return false; 493 } 494 495 496 bool 497 FindMatchingModuleSpec (const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const 498 { 499 Mutex::Locker locker(m_mutex); 500 bool exact_arch_match = true; 501 for (auto spec: m_specs) 502 { 503 if (spec.Matches(module_spec, exact_arch_match)) 504 { 505 match_module_spec = spec; 506 return true; 507 } 508 } 509 510 // If there was an architecture, retry with a compatible arch 511 if (module_spec.GetArchitecturePtr()) 512 { 513 exact_arch_match = false; 514 for (auto spec: m_specs) 515 { 516 if (spec.Matches(module_spec, exact_arch_match)) 517 { 518 match_module_spec = spec; 519 return true; 520 } 521 } 522 } 523 match_module_spec.Clear(); 524 return false; 525 } 526 527 size_t 528 FindMatchingModuleSpecs (const ModuleSpec &module_spec, ModuleSpecList &matching_list) const 529 { 530 Mutex::Locker locker(m_mutex); 531 bool exact_arch_match = true; 532 const size_t initial_match_count = matching_list.GetSize(); 533 for (auto spec: m_specs) 534 { 535 if (spec.Matches(module_spec, exact_arch_match)) 536 matching_list.Append (spec); 537 } 538 539 // If there was an architecture, retry with a compatible arch if no matches were found 540 if (module_spec.GetArchitecturePtr() && (initial_match_count == matching_list.GetSize())) 541 { 542 exact_arch_match = false; 543 for (auto spec: m_specs) 544 { 545 if (spec.Matches(module_spec, exact_arch_match)) 546 matching_list.Append (spec); 547 } 548 } 549 return matching_list.GetSize() - initial_match_count; 550 } 551 552 void 553 Dump (Stream &strm) 554 { 555 Mutex::Locker locker(m_mutex); 556 uint32_t idx = 0; 557 for (auto spec: m_specs) 558 { 559 strm.Printf("[%u] ", idx); 560 spec.Dump (strm); 561 strm.EOL(); 562 ++idx; 563 } 564 } 565 566protected: 567 typedef std::vector<ModuleSpec> collection; ///< The module collection type. 568 collection m_specs; ///< The collection of modules. 569 mutable Mutex m_mutex; 570}; 571 572} // namespace lldb_private 573 574#endif // liblldb_ModuleSpec_h_ 575