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