10b57cec5SDimitry Andric //===-- ObjectContainerBSDArchive.h -----------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 95ffd83dbSDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H 105ffd83dbSDimitry Andric #define LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "lldb/Core/UniqueCStringMap.h" 130b57cec5SDimitry Andric #include "lldb/Symbol/ObjectContainer.h" 140b57cec5SDimitry Andric #include "lldb/Utility/ArchSpec.h" 150b57cec5SDimitry Andric #include "lldb/Utility/ConstString.h" 160b57cec5SDimitry Andric #include "lldb/Utility/FileSpec.h" 170b57cec5SDimitry Andric 18753f127fSDimitry Andric #include "llvm/Object/Archive.h" 190b57cec5SDimitry Andric #include "llvm/Support/Chrono.h" 20753f127fSDimitry Andric #include "llvm/Support/Path.h" 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric #include <map> 230b57cec5SDimitry Andric #include <memory> 240b57cec5SDimitry Andric #include <mutex> 250b57cec5SDimitry Andric 26753f127fSDimitry Andric enum class ArchiveType { Invalid, Archive, ThinArchive }; 27753f127fSDimitry Andric 280b57cec5SDimitry Andric class ObjectContainerBSDArchive : public lldb_private::ObjectContainer { 290b57cec5SDimitry Andric public: 300b57cec5SDimitry Andric ObjectContainerBSDArchive(const lldb::ModuleSP &module_sp, 310b57cec5SDimitry Andric lldb::DataBufferSP &data_sp, 320b57cec5SDimitry Andric lldb::offset_t data_offset, 330b57cec5SDimitry Andric const lldb_private::FileSpec *file, 34753f127fSDimitry Andric lldb::offset_t offset, lldb::offset_t length, 35753f127fSDimitry Andric ArchiveType archive_type); 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric ~ObjectContainerBSDArchive() override; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric // Static Functions 400b57cec5SDimitry Andric static void Initialize(); 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric static void Terminate(); 430b57cec5SDimitry Andric GetPluginNameStatic()44349cc55cSDimitry Andric static llvm::StringRef GetPluginNameStatic() { return "bsd-archive"; } 450b57cec5SDimitry Andric GetPluginDescriptionStatic()46349cc55cSDimitry Andric static llvm::StringRef GetPluginDescriptionStatic() { 47349cc55cSDimitry Andric return "BSD Archive object container reader."; 48349cc55cSDimitry Andric } 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric static lldb_private::ObjectContainer * 510b57cec5SDimitry Andric CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, 520b57cec5SDimitry Andric lldb::offset_t data_offset, const lldb_private::FileSpec *file, 530b57cec5SDimitry Andric lldb::offset_t offset, lldb::offset_t length); 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, 560b57cec5SDimitry Andric lldb::DataBufferSP &data_sp, 570b57cec5SDimitry Andric lldb::offset_t data_offset, 580b57cec5SDimitry Andric lldb::offset_t file_offset, 590b57cec5SDimitry Andric lldb::offset_t length, 600b57cec5SDimitry Andric lldb_private::ModuleSpecList &specs); 610b57cec5SDimitry Andric 62753f127fSDimitry Andric static ArchiveType MagicBytesMatch(const lldb_private::DataExtractor &data); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric // Member Functions 650b57cec5SDimitry Andric bool ParseHeader() override; 660b57cec5SDimitry Andric GetNumObjects()670b57cec5SDimitry Andric size_t GetNumObjects() const override { 680b57cec5SDimitry Andric if (m_archive_sp) 690b57cec5SDimitry Andric return m_archive_sp->GetNumObjects(); 700b57cec5SDimitry Andric return 0; 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric // PluginInterface protocol GetPluginName()76349cc55cSDimitry Andric llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric protected: 790b57cec5SDimitry Andric struct Object { 800b57cec5SDimitry Andric Object(); 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric void Clear(); 830b57cec5SDimitry Andric 84753f127fSDimitry Andric lldb::offset_t ExtractFromThin(const lldb_private::DataExtractor &data, 85753f127fSDimitry Andric lldb::offset_t offset, 86753f127fSDimitry Andric llvm::StringRef stringTable); 87753f127fSDimitry Andric 880b57cec5SDimitry Andric lldb::offset_t Extract(const lldb_private::DataExtractor &data, 890b57cec5SDimitry Andric lldb::offset_t offset); 900b57cec5SDimitry Andric /// Object name in the archive. 910b57cec5SDimitry Andric lldb_private::ConstString ar_name; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric /// Object modification time in the archive. 94fe6060f1SDimitry Andric uint32_t modification_time = 0; 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric /// Object size in bytes in the archive. 97fe6060f1SDimitry Andric uint32_t size = 0; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric /// File offset in bytes from the beginning of the file of the object data. 100fe6060f1SDimitry Andric lldb::offset_t file_offset = 0; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric /// Length of the object data. 103fe6060f1SDimitry Andric lldb::offset_t file_size = 0; 104*5f757f3fSDimitry Andric 105*5f757f3fSDimitry Andric void Dump() const; 1060b57cec5SDimitry Andric }; 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric class Archive { 1090b57cec5SDimitry Andric public: 1100b57cec5SDimitry Andric typedef std::shared_ptr<Archive> shared_ptr; 1110b57cec5SDimitry Andric typedef std::multimap<lldb_private::FileSpec, shared_ptr> Map; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric Archive(const lldb_private::ArchSpec &arch, 1140b57cec5SDimitry Andric const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset, 115753f127fSDimitry Andric lldb_private::DataExtractor &data, ArchiveType archive_type); 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric ~Archive(); 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric static Map &GetArchiveCache(); 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric static std::recursive_mutex &GetArchiveCacheMutex(); 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric static Archive::shared_ptr FindCachedArchive( 1240b57cec5SDimitry Andric const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch, 1250b57cec5SDimitry Andric const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset); 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric static Archive::shared_ptr ParseAndCacheArchiveForFile( 1280b57cec5SDimitry Andric const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch, 1290b57cec5SDimitry Andric const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset, 130753f127fSDimitry Andric lldb_private::DataExtractor &data, ArchiveType archive_type); 1310b57cec5SDimitry Andric GetNumObjects()1320b57cec5SDimitry Andric size_t GetNumObjects() const { return m_objects.size(); } 1330b57cec5SDimitry Andric GetObjectAtIndex(size_t idx)1340b57cec5SDimitry Andric const Object *GetObjectAtIndex(size_t idx) { 1350b57cec5SDimitry Andric if (idx < m_objects.size()) 1360b57cec5SDimitry Andric return &m_objects[idx]; 1370b57cec5SDimitry Andric return nullptr; 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric size_t ParseObjects(); 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric Object *FindObject(lldb_private::ConstString object_name, 1430b57cec5SDimitry Andric const llvm::sys::TimePoint<> &object_mod_time); 1440b57cec5SDimitry Andric GetFileOffset()1450b57cec5SDimitry Andric lldb::offset_t GetFileOffset() const { return m_file_offset; } 1460b57cec5SDimitry Andric GetModificationTime()1470b57cec5SDimitry Andric const llvm::sys::TimePoint<> &GetModificationTime() { 1480b57cec5SDimitry Andric return m_modification_time; 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric GetArchitecture()1510b57cec5SDimitry Andric const lldb_private::ArchSpec &GetArchitecture() const { return m_arch; } 1520b57cec5SDimitry Andric SetArchitecture(const lldb_private::ArchSpec & arch)1530b57cec5SDimitry Andric void SetArchitecture(const lldb_private::ArchSpec &arch) { m_arch = arch; } 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric bool HasNoExternalReferences() const; 1560b57cec5SDimitry Andric GetData()1570b57cec5SDimitry Andric lldb_private::DataExtractor &GetData() { return m_data; } 1580b57cec5SDimitry Andric GetArchiveType()159753f127fSDimitry Andric ArchiveType GetArchiveType() { return m_archive_type; } 160753f127fSDimitry Andric 1610b57cec5SDimitry Andric protected: 1620b57cec5SDimitry Andric typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap; 1630b57cec5SDimitry Andric // Member Variables 1640b57cec5SDimitry Andric lldb_private::ArchSpec m_arch; 1650b57cec5SDimitry Andric llvm::sys::TimePoint<> m_modification_time; 1660b57cec5SDimitry Andric lldb::offset_t m_file_offset; 1670b57cec5SDimitry Andric std::vector<Object> m_objects; 1680b57cec5SDimitry Andric ObjectNameToIndexMap m_object_name_to_index_map; 1690b57cec5SDimitry Andric lldb_private::DataExtractor m_data; ///< The data for this object container 1700b57cec5SDimitry Andric ///so we don't lose data if the .a files 1710b57cec5SDimitry Andric ///gets modified 172753f127fSDimitry Andric ArchiveType m_archive_type; 1730b57cec5SDimitry Andric }; 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric void SetArchive(Archive::shared_ptr &archive_sp); 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric Archive::shared_ptr m_archive_sp; 178753f127fSDimitry Andric 179753f127fSDimitry Andric ArchiveType m_archive_type; 1800b57cec5SDimitry Andric }; 1810b57cec5SDimitry Andric 1825ffd83dbSDimitry Andric #endif // LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H 183