1 //===-- ObjectContainer.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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_SYMBOL_OBJECTCONTAINER_H
10 #define LLDB_SYMBOL_OBJECTCONTAINER_H
11 
12 #include "lldb/Core/ModuleChild.h"
13 #include "lldb/Core/PluginInterface.h"
14 #include "lldb/Utility/DataExtractor.h"
15 #include "lldb/Utility/Endian.h"
16 #include "lldb/Utility/FileSpec.h"
17 #include "lldb/lldb-private.h"
18 
19 namespace lldb_private {
20 
21 /// \class ObjectContainer ObjectContainer.h "lldb/Symbol/ObjectContainer.h"
22 /// A plug-in interface definition class for object containers.
23 ///
24 /// Object containers contain object files from one or more architectures, and
25 /// also can contain one or more named objects.
26 ///
27 /// Typical object containers are static libraries (.a files) that contain
28 /// multiple named object files, and universal files that contain multiple
29 /// architectures.
30 class ObjectContainer : public PluginInterface, public ModuleChild {
31 public:
32   /// Construct with a parent module, offset, and header data.
33   ///
34   /// Object files belong to modules and a valid module must be supplied upon
35   /// construction. The at an offset within a file for objects that contain
36   /// more than one architecture or object.
37   ObjectContainer(const lldb::ModuleSP &module_sp, const FileSpec *file,
38                   lldb::offset_t file_offset, lldb::offset_t length,
39                   lldb::DataBufferSP data_sp, lldb::offset_t data_offset);
40 
41   /// Destructor.
42   ///
43   /// The destructor is virtual since this class is designed to be inherited
44   /// from by the plug-in instance.
45   ~ObjectContainer() override = default;
46 
47   /// Gets the architecture given an index.
48   ///
49   /// Copies the architecture specification for index \a idx.
50   ///
51   /// \param[in] idx
52   ///     The architecture index to extract.
53   ///
54   /// \param[out] arch
55   ///     A architecture object that will be filled in if \a idx is a
56   ///     architecture valid index.
57   ///
58   /// \return
59   ///     Returns \b true if \a idx is valid and \a arch has been
60   ///     filled in, \b false otherwise.
61   ///
62   /// \see ObjectContainer::GetNumArchitectures() const
63   virtual bool GetArchitectureAtIndex(uint32_t idx, ArchSpec &arch) const {
64     return false;
65   }
66 
67   /// Returns the offset into a file at which this object resides.
68   ///
69   /// Some files contain many object files, and this function allows access to
70   /// an object's offset within the file.
71   ///
72   /// \return
73   ///     The offset in bytes into the file. Defaults to zero for
74   ///     simple object files that a represented by an entire file.
75   virtual lldb::addr_t GetOffset() const { return m_offset; }
76 
77   virtual lldb::addr_t GetByteSize() const { return m_length; }
78 
79   /// Get the number of objects within this object file (archives).
80   ///
81   /// \return
82   ///     Zero for object files that are not archives, or the number
83   ///     of objects contained in the archive.
84   virtual size_t GetNumObjects() const { return 0; }
85 
86   /// Get the number of architectures in this object file.
87   ///
88   /// The default implementation returns 1 as for object files that contain a
89   /// single architecture. ObjectContainer instances that contain more than
90   /// one architecture should override this function and return an appropriate
91   /// value.
92   ///
93   /// \return
94   ///     The number of architectures contained in this object file.
95   virtual size_t GetNumArchitectures() const { return 0; }
96 
97   /// Attempts to parse the object header.
98   ///
99   /// This function is used as a test to see if a given plug-in instance can
100   /// parse the header data already contained in ObjectContainer::m_data. If
101   /// an object file parser does not recognize that magic bytes in a header,
102   /// false should be returned and the next plug-in can attempt to parse an
103   /// object file.
104   ///
105   /// \return
106   ///     Returns \b true if the header was parsed successfully, \b
107   ///     false otherwise.
108   virtual bool ParseHeader() = 0;
109 
110   /// Selects an architecture in an object file.
111   ///
112   /// Object files that contain a single architecture should verify that the
113   /// specified \a arch matches the architecture in in object file and return
114   /// \b true or \b false accordingly.
115   ///
116   /// Object files that contain more than one architecture should attempt to
117   /// select that architecture, and if successful, clear out any previous
118   /// state from any previously selected architecture and prepare to return
119   /// information for the new architecture.
120   ///
121   /// \return
122   ///     Returns a pointer to the object file of the requested \a
123   ///     arch and optional \a name. Returns nullptr of no such object
124   ///     file exists in the container.
125   virtual lldb::ObjectFileSP GetObjectFile(const FileSpec *file) = 0;
126 
127   static lldb::ObjectContainerSP
128   FindPlugin(const lldb::ModuleSP &module_sp, const lldb::ProcessSP &process_sp,
129              lldb::addr_t header_addr, lldb::WritableDataBufferSP file_data_sp);
130 
131 protected:
132   /// The file that represents this container objects (which can be different
133   /// from the module's file).
134   FileSpec m_file;
135 
136   /// The offset in bytes into the file, or the address in memory
137   lldb::addr_t m_offset;
138 
139   /// The size in bytes if known (can be zero).
140   lldb::addr_t m_length;
141 
142   /// The data for this object file so things can be parsed lazily.
143   DataExtractor m_data;
144 
145 private:
146   ObjectContainer(const ObjectContainer &) = delete;
147   const ObjectContainer &operator=(const ObjectContainer &) = delete;
148 };
149 
150 } // namespace lldb_private
151 
152 #endif // LLDB_SYMBOL_OBJECTCONTAINER_H
153