1 //===-- ObjectContainerBSDArchive.h -----------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H 10 #define LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H 11 12 #include "lldb/Core/UniqueCStringMap.h" 13 #include "lldb/Symbol/ObjectContainer.h" 14 #include "lldb/Utility/ArchSpec.h" 15 #include "lldb/Utility/ConstString.h" 16 #include "lldb/Utility/FileSpec.h" 17 18 #include "llvm/Support/Chrono.h" 19 20 #include <map> 21 #include <memory> 22 #include <mutex> 23 24 class ObjectContainerBSDArchive : public lldb_private::ObjectContainer { 25 public: 26 ObjectContainerBSDArchive(const lldb::ModuleSP &module_sp, 27 lldb::DataBufferSP &data_sp, 28 lldb::offset_t data_offset, 29 const lldb_private::FileSpec *file, 30 lldb::offset_t offset, lldb::offset_t length); 31 32 ~ObjectContainerBSDArchive() override; 33 34 // Static Functions 35 static void Initialize(); 36 37 static void Terminate(); 38 39 static lldb_private::ConstString GetPluginNameStatic(); 40 41 static const char *GetPluginDescriptionStatic(); 42 43 static lldb_private::ObjectContainer * 44 CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, 45 lldb::offset_t data_offset, const lldb_private::FileSpec *file, 46 lldb::offset_t offset, lldb::offset_t length); 47 48 static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, 49 lldb::DataBufferSP &data_sp, 50 lldb::offset_t data_offset, 51 lldb::offset_t file_offset, 52 lldb::offset_t length, 53 lldb_private::ModuleSpecList &specs); 54 55 static bool MagicBytesMatch(const lldb_private::DataExtractor &data); 56 57 // Member Functions 58 bool ParseHeader() override; 59 GetNumObjects()60 size_t GetNumObjects() const override { 61 if (m_archive_sp) 62 return m_archive_sp->GetNumObjects(); 63 return 0; 64 } 65 66 void Dump(lldb_private::Stream *s) const override; 67 68 lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override; 69 70 // PluginInterface protocol 71 lldb_private::ConstString GetPluginName() override; 72 73 uint32_t GetPluginVersion() override; 74 75 protected: 76 struct Object { 77 Object(); 78 79 void Clear(); 80 81 lldb::offset_t Extract(const lldb_private::DataExtractor &data, 82 lldb::offset_t offset); 83 /// Object name in the archive. 84 lldb_private::ConstString ar_name; 85 86 /// Object modification time in the archive. 87 uint32_t modification_time; 88 89 /// Object user id in the archive. 90 uint16_t uid; 91 92 /// Object group id in the archive. 93 uint16_t gid; 94 95 /// Object octal file permissions in the archive. 96 uint16_t mode; 97 98 /// Object size in bytes in the archive. 99 uint32_t size; 100 101 /// File offset in bytes from the beginning of the file of the object data. 102 lldb::offset_t file_offset; 103 104 /// Length of the object data. 105 lldb::offset_t file_size; 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 GetNumObjects()132 size_t GetNumObjects() const { return m_objects.size(); } 133 GetObjectAtIndex(size_t idx)134 const Object *GetObjectAtIndex(size_t idx) { 135 if (idx < m_objects.size()) 136 return &m_objects[idx]; 137 return nullptr; 138 } 139 140 size_t ParseObjects(); 141 142 Object *FindObject(lldb_private::ConstString object_name, 143 const llvm::sys::TimePoint<> &object_mod_time); 144 GetFileOffset()145 lldb::offset_t GetFileOffset() const { return m_file_offset; } 146 GetModificationTime()147 const llvm::sys::TimePoint<> &GetModificationTime() { 148 return m_modification_time; 149 } 150 GetArchitecture()151 const lldb_private::ArchSpec &GetArchitecture() const { return m_arch; } 152 SetArchitecture(const lldb_private::ArchSpec & arch)153 void SetArchitecture(const lldb_private::ArchSpec &arch) { m_arch = arch; } 154 155 bool HasNoExternalReferences() const; 156 GetData()157 lldb_private::DataExtractor &GetData() { return m_data; } 158 159 protected: 160 typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap; 161 // Member Variables 162 lldb_private::ArchSpec m_arch; 163 llvm::sys::TimePoint<> m_modification_time; 164 lldb::offset_t m_file_offset; 165 std::vector<Object> 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 // LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H 178