reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
//===-- ObjectContainerBSDArchive.h -----------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_ObjectContainerBSDArchive_h_
#define liblldb_ObjectContainerBSDArchive_h_

#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ObjectContainer.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/FileSpec.h"

#include "llvm/Support/Chrono.h"

#include <map>
#include <memory>
#include <mutex>

class ObjectContainerBSDArchive : public lldb_private::ObjectContainer {
public:
  ObjectContainerBSDArchive(const lldb::ModuleSP &module_sp,
                            lldb::DataBufferSP &data_sp,
                            lldb::offset_t data_offset,
                            const lldb_private::FileSpec *file,
                            lldb::offset_t offset, lldb::offset_t length);

  ~ObjectContainerBSDArchive() override;

  // Static Functions
  static void Initialize();

  static void Terminate();

  static lldb_private::ConstString GetPluginNameStatic();

  static const char *GetPluginDescriptionStatic();

  static lldb_private::ObjectContainer *
  CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
                 lldb::offset_t data_offset, const lldb_private::FileSpec *file,
                 lldb::offset_t offset, lldb::offset_t length);

  static size_t GetModuleSpecifications(const lldb_private::FileSpec &file,
                                        lldb::DataBufferSP &data_sp,
                                        lldb::offset_t data_offset,
                                        lldb::offset_t file_offset,
                                        lldb::offset_t length,
                                        lldb_private::ModuleSpecList &specs);

  static bool MagicBytesMatch(const lldb_private::DataExtractor &data);

  // Member Functions
  bool ParseHeader() override;

  size_t GetNumObjects() const override {
    if (m_archive_sp)
      return m_archive_sp->GetNumObjects();
    return 0;
  }

  void Dump(lldb_private::Stream *s) const override;

  lldb::ObjectFileSP GetObjectFile(const lldb_private::FileSpec *file) override;

  // PluginInterface protocol
  lldb_private::ConstString GetPluginName() override;

  uint32_t GetPluginVersion() override;

protected:
  struct Object {
    Object();

    void Clear();

    lldb::offset_t Extract(const lldb_private::DataExtractor &data,
                           lldb::offset_t offset);
    /// Object name in the archive.
    lldb_private::ConstString ar_name;

    /// Object modification time in the archive.
    uint32_t modification_time;

    /// Object user id in the archive.
    uint16_t uid;

    /// Object group id in the archive.
    uint16_t gid;

    /// Object octal file permissions in the archive.
    uint16_t mode;

    /// Object size in bytes in the archive.
    uint32_t size;

    /// File offset in bytes from the beginning of the file of the object data.
    lldb::offset_t file_offset;

    /// Length of the object data.
    lldb::offset_t file_size;
  };

  class Archive {
  public:
    typedef std::shared_ptr<Archive> shared_ptr;
    typedef std::multimap<lldb_private::FileSpec, shared_ptr> Map;

    Archive(const lldb_private::ArchSpec &arch,
            const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset,
            lldb_private::DataExtractor &data);

    ~Archive();

    static Map &GetArchiveCache();

    static std::recursive_mutex &GetArchiveCacheMutex();

    static Archive::shared_ptr FindCachedArchive(
        const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch,
        const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset);

    static Archive::shared_ptr ParseAndCacheArchiveForFile(
        const lldb_private::FileSpec &file, const lldb_private::ArchSpec &arch,
        const llvm::sys::TimePoint<> &mod_time, lldb::offset_t file_offset,
        lldb_private::DataExtractor &data);

    size_t GetNumObjects() const { return m_objects.size(); }

    const Object *GetObjectAtIndex(size_t idx) {
      if (idx < m_objects.size())
        return &m_objects[idx];
      return nullptr;
    }

    size_t ParseObjects();

    Object *FindObject(lldb_private::ConstString object_name,
                       const llvm::sys::TimePoint<> &object_mod_time);

    lldb::offset_t GetFileOffset() const { return m_file_offset; }

    const llvm::sys::TimePoint<> &GetModificationTime() {
      return m_modification_time;
    }

    const lldb_private::ArchSpec &GetArchitecture() const { return m_arch; }

    void SetArchitecture(const lldb_private::ArchSpec &arch) { m_arch = arch; }

    bool HasNoExternalReferences() const;

    lldb_private::DataExtractor &GetData() { return m_data; }

  protected:
    typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap;
    // Member Variables
    lldb_private::ArchSpec m_arch;
    llvm::sys::TimePoint<> m_modification_time;
    lldb::offset_t m_file_offset;
    std::vector<Object> m_objects;
    ObjectNameToIndexMap m_object_name_to_index_map;
    lldb_private::DataExtractor m_data; ///< The data for this object container
                                        ///so we don't lose data if the .a files
                                        ///gets modified
  };

  void SetArchive(Archive::shared_ptr &archive_sp);

  Archive::shared_ptr m_archive_sp;
};

#endif // liblldb_ObjectContainerBSDArchive_h_