blob: 075e48fbc526f6157ad7e9089635c03b8d28e5db [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ObjectFile.cpp ------------------------------------------*- 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#include "lldb/lldb-private.h"
Greg Claytone40b6422011-09-18 18:59:15 +000011#include "lldb/lldb-private-log.h"
Greg Claytondb2dc2b2012-01-12 05:25:17 +000012#include "lldb/Core/DataBuffer.h"
Greg Claytone40b6422011-09-18 18:59:15 +000013#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000014#include "lldb/Core/Module.h"
15#include "lldb/Core/PluginManager.h"
16#include "lldb/Core/RegularExpression.h"
17#include "lldb/Core/Timer.h"
18#include "lldb/Symbol/ObjectFile.h"
19#include "lldb/Symbol/ObjectContainer.h"
20#include "lldb/Symbol/SymbolFile.h"
21
22using namespace lldb;
23using namespace lldb_private;
24
Greg Claytone40b6422011-09-18 18:59:15 +000025ObjectFileSP
Greg Claytondb2dc2b2012-01-12 05:25:17 +000026ObjectFile::FindPlugin (Module* module, const FileSpec* file, addr_t file_offset, addr_t file_size, DataBufferSP &file_data_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000027{
28 Timer scoped_timer (__PRETTY_FUNCTION__,
29 "ObjectFile::FindPlugin (module = %s/%s, file = %p, file_offset = 0x%z8.8x, file_size = 0x%z8.8x)",
30 module->GetFileSpec().GetDirectory().AsCString(),
31 module->GetFileSpec().GetFilename().AsCString(),
32 file, file_offset, file_size);
Greg Claytone40b6422011-09-18 18:59:15 +000033 ObjectFileSP object_file_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000034
35 if (module != NULL)
36 {
37 if (file)
38 {
Greg Claytondb2dc2b2012-01-12 05:25:17 +000039 // Memory map the entire file contents
40 if (!file_data_sp)
41 {
42 assert (file_offset == 0);
43 file_data_sp = file->MemoryMapFileContents(file_offset, file_size);
44 }
Chris Lattner24943d22010-06-08 16:52:24 +000045
Greg Claytondb2dc2b2012-01-12 05:25:17 +000046 if (!file_data_sp || file_data_sp->GetByteSize() == 0)
Chris Lattner24943d22010-06-08 16:52:24 +000047 {
48 // Check for archive file with format "/path/to/archive.a(object.o)"
49 char path_with_object[PATH_MAX*2];
50 module->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object));
51
52 RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$");
53 if (g_object_regex.Execute (path_with_object, 2))
54 {
55 FileSpec archive_file;
56 std::string path;
57 std::string object;
58 if (g_object_regex.GetMatchAtIndex (path_with_object, 1, path) &&
59 g_object_regex.GetMatchAtIndex (path_with_object, 2, object))
60 {
Greg Clayton537a7a82010-10-20 20:54:39 +000061 archive_file.SetFile (path.c_str(), false);
Chris Lattner24943d22010-06-08 16:52:24 +000062 file_size = archive_file.GetByteSize();
63 if (file_size > 0)
Greg Claytondb2dc2b2012-01-12 05:25:17 +000064 {
Chris Lattner24943d22010-06-08 16:52:24 +000065 module->SetFileSpecAndObjectName (archive_file, ConstString(object.c_str()));
Greg Claytondb2dc2b2012-01-12 05:25:17 +000066 file_data_sp = archive_file.MemoryMapFileContents(file_offset, file_size);
67 }
Chris Lattner24943d22010-06-08 16:52:24 +000068 }
69 }
70 }
71
Greg Claytondb2dc2b2012-01-12 05:25:17 +000072 if (file_data_sp && file_data_sp->GetByteSize() > 0)
Chris Lattner24943d22010-06-08 16:52:24 +000073 {
Greg Claytondb2dc2b2012-01-12 05:25:17 +000074 uint32_t idx;
Chris Lattner24943d22010-06-08 16:52:24 +000075
Greg Claytondb2dc2b2012-01-12 05:25:17 +000076 // Check if this is a normal object file by iterating through
77 // all object file plugin instances.
78 ObjectFileCreateInstance create_object_file_callback;
79 for (idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
80 {
81 object_file_sp.reset (create_object_file_callback(module, file_data_sp, file, file_offset, file_size));
82 if (object_file_sp.get())
83 return object_file_sp;
84 }
Chris Lattner24943d22010-06-08 16:52:24 +000085
Greg Claytondb2dc2b2012-01-12 05:25:17 +000086 // Check if this is a object container by iterating through
87 // all object container plugin instances and then trying to get
88 // an object file from the container.
89 ObjectContainerCreateInstance create_object_container_callback;
90 for (idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
91 {
92 std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module, file_data_sp, file, file_offset, file_size));
Chris Lattner24943d22010-06-08 16:52:24 +000093
Greg Claytondb2dc2b2012-01-12 05:25:17 +000094 if (object_container_ap.get())
95 object_file_sp = object_container_ap->GetObjectFile(file);
96
97 if (object_file_sp.get())
98 return object_file_sp;
99 }
Chris Lattner24943d22010-06-08 16:52:24 +0000100 }
101 }
102 }
Greg Claytone40b6422011-09-18 18:59:15 +0000103 // We didn't find it, so clear our shared pointer in case it
104 // contains anything and return an empty shared pointer
105 object_file_sp.reset();
106 return object_file_sp;
107}
108
109ObjectFile::ObjectFile (Module* module,
110 const FileSpec *file_spec_ptr,
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000111 addr_t file_offset,
112 addr_t file_size,
113 DataBufferSP& file_data_sp) :
Greg Claytone40b6422011-09-18 18:59:15 +0000114 ModuleChild (module),
115 m_file (), // This file could be different from the original module's file
116 m_type (eTypeInvalid),
117 m_strata (eStrataInvalid),
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000118 m_offset (file_offset),
119 m_length (file_size),
120 m_data (),
Greg Claytone40b6422011-09-18 18:59:15 +0000121 m_unwind_table (*this)
122{
123 if (file_spec_ptr)
124 m_file = *file_spec_ptr;
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000125 if (file_data_sp)
126 m_data.SetData (file_data_sp, file_offset, file_size);
Greg Claytone40b6422011-09-18 18:59:15 +0000127 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
128 if (log)
129 {
130 if (m_file)
131 {
132 log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n",
133 this,
134 m_module->GetFileSpec().GetDirectory().AsCString(),
135 m_module->GetFileSpec().GetFilename().AsCString(),
136 m_file.GetDirectory().AsCString(),
137 m_file.GetFilename().AsCString(),
138 m_offset,
139 m_length);
140 }
141 else
142 {
143 log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n",
144 this,
145 m_module->GetFileSpec().GetDirectory().AsCString(),
146 m_module->GetFileSpec().GetFilename().AsCString(),
147 m_offset,
148 m_length);
149 }
150 }
151}
152
153ObjectFile::~ObjectFile()
154{
155 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
156 if (log)
157 {
158 if (m_file)
159 {
160 log->Printf ("%p ObjectFile::~ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n",
161 this,
162 m_module->GetFileSpec().GetDirectory().AsCString(),
163 m_module->GetFileSpec().GetFilename().AsCString(),
164 m_file.GetDirectory().AsCString(),
165 m_file.GetFilename().AsCString(),
166 m_offset,
167 m_length);
168 }
169 else
170 {
171 log->Printf ("%p ObjectFile::~ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n",
172 this,
173 m_module->GetFileSpec().GetDirectory().AsCString(),
174 m_module->GetFileSpec().GetFilename().AsCString(),
175 m_offset,
176 m_length);
177 }
178 }
Chris Lattner24943d22010-06-08 16:52:24 +0000179}
Jim Ingham7508e732010-08-09 23:31:02 +0000180
181bool
182ObjectFile::SetModulesArchitecture (const ArchSpec &new_arch)
183{
184 return m_module->SetArchitecture (new_arch);
185}
186
Greg Claytonb3448432011-03-24 21:19:54 +0000187AddressClass
Greg Claytone40b6422011-09-18 18:59:15 +0000188ObjectFile::GetAddressClass (addr_t file_addr)
Greg Claytonb1888f22011-03-19 01:12:21 +0000189{
190 Symtab *symtab = GetSymtab();
191 if (symtab)
192 {
193 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
194 if (symbol)
195 {
196 const AddressRange *range_ptr = symbol->GetAddressRangePtr();
197 if (range_ptr)
198 {
199 const Section *section = range_ptr->GetBaseAddress().GetSection();
200 if (section)
201 {
Greg Claytonb3448432011-03-24 21:19:54 +0000202 const SectionType section_type = section->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000203 switch (section_type)
204 {
205 case eSectionTypeInvalid: return eAddressClassUnknown;
206 case eSectionTypeCode: return eAddressClassCode;
207 case eSectionTypeContainer: return eAddressClassUnknown;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000208 case eSectionTypeData:
209 case eSectionTypeDataCString:
210 case eSectionTypeDataCStringPointers:
211 case eSectionTypeDataSymbolAddress:
212 case eSectionTypeData4:
213 case eSectionTypeData8:
214 case eSectionTypeData16:
215 case eSectionTypeDataPointers:
216 case eSectionTypeZeroFill:
217 case eSectionTypeDataObjCMessageRefs:
218 case eSectionTypeDataObjCCFStrings:
219 return eAddressClassData;
220 case eSectionTypeDebug:
221 case eSectionTypeDWARFDebugAbbrev:
222 case eSectionTypeDWARFDebugAranges:
223 case eSectionTypeDWARFDebugFrame:
224 case eSectionTypeDWARFDebugInfo:
225 case eSectionTypeDWARFDebugLine:
226 case eSectionTypeDWARFDebugLoc:
227 case eSectionTypeDWARFDebugMacInfo:
228 case eSectionTypeDWARFDebugPubNames:
229 case eSectionTypeDWARFDebugPubTypes:
230 case eSectionTypeDWARFDebugRanges:
231 case eSectionTypeDWARFDebugStr:
232 case eSectionTypeDWARFAppleNames:
233 case eSectionTypeDWARFAppleTypes:
234 case eSectionTypeDWARFAppleNamespaces:
235 case eSectionTypeDWARFAppleObjC:
236 return eAddressClassDebug;
Greg Claytonb1888f22011-03-19 01:12:21 +0000237 case eSectionTypeEHFrame: return eAddressClassRuntime;
238 case eSectionTypeOther: return eAddressClassUnknown;
239 }
240 }
241 }
242
Greg Claytonb3448432011-03-24 21:19:54 +0000243 const SymbolType symbol_type = symbol->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000244 switch (symbol_type)
245 {
246 case eSymbolTypeAny: return eAddressClassUnknown;
247 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Greg Claytonb1888f22011-03-19 01:12:21 +0000248 case eSymbolTypeCode: return eAddressClassCode;
249 case eSymbolTypeTrampoline: return eAddressClassCode;
250 case eSymbolTypeData: return eAddressClassData;
251 case eSymbolTypeRuntime: return eAddressClassRuntime;
252 case eSymbolTypeException: return eAddressClassRuntime;
253 case eSymbolTypeSourceFile: return eAddressClassDebug;
254 case eSymbolTypeHeaderFile: return eAddressClassDebug;
255 case eSymbolTypeObjectFile: return eAddressClassDebug;
256 case eSymbolTypeCommonBlock: return eAddressClassDebug;
257 case eSymbolTypeBlock: return eAddressClassDebug;
258 case eSymbolTypeLocal: return eAddressClassData;
259 case eSymbolTypeParam: return eAddressClassData;
260 case eSymbolTypeVariable: return eAddressClassData;
261 case eSymbolTypeVariableType: return eAddressClassDebug;
262 case eSymbolTypeLineEntry: return eAddressClassDebug;
263 case eSymbolTypeLineHeader: return eAddressClassDebug;
264 case eSymbolTypeScopeBegin: return eAddressClassDebug;
265 case eSymbolTypeScopeEnd: return eAddressClassDebug;
266 case eSymbolTypeAdditional: return eAddressClassUnknown;
267 case eSymbolTypeCompiler: return eAddressClassDebug;
268 case eSymbolTypeInstrumentation:return eAddressClassDebug;
269 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton3f69eac2011-12-03 02:30:59 +0000270 case eSymbolTypeObjCClass: return eAddressClassRuntime;
271 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
272 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Claytonb1888f22011-03-19 01:12:21 +0000273 }
274 }
275 }
276 return eAddressClassUnknown;
277}
278
Greg Claytone40b6422011-09-18 18:59:15 +0000279ObjectFileSP
280ObjectFile::GetSP ()
281{
282 // This object contains an instrusive ref count base class so we can
283 // easily make a shared pointer to this object
284 return ObjectFileSP (this);
285}
286
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000287size_t
288ObjectFile::GetData (off_t offset, size_t length, DataExtractor &data) const
289{
290 // The entire file has already been mmap'ed into m_data, so just copy from there
291 // as the back mmap buffer will be shared with shared pointers.
292 return data.SetData (m_data, offset, length);
293}
294
295size_t
296ObjectFile::CopyData (off_t offset, size_t length, void *dst) const
297{
298 // The entire file has already been mmap'ed into m_data, so just copy from there
299 return m_data.CopyByteOrderedData (offset, length, dst, length, lldb::endian::InlHostByteOrder());
300}
Greg Claytonb1888f22011-03-19 01:12:21 +0000301