1195534Sscottl//===-- ModuleSpec.h --------------------------------------------*- C++ -*-===// 2238805Smav// 3195534Sscottl// The LLVM Compiler Infrastructure 4195534Sscottl// 5195534Sscottl// This file is distributed under the University of Illinois Open Source 6195534Sscottl// License. See LICENSE.TXT for details. 7195534Sscottl// 8195534Sscottl//===----------------------------------------------------------------------===// 9195534Sscottl 10195534Sscottl#ifndef liblldb_ModuleSpec_h_ 11195534Sscottl#define liblldb_ModuleSpec_h_ 12195534Sscottl 13195534Sscottl#include "lldb/Core/ArchSpec.h" 14195534Sscottl#include "lldb/Core/Stream.h" 15195534Sscottl#include "lldb/Core/UUID.h" 16195534Sscottl#include "lldb/Host/FileSpec.h" 17195534Sscottl#include "lldb/Target/PathMappingList.h" 18195534Sscottl 19195534Sscottlnamespace lldb_private { 20195534Sscottl 21195534Sscottlclass ModuleSpec 22195534Sscottl{ 23195534Sscottlpublic: 24195534Sscottl ModuleSpec () : 25195534Sscottl m_file (), 26195534Sscottl m_platform_file (), 27195534Sscottl m_symbol_file (), 28195534Sscottl m_arch (), 29195534Sscottl m_uuid (), 30195534Sscottl m_object_name (), 31195534Sscottl m_object_offset (0), 32195534Sscottl m_object_mod_time (), 33195534Sscottl m_source_mappings () 34195534Sscottl { 35220576Smav } 36195534Sscottl 37195534Sscottl ModuleSpec (const FileSpec &file_spec) : 38195534Sscottl m_file (file_spec), 39195534Sscottl m_platform_file (), 40195534Sscottl m_symbol_file (), 41195534Sscottl m_arch (), 42195534Sscottl m_uuid (), 43195534Sscottl m_object_name (), 44195534Sscottl m_object_offset (0), 45195534Sscottl m_object_mod_time (), 46195534Sscottl m_source_mappings () 47195534Sscottl { 48271146Simp } 49271146Simp 50195534Sscottl ModuleSpec (const FileSpec &file_spec, const ArchSpec &arch) : 51276344Smarius m_file (file_spec), 52199176Smav m_platform_file (), 53203030Smav m_symbol_file (), 54199176Smav m_arch (arch), 55199322Smav m_uuid (), 56199176Smav m_object_name (), 57271146Simp m_object_offset (0), 58278034Ssmh m_object_mod_time (), 59278034Ssmh m_source_mappings () 60278034Ssmh { 61278034Ssmh } 62278034Ssmh 63278034Ssmh ModuleSpec (const ModuleSpec &rhs) : 64278034Ssmh m_file (rhs.m_file), 65278034Ssmh m_platform_file (rhs.m_platform_file), 66278034Ssmh m_symbol_file (rhs.m_symbol_file), 67278034Ssmh m_arch (rhs.m_arch), 68278034Ssmh m_uuid (rhs.m_uuid), 69271146Simp m_object_name (rhs.m_object_name), 70271146Simp m_object_offset (rhs.m_object_offset), 71334453Smarius m_object_mod_time (rhs.m_object_mod_time), 72327568Smav m_source_mappings (rhs.m_source_mappings) 73244146Smav { 74244146Smav } 75244146Smav 76244146Smav ModuleSpec & 77244146Smav operator = (const ModuleSpec &rhs) 78326120Smav { 79326120Smav if (this != &rhs) 80326120Smav { 81326120Smav m_file = rhs.m_file; 82326120Smav m_platform_file = rhs.m_platform_file; 83317673Smav m_symbol_file = rhs.m_symbol_file; 84317673Smav m_arch = rhs.m_arch; 85317673Smav m_uuid = rhs.m_uuid; 86317673Smav m_object_name = rhs.m_object_name; 87317673Smav m_object_offset = rhs.m_object_offset; 88317673Smav m_object_mod_time = rhs.m_object_mod_time; 89317673Smav m_source_mappings = rhs.m_source_mappings; 90317673Smav } 91317673Smav return *this; 92203030Smav } 93203030Smav 94203030Smav FileSpec * 95203030Smav GetFileSpecPtr () 96203030Smav { 97203030Smav if (m_file) 98203030Smav return &m_file; 99203030Smav return NULL; 100203030Smav } 101203030Smav 102322572Smav const FileSpec * 103203030Smav GetFileSpecPtr () const 104203030Smav { 105322572Smav if (m_file) 106203030Smav return &m_file; 107203030Smav return NULL; 108203030Smav } 109203030Smav 110203030Smav FileSpec & 111203030Smav GetFileSpec () 112203030Smav { 113203030Smav return m_file; 114203030Smav } 115203030Smav const FileSpec & 116203030Smav GetFileSpec () const 117203030Smav { 118322572Smav return m_file; 119203030Smav } 120322572Smav 121322573Smav FileSpec * 122322573Smav GetPlatformFileSpecPtr () 123322573Smav { 124322573Smav if (m_platform_file) 125322573Smav return &m_platform_file; 126322573Smav return NULL; 127331195Seadler } 128331195Seadler 129331195Seadler const FileSpec * 130331195Seadler GetPlatformFileSpecPtr () const 131331195Seadler { 132331195Seadler if (m_platform_file) 133331195Seadler return &m_platform_file; 134331195Seadler return NULL; 135331195Seadler } 136331195Seadler 137331195Seadler FileSpec & 138331195Seadler GetPlatformFileSpec () 139331195Seadler { 140331195Seadler return m_platform_file; 141331195Seadler } 142331195Seadler 143331195Seadler const FileSpec & 144331195Seadler GetPlatformFileSpec () const 145331195Seadler { 146331195Seadler return m_platform_file; 147211922Smav } 148211922Smav 149322572Smav FileSpec * 150322572Smav GetSymbolFileSpecPtr () 151322572Smav { 152218605Smav if (m_symbol_file) 153218605Smav return &m_symbol_file; 154218605Smav return NULL; 155322572Smav } 156221789Sjfv 157221789Sjfv const FileSpec * 158258162Smav GetSymbolFileSpecPtr () const 159258162Smav { 160258162Smav if (m_symbol_file) 161258162Smav return &m_symbol_file; 162258162Smav return NULL; 163258162Smav } 164258162Smav 165258162Smav FileSpec & 166258162Smav GetSymbolFileSpec () 167258162Smav { 168258162Smav return m_symbol_file; 169258162Smav } 170258162Smav 171258162Smav const FileSpec & 172258162Smav GetSymbolFileSpec () const 173258162Smav { 174258162Smav return m_symbol_file; 175258162Smav } 176258162Smav 177258162Smav 178258162Smav ArchSpec * 179258162Smav GetArchitecturePtr () 180278034Ssmh { 181244983Sjfv if (m_arch.IsValid()) 182244983Sjfv return &m_arch; 183258162Smav return NULL; 184258162Smav } 185258162Smav 186258162Smav const ArchSpec * 187258162Smav GetArchitecturePtr () const 188258162Smav { 189275101Smav if (m_arch.IsValid()) 190275101Smav return &m_arch; 191275101Smav return NULL; 192275101Smav } 193275101Smav 194275101Smav ArchSpec & 195275101Smav GetArchitecture () 196275101Smav { 197258162Smav return m_arch; 198258162Smav } 199258162Smav 200258162Smav const ArchSpec & 201258162Smav GetArchitecture () const 202258162Smav { 203258162Smav return m_arch; 204322572Smav } 205322572Smav 206258162Smav UUID * 207258162Smav GetUUIDPtr () 208258162Smav { 209258162Smav if (m_uuid.IsValid()) 210258162Smav return &m_uuid; 211258162Smav return NULL; 212258162Smav } 213258162Smav 214298983Smav const UUID * 215298983Smav GetUUIDPtr () const 216298983Smav { 217298983Smav if (m_uuid.IsValid()) 218298983Smav return &m_uuid; 219298983Smav return NULL; 220298983Smav } 221298983Smav 222298983Smav UUID & 223322572Smav GetUUID () 224322572Smav { 225322572Smav return m_uuid; 226322572Smav } 227322572Smav 228322572Smav const UUID & 229322572Smav GetUUID () const 230322572Smav { 231322572Smav return m_uuid; 232322572Smav } 233322572Smav 234221789Sjfv ConstString & 235239907Smav GetObjectName () 236304658Savg { 237239907Smav return m_object_name; 238203030Smav } 239203030Smav 240203030Smav const ConstString & 241203030Smav GetObjectName () const 242285020Smav { 243285020Smav return m_object_name; 244285020Smav } 245285020Smav 246285020Smav uint64_t 247285020Smav GetObjectOffset () const 248285020Smav { 249285020Smav return m_object_offset; 250271163Smav } 251271163Smav 252271163Smav void 253271163Smav SetObjectOffset (uint64_t object_offset) 254271163Smav { 255271163Smav m_object_offset = object_offset; 256271163Smav } 257271163Smav 258271163Smav TimeValue & 259271163Smav GetObjectModificationTime () 260271163Smav { 261271163Smav return m_object_mod_time; 262271163Smav } 263271163Smav 264271163Smav const TimeValue & 265271163Smav GetObjectModificationTime () const 266271163Smav { 267271163Smav return m_object_mod_time; 268271163Smav } 269271163Smav 270271163Smav PathMappingList & 271271163Smav GetSourceMappingList () const 272271163Smav { 273271163Smav return m_source_mappings; 274271163Smav } 275207499Smav 276207499Smav void 277207499Smav Clear () 278207499Smav { 279207499Smav m_file.Clear(); 280207499Smav m_platform_file.Clear(); 281207499Smav m_symbol_file.Clear(); 282207499Smav m_arch.Clear(); 283207499Smav m_uuid.Clear(); 284207499Smav m_object_name.Clear(); 285207499Smav m_object_offset = 0; 286207499Smav m_source_mappings.Clear(false); 287207499Smav m_object_mod_time.Clear(); 288207499Smav } 289207499Smav 290207499Smav 291207499Smav explicit operator bool () const 292207499Smav { 293207499Smav if (m_file) 294207499Smav return true; 295207499Smav if (m_platform_file) 296207499Smav return true; 297207499Smav if (m_symbol_file) 298207499Smav return true; 299207499Smav if (m_arch.IsValid()) 300207499Smav return true; 301207499Smav if (m_uuid.IsValid()) 302207499Smav return true; 303207499Smav if (m_object_name) 304207499Smav return true; 305207499Smav if (m_object_mod_time.IsValid()) 306207499Smav return true; 307207499Smav return false; 308207499Smav } 309207499Smav 310207499Smav void 311207499Smav Dump (Stream &strm) 312207499Smav { 313207499Smav bool dumped_something = false; 314207499Smav if (m_file) 315207499Smav { 316207499Smav strm.PutCString("file = '"); 317207499Smav strm << m_file; 318207499Smav strm.PutCString("'"); 319207499Smav dumped_something = true; 320207499Smav } 321207499Smav if (m_platform_file) 322207499Smav { 323207499Smav if (dumped_something) 324207499Smav strm.PutCString(", "); 325207499Smav strm.PutCString("platform_file = '"); 326207499Smav strm << m_platform_file; 327207499Smav strm.PutCString("'"); 328207499Smav dumped_something = true; 329207499Smav } 330207499Smav if (m_symbol_file) 331207499Smav { 332207499Smav if (dumped_something) 333224603Smav strm.PutCString(", "); 334207499Smav strm.PutCString("symbol_file = '"); 335207499Smav strm << m_symbol_file; 336207499Smav strm.PutCString("'"); 337207499Smav dumped_something = true; 338207499Smav } 339207499Smav if (m_arch.IsValid()) 340207499Smav { 341207499Smav if (dumped_something) 342207499Smav strm.PutCString(", "); 343207499Smav strm.Printf("arch = %s", m_arch.GetTriple().str().c_str()); 344271403Smav dumped_something = true; 345208907Smav } 346208907Smav if (m_uuid.IsValid()) 347203030Smav { 348203030Smav if (dumped_something) 349203030Smav strm.PutCString(", "); 350279573Semaste strm.PutCString("uuid = "); 351297447Szbb m_uuid.Dump(&strm); 352203030Smav dumped_something = true; 353199176Smav } 354199176Smav if (m_object_name) 355271146Simp { 356271146Simp if (dumped_something) 357271146Simp strm.PutCString(", "); 358220565Smav strm.Printf("object_name = %s", m_object_name.GetCString()); 359271146Simp dumped_something = true; 360271146Simp } 361271146Simp if (m_object_offset > 0) 362271146Simp { 363271146Simp if (dumped_something) 364228200Smav strm.PutCString(", "); 365195534Sscottl strm.Printf("object_offset = 0x%" PRIx64, m_object_offset); 366195534Sscottl dumped_something = true; 367195534Sscottl } 368199176Smav if (m_object_mod_time.IsValid()) 369199322Smav { 370199322Smav if (dumped_something) 371203030Smav strm.PutCString(", "); 372199322Smav strm.Printf("object_mod_time = 0x%" PRIx64, m_object_mod_time.GetAsSecondsSinceJan1_1970()); 373260163Szbb dumped_something = true; 374260163Szbb } 375260163Szbb } 376260163Szbb 377260163Szbb bool 378260163Szbb Matches (const ModuleSpec &match_module_spec, bool exact_arch_match) const 379260163Szbb { 380199322Smav if (match_module_spec.GetUUIDPtr() && match_module_spec.GetUUID() != GetUUID()) 381199322Smav return false; 382199322Smav if (match_module_spec.GetObjectName() && match_module_spec.GetObjectName() != GetObjectName()) 383199322Smav return false; 384199322Smav if (match_module_spec.GetFileSpecPtr()) 385288111Smav { 386288111Smav const FileSpec &fspec = match_module_spec.GetFileSpec(); 387288111Smav if (!FileSpec::Equal(fspec, GetFileSpec(), fspec.GetDirectory().IsEmpty() == false)) 388199322Smav return false; 389199322Smav } 390199322Smav if (match_module_spec.GetPlatformFileSpecPtr()) 391203030Smav { 392228200Smav const FileSpec &fspec = match_module_spec.GetPlatformFileSpec(); 393228200Smav if (!FileSpec::Equal(fspec, GetPlatformFileSpec(), fspec.GetDirectory().IsEmpty() == false)) 394199717Smav return false; 395199717Smav 396199717Smav } 397199717Smav if (match_module_spec.GetSymbolFileSpecPtr()) 398199322Smav { 399199322Smav const FileSpec &fspec = match_module_spec.GetSymbolFileSpec(); 400199322Smav if (!FileSpec::Equal(fspec, GetSymbolFileSpec(), fspec.GetDirectory().IsEmpty() == false)) 401280393Smav return false; 402199322Smav 403199322Smav } 404288111Smav if (match_module_spec.GetArchitecturePtr()) 405199322Smav { 406199322Smav if (exact_arch_match) 407280393Smav { 408199322Smav if (!GetArchitecture().IsExactMatch(match_module_spec.GetArchitecture())) 409199322Smav return false; 410199322Smav } 411199322Smav else 412199322Smav { 413199322Smav if (!GetArchitecture().IsCompatibleMatch(match_module_spec.GetArchitecture())) 414199176Smav return false; 415199176Smav } 416203030Smav } 417195534Sscottl return true; 418199322Smav } 419199322Smav 420199176Smavprotected: 421199176Smav FileSpec m_file; 422203030Smav FileSpec m_platform_file; 423203030Smav FileSpec m_symbol_file; 424199176Smav ArchSpec m_arch; 425199176Smav UUID m_uuid; 426199176Smav ConstString m_object_name; 427280393Smav uint64_t m_object_offset; 428199176Smav TimeValue m_object_mod_time; 429199176Smav mutable PathMappingList m_source_mappings; 430199176Smav}; 431280393Smav 432195534Sscottlclass ModuleSpecList 433195534Sscottl{ 434195534Sscottlpublic: 435285789Szbb ModuleSpecList () : 436285789Szbb m_specs(), 437285789Szbb m_mutex(Mutex::eMutexTypeRecursive) 438285789Szbb { 439285789Szbb } 440285789Szbb 441285789Szbb ModuleSpecList (const ModuleSpecList &rhs) : 442285789Szbb m_specs(), 443285789Szbb m_mutex(Mutex::eMutexTypeRecursive) 444285789Szbb { 445285789Szbb Mutex::Locker lhs_locker(m_mutex); 446285789Szbb Mutex::Locker rhs_locker(rhs.m_mutex); 447285789Szbb m_specs = rhs.m_specs; 448285789Szbb } 449285789Szbb 450285789Szbb ~ModuleSpecList () 451285789Szbb { 452285789Szbb } 453285789Szbb 454285789Szbb ModuleSpecList & 455285789Szbb operator = (const ModuleSpecList &rhs) 456285789Szbb { 457271146Simp if (this != &rhs) 458195534Sscottl { 459195534Sscottl Mutex::Locker lhs_locker(m_mutex); 460271146Simp Mutex::Locker rhs_locker(rhs.m_mutex); 461199322Smav m_specs = rhs.m_specs; 462203030Smav } 463285789Szbb return *this; 464285789Szbb } 465195534Sscottl 466285789Szbb size_t 467285789Szbb GetSize() const 468285789Szbb { 469199322Smav Mutex::Locker locker(m_mutex); 470203030Smav return m_specs.size(); 471203030Smav } 472203030Smav 473199322Smav void 474199322Smav Clear () 475271146Simp { 476271146Simp Mutex::Locker locker(m_mutex); 477271146Simp m_specs.clear(); 478271146Simp } 479271146Simp 480271146Simp void 481297921Smav Append (const ModuleSpec &spec) 482297921Smav { 483271146Simp Mutex::Locker locker(m_mutex); 484271146Simp m_specs.push_back (spec); 485271146Simp } 486271146Simp 487277100Skib void 488277100Skib Append (const ModuleSpecList &rhs) 489277100Skib { 490277100Skib Mutex::Locker lhs_locker(m_mutex); 491277100Skib Mutex::Locker rhs_locker(rhs.m_mutex); 492277100Skib m_specs.insert(m_specs.end(), rhs.m_specs.begin(), rhs.m_specs.end()); 493195534Sscottl } 494195534Sscottl 495195534Sscottl // The index "i" must be valid and this can't be used in 496285789Szbb // multi-threaded code as no mutex lock is taken. 497297447Szbb ModuleSpec & 498297447Szbb GetModuleSpecRefAtIndex (size_t i) 499297447Szbb { 500285789Szbb return m_specs[i]; 501285789Szbb } 502285789Szbb bool 503285789Szbb GetModuleSpecAtIndex (size_t i, ModuleSpec &module_spec) const 504285789Szbb { 505285789Szbb Mutex::Locker locker(m_mutex); 506285789Szbb if (i < m_specs.size()) 507285789Szbb { 508285789Szbb module_spec = m_specs[i]; 509285789Szbb return true; 510285789Szbb } 511285789Szbb module_spec.Clear(); 512285789Szbb return false; 513285789Szbb } 514285789Szbb 515285789Szbb 516285789Szbb bool 517285789Szbb FindMatchingModuleSpec (const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const 518285789Szbb { 519285789Szbb Mutex::Locker locker(m_mutex); 520285789Szbb bool exact_arch_match = true; 521285789Szbb for (auto spec: m_specs) 522285789Szbb { 523285789Szbb if (spec.Matches(module_spec, exact_arch_match)) 524285789Szbb { 525285789Szbb match_module_spec = spec; 526285789Szbb return true; 527285789Szbb } 528285789Szbb } 529285789Szbb 530285789Szbb // If there was an architecture, retry with a compatible arch 531285789Szbb if (module_spec.GetArchitecturePtr()) 532285789Szbb { 533285789Szbb exact_arch_match = false; 534285789Szbb for (auto spec: m_specs) 535285789Szbb { 536285789Szbb if (spec.Matches(module_spec, exact_arch_match)) 537285789Szbb { 538285789Szbb match_module_spec = spec; 539285789Szbb return true; 540285789Szbb } 541285789Szbb } 542285789Szbb } 543285789Szbb match_module_spec.Clear(); 544285789Szbb return false; 545285789Szbb } 546207511Smav 547195534Sscottl size_t 548271146Simp FindMatchingModuleSpecs (const ModuleSpec &module_spec, ModuleSpecList &matching_list) const 549285789Szbb { 550195534Sscottl Mutex::Locker locker(m_mutex); 551297793Spfg bool exact_arch_match = true; 552222304Smav const size_t initial_match_count = matching_list.GetSize(); 553195534Sscottl for (auto spec: m_specs) 554195534Sscottl { 555271146Simp if (spec.Matches(module_spec, exact_arch_match)) 556195534Sscottl matching_list.Append (spec); 557245875Smav } 558256843Smav 559278034Ssmh // If there was an architecture, retry with a compatible arch if no matches were found 560278034Ssmh if (module_spec.GetArchitecturePtr() && (initial_match_count == matching_list.GetSize())) 561278034Ssmh { 562278034Ssmh exact_arch_match = false; 563195534Sscottl for (auto spec: m_specs) 564256843Smav { 565256843Smav if (spec.Matches(module_spec, exact_arch_match)) 566285789Szbb matching_list.Append (spec); 567285789Szbb } 568256843Smav } 569256843Smav return matching_list.GetSize() - initial_match_count; 570285789Szbb } 571285789Szbb 572285789Szbb void 573285789Szbb Dump (Stream &strm) 574256843Smav { 575285789Szbb Mutex::Locker locker(m_mutex); 576285789Szbb uint32_t idx = 0; 577285789Szbb for (auto spec: m_specs) 578285789Szbb { 579285789Szbb strm.Printf("[%u] ", idx); 580285789Szbb spec.Dump (strm); 581285789Szbb strm.EOL(); 582285789Szbb ++idx; 583285789Szbb } 584285789Szbb } 585285789Szbb 586285789Szbbprotected: 587285789Szbb typedef std::vector<ModuleSpec> collection; ///< The module collection type. 588285789Szbb collection m_specs; ///< The collection of modules. 589285789Szbb mutable Mutex m_mutex; 590285789Szbb}; 591285789Szbb 592285789Szbb} // namespace lldb_private 593285789Szbb 594285789Szbb#endif // liblldb_ModuleSpec_h_ 595285789Szbb