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