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" 11*762f7135SGreg Clayton #include "lldb/lldb-private-log.h" 12*762f7135SGreg 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 24*762f7135SGreg Clayton ObjectFileSP 25*762f7135SGreg 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); 32*762f7135SGreg 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 { 77*762f7135SGreg Clayton object_file_sp.reset (create_object_file_callback(module, file_header_data_sp, file, file_offset, file_size)); 78*762f7135SGreg Clayton if (object_file_sp.get()) 79*762f7135SGreg 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()) 91*762f7135SGreg Clayton object_file_sp = object_container_ap->GetObjectFile(file); 9230fdc8d8SChris Lattner 93*762f7135SGreg Clayton if (object_file_sp.get()) 94*762f7135SGreg Clayton return object_file_sp; 9530fdc8d8SChris Lattner } 9630fdc8d8SChris Lattner } 9730fdc8d8SChris Lattner } 98*762f7135SGreg Clayton // We didn't find it, so clear our shared pointer in case it 99*762f7135SGreg Clayton // contains anything and return an empty shared pointer 100*762f7135SGreg Clayton object_file_sp.reset(); 101*762f7135SGreg Clayton return object_file_sp; 102*762f7135SGreg Clayton } 103*762f7135SGreg Clayton 104*762f7135SGreg Clayton ObjectFile::ObjectFile (Module* module, 105*762f7135SGreg Clayton const FileSpec *file_spec_ptr, 106*762f7135SGreg Clayton addr_t offset, 107*762f7135SGreg Clayton addr_t length, 108*762f7135SGreg Clayton DataBufferSP& headerDataSP) : 109*762f7135SGreg Clayton ModuleChild (module), 110*762f7135SGreg Clayton m_file (), // This file could be different from the original module's file 111*762f7135SGreg Clayton m_type (eTypeInvalid), 112*762f7135SGreg Clayton m_strata (eStrataInvalid), 113*762f7135SGreg Clayton m_offset (offset), 114*762f7135SGreg Clayton m_length (length), 115*762f7135SGreg Clayton m_data (headerDataSP, endian::InlHostByteOrder(), 4), 116*762f7135SGreg Clayton m_unwind_table (*this) 117*762f7135SGreg Clayton { 118*762f7135SGreg Clayton if (file_spec_ptr) 119*762f7135SGreg Clayton m_file = *file_spec_ptr; 120*762f7135SGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 121*762f7135SGreg Clayton if (log) 122*762f7135SGreg Clayton { 123*762f7135SGreg Clayton if (m_file) 124*762f7135SGreg Clayton { 125*762f7135SGreg Clayton log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n", 126*762f7135SGreg Clayton this, 127*762f7135SGreg Clayton m_module->GetFileSpec().GetDirectory().AsCString(), 128*762f7135SGreg Clayton m_module->GetFileSpec().GetFilename().AsCString(), 129*762f7135SGreg Clayton m_file.GetDirectory().AsCString(), 130*762f7135SGreg Clayton m_file.GetFilename().AsCString(), 131*762f7135SGreg Clayton m_offset, 132*762f7135SGreg Clayton m_length); 133*762f7135SGreg Clayton } 134*762f7135SGreg Clayton else 135*762f7135SGreg Clayton { 136*762f7135SGreg Clayton log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n", 137*762f7135SGreg Clayton this, 138*762f7135SGreg Clayton m_module->GetFileSpec().GetDirectory().AsCString(), 139*762f7135SGreg Clayton m_module->GetFileSpec().GetFilename().AsCString(), 140*762f7135SGreg Clayton m_offset, 141*762f7135SGreg Clayton m_length); 142*762f7135SGreg Clayton } 143*762f7135SGreg Clayton } 144*762f7135SGreg Clayton } 145*762f7135SGreg Clayton 146*762f7135SGreg Clayton ObjectFile::~ObjectFile() 147*762f7135SGreg Clayton { 148*762f7135SGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 149*762f7135SGreg Clayton if (log) 150*762f7135SGreg Clayton { 151*762f7135SGreg Clayton if (m_file) 152*762f7135SGreg Clayton { 153*762f7135SGreg Clayton log->Printf ("%p ObjectFile::~ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n", 154*762f7135SGreg Clayton this, 155*762f7135SGreg Clayton m_module->GetFileSpec().GetDirectory().AsCString(), 156*762f7135SGreg Clayton m_module->GetFileSpec().GetFilename().AsCString(), 157*762f7135SGreg Clayton m_file.GetDirectory().AsCString(), 158*762f7135SGreg Clayton m_file.GetFilename().AsCString(), 159*762f7135SGreg Clayton m_offset, 160*762f7135SGreg Clayton m_length); 161*762f7135SGreg Clayton } 162*762f7135SGreg Clayton else 163*762f7135SGreg Clayton { 164*762f7135SGreg Clayton log->Printf ("%p ObjectFile::~ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n", 165*762f7135SGreg Clayton this, 166*762f7135SGreg Clayton m_module->GetFileSpec().GetDirectory().AsCString(), 167*762f7135SGreg Clayton m_module->GetFileSpec().GetFilename().AsCString(), 168*762f7135SGreg Clayton m_offset, 169*762f7135SGreg Clayton m_length); 170*762f7135SGreg Clayton } 171*762f7135SGreg 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 181*762f7135SGreg 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; 201ded470d3SGreg Clayton case eSectionTypeData: return eAddressClassData; 202e0d378b3SGreg Clayton case eSectionTypeDataCString: return eAddressClassData; 203ded470d3SGreg Clayton case eSectionTypeDataCStringPointers: return eAddressClassData; 204ded470d3SGreg Clayton case eSectionTypeDataSymbolAddress: return eAddressClassData; 205ded470d3SGreg Clayton case eSectionTypeData4: return eAddressClassData; 206ded470d3SGreg Clayton case eSectionTypeData8: return eAddressClassData; 207ded470d3SGreg Clayton case eSectionTypeData16: return eAddressClassData; 208ded470d3SGreg Clayton case eSectionTypeDataPointers: return eAddressClassData; 209ded470d3SGreg Clayton case eSectionTypeZeroFill: return eAddressClassData; 210e0d378b3SGreg Clayton case eSectionTypeDataObjCMessageRefs: return eAddressClassData; 211e0d378b3SGreg Clayton case eSectionTypeDataObjCCFStrings: return eAddressClassData; 212ded470d3SGreg Clayton case eSectionTypeDebug: return eAddressClassDebug; 213ded470d3SGreg Clayton case eSectionTypeDWARFDebugAbbrev: return eAddressClassDebug; 214ded470d3SGreg Clayton case eSectionTypeDWARFDebugAranges: return eAddressClassDebug; 215ded470d3SGreg Clayton case eSectionTypeDWARFDebugFrame: return eAddressClassDebug; 216ded470d3SGreg Clayton case eSectionTypeDWARFDebugInfo: return eAddressClassDebug; 217ded470d3SGreg Clayton case eSectionTypeDWARFDebugLine: return eAddressClassDebug; 218ded470d3SGreg Clayton case eSectionTypeDWARFDebugLoc: return eAddressClassDebug; 219ded470d3SGreg Clayton case eSectionTypeDWARFDebugMacInfo: return eAddressClassDebug; 220ded470d3SGreg Clayton case eSectionTypeDWARFDebugPubNames: return eAddressClassDebug; 221ded470d3SGreg Clayton case eSectionTypeDWARFDebugPubTypes: return eAddressClassDebug; 222ded470d3SGreg Clayton case eSectionTypeDWARFDebugRanges: return eAddressClassDebug; 223ded470d3SGreg Clayton case eSectionTypeDWARFDebugStr: return eAddressClassDebug; 224f9eec20bSGreg Clayton case eSectionTypeDWARFDebugNames: return eAddressClassDebug; 225f9eec20bSGreg Clayton case eSectionTypeDWARFDebugTypes: return eAddressClassDebug; 226ded470d3SGreg Clayton case eSectionTypeEHFrame: return eAddressClassRuntime; 227ded470d3SGreg Clayton case eSectionTypeOther: return eAddressClassUnknown; 228ded470d3SGreg Clayton } 229ded470d3SGreg Clayton } 230ded470d3SGreg Clayton } 231ded470d3SGreg Clayton 232e0d378b3SGreg Clayton const SymbolType symbol_type = symbol->GetType(); 233ded470d3SGreg Clayton switch (symbol_type) 234ded470d3SGreg Clayton { 235ded470d3SGreg Clayton case eSymbolTypeAny: return eAddressClassUnknown; 236ded470d3SGreg Clayton case eSymbolTypeAbsolute: return eAddressClassUnknown; 237ded470d3SGreg Clayton case eSymbolTypeExtern: return eAddressClassUnknown; 238ded470d3SGreg Clayton case eSymbolTypeCode: return eAddressClassCode; 239ded470d3SGreg Clayton case eSymbolTypeTrampoline: return eAddressClassCode; 240ded470d3SGreg Clayton case eSymbolTypeData: return eAddressClassData; 241ded470d3SGreg Clayton case eSymbolTypeRuntime: return eAddressClassRuntime; 242ded470d3SGreg Clayton case eSymbolTypeException: return eAddressClassRuntime; 243ded470d3SGreg Clayton case eSymbolTypeSourceFile: return eAddressClassDebug; 244ded470d3SGreg Clayton case eSymbolTypeHeaderFile: return eAddressClassDebug; 245ded470d3SGreg Clayton case eSymbolTypeObjectFile: return eAddressClassDebug; 246ded470d3SGreg Clayton case eSymbolTypeCommonBlock: return eAddressClassDebug; 247ded470d3SGreg Clayton case eSymbolTypeBlock: return eAddressClassDebug; 248ded470d3SGreg Clayton case eSymbolTypeLocal: return eAddressClassData; 249ded470d3SGreg Clayton case eSymbolTypeParam: return eAddressClassData; 250ded470d3SGreg Clayton case eSymbolTypeVariable: return eAddressClassData; 251ded470d3SGreg Clayton case eSymbolTypeVariableType: return eAddressClassDebug; 252ded470d3SGreg Clayton case eSymbolTypeLineEntry: return eAddressClassDebug; 253ded470d3SGreg Clayton case eSymbolTypeLineHeader: return eAddressClassDebug; 254ded470d3SGreg Clayton case eSymbolTypeScopeBegin: return eAddressClassDebug; 255ded470d3SGreg Clayton case eSymbolTypeScopeEnd: return eAddressClassDebug; 256ded470d3SGreg Clayton case eSymbolTypeAdditional: return eAddressClassUnknown; 257ded470d3SGreg Clayton case eSymbolTypeCompiler: return eAddressClassDebug; 258ded470d3SGreg Clayton case eSymbolTypeInstrumentation:return eAddressClassDebug; 259ded470d3SGreg Clayton case eSymbolTypeUndefined: return eAddressClassUnknown; 260ded470d3SGreg Clayton } 261ded470d3SGreg Clayton } 262ded470d3SGreg Clayton } 263ded470d3SGreg Clayton return eAddressClassUnknown; 264ded470d3SGreg Clayton } 265ded470d3SGreg Clayton 266*762f7135SGreg Clayton ObjectFileSP 267*762f7135SGreg Clayton ObjectFile::GetSP () 268*762f7135SGreg Clayton { 269*762f7135SGreg Clayton // This object contains an instrusive ref count base class so we can 270*762f7135SGreg Clayton // easily make a shared pointer to this object 271*762f7135SGreg Clayton return ObjectFileSP (this); 272*762f7135SGreg Clayton } 273*762f7135SGreg Clayton 274ded470d3SGreg Clayton 275