blob: 7411c0cdf5f109a51a4fbf13eef9f5582dbb5b3e [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;
201 case eSectionTypeData: return eAddressClassData;
Greg Claytonb3448432011-03-24 21:19:54 +0000202 case eSectionTypeDataCString: return eAddressClassData;
Greg Claytonb1888f22011-03-19 01:12:21 +0000203 case eSectionTypeDataCStringPointers: return eAddressClassData;
204 case eSectionTypeDataSymbolAddress: return eAddressClassData;
205 case eSectionTypeData4: return eAddressClassData;
206 case eSectionTypeData8: return eAddressClassData;
207 case eSectionTypeData16: return eAddressClassData;
208 case eSectionTypeDataPointers: return eAddressClassData;
209 case eSectionTypeZeroFill: return eAddressClassData;
Greg Claytonb3448432011-03-24 21:19:54 +0000210 case eSectionTypeDataObjCMessageRefs: return eAddressClassData;
211 case eSectionTypeDataObjCCFStrings: return eAddressClassData;
Greg Claytonb1888f22011-03-19 01:12:21 +0000212 case eSectionTypeDebug: return eAddressClassDebug;
213 case eSectionTypeDWARFDebugAbbrev: return eAddressClassDebug;
214 case eSectionTypeDWARFDebugAranges: return eAddressClassDebug;
215 case eSectionTypeDWARFDebugFrame: return eAddressClassDebug;
216 case eSectionTypeDWARFDebugInfo: return eAddressClassDebug;
217 case eSectionTypeDWARFDebugLine: return eAddressClassDebug;
218 case eSectionTypeDWARFDebugLoc: return eAddressClassDebug;
219 case eSectionTypeDWARFDebugMacInfo: return eAddressClassDebug;
220 case eSectionTypeDWARFDebugPubNames: return eAddressClassDebug;
221 case eSectionTypeDWARFDebugPubTypes: return eAddressClassDebug;
222 case eSectionTypeDWARFDebugRanges: return eAddressClassDebug;
223 case eSectionTypeDWARFDebugStr: return eAddressClassDebug;
Greg Claytonc8cf5e22011-09-01 23:16:13 +0000224 case eSectionTypeDWARFDebugNames: return eAddressClassDebug;
225 case eSectionTypeDWARFDebugTypes: return eAddressClassDebug;
Greg Claytonb1888f22011-03-19 01:12:21 +0000226 case eSectionTypeEHFrame: return eAddressClassRuntime;
227 case eSectionTypeOther: return eAddressClassUnknown;
228 }
229 }
230 }
231
Greg Claytonb3448432011-03-24 21:19:54 +0000232 const SymbolType symbol_type = symbol->GetType();
Greg Claytonb1888f22011-03-19 01:12:21 +0000233 switch (symbol_type)
234 {
235 case eSymbolTypeAny: return eAddressClassUnknown;
236 case eSymbolTypeAbsolute: return eAddressClassUnknown;
237 case eSymbolTypeExtern: return eAddressClassUnknown;
238 case eSymbolTypeCode: return eAddressClassCode;
239 case eSymbolTypeTrampoline: return eAddressClassCode;
240 case eSymbolTypeData: return eAddressClassData;
241 case eSymbolTypeRuntime: return eAddressClassRuntime;
242 case eSymbolTypeException: return eAddressClassRuntime;
243 case eSymbolTypeSourceFile: return eAddressClassDebug;
244 case eSymbolTypeHeaderFile: return eAddressClassDebug;
245 case eSymbolTypeObjectFile: return eAddressClassDebug;
246 case eSymbolTypeCommonBlock: return eAddressClassDebug;
247 case eSymbolTypeBlock: return eAddressClassDebug;
248 case eSymbolTypeLocal: return eAddressClassData;
249 case eSymbolTypeParam: return eAddressClassData;
250 case eSymbolTypeVariable: return eAddressClassData;
251 case eSymbolTypeVariableType: return eAddressClassDebug;
252 case eSymbolTypeLineEntry: return eAddressClassDebug;
253 case eSymbolTypeLineHeader: return eAddressClassDebug;
254 case eSymbolTypeScopeBegin: return eAddressClassDebug;
255 case eSymbolTypeScopeEnd: return eAddressClassDebug;
256 case eSymbolTypeAdditional: return eAddressClassUnknown;
257 case eSymbolTypeCompiler: return eAddressClassDebug;
258 case eSymbolTypeInstrumentation:return eAddressClassDebug;
259 case eSymbolTypeUndefined: return eAddressClassUnknown;
260 }
261 }
262 }
263 return eAddressClassUnknown;
264}
265
Greg Claytone40b6422011-09-18 18:59:15 +0000266ObjectFileSP
267ObjectFile::GetSP ()
268{
269 // This object contains an instrusive ref count base class so we can
270 // easily make a shared pointer to this object
271 return ObjectFileSP (this);
272}
273
Greg Claytonb1888f22011-03-19 01:12:21 +0000274