1 //===-- ObjectContainerBSDArchive.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_ObjectContainerBSDArchive_h_
11 #define liblldb_ObjectContainerBSDArchive_h_
12 
13 #include "lldb/Symbol/ObjectContainer.h"
14 
15 #include "lldb/Core/ArchSpec.h"
16 #include "lldb/Core/ConstString.h"
17 #include "lldb/Host/FileSpec.h"
18 #include "lldb/Core/UniqueCStringMap.h"
19 #include "lldb/Host/TimeValue.h"
20 
21 class ObjectContainerBSDArchive :
22     public lldb_private::ObjectContainer
23 {
24 public:
25 
26     //------------------------------------------------------------------
27     // Static Functions
28     //------------------------------------------------------------------
29     static void
30     Initialize();
31 
32     static void
33     Terminate();
34 
35     static lldb_private::ConstString
36     GetPluginNameStatic();
37 
38     static const char *
39     GetPluginDescriptionStatic();
40 
41     static lldb_private::ObjectContainer *
42     CreateInstance (const lldb::ModuleSP &module_sp,
43                     lldb::DataBufferSP& data_sp,
44                     lldb::offset_t data_offset,
45                     const lldb_private::FileSpec *file,
46                     lldb::offset_t offset,
47                     lldb::offset_t length);
48 
49     static size_t
50     GetModuleSpecifications (const lldb_private::FileSpec& file,
51                              lldb::DataBufferSP& data_sp,
52                              lldb::offset_t data_offset,
53                              lldb::offset_t file_offset,
54                              lldb::offset_t length,
55                              lldb_private::ModuleSpecList &specs);
56 
57     static bool
58     MagicBytesMatch (const lldb_private::DataExtractor &data);
59 
60     //------------------------------------------------------------------
61     // Member Functions
62     //------------------------------------------------------------------
63     ObjectContainerBSDArchive (const lldb::ModuleSP &module_sp,
64                                lldb::DataBufferSP& data_sp,
65                                lldb::offset_t data_offset,
66                                const lldb_private::FileSpec *file,
67                                lldb::offset_t offset,
68                                lldb::offset_t length);
69 
70     virtual
71     ~ObjectContainerBSDArchive();
72 
73     virtual bool
74     ParseHeader ();
75 
76     virtual size_t
GetNumObjects()77     GetNumObjects () const
78     {
79         if (m_archive_sp)
80             return m_archive_sp->GetNumObjects();
81         return 0;
82     }
83     virtual void
84     Dump (lldb_private::Stream *s) const;
85 
86     virtual lldb::ObjectFileSP
87     GetObjectFile (const lldb_private::FileSpec *file);
88 
89     //------------------------------------------------------------------
90     // PluginInterface protocol
91     //------------------------------------------------------------------
92     virtual lldb_private::ConstString
93     GetPluginName();
94 
95     virtual uint32_t
96     GetPluginVersion();
97 
98 protected:
99 
100     struct Object
101     {
102         Object();
103 
104         void
105         Clear();
106 
107         lldb::offset_t
108         Extract (const lldb_private::DataExtractor& data, lldb::offset_t offset);
109 
110         lldb_private::ConstString       ar_name;        // name
111         uint32_t        ar_date;        // modification time
112         uint16_t        ar_uid;         // user id
113         uint16_t        ar_gid;         // group id
114         uint16_t        ar_mode;        // octal file permissions
115         uint32_t        ar_size;        // size in bytes
116         lldb::offset_t  ar_file_offset; // file offset in bytes from the beginning of the file of the object data
117         lldb::offset_t  ar_file_size;   // length of the object data
118 
119         typedef std::vector<Object>         collection;
120         typedef collection::iterator        iterator;
121         typedef collection::const_iterator  const_iterator;
122     };
123 
124     class Archive
125     {
126     public:
127         typedef std::shared_ptr<Archive> shared_ptr;
128         typedef std::multimap<lldb_private::FileSpec, shared_ptr> Map;
129 
130         static Map &
131         GetArchiveCache ();
132 
133         static lldb_private::Mutex &
134         GetArchiveCacheMutex ();
135 
136         static Archive::shared_ptr
137         FindCachedArchive (const lldb_private::FileSpec &file,
138                            const lldb_private::ArchSpec &arch,
139                            const lldb_private::TimeValue &mod_time,
140                            lldb::offset_t file_offset);
141 
142         static Archive::shared_ptr
143         ParseAndCacheArchiveForFile (const lldb_private::FileSpec &file,
144                                      const lldb_private::ArchSpec &arch,
145                                      const lldb_private::TimeValue &mod_time,
146                                      lldb::offset_t file_offset,
147                                      lldb_private::DataExtractor &data);
148 
149         Archive (const lldb_private::ArchSpec &arch,
150                  const lldb_private::TimeValue &mod_time,
151                  lldb::offset_t file_offset,
152                  lldb_private::DataExtractor &data);
153 
154         ~Archive ();
155 
156         size_t
GetNumObjects()157         GetNumObjects () const
158         {
159             return m_objects.size();
160         }
161 
162         const Object *
GetObjectAtIndex(size_t idx)163         GetObjectAtIndex (size_t idx)
164         {
165             if (idx < m_objects.size())
166                 return &m_objects[idx];
167             return NULL;
168         }
169 
170         size_t
171         ParseObjects ();
172 
173         Object *
174         FindObject (const lldb_private::ConstString &object_name,
175                     const lldb_private::TimeValue &object_mod_time);
176 
177         lldb::offset_t
GetFileOffset()178         GetFileOffset () const
179         {
180             return m_file_offset;
181         }
182 
183         const lldb_private::TimeValue &
GetModificationTime()184         GetModificationTime()
185         {
186             return m_time;
187         }
188 
189         const lldb_private::ArchSpec &
GetArchitecture()190         GetArchitecture () const
191         {
192             return m_arch;
193         }
194 
195         void
SetArchitecture(const lldb_private::ArchSpec & arch)196         SetArchitecture (const lldb_private::ArchSpec &arch)
197         {
198             m_arch = arch;
199         }
200 
201         bool
202         HasNoExternalReferences() const;
203 
204         lldb_private::DataExtractor &
GetData()205         GetData ()
206         {
207             return m_data;
208         }
209 
210     protected:
211         typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap;
212         //----------------------------------------------------------------------
213         // Member Variables
214         //----------------------------------------------------------------------
215         lldb_private::ArchSpec m_arch;
216         lldb_private::TimeValue m_time;
217         lldb::offset_t m_file_offset;
218         Object::collection m_objects;
219         ObjectNameToIndexMap m_object_name_to_index_map;
220         lldb_private::DataExtractor m_data; ///< The data for this object container so we don't lose data if the .a files gets modified
221     };
222 
223     void
224     SetArchive (Archive::shared_ptr &archive_sp);
225 
226     Archive::shared_ptr m_archive_sp;
227 };
228 
229 #endif  // liblldb_ObjectContainerBSDArchive_h_
230