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