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 44 static llvm::StringRef GetPluginNameStatic() { return "bsd-archive"; } 45 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 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 // PluginInterface protocol 78 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 79 80 protected: 81 struct Object { 82 Object(); 83 84 void Clear(); 85 86 lldb::offset_t ExtractFromThin(const lldb_private::DataExtractor &data, 87 lldb::offset_t offset, 88 llvm::StringRef stringTable); 89 90 lldb::offset_t Extract(const lldb_private::DataExtractor &data, 91 lldb::offset_t offset); 92 /// Object name in the archive. 93 lldb_private::ConstString ar_name; 94 95 /// Object modification time in the archive. 96 uint32_t modification_time = 0; 97 98 /// Object user id in the archive. 99 uint16_t uid = 0; 100 101 /// Object group id in the archive. 102 uint16_t gid = 0; 103 104 /// Object octal file permissions in the archive. 105 uint16_t mode = 0; 106 107 /// Object size in bytes in the archive. 108 uint32_t size = 0; 109 110 /// File offset in bytes from the beginning of the file of the object data. 111 lldb::offset_t file_offset = 0; 112 113 /// Length of the object data. 114 lldb::offset_t file_size = 0; 115 }; 116 117 class Archive { 118 public: 119 typedef std::shared_ptr<Archive> shared_ptr; 120 typedef std::multimap<lldb_private::FileSpec, shared_ptr> Map; 121 122 Archive(const lldb_private::ArchSpec &arch, 123 const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset, 124 lldb_private::DataExtractor &data, ArchiveType archive_type); 125 126 ~Archive(); 127 128 static Map &GetArchiveCache(); 129 130 static std::recursive_mutex &GetArchiveCacheMutex(); 131 132 static Archive::shared_ptr FindCachedArchive( 133 const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch, 134 const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset); 135 136 static Archive::shared_ptr ParseAndCacheArchiveForFile( 137 const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch, 138 const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset, 139 lldb_private::DataExtractor &data, ArchiveType archive_type); 140 141 size_t GetNumObjects() const { return m_objects.size(); } 142 143 const Object *GetObjectAtIndex(size_t idx) { 144 if (idx < m_objects.size()) 145 return &m_objects[idx]; 146 return nullptr; 147 } 148 149 size_t ParseObjects(); 150 151 Object *FindObject(lldb_private::ConstString object_name, 152 const llvm::sys::TimePoint<> &object_mod_time); 153 154 lldb::offset_t GetFileOffset() const { return m_file_offset; } 155 156 const llvm::sys::TimePoint<> &GetModificationTime() { 157 return m_modification_time; 158 } 159 160 const lldb_private::ArchSpec &GetArchitecture() const { return m_arch; } 161 162 void SetArchitecture(const lldb_private::ArchSpec &arch) { m_arch = arch; } 163 164 bool HasNoExternalReferences() const; 165 166 lldb_private::DataExtractor &GetData() { return m_data; } 167 168 ArchiveType GetArchiveType() { return m_archive_type; } 169 170 protected: 171 typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap; 172 // Member Variables 173 lldb_private::ArchSpec m_arch; 174 llvm::sys::TimePoint<> m_modification_time; 175 lldb::offset_t m_file_offset; 176 std::vector<Object> m_objects; 177 ObjectNameToIndexMap m_object_name_to_index_map; 178 lldb_private::DataExtractor m_data; ///< The data for this object container 179 ///so we don't lose data if the .a files 180 ///gets modified 181 ArchiveType m_archive_type; 182 }; 183 184 void SetArchive(Archive::shared_ptr &archive_sp); 185 186 Archive::shared_ptr m_archive_sp; 187 188 ArchiveType m_archive_type; 189 }; 190 191 #endif // LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H 192