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