183 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H10#define LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H11 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 26enum class ArchiveType { Invalid, Archive, ThinArchive };27 28class ObjectContainerBSDArchive : public lldb_private::ObjectContainer {29public: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 Functions40 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 Functions65 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 lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override;74 75 // PluginInterface protocol76 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }77 78protected: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 size in bytes in the archive.97 uint32_t size = 0;98 99 /// File offset in bytes from the beginning of the file of the object data.100 lldb::offset_t file_offset = 0;101 102 /// Length of the object data.103 lldb::offset_t file_size = 0;104 105 void Dump() const;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, ArchiveType archive_type);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, ArchiveType archive_type);131 132 size_t GetNumObjects() const { return m_objects.size(); }133 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 145 lldb::offset_t GetFileOffset() const { return m_file_offset; }146 147 const llvm::sys::TimePoint<> &GetModificationTime() {148 return m_modification_time;149 }150 151 const lldb_private::ArchSpec &GetArchitecture() const { return m_arch; }152 153 void SetArchitecture(const lldb_private::ArchSpec &arch) { m_arch = arch; }154 155 bool HasNoExternalReferences() const;156 157 lldb_private::DataExtractor &GetData() { return m_data; }158 159 ArchiveType GetArchiveType() { return m_archive_type; }160 161 protected:162 typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap;163 // Member Variables164 lldb_private::ArchSpec m_arch;165 llvm::sys::TimePoint<> m_modification_time;166 lldb::offset_t m_file_offset;167 std::vector<Object> m_objects;168 ObjectNameToIndexMap m_object_name_to_index_map;169 lldb_private::DataExtractor m_data; ///< The data for this object container170 ///so we don't lose data if the .a files171 ///gets modified172 ArchiveType m_archive_type;173 };174 175 void SetArchive(Archive::shared_ptr &archive_sp);176 177 Archive::shared_ptr m_archive_sp;178 179 ArchiveType m_archive_type;180};181 182#endif // LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H183