blob: f3839c0f1d376c39e1e1ba86f1766bad4216d932 [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"
12#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000013#include "lldb/Core/Module.h"
14#include "lldb/Core/PluginManager.h"
15#include "lldb/Core/RegularExpression.h"
16#include "lldb/Core/Timer.h"
17#include "lldb/Symbol/ObjectFile.h"
18#include "lldb/Symbol/ObjectContainer.h"
19#include "lldb/Symbol/SymbolFile.h"
20
21using namespace lldb;
22using namespace lldb_private;
23
Greg Claytone40b6422011-09-18 18:59:15 +000024ObjectFileSP
25ObjectFile::FindPlugin (Module* module, const FileSpec* file, addr_t file_offset, addr_t file_size)
Chris Lattner24943d22010-06-08 16:52:24 +000026{
27 Timer scoped_timer (__PRETTY_FUNCTION__,
28 "ObjectFile::FindPlugin (module = %s/%s, file = %p, file_offset = 0x%z8.8x, file_size = 0x%z8.8x)",
29 module->GetFileSpec().GetDirectory().AsCString(),
30 module->GetFileSpec().GetFilename().AsCString(),
31 file, file_offset, file_size);
Greg Claytone40b6422011-09-18 18:59:15 +000032 ObjectFileSP object_file_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000033
34 if (module != NULL)
35 {
36 if (file)
37 {
38 if (file_size == 0)
39 file_size = file->GetByteSize();
40
41 if (file_size == 0)
42 {
43 // Check for archive file with format "/path/to/archive.a(object.o)"
44 char path_with_object[PATH_MAX*2];
45 module->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object));
46
47 RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$");
48 if (g_object_regex.Execute (path_with_object, 2))
49 {
50 FileSpec archive_file;
51 std::string path;
52 std::string object;
53 if (g_object_regex.GetMatchAtIndex (path_with_object, 1, path) &&
54 g_object_regex.GetMatchAtIndex (path_with_object, 2, object))
55 {
Greg Clayton537a7a82010-10-20 20:54:39 +000056 archive_file.SetFile (path.c_str(), false);
Chris Lattner24943d22010-06-08 16:52:24 +000057 file_size = archive_file.GetByteSize();
58 if (file_size > 0)
59 module->SetFileSpecAndObjectName (archive_file, ConstString(object.c_str()));
60 }
61 }
62 }
63
Johnny Chen89e4bae2010-11-05 21:43:19 +000064 // No need to delegate further if (file_offset, file_size) exceeds the total file size.
65 // This is the base case.
Greg Claytonb72d0f02011-04-12 05:54:46 +000066// if (file_offset + file_size > file->GetByteSize())
67// return NULL;
Johnny Chen89e4bae2010-11-05 21:43:19 +000068
Chris Lattner24943d22010-06-08 16:52:24 +000069 DataBufferSP file_header_data_sp(file->ReadFileContents(file_offset, 512));
70 uint32_t idx;
71
72 // Check if this is a normal object file by iterating through
73 // all object file plugin instances.
74 ObjectFileCreateInstance create_object_file_callback;
75 for (idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
76 {
Greg Claytone40b6422011-09-18 18:59:15 +000077 object_file_sp.reset (create_object_file_callback(module, file_header_data_sp, file, file_offset, file_size));
78 if (object_file_sp.get())
79 return object_file_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000080 }
81
82 // Check if this is a object container by iterating through
83 // all object container plugin instances and then trying to get
84 // an object file from the container.
85 ObjectContainerCreateInstance create_object_container_callback;
86 for (idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
87 {
88 std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module, file_header_data_sp, file, file_offset, file_size));
89
90 if (object_container_ap.get())
Greg Claytone40b6422011-09-18 18:59:15 +000091 object_file_sp = object_container_ap->GetObjectFile(file);
Chris Lattner24943d22010-06-08 16:52:24 +000092
Greg Claytone40b6422011-09-18 18:59:15 +000093 if (object_file_sp.get())
94 return object_file_sp;
Chris Lattner24943d22010-06-08 16:52:24 +000095 }
96 }
97 }
Greg Claytone40b6422011-09-18 18:59:15 +000098 // We didn't find it, so clear our shared pointer in case it
99 // contains anything and return an empty shared pointer
100 object_file_sp.reset();
101 return object_file_sp;
102}
103
104ObjectFile::ObjectFile (Module* module,
105 const FileSpec *file_spec_ptr,
106 addr_t offset,
107 addr_t length,
108 DataBufferSP& headerDataSP) :
109 ModuleChild (module),
110 m_file (), // This file could be different from the original module's file
111 m_type (eTypeInvalid),
112 m_strata (eStrataInvalid),
113 m_offset (offset),
114 m_length (length),
115 m_data (headerDataSP, endian::InlHostByteOrder(), 4),
116 m_unwind_table (*this)
117{
118 if (file_spec_ptr)
119 m_file = *file_spec_ptr;
120 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
121 if (log)
122 {
123 if (m_file)
124 {
125 log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n",
126 this,
127 m_module->GetFileSpec().GetDirectory().AsCString(),
128 m_module->GetFileSpec().GetFilename().AsCString(),
129 m_file.GetDirectory().AsCString(),
130 m_file.GetFilename().AsCString(),
131 m_offset,
132 m_length);
133 }
134 else
135 {
136 log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n",
137 this,
138 m_module->GetFileSpec().GetDirectory().AsCString(),
139 m_module->GetFileSpec().GetFilename().AsCString(),
140 m_offset,
141 m_length);
142 }
143 }
144}
145
146ObjectFile::~ObjectFile()
147{
148 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
149 if (log)
150 {
151 if (m_file)
152 {
153 log->Printf ("%p ObjectFile::~ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n",
154 this,
155 m_module->GetFileSpec().GetDirectory().AsCString(),
156 m_module->GetFileSpec().GetFilename().AsCString(),
157 m_file.GetDirectory().AsCString(),
158 m_file.GetFilename().AsCString(),
159 m_offset,
160 m_length);
161 }
162 else
163 {
164 log->Printf ("%p ObjectFile::~ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n",
165 this,
166 m_module->GetFileSpec().GetDirectory().AsCString(),
167 m_module->GetFileSpec().GetFilename().AsCString(),
168 m_offset,
169 m_length);
170 }
171 }
Chris Lattner24943d22010-06-08 16:52:24 +0000172}
Jim Ingham7508e732010-08-09 23:31:02 +0000173
174bool
175ObjectFile::SetModulesArchitecture (const ArchSpec &new_arch)
176{
177 return m_module->SetArchitecture (new_arch);
178}
179
Greg Claytonb3448432011-03-24 21:19:54 +0000180AddressClass
Greg Claytone40b6422011-09-18 18:59:15 +0000181ObjectFile::GetAddressClass (addr_t file_addr)
Greg Claytonb1888f22011-03-19 01:12:21 +0000182{
183 Symtab *symtab = GetSymtab();
184 if (symtab)
185 {
186 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
187 if (symbol)
188 {
189 const AddressRange *range_ptr = symbol->GetAddressRangePtr();
190 if (range_ptr)
191 {
192 const Section *section = range_ptr->GetBaseAddress().GetSection();
193 if (section)
194 {
Greg Claytonb3448432011-03-24 21:19:54 +0000195 const SectionType section_type = section->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000196 switch (section_type)
197 {
198 case eSectionTypeInvalid: return eAddressClassUnknown;
199 case eSectionTypeCode: return eAddressClassCode;
200 case eSectionTypeContainer: return eAddressClassUnknown;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000201 case eSectionTypeData:
202 case eSectionTypeDataCString:
203 case eSectionTypeDataCStringPointers:
204 case eSectionTypeDataSymbolAddress:
205 case eSectionTypeData4:
206 case eSectionTypeData8:
207 case eSectionTypeData16:
208 case eSectionTypeDataPointers:
209 case eSectionTypeZeroFill:
210 case eSectionTypeDataObjCMessageRefs:
211 case eSectionTypeDataObjCCFStrings:
212 return eAddressClassData;
213 case eSectionTypeDebug:
214 case eSectionTypeDWARFDebugAbbrev:
215 case eSectionTypeDWARFDebugAranges:
216 case eSectionTypeDWARFDebugFrame:
217 case eSectionTypeDWARFDebugInfo:
218 case eSectionTypeDWARFDebugLine:
219 case eSectionTypeDWARFDebugLoc:
220 case eSectionTypeDWARFDebugMacInfo:
221 case eSectionTypeDWARFDebugPubNames:
222 case eSectionTypeDWARFDebugPubTypes:
223 case eSectionTypeDWARFDebugRanges:
224 case eSectionTypeDWARFDebugStr:
225 case eSectionTypeDWARFAppleNames:
226 case eSectionTypeDWARFAppleTypes:
227 case eSectionTypeDWARFAppleNamespaces:
228 case eSectionTypeDWARFAppleObjC:
229 return eAddressClassDebug;
Greg Claytonb1888f22011-03-19 01:12:21 +0000230 case eSectionTypeEHFrame: return eAddressClassRuntime;
231 case eSectionTypeOther: return eAddressClassUnknown;
232 }
233 }
234 }
235
Greg Claytonb3448432011-03-24 21:19:54 +0000236 const SymbolType symbol_type = symbol->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000237 switch (symbol_type)
238 {
239 case eSymbolTypeAny: return eAddressClassUnknown;
240 case eSymbolTypeAbsolute: return eAddressClassUnknown;
Greg Claytonb1888f22011-03-19 01:12:21 +0000241 case eSymbolTypeCode: return eAddressClassCode;
242 case eSymbolTypeTrampoline: return eAddressClassCode;
243 case eSymbolTypeData: return eAddressClassData;
244 case eSymbolTypeRuntime: return eAddressClassRuntime;
245 case eSymbolTypeException: return eAddressClassRuntime;
246 case eSymbolTypeSourceFile: return eAddressClassDebug;
247 case eSymbolTypeHeaderFile: return eAddressClassDebug;
248 case eSymbolTypeObjectFile: return eAddressClassDebug;
249 case eSymbolTypeCommonBlock: return eAddressClassDebug;
250 case eSymbolTypeBlock: return eAddressClassDebug;
251 case eSymbolTypeLocal: return eAddressClassData;
252 case eSymbolTypeParam: return eAddressClassData;
253 case eSymbolTypeVariable: return eAddressClassData;
254 case eSymbolTypeVariableType: return eAddressClassDebug;
255 case eSymbolTypeLineEntry: return eAddressClassDebug;
256 case eSymbolTypeLineHeader: return eAddressClassDebug;
257 case eSymbolTypeScopeBegin: return eAddressClassDebug;
258 case eSymbolTypeScopeEnd: return eAddressClassDebug;
259 case eSymbolTypeAdditional: return eAddressClassUnknown;
260 case eSymbolTypeCompiler: return eAddressClassDebug;
261 case eSymbolTypeInstrumentation:return eAddressClassDebug;
262 case eSymbolTypeUndefined: return eAddressClassUnknown;
Greg Clayton3f69eac2011-12-03 02:30:59 +0000263 case eSymbolTypeObjCClass: return eAddressClassRuntime;
264 case eSymbolTypeObjCMetaClass: return eAddressClassRuntime;
265 case eSymbolTypeObjCIVar: return eAddressClassRuntime;
Greg Claytonb1888f22011-03-19 01:12:21 +0000266 }
267 }
268 }
269 return eAddressClassUnknown;
270}
271
Greg Claytone40b6422011-09-18 18:59:15 +0000272ObjectFileSP
273ObjectFile::GetSP ()
274{
275 // This object contains an instrusive ref count base class so we can
276 // easily make a shared pointer to this object
277 return ObjectFileSP (this);
278}
279
Greg Claytonb1888f22011-03-19 01:12:21 +0000280