130fdc8d8SChris Lattner //===-- ObjectFile.cpp ------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "lldb/lldb-private.h"
11762f7135SGreg Clayton #include "lldb/lldb-private-log.h"
12762f7135SGreg Clayton #include "lldb/Core/Log.h"
1330fdc8d8SChris Lattner #include "lldb/Core/Module.h"
1430fdc8d8SChris Lattner #include "lldb/Core/PluginManager.h"
1530fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
1630fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
1730fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
1830fdc8d8SChris Lattner #include "lldb/Symbol/ObjectContainer.h"
1930fdc8d8SChris Lattner #include "lldb/Symbol/SymbolFile.h"
2030fdc8d8SChris Lattner 
2130fdc8d8SChris Lattner using namespace lldb;
2230fdc8d8SChris Lattner using namespace lldb_private;
2330fdc8d8SChris Lattner 
24762f7135SGreg Clayton ObjectFileSP
25762f7135SGreg Clayton ObjectFile::FindPlugin (Module* module, const FileSpec* file, addr_t file_offset, addr_t file_size)
2630fdc8d8SChris Lattner {
2730fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
2830fdc8d8SChris Lattner                         "ObjectFile::FindPlugin (module = %s/%s, file = %p, file_offset = 0x%z8.8x, file_size = 0x%z8.8x)",
2930fdc8d8SChris Lattner                         module->GetFileSpec().GetDirectory().AsCString(),
3030fdc8d8SChris Lattner                         module->GetFileSpec().GetFilename().AsCString(),
3130fdc8d8SChris Lattner                         file, file_offset, file_size);
32762f7135SGreg Clayton     ObjectFileSP object_file_sp;
3330fdc8d8SChris Lattner 
3430fdc8d8SChris Lattner     if (module != NULL)
3530fdc8d8SChris Lattner     {
3630fdc8d8SChris Lattner         if (file)
3730fdc8d8SChris Lattner         {
3830fdc8d8SChris Lattner             if (file_size == 0)
3930fdc8d8SChris Lattner                 file_size = file->GetByteSize();
4030fdc8d8SChris Lattner 
4130fdc8d8SChris Lattner             if (file_size == 0)
4230fdc8d8SChris Lattner             {
4330fdc8d8SChris Lattner                 // Check for archive file with format "/path/to/archive.a(object.o)"
4430fdc8d8SChris Lattner                 char path_with_object[PATH_MAX*2];
4530fdc8d8SChris Lattner                 module->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object));
4630fdc8d8SChris Lattner 
4730fdc8d8SChris Lattner                 RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$");
4830fdc8d8SChris Lattner                 if (g_object_regex.Execute (path_with_object, 2))
4930fdc8d8SChris Lattner                 {
5030fdc8d8SChris Lattner                     FileSpec archive_file;
5130fdc8d8SChris Lattner                     std::string path;
5230fdc8d8SChris Lattner                     std::string object;
5330fdc8d8SChris Lattner                     if (g_object_regex.GetMatchAtIndex (path_with_object, 1, path) &&
5430fdc8d8SChris Lattner                         g_object_regex.GetMatchAtIndex (path_with_object, 2, object))
5530fdc8d8SChris Lattner                     {
56274060b6SGreg Clayton                         archive_file.SetFile (path.c_str(), false);
5730fdc8d8SChris Lattner                         file_size = archive_file.GetByteSize();
5830fdc8d8SChris Lattner                         if (file_size > 0)
5930fdc8d8SChris Lattner                             module->SetFileSpecAndObjectName (archive_file, ConstString(object.c_str()));
6030fdc8d8SChris Lattner                     }
6130fdc8d8SChris Lattner                 }
6230fdc8d8SChris Lattner             }
6330fdc8d8SChris Lattner 
6476c381b6SJohnny Chen             // No need to delegate further if (file_offset, file_size) exceeds the total file size.
6576c381b6SJohnny Chen             // This is the base case.
668b82f087SGreg Clayton //            if (file_offset + file_size > file->GetByteSize())
678b82f087SGreg Clayton //                return NULL;
6876c381b6SJohnny Chen 
6930fdc8d8SChris Lattner             DataBufferSP file_header_data_sp(file->ReadFileContents(file_offset, 512));
7030fdc8d8SChris Lattner             uint32_t idx;
7130fdc8d8SChris Lattner 
7230fdc8d8SChris Lattner             // Check if this is a normal object file by iterating through
7330fdc8d8SChris Lattner             // all object file plugin instances.
7430fdc8d8SChris Lattner             ObjectFileCreateInstance create_object_file_callback;
7530fdc8d8SChris Lattner             for (idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
7630fdc8d8SChris Lattner             {
77762f7135SGreg Clayton                 object_file_sp.reset (create_object_file_callback(module, file_header_data_sp, file, file_offset, file_size));
78762f7135SGreg Clayton                 if (object_file_sp.get())
79762f7135SGreg Clayton                     return object_file_sp;
8030fdc8d8SChris Lattner             }
8130fdc8d8SChris Lattner 
8230fdc8d8SChris Lattner             // Check if this is a object container by iterating through
8330fdc8d8SChris Lattner             // all object container plugin instances and then trying to get
8430fdc8d8SChris Lattner             // an object file from the container.
8530fdc8d8SChris Lattner             ObjectContainerCreateInstance create_object_container_callback;
8630fdc8d8SChris Lattner             for (idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
8730fdc8d8SChris Lattner             {
8830fdc8d8SChris Lattner                 std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module, file_header_data_sp, file, file_offset, file_size));
8930fdc8d8SChris Lattner 
9030fdc8d8SChris Lattner                 if (object_container_ap.get())
91762f7135SGreg Clayton                     object_file_sp = object_container_ap->GetObjectFile(file);
9230fdc8d8SChris Lattner 
93762f7135SGreg Clayton                 if (object_file_sp.get())
94762f7135SGreg Clayton                     return object_file_sp;
9530fdc8d8SChris Lattner             }
9630fdc8d8SChris Lattner         }
9730fdc8d8SChris Lattner     }
98762f7135SGreg Clayton     // We didn't find it, so clear our shared pointer in case it
99762f7135SGreg Clayton     // contains anything and return an empty shared pointer
100762f7135SGreg Clayton     object_file_sp.reset();
101762f7135SGreg Clayton     return object_file_sp;
102762f7135SGreg Clayton }
103762f7135SGreg Clayton 
104762f7135SGreg Clayton ObjectFile::ObjectFile (Module* module,
105762f7135SGreg Clayton                         const FileSpec *file_spec_ptr,
106762f7135SGreg Clayton                         addr_t offset,
107762f7135SGreg Clayton                         addr_t length,
108762f7135SGreg Clayton                         DataBufferSP& headerDataSP) :
109762f7135SGreg Clayton     ModuleChild (module),
110762f7135SGreg Clayton     m_file (),  // This file could be different from the original module's file
111762f7135SGreg Clayton     m_type (eTypeInvalid),
112762f7135SGreg Clayton     m_strata (eStrataInvalid),
113762f7135SGreg Clayton     m_offset (offset),
114762f7135SGreg Clayton     m_length (length),
115762f7135SGreg Clayton     m_data (headerDataSP, endian::InlHostByteOrder(), 4),
116762f7135SGreg Clayton     m_unwind_table (*this)
117762f7135SGreg Clayton {
118762f7135SGreg Clayton     if (file_spec_ptr)
119762f7135SGreg Clayton         m_file = *file_spec_ptr;
120762f7135SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
121762f7135SGreg Clayton     if (log)
122762f7135SGreg Clayton     {
123762f7135SGreg Clayton         if (m_file)
124762f7135SGreg Clayton         {
125762f7135SGreg Clayton             log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n",
126762f7135SGreg Clayton                          this,
127762f7135SGreg Clayton                          m_module->GetFileSpec().GetDirectory().AsCString(),
128762f7135SGreg Clayton                          m_module->GetFileSpec().GetFilename().AsCString(),
129762f7135SGreg Clayton                          m_file.GetDirectory().AsCString(),
130762f7135SGreg Clayton                          m_file.GetFilename().AsCString(),
131762f7135SGreg Clayton                          m_offset,
132762f7135SGreg Clayton                          m_length);
133762f7135SGreg Clayton         }
134762f7135SGreg Clayton         else
135762f7135SGreg Clayton         {
136762f7135SGreg Clayton             log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n",
137762f7135SGreg Clayton                          this,
138762f7135SGreg Clayton                          m_module->GetFileSpec().GetDirectory().AsCString(),
139762f7135SGreg Clayton                          m_module->GetFileSpec().GetFilename().AsCString(),
140762f7135SGreg Clayton                          m_offset,
141762f7135SGreg Clayton                          m_length);
142762f7135SGreg Clayton         }
143762f7135SGreg Clayton     }
144762f7135SGreg Clayton }
145762f7135SGreg Clayton 
146762f7135SGreg Clayton ObjectFile::~ObjectFile()
147762f7135SGreg Clayton {
148762f7135SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
149762f7135SGreg Clayton     if (log)
150762f7135SGreg Clayton     {
151762f7135SGreg Clayton         if (m_file)
152762f7135SGreg Clayton         {
153762f7135SGreg Clayton             log->Printf ("%p ObjectFile::~ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n",
154762f7135SGreg Clayton                          this,
155762f7135SGreg Clayton                          m_module->GetFileSpec().GetDirectory().AsCString(),
156762f7135SGreg Clayton                          m_module->GetFileSpec().GetFilename().AsCString(),
157762f7135SGreg Clayton                          m_file.GetDirectory().AsCString(),
158762f7135SGreg Clayton                          m_file.GetFilename().AsCString(),
159762f7135SGreg Clayton                          m_offset,
160762f7135SGreg Clayton                          m_length);
161762f7135SGreg Clayton         }
162762f7135SGreg Clayton         else
163762f7135SGreg Clayton         {
164762f7135SGreg Clayton             log->Printf ("%p ObjectFile::~ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n",
165762f7135SGreg Clayton                          this,
166762f7135SGreg Clayton                          m_module->GetFileSpec().GetDirectory().AsCString(),
167762f7135SGreg Clayton                          m_module->GetFileSpec().GetFilename().AsCString(),
168762f7135SGreg Clayton                          m_offset,
169762f7135SGreg Clayton                          m_length);
170762f7135SGreg Clayton         }
171762f7135SGreg Clayton     }
17230fdc8d8SChris Lattner }
1735aee162fSJim Ingham 
1745aee162fSJim Ingham bool
1755aee162fSJim Ingham ObjectFile::SetModulesArchitecture (const ArchSpec &new_arch)
1765aee162fSJim Ingham {
1775aee162fSJim Ingham     return m_module->SetArchitecture (new_arch);
1785aee162fSJim Ingham }
1795aee162fSJim Ingham 
180e0d378b3SGreg Clayton AddressClass
181762f7135SGreg Clayton ObjectFile::GetAddressClass (addr_t file_addr)
182ded470d3SGreg Clayton {
183ded470d3SGreg Clayton     Symtab *symtab = GetSymtab();
184ded470d3SGreg Clayton     if (symtab)
185ded470d3SGreg Clayton     {
186ded470d3SGreg Clayton         Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
187ded470d3SGreg Clayton         if (symbol)
188ded470d3SGreg Clayton         {
189ded470d3SGreg Clayton             const AddressRange *range_ptr = symbol->GetAddressRangePtr();
190ded470d3SGreg Clayton             if (range_ptr)
191ded470d3SGreg Clayton             {
192ded470d3SGreg Clayton                 const Section *section = range_ptr->GetBaseAddress().GetSection();
193ded470d3SGreg Clayton                 if (section)
194ded470d3SGreg Clayton                 {
195e0d378b3SGreg Clayton                     const SectionType section_type = section->GetType();
196ded470d3SGreg Clayton                     switch (section_type)
197ded470d3SGreg Clayton                     {
198ded470d3SGreg Clayton                     case eSectionTypeInvalid:               return eAddressClassUnknown;
199ded470d3SGreg Clayton                     case eSectionTypeCode:                  return eAddressClassCode;
200ded470d3SGreg Clayton                     case eSectionTypeContainer:             return eAddressClassUnknown;
2015009f9d5SGreg Clayton                     case eSectionTypeData:
2025009f9d5SGreg Clayton                     case eSectionTypeDataCString:
2035009f9d5SGreg Clayton                     case eSectionTypeDataCStringPointers:
2045009f9d5SGreg Clayton                     case eSectionTypeDataSymbolAddress:
2055009f9d5SGreg Clayton                     case eSectionTypeData4:
2065009f9d5SGreg Clayton                     case eSectionTypeData8:
2075009f9d5SGreg Clayton                     case eSectionTypeData16:
2085009f9d5SGreg Clayton                     case eSectionTypeDataPointers:
2095009f9d5SGreg Clayton                     case eSectionTypeZeroFill:
2105009f9d5SGreg Clayton                     case eSectionTypeDataObjCMessageRefs:
2115009f9d5SGreg Clayton                     case eSectionTypeDataObjCCFStrings:
2125009f9d5SGreg Clayton                         return eAddressClassData;
2135009f9d5SGreg Clayton                     case eSectionTypeDebug:
2145009f9d5SGreg Clayton                     case eSectionTypeDWARFDebugAbbrev:
2155009f9d5SGreg Clayton                     case eSectionTypeDWARFDebugAranges:
2165009f9d5SGreg Clayton                     case eSectionTypeDWARFDebugFrame:
2175009f9d5SGreg Clayton                     case eSectionTypeDWARFDebugInfo:
2185009f9d5SGreg Clayton                     case eSectionTypeDWARFDebugLine:
2195009f9d5SGreg Clayton                     case eSectionTypeDWARFDebugLoc:
2205009f9d5SGreg Clayton                     case eSectionTypeDWARFDebugMacInfo:
2215009f9d5SGreg Clayton                     case eSectionTypeDWARFDebugPubNames:
2225009f9d5SGreg Clayton                     case eSectionTypeDWARFDebugPubTypes:
2235009f9d5SGreg Clayton                     case eSectionTypeDWARFDebugRanges:
2245009f9d5SGreg Clayton                     case eSectionTypeDWARFDebugStr:
2255009f9d5SGreg Clayton                     case eSectionTypeDWARFAppleNames:
2265009f9d5SGreg Clayton                     case eSectionTypeDWARFAppleTypes:
2275009f9d5SGreg Clayton                     case eSectionTypeDWARFAppleNamespaces:
2285009f9d5SGreg Clayton                     case eSectionTypeDWARFAppleObjC:
2295009f9d5SGreg Clayton                         return eAddressClassDebug;
230ded470d3SGreg Clayton                     case eSectionTypeEHFrame:               return eAddressClassRuntime;
231ded470d3SGreg Clayton                     case eSectionTypeOther:                 return eAddressClassUnknown;
232ded470d3SGreg Clayton                     }
233ded470d3SGreg Clayton                 }
234ded470d3SGreg Clayton             }
235ded470d3SGreg Clayton 
236e0d378b3SGreg Clayton             const SymbolType symbol_type = symbol->GetType();
237ded470d3SGreg Clayton             switch (symbol_type)
238ded470d3SGreg Clayton             {
239ded470d3SGreg Clayton             case eSymbolTypeAny:            return eAddressClassUnknown;
240ded470d3SGreg Clayton             case eSymbolTypeAbsolute:       return eAddressClassUnknown;
241ded470d3SGreg Clayton             case eSymbolTypeCode:           return eAddressClassCode;
242ded470d3SGreg Clayton             case eSymbolTypeTrampoline:     return eAddressClassCode;
243ded470d3SGreg Clayton             case eSymbolTypeData:           return eAddressClassData;
244ded470d3SGreg Clayton             case eSymbolTypeRuntime:        return eAddressClassRuntime;
245ded470d3SGreg Clayton             case eSymbolTypeException:      return eAddressClassRuntime;
246ded470d3SGreg Clayton             case eSymbolTypeSourceFile:     return eAddressClassDebug;
247ded470d3SGreg Clayton             case eSymbolTypeHeaderFile:     return eAddressClassDebug;
248ded470d3SGreg Clayton             case eSymbolTypeObjectFile:     return eAddressClassDebug;
249ded470d3SGreg Clayton             case eSymbolTypeCommonBlock:    return eAddressClassDebug;
250ded470d3SGreg Clayton             case eSymbolTypeBlock:          return eAddressClassDebug;
251ded470d3SGreg Clayton             case eSymbolTypeLocal:          return eAddressClassData;
252ded470d3SGreg Clayton             case eSymbolTypeParam:          return eAddressClassData;
253ded470d3SGreg Clayton             case eSymbolTypeVariable:       return eAddressClassData;
254ded470d3SGreg Clayton             case eSymbolTypeVariableType:   return eAddressClassDebug;
255ded470d3SGreg Clayton             case eSymbolTypeLineEntry:      return eAddressClassDebug;
256ded470d3SGreg Clayton             case eSymbolTypeLineHeader:     return eAddressClassDebug;
257ded470d3SGreg Clayton             case eSymbolTypeScopeBegin:     return eAddressClassDebug;
258ded470d3SGreg Clayton             case eSymbolTypeScopeEnd:       return eAddressClassDebug;
259ded470d3SGreg Clayton             case eSymbolTypeAdditional:     return eAddressClassUnknown;
260ded470d3SGreg Clayton             case eSymbolTypeCompiler:       return eAddressClassDebug;
261ded470d3SGreg Clayton             case eSymbolTypeInstrumentation:return eAddressClassDebug;
262ded470d3SGreg Clayton             case eSymbolTypeUndefined:      return eAddressClassUnknown;
263*456809c1SGreg Clayton             case eSymbolTypeObjCClass:      return eAddressClassRuntime;
264*456809c1SGreg Clayton             case eSymbolTypeObjCMetaClass:  return eAddressClassRuntime;
265*456809c1SGreg Clayton             case eSymbolTypeObjCIVar:       return eAddressClassRuntime;
266ded470d3SGreg Clayton             }
267ded470d3SGreg Clayton         }
268ded470d3SGreg Clayton     }
269ded470d3SGreg Clayton     return eAddressClassUnknown;
270ded470d3SGreg Clayton }
271ded470d3SGreg Clayton 
272762f7135SGreg Clayton ObjectFileSP
273762f7135SGreg Clayton ObjectFile::GetSP ()
274762f7135SGreg Clayton {
275762f7135SGreg Clayton     // This object contains an instrusive ref count base class so we can
276762f7135SGreg Clayton     // easily make a shared pointer to this object
277762f7135SGreg Clayton     return ObjectFileSP (this);
278762f7135SGreg Clayton }
279762f7135SGreg Clayton 
280ded470d3SGreg Clayton 
281