1254721Semaste//===-- ObjectContainerBSDArchive.h -----------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#ifndef liblldb_ObjectContainerBSDArchive_h_ 10254721Semaste#define liblldb_ObjectContainerBSDArchive_h_ 11254721Semaste 12314564Sdim#include "lldb/Core/UniqueCStringMap.h" 13314564Sdim#include "lldb/Symbol/ObjectContainer.h" 14327952Sdim#include "lldb/Utility/ArchSpec.h" 15321369Sdim#include "lldb/Utility/ConstString.h" 16321369Sdim#include "lldb/Utility/FileSpec.h" 17254721Semaste 18314564Sdim#include "llvm/Support/Chrono.h" 19314564Sdim 20321369Sdim#include <map> 21321369Sdim#include <memory> 22314564Sdim#include <mutex> 23314564Sdim 24314564Sdimclass ObjectContainerBSDArchive : public lldb_private::ObjectContainer { 25254721Semastepublic: 26314564Sdim ObjectContainerBSDArchive(const lldb::ModuleSP &module_sp, 27314564Sdim lldb::DataBufferSP &data_sp, 28314564Sdim lldb::offset_t data_offset, 29314564Sdim const lldb_private::FileSpec *file, 30314564Sdim lldb::offset_t offset, lldb::offset_t length); 31254721Semaste 32314564Sdim ~ObjectContainerBSDArchive() override; 33296417Sdim 34314564Sdim // Static Functions 35314564Sdim static void Initialize(); 36254721Semaste 37314564Sdim static void Terminate(); 38254721Semaste 39314564Sdim static lldb_private::ConstString GetPluginNameStatic(); 40254721Semaste 41314564Sdim static const char *GetPluginDescriptionStatic(); 42254721Semaste 43314564Sdim static lldb_private::ObjectContainer * 44314564Sdim CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, 45314564Sdim lldb::offset_t data_offset, const lldb_private::FileSpec *file, 46314564Sdim lldb::offset_t offset, lldb::offset_t length); 47254721Semaste 48314564Sdim static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, 49314564Sdim lldb::DataBufferSP &data_sp, 50314564Sdim lldb::offset_t data_offset, 51314564Sdim lldb::offset_t file_offset, 52314564Sdim lldb::offset_t length, 53314564Sdim lldb_private::ModuleSpecList &specs); 54254721Semaste 55314564Sdim static bool MagicBytesMatch(const lldb_private::DataExtractor &data); 56254721Semaste 57314564Sdim // Member Functions 58314564Sdim bool ParseHeader() override; 59254721Semaste 60314564Sdim size_t GetNumObjects() const override { 61314564Sdim if (m_archive_sp) 62314564Sdim return m_archive_sp->GetNumObjects(); 63314564Sdim return 0; 64314564Sdim } 65254721Semaste 66314564Sdim void Dump(lldb_private::Stream *s) const override; 67254721Semaste 68314564Sdim lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override; 69296417Sdim 70314564Sdim // PluginInterface protocol 71314564Sdim lldb_private::ConstString GetPluginName() override; 72254721Semaste 73314564Sdim uint32_t GetPluginVersion() override; 74254721Semaste 75254721Semasteprotected: 76314564Sdim struct Object { 77314564Sdim Object(); 78254721Semaste 79314564Sdim void Clear(); 80254721Semaste 81314564Sdim lldb::offset_t Extract(const lldb_private::DataExtractor &data, 82314564Sdim lldb::offset_t offset); 83353358Sdim /// Object name in the archive. 84353358Sdim lldb_private::ConstString ar_name; 85254721Semaste 86353358Sdim /// Object modification time in the archive. 87353358Sdim uint32_t modification_time; 88254721Semaste 89353358Sdim /// Object user id in the archive. 90353358Sdim uint16_t uid; 91353358Sdim 92353358Sdim /// Object group id in the archive. 93353358Sdim uint16_t gid; 94353358Sdim 95353358Sdim /// Object octal file permissions in the archive. 96353358Sdim uint16_t mode; 97353358Sdim 98353358Sdim /// Object size in bytes in the archive. 99353358Sdim uint32_t size; 100353358Sdim 101353358Sdim /// File offset in bytes from the beginning of the file of the object data. 102353358Sdim lldb::offset_t file_offset; 103353358Sdim 104353358Sdim /// Length of the object data. 105353358Sdim lldb::offset_t file_size; 106314564Sdim }; 107254721Semaste 108314564Sdim class Archive { 109314564Sdim public: 110314564Sdim typedef std::shared_ptr<Archive> shared_ptr; 111314564Sdim typedef std::multimap<lldb_private::FileSpec, shared_ptr> Map; 112254721Semaste 113314564Sdim Archive(const lldb_private::ArchSpec &arch, 114314564Sdim const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset, 115314564Sdim lldb_private::DataExtractor &data); 116296417Sdim 117314564Sdim ~Archive(); 118296417Sdim 119314564Sdim static Map &GetArchiveCache(); 120254721Semaste 121314564Sdim static std::recursive_mutex &GetArchiveCacheMutex(); 122254721Semaste 123314564Sdim static Archive::shared_ptr FindCachedArchive( 124314564Sdim const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch, 125314564Sdim const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset); 126254721Semaste 127314564Sdim static Archive::shared_ptr ParseAndCacheArchiveForFile( 128314564Sdim const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch, 129314564Sdim const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset, 130314564Sdim lldb_private::DataExtractor &data); 131254721Semaste 132314564Sdim size_t GetNumObjects() const { return m_objects.size(); } 133254721Semaste 134314564Sdim const Object *GetObjectAtIndex(size_t idx) { 135314564Sdim if (idx < m_objects.size()) 136314564Sdim return &m_objects[idx]; 137353358Sdim return nullptr; 138314564Sdim } 139254721Semaste 140314564Sdim size_t ParseObjects(); 141254721Semaste 142353358Sdim Object *FindObject(lldb_private::ConstString object_name, 143314564Sdim const llvm::sys::TimePoint<> &object_mod_time); 144254721Semaste 145314564Sdim lldb::offset_t GetFileOffset() const { return m_file_offset; } 146254721Semaste 147353358Sdim const llvm::sys::TimePoint<> &GetModificationTime() { 148353358Sdim return m_modification_time; 149353358Sdim } 150254721Semaste 151314564Sdim const lldb_private::ArchSpec &GetArchitecture() const { return m_arch; } 152254721Semaste 153314564Sdim void SetArchitecture(const lldb_private::ArchSpec &arch) { m_arch = arch; } 154254721Semaste 155314564Sdim bool HasNoExternalReferences() const; 156254721Semaste 157314564Sdim lldb_private::DataExtractor &GetData() { return m_data; } 158254721Semaste 159314564Sdim protected: 160314564Sdim typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap; 161314564Sdim // Member Variables 162314564Sdim lldb_private::ArchSpec m_arch; 163353358Sdim llvm::sys::TimePoint<> m_modification_time; 164314564Sdim lldb::offset_t m_file_offset; 165353358Sdim std::vector<Object> m_objects; 166314564Sdim ObjectNameToIndexMap m_object_name_to_index_map; 167314564Sdim lldb_private::DataExtractor m_data; ///< The data for this object container 168314564Sdim ///so we don't lose data if the .a files 169314564Sdim ///gets modified 170314564Sdim }; 171254721Semaste 172314564Sdim void SetArchive(Archive::shared_ptr &archive_sp); 173254721Semaste 174314564Sdim Archive::shared_ptr m_archive_sp; 175254721Semaste}; 176254721Semaste 177296417Sdim#endif // liblldb_ObjectContainerBSDArchive_h_ 178