1 //===-- ObjectContainerBSDArchive.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_ObjectContainerBSDArchive_h_ 11 #define liblldb_ObjectContainerBSDArchive_h_ 12 13 #include "lldb/Core/UniqueCStringMap.h" 14 #include "lldb/Symbol/ObjectContainer.h" 15 #include "lldb/Utility/ArchSpec.h" 16 #include "lldb/Utility/ConstString.h" 17 #include "lldb/Utility/FileSpec.h" 18 19 #include "llvm/Support/Chrono.h" 20 21 #include <map> 22 #include <memory> 23 #include <mutex> 24 25 class ObjectContainerBSDArchive : public lldb_private::ObjectContainer { 26 public: 27 ObjectContainerBSDArchive(const lldb::ModuleSP &module_sp, 28 lldb::DataBufferSP &data_sp, 29 lldb::offset_t data_offset, 30 const lldb_private::FileSpec *file, 31 lldb::offset_t offset, lldb::offset_t length); 32 33 ~ObjectContainerBSDArchive() override; 34 35 //------------------------------------------------------------------ 36 // Static Functions 37 //------------------------------------------------------------------ 38 static void Initialize(); 39 40 static void Terminate(); 41 42 static lldb_private::ConstString GetPluginNameStatic(); 43 44 static const char *GetPluginDescriptionStatic(); 45 46 static lldb_private::ObjectContainer * 47 CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, 48 lldb::offset_t data_offset, const lldb_private::FileSpec *file, 49 lldb::offset_t offset, lldb::offset_t length); 50 51 static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, 52 lldb::DataBufferSP &data_sp, 53 lldb::offset_t data_offset, 54 lldb::offset_t file_offset, 55 lldb::offset_t length, 56 lldb_private::ModuleSpecList &specs); 57 58 static bool MagicBytesMatch(const lldb_private::DataExtractor &data); 59 60 //------------------------------------------------------------------ 61 // Member Functions 62 //------------------------------------------------------------------ 63 bool ParseHeader() override; 64 GetNumObjects()65 size_t GetNumObjects() const override { 66 if (m_archive_sp) 67 return m_archive_sp->GetNumObjects(); 68 return 0; 69 } 70 71 void Dump(lldb_private::Stream *s) const override; 72 73 lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override; 74 75 //------------------------------------------------------------------ 76 // PluginInterface protocol 77 //------------------------------------------------------------------ 78 lldb_private::ConstString GetPluginName() override; 79 80 uint32_t GetPluginVersion() override; 81 82 protected: 83 struct Object { 84 Object(); 85 86 void Clear(); 87 88 lldb::offset_t Extract(const lldb_private::DataExtractor &data, 89 lldb::offset_t offset); 90 91 lldb_private::ConstString ar_name; // name 92 uint32_t ar_date; // modification time 93 uint16_t ar_uid; // user id 94 uint16_t ar_gid; // group id 95 uint16_t ar_mode; // octal file permissions 96 uint32_t ar_size; // size in bytes 97 lldb::offset_t ar_file_offset; // file offset in bytes from the beginning of 98 // the file of the object data 99 lldb::offset_t ar_file_size; // length of the object data 100 101 typedef std::vector<Object> collection; 102 typedef collection::iterator iterator; 103 typedef collection::const_iterator const_iterator; 104 }; 105 106 class Archive { 107 public: 108 typedef std::shared_ptr<Archive> shared_ptr; 109 typedef std::multimap<lldb_private::FileSpec, shared_ptr> Map; 110 111 Archive(const lldb_private::ArchSpec &arch, 112 const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset, 113 lldb_private::DataExtractor &data); 114 115 ~Archive(); 116 117 static Map &GetArchiveCache(); 118 119 static std::recursive_mutex &GetArchiveCacheMutex(); 120 121 static Archive::shared_ptr FindCachedArchive( 122 const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch, 123 const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset); 124 125 static Archive::shared_ptr ParseAndCacheArchiveForFile( 126 const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch, 127 const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset, 128 lldb_private::DataExtractor &data); 129 GetNumObjects()130 size_t GetNumObjects() const { return m_objects.size(); } 131 GetObjectAtIndex(size_t idx)132 const Object *GetObjectAtIndex(size_t idx) { 133 if (idx < m_objects.size()) 134 return &m_objects[idx]; 135 return NULL; 136 } 137 138 size_t ParseObjects(); 139 140 Object *FindObject(const lldb_private::ConstString &object_name, 141 const llvm::sys::TimePoint<> &object_mod_time); 142 GetFileOffset()143 lldb::offset_t GetFileOffset() const { return m_file_offset; } 144 GetModificationTime()145 const llvm::sys::TimePoint<> &GetModificationTime() { return m_time; } 146 GetArchitecture()147 const lldb_private::ArchSpec &GetArchitecture() const { return m_arch; } 148 SetArchitecture(const lldb_private::ArchSpec & arch)149 void SetArchitecture(const lldb_private::ArchSpec &arch) { m_arch = arch; } 150 151 bool HasNoExternalReferences() const; 152 GetData()153 lldb_private::DataExtractor &GetData() { return m_data; } 154 155 protected: 156 typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap; 157 //---------------------------------------------------------------------- 158 // Member Variables 159 //---------------------------------------------------------------------- 160 lldb_private::ArchSpec m_arch; 161 llvm::sys::TimePoint<> m_time; 162 lldb::offset_t m_file_offset; 163 Object::collection m_objects; 164 ObjectNameToIndexMap m_object_name_to_index_map; 165 lldb_private::DataExtractor m_data; ///< The data for this object container 166 ///so we don't lose data if the .a files 167 ///gets modified 168 }; 169 170 void SetArchive(Archive::shared_ptr &archive_sp); 171 172 Archive::shared_ptr m_archive_sp; 173 }; 174 175 #endif // liblldb_ObjectContainerBSDArchive_h_ 176