1 //===-- ObjectContainer.h ---------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_ObjectContainer_h_
11 #define liblldb_ObjectContainer_h_
12 
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 // Project includes
17 
18 #include "lldb/lldb-private.h"
19 #include "lldb/Core/DataExtractor.h"
20 #include "lldb/Host/FileSpec.h"
21 #include "lldb/Core/ModuleChild.h"
22 #include "lldb/Core/PluginInterface.h"
23 #include "lldb/Host/Endian.h"
24 
25 namespace lldb_private {
26 
27 //----------------------------------------------------------------------
28 /// @class ObjectContainer ObjectContainer.h "lldb/Symbol/ObjectContainer.h"
29 /// @brief A plug-in interface definition class for object containers.
30 ///
31 /// Object containers contain object files from one or more
32 /// architectures, and also can contain one or more named objects.
33 ///
34 /// Typical object containers are static libraries (.a files) that
35 /// contain multiple named object files, and universal files that contain
36 /// multiple architectures.
37 //----------------------------------------------------------------------
38 class ObjectContainer :
39     public PluginInterface,
40     public ModuleChild
41 {
42 public:
43     //------------------------------------------------------------------
44     /// Construct with a parent module, offset, and header data.
45     ///
46     /// Object files belong to modules and a valid module must be
47     /// supplied upon construction. The at an offset within a file for
48     /// objects that contain more than one architecture or object.
49     //------------------------------------------------------------------
ObjectContainer(const lldb::ModuleSP & module_sp,const FileSpec * file,lldb::offset_t file_offset,lldb::offset_t length,lldb::DataBufferSP & data_sp,lldb::offset_t data_offset)50     ObjectContainer (const lldb::ModuleSP &module_sp,
51                      const FileSpec *file,
52                      lldb::offset_t file_offset,
53                      lldb::offset_t length,
54                      lldb::DataBufferSP& data_sp,
55                      lldb::offset_t data_offset) :
56         ModuleChild (module_sp),
57         m_file (),  // This file can be different than the module's file spec
58         m_offset (file_offset),
59         m_length (length),
60         m_data ()
61     {
62         if (file)
63             m_file = *file;
64         if (data_sp)
65             m_data.SetData (data_sp, data_offset, length);
66     }
67 
68     //------------------------------------------------------------------
69     /// Destructor.
70     ///
71     /// The destructor is virtual since this class is designed to be
72     /// inherited from by the plug-in instance.
73     //------------------------------------------------------------------
74     virtual
~ObjectContainer()75     ~ObjectContainer()
76     {
77     }
78 
79     //------------------------------------------------------------------
80     /// Dump a description of this object to a Stream.
81     ///
82     /// Dump a description of the current contents of this object
83     /// to the supplied stream \a s. The dumping should include the
84     /// section list if it has been parsed, and the symbol table
85     /// if it has been parsed.
86     ///
87     /// @param[in] s
88     ///     The stream to which to dump the object descripton.
89     //------------------------------------------------------------------
90     virtual void
91     Dump (Stream *s) const = 0;
92 
93     //------------------------------------------------------------------
94     /// Gets the architecture given an index.
95     ///
96     /// Copies the architecture specification for index \a idx.
97     ///
98     /// @param[in] idx
99     ///     The architecture index to extract.
100     ///
101     /// @param[out] arch
102     ///     A architecture object that will be filled in if \a idx is a
103     ///     architecture valid index.
104     ///
105     /// @return
106     ///     Returns \b true if \a idx is valid and \a arch has been
107     ///     filled in, \b false otherwise.
108     ///
109     /// @see ObjectContainer::GetNumArchitectures() const
110     //------------------------------------------------------------------
111     virtual bool
GetArchitectureAtIndex(uint32_t idx,ArchSpec & arch)112     GetArchitectureAtIndex (uint32_t idx, ArchSpec& arch) const
113     {
114         return false;
115     }
116 
117     //------------------------------------------------------------------
118     /// Returns the offset into a file at which this object resides.
119     ///
120     /// Some files contain many object files, and this function allows
121     /// access to an object's offset within the file.
122     ///
123     /// @return
124     ///     The offset in bytes into the file. Defaults to zero for
125     ///     simple object files that a represented by an entire file.
126     //------------------------------------------------------------------
127     virtual lldb::addr_t
GetOffset()128     GetOffset () const
129     { return m_offset; }
130 
131     virtual lldb::addr_t
GetByteSize()132     GetByteSize () const
133     { return m_length; }
134 
135     //------------------------------------------------------------------
136     /// Get the number of objects within this object file (archives).
137     ///
138     /// @return
139     ///     Zero for object files that are not archives, or the number
140     ///     of objects contained in the archive.
141     //------------------------------------------------------------------
142     virtual size_t
GetNumObjects()143     GetNumObjects () const
144     { return 0; }
145 
146     //------------------------------------------------------------------
147     /// Get the number of architectures in this object file.
148     ///
149     /// The default implementation returns 1 as for object files that
150     /// contain a single architecture. ObjectContainer instances that
151     /// contain more than one architecture should override this function
152     /// and return an appropriate value.
153     ///
154     /// @return
155     ///     The number of architectures contained in this object file.
156     //------------------------------------------------------------------
157     virtual size_t
GetNumArchitectures()158     GetNumArchitectures () const
159     { return 0; }
160 
161     //------------------------------------------------------------------
162     /// Attempts to parse the object header.
163     ///
164     /// This function is used as a test to see if a given plug-in
165     /// instance can parse the header data already contained in
166     /// ObjectContainer::m_data. If an object file parser does not
167     /// recognize that magic bytes in a header, false should be returned
168     /// and the next plug-in can attempt to parse an object file.
169     ///
170     /// @return
171     ///     Returns \b true if the header was parsed succesfully, \b
172     ///     false otherwise.
173     //------------------------------------------------------------------
174     virtual bool
175     ParseHeader () = 0;
176 
177     //------------------------------------------------------------------
178     /// Selects an architecture in an object file.
179     ///
180     /// Object files that contain a single architecture should verify
181     /// that the specified \a arch matches the architecture in in
182     /// object file and return \b true or \b false accordingly.
183     ///
184     /// Object files that contain more than one architecture should
185     /// attempt to select that architecture, and if successful, clear
186     /// out any previous state from any previously selected architecture
187     /// and prepare to return information for the new architecture.
188     ///
189     /// @return
190     ///     Returns a pointer to the object file of the requested \a
191     ///     arch and optional \a name. Returns NULL of no such object
192     ///     file exists in the container.
193     //------------------------------------------------------------------
194     virtual lldb::ObjectFileSP
195     GetObjectFile (const FileSpec *file) = 0;
196 
197     virtual bool
ObjectAtIndexIsContainer(uint32_t object_idx)198     ObjectAtIndexIsContainer (uint32_t object_idx)
199     {
200         return false;
201     }
202 
203     virtual ObjectFile *
GetObjectFileAtIndex(uint32_t object_idx)204     GetObjectFileAtIndex (uint32_t object_idx)
205     {
206         return NULL;
207     }
208 
209     virtual ObjectContainer *
GetObjectContainerAtIndex(uint32_t object_idx)210     GetObjectContainerAtIndex (uint32_t object_idx)
211     {
212         return NULL;
213     }
214 
215     virtual const char *
GetObjectNameAtIndex(uint32_t object_idx)216     GetObjectNameAtIndex (uint32_t object_idx) const
217     {
218         return NULL;
219     }
220 
221 protected:
222     //------------------------------------------------------------------
223     // Member variables.
224     //------------------------------------------------------------------
225     FileSpec m_file; ///< The file that represents this container objects (which can be different from the module's file).
226     lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory
227     lldb::addr_t m_length; ///< The size in bytes if known (can be zero).
228     DataExtractor m_data; ///< The data for this object file so things can be parsed lazily.
229 
230 private:
231     DISALLOW_COPY_AND_ASSIGN (ObjectContainer);
232 };
233 
234 } // namespace lldb_private
235 
236 #endif  // liblldb_ObjectContainer_h_
237