1254721Semaste//===-- ObjectFile.cpp ------------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-private.h" 11254721Semaste#include "lldb/lldb-private-log.h" 12254721Semaste#include "lldb/Core/DataBuffer.h" 13254721Semaste#include "lldb/Core/DataBufferHeap.h" 14254721Semaste#include "lldb/Core/Log.h" 15254721Semaste#include "lldb/Core/Module.h" 16254721Semaste#include "lldb/Core/ModuleSpec.h" 17254721Semaste#include "lldb/Core/PluginManager.h" 18254721Semaste#include "lldb/Core/RegularExpression.h" 19254721Semaste#include "lldb/Core/Section.h" 20254721Semaste#include "lldb/Core/Timer.h" 21254721Semaste#include "lldb/Symbol/ObjectFile.h" 22254721Semaste#include "lldb/Symbol/ObjectContainer.h" 23254721Semaste#include "lldb/Symbol/SymbolFile.h" 24254721Semaste#include "lldb/Target/Process.h" 25254721Semaste#include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h" 26254721Semaste 27254721Semasteusing namespace lldb; 28254721Semasteusing namespace lldb_private; 29254721Semaste 30254721SemasteObjectFileSP 31254721SemasteObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, 32254721Semaste const FileSpec* file, 33254721Semaste lldb::offset_t file_offset, 34254721Semaste lldb::offset_t file_size, 35254721Semaste DataBufferSP &data_sp, 36254721Semaste lldb::offset_t &data_offset) 37254721Semaste{ 38254721Semaste ObjectFileSP object_file_sp; 39254721Semaste 40254721Semaste if (module_sp) 41254721Semaste { 42254721Semaste Timer scoped_timer (__PRETTY_FUNCTION__, 43254721Semaste "ObjectFile::FindPlugin (module = %s, file = %p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")", 44254721Semaste module_sp->GetFileSpec().GetPath().c_str(), 45254721Semaste file, (uint64_t) file_offset, (uint64_t) file_size); 46254721Semaste if (file) 47254721Semaste { 48254721Semaste FileSpec archive_file; 49254721Semaste ObjectContainerCreateInstance create_object_container_callback; 50254721Semaste 51254721Semaste const bool file_exists = file->Exists(); 52254721Semaste if (!data_sp) 53254721Semaste { 54254721Semaste // We have an object name which most likely means we have 55254721Semaste // a .o file in a static archive (.a file). Try and see if 56254721Semaste // we have a cached archive first without reading any data 57254721Semaste // first 58254721Semaste if (file_exists && module_sp->GetObjectName()) 59254721Semaste { 60254721Semaste for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx) 61254721Semaste { 62254721Semaste std::unique_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); 63254721Semaste 64254721Semaste if (object_container_ap.get()) 65254721Semaste object_file_sp = object_container_ap->GetObjectFile(file); 66254721Semaste 67254721Semaste if (object_file_sp.get()) 68254721Semaste return object_file_sp; 69254721Semaste } 70254721Semaste } 71254721Semaste // Ok, we didn't find any containers that have a named object, now 72254721Semaste // lets read the first 512 bytes from the file so the object file 73254721Semaste // and object container plug-ins can use these bytes to see if they 74254721Semaste // can parse this file. 75254721Semaste if (file_size > 0) 76254721Semaste { 77254721Semaste data_sp = file->ReadFileContents(file_offset, std::min<size_t>(512, file_size)); 78254721Semaste data_offset = 0; 79254721Semaste } 80254721Semaste } 81254721Semaste 82254721Semaste if (!data_sp || data_sp->GetByteSize() == 0) 83254721Semaste { 84254721Semaste // Check for archive file with format "/path/to/archive.a(object.o)" 85254721Semaste char path_with_object[PATH_MAX*2]; 86254721Semaste module_sp->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object)); 87254721Semaste 88254721Semaste ConstString archive_object; 89254721Semaste const bool must_exist = true; 90254721Semaste if (ObjectFile::SplitArchivePathWithObject (path_with_object, archive_file, archive_object, must_exist)) 91254721Semaste { 92254721Semaste file_size = archive_file.GetByteSize(); 93254721Semaste if (file_size > 0) 94254721Semaste { 95254721Semaste file = &archive_file; 96254721Semaste module_sp->SetFileSpecAndObjectName (archive_file, archive_object); 97254721Semaste // Check if this is a object container by iterating through all object 98254721Semaste // container plugin instances and then trying to get an object file 99254721Semaste // from the container plugins since we had a name. Also, don't read 100254721Semaste // ANY data in case there is data cached in the container plug-ins 101254721Semaste // (like BSD archives caching the contained objects within an file). 102254721Semaste for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx) 103254721Semaste { 104254721Semaste std::unique_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); 105254721Semaste 106254721Semaste if (object_container_ap.get()) 107254721Semaste object_file_sp = object_container_ap->GetObjectFile(file); 108254721Semaste 109254721Semaste if (object_file_sp.get()) 110254721Semaste return object_file_sp; 111254721Semaste } 112254721Semaste // We failed to find any cached object files in the container 113254721Semaste // plug-ins, so lets read the first 512 bytes and try again below... 114254721Semaste data_sp = archive_file.ReadFileContents(file_offset, 512); 115254721Semaste } 116254721Semaste } 117254721Semaste } 118254721Semaste 119254721Semaste if (data_sp && data_sp->GetByteSize() > 0) 120254721Semaste { 121254721Semaste // Check if this is a normal object file by iterating through 122254721Semaste // all object file plugin instances. 123254721Semaste ObjectFileCreateInstance create_object_file_callback; 124254721Semaste for (uint32_t idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx) 125254721Semaste { 126254721Semaste object_file_sp.reset (create_object_file_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); 127254721Semaste if (object_file_sp.get()) 128254721Semaste return object_file_sp; 129254721Semaste } 130254721Semaste 131254721Semaste // Check if this is a object container by iterating through 132254721Semaste // all object container plugin instances and then trying to get 133254721Semaste // an object file from the container. 134254721Semaste for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx) 135254721Semaste { 136254721Semaste std::unique_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); 137254721Semaste 138254721Semaste if (object_container_ap.get()) 139254721Semaste object_file_sp = object_container_ap->GetObjectFile(file); 140254721Semaste 141254721Semaste if (object_file_sp.get()) 142254721Semaste return object_file_sp; 143254721Semaste } 144254721Semaste } 145254721Semaste } 146254721Semaste } 147254721Semaste // We didn't find it, so clear our shared pointer in case it 148254721Semaste // contains anything and return an empty shared pointer 149254721Semaste object_file_sp.reset(); 150254721Semaste return object_file_sp; 151254721Semaste} 152254721Semaste 153254721SemasteObjectFileSP 154254721SemasteObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, 155254721Semaste const ProcessSP &process_sp, 156254721Semaste lldb::addr_t header_addr, 157254721Semaste DataBufferSP &data_sp) 158254721Semaste{ 159254721Semaste ObjectFileSP object_file_sp; 160254721Semaste 161254721Semaste if (module_sp) 162254721Semaste { 163254721Semaste Timer scoped_timer (__PRETTY_FUNCTION__, 164254721Semaste "ObjectFile::FindPlugin (module = %s, process = %p, header_addr = 0x%" PRIx64 ")", 165254721Semaste module_sp->GetFileSpec().GetPath().c_str(), 166254721Semaste process_sp.get(), header_addr); 167254721Semaste uint32_t idx; 168254721Semaste 169254721Semaste // Check if this is a normal object file by iterating through 170254721Semaste // all object file plugin instances. 171254721Semaste ObjectFileCreateMemoryInstance create_callback; 172254721Semaste for (idx = 0; (create_callback = PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx)) != NULL; ++idx) 173254721Semaste { 174254721Semaste object_file_sp.reset (create_callback(module_sp, data_sp, process_sp, header_addr)); 175254721Semaste if (object_file_sp.get()) 176254721Semaste return object_file_sp; 177254721Semaste } 178254721Semaste 179254721Semaste } 180254721Semaste // We didn't find it, so clear our shared pointer in case it 181254721Semaste // contains anything and return an empty shared pointer 182254721Semaste object_file_sp.reset(); 183254721Semaste return object_file_sp; 184254721Semaste} 185254721Semaste 186254721Semastesize_t 187254721SemasteObjectFile::GetModuleSpecifications (const FileSpec &file, 188254721Semaste lldb::offset_t file_offset, 189254721Semaste lldb::offset_t file_size, 190254721Semaste ModuleSpecList &specs) 191254721Semaste{ 192254721Semaste DataBufferSP data_sp (file.ReadFileContents(file_offset, 512)); 193254721Semaste if (data_sp) 194254721Semaste { 195254721Semaste if (file_size == 0) 196254721Semaste { 197254721Semaste const lldb::offset_t actual_file_size = file.GetByteSize(); 198254721Semaste if (actual_file_size > file_offset) 199254721Semaste file_size = actual_file_size - file_offset; 200254721Semaste } 201254721Semaste return ObjectFile::GetModuleSpecifications (file, // file spec 202254721Semaste data_sp, // data bytes 203254721Semaste 0, // data offset 204254721Semaste file_offset,// file offset 205254721Semaste file_size, // file length 206254721Semaste specs); 207254721Semaste } 208254721Semaste return 0; 209254721Semaste} 210254721Semaste 211254721Semastesize_t 212254721SemasteObjectFile::GetModuleSpecifications (const lldb_private::FileSpec& file, 213254721Semaste lldb::DataBufferSP& data_sp, 214254721Semaste lldb::offset_t data_offset, 215254721Semaste lldb::offset_t file_offset, 216254721Semaste lldb::offset_t file_size, 217254721Semaste lldb_private::ModuleSpecList &specs) 218254721Semaste{ 219254721Semaste const size_t initial_count = specs.GetSize(); 220254721Semaste ObjectFileGetModuleSpecifications callback; 221254721Semaste uint32_t i; 222254721Semaste // Try the ObjectFile plug-ins 223254721Semaste for (i = 0; (callback = PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(i)) != NULL; ++i) 224254721Semaste { 225254721Semaste if (callback (file, data_sp, data_offset, file_offset, file_size, specs) > 0) 226254721Semaste return specs.GetSize() - initial_count; 227254721Semaste } 228254721Semaste 229254721Semaste // Try the ObjectContainer plug-ins 230254721Semaste for (i = 0; (callback = PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(i)) != NULL; ++i) 231254721Semaste { 232254721Semaste if (callback (file, data_sp, data_offset, file_offset, file_size, specs) > 0) 233254721Semaste return specs.GetSize() - initial_count; 234254721Semaste } 235254721Semaste return 0; 236254721Semaste} 237254721Semaste 238254721SemasteObjectFile::ObjectFile (const lldb::ModuleSP &module_sp, 239254721Semaste const FileSpec *file_spec_ptr, 240254721Semaste lldb::offset_t file_offset, 241254721Semaste lldb::offset_t length, 242254721Semaste lldb::DataBufferSP& data_sp, 243254721Semaste lldb::offset_t data_offset 244254721Semaste) : 245254721Semaste ModuleChild (module_sp), 246254721Semaste m_file (), // This file could be different from the original module's file 247254721Semaste m_type (eTypeInvalid), 248254721Semaste m_strata (eStrataInvalid), 249254721Semaste m_file_offset (file_offset), 250254721Semaste m_length (length), 251254721Semaste m_data (), 252254721Semaste m_unwind_table (*this), 253254721Semaste m_process_wp(), 254254721Semaste m_memory_addr (LLDB_INVALID_ADDRESS), 255254721Semaste m_sections_ap(), 256254721Semaste m_symtab_ap () 257254721Semaste{ 258254721Semaste if (file_spec_ptr) 259254721Semaste m_file = *file_spec_ptr; 260254721Semaste if (data_sp) 261254721Semaste m_data.SetData (data_sp, data_offset, length); 262254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 263254721Semaste if (log) 264254721Semaste { 265254721Semaste if (m_file) 266254721Semaste { 267254721Semaste log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s), file = %s, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64, 268254721Semaste this, 269254721Semaste module_sp.get(), 270254721Semaste module_sp->GetSpecificationDescription().c_str(), 271254721Semaste m_file.GetPath().c_str(), 272254721Semaste m_file_offset, 273254721Semaste m_length); 274254721Semaste } 275254721Semaste else 276254721Semaste { 277254721Semaste log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s), file = <NULL>, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64, 278254721Semaste this, 279254721Semaste module_sp.get(), 280254721Semaste module_sp->GetSpecificationDescription().c_str(), 281254721Semaste m_file_offset, 282254721Semaste m_length); 283254721Semaste } 284254721Semaste } 285254721Semaste} 286254721Semaste 287254721Semaste 288254721SemasteObjectFile::ObjectFile (const lldb::ModuleSP &module_sp, 289254721Semaste const ProcessSP &process_sp, 290254721Semaste lldb::addr_t header_addr, 291254721Semaste DataBufferSP& header_data_sp) : 292254721Semaste ModuleChild (module_sp), 293254721Semaste m_file (), 294254721Semaste m_type (eTypeInvalid), 295254721Semaste m_strata (eStrataInvalid), 296254721Semaste m_file_offset (0), 297254721Semaste m_length (0), 298254721Semaste m_data (), 299254721Semaste m_unwind_table (*this), 300254721Semaste m_process_wp (process_sp), 301254721Semaste m_memory_addr (header_addr), 302254721Semaste m_sections_ap(), 303254721Semaste m_symtab_ap () 304254721Semaste{ 305254721Semaste if (header_data_sp) 306254721Semaste m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize()); 307254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 308254721Semaste if (log) 309254721Semaste { 310254721Semaste log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s), process = %p, header_addr = 0x%" PRIx64, 311254721Semaste this, 312254721Semaste module_sp.get(), 313254721Semaste module_sp->GetSpecificationDescription().c_str(), 314254721Semaste process_sp.get(), 315254721Semaste m_memory_addr); 316254721Semaste } 317254721Semaste} 318254721Semaste 319254721Semaste 320254721SemasteObjectFile::~ObjectFile() 321254721Semaste{ 322254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 323254721Semaste if (log) 324254721Semaste log->Printf ("%p ObjectFile::~ObjectFile ()\n", this); 325254721Semaste} 326254721Semaste 327254721Semastebool 328254721SemasteObjectFile::SetModulesArchitecture (const ArchSpec &new_arch) 329254721Semaste{ 330254721Semaste ModuleSP module_sp (GetModule()); 331254721Semaste if (module_sp) 332254721Semaste return module_sp->SetArchitecture (new_arch); 333254721Semaste return false; 334254721Semaste} 335254721Semaste 336254721SemasteAddressClass 337254721SemasteObjectFile::GetAddressClass (addr_t file_addr) 338254721Semaste{ 339254721Semaste Symtab *symtab = GetSymtab(); 340254721Semaste if (symtab) 341254721Semaste { 342254721Semaste Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr); 343254721Semaste if (symbol) 344254721Semaste { 345254721Semaste if (symbol->ValueIsAddress()) 346254721Semaste { 347254721Semaste const SectionSP section_sp (symbol->GetAddress().GetSection()); 348254721Semaste if (section_sp) 349254721Semaste { 350254721Semaste const SectionType section_type = section_sp->GetType(); 351254721Semaste switch (section_type) 352254721Semaste { 353254721Semaste case eSectionTypeInvalid: return eAddressClassUnknown; 354254721Semaste case eSectionTypeCode: return eAddressClassCode; 355254721Semaste case eSectionTypeContainer: return eAddressClassUnknown; 356254721Semaste case eSectionTypeData: 357254721Semaste case eSectionTypeDataCString: 358254721Semaste case eSectionTypeDataCStringPointers: 359254721Semaste case eSectionTypeDataSymbolAddress: 360254721Semaste case eSectionTypeData4: 361254721Semaste case eSectionTypeData8: 362254721Semaste case eSectionTypeData16: 363254721Semaste case eSectionTypeDataPointers: 364254721Semaste case eSectionTypeZeroFill: 365254721Semaste case eSectionTypeDataObjCMessageRefs: 366254721Semaste case eSectionTypeDataObjCCFStrings: 367254721Semaste return eAddressClassData; 368254721Semaste case eSectionTypeDebug: 369254721Semaste case eSectionTypeDWARFDebugAbbrev: 370254721Semaste case eSectionTypeDWARFDebugAranges: 371254721Semaste case eSectionTypeDWARFDebugFrame: 372254721Semaste case eSectionTypeDWARFDebugInfo: 373254721Semaste case eSectionTypeDWARFDebugLine: 374254721Semaste case eSectionTypeDWARFDebugLoc: 375254721Semaste case eSectionTypeDWARFDebugMacInfo: 376254721Semaste case eSectionTypeDWARFDebugPubNames: 377254721Semaste case eSectionTypeDWARFDebugPubTypes: 378254721Semaste case eSectionTypeDWARFDebugRanges: 379254721Semaste case eSectionTypeDWARFDebugStr: 380254721Semaste case eSectionTypeDWARFAppleNames: 381254721Semaste case eSectionTypeDWARFAppleTypes: 382254721Semaste case eSectionTypeDWARFAppleNamespaces: 383254721Semaste case eSectionTypeDWARFAppleObjC: 384254721Semaste return eAddressClassDebug; 385254721Semaste case eSectionTypeEHFrame: return eAddressClassRuntime; 386254721Semaste case eSectionTypeELFSymbolTable: 387254721Semaste case eSectionTypeELFDynamicSymbols: 388254721Semaste case eSectionTypeELFRelocationEntries: 389254721Semaste case eSectionTypeELFDynamicLinkInfo: 390254721Semaste case eSectionTypeOther: return eAddressClassUnknown; 391254721Semaste } 392254721Semaste } 393254721Semaste } 394254721Semaste 395254721Semaste const SymbolType symbol_type = symbol->GetType(); 396254721Semaste switch (symbol_type) 397254721Semaste { 398254721Semaste case eSymbolTypeAny: return eAddressClassUnknown; 399254721Semaste case eSymbolTypeAbsolute: return eAddressClassUnknown; 400254721Semaste case eSymbolTypeCode: return eAddressClassCode; 401254721Semaste case eSymbolTypeTrampoline: return eAddressClassCode; 402254721Semaste case eSymbolTypeResolver: return eAddressClassCode; 403254721Semaste case eSymbolTypeData: return eAddressClassData; 404254721Semaste case eSymbolTypeRuntime: return eAddressClassRuntime; 405254721Semaste case eSymbolTypeException: return eAddressClassRuntime; 406254721Semaste case eSymbolTypeSourceFile: return eAddressClassDebug; 407254721Semaste case eSymbolTypeHeaderFile: return eAddressClassDebug; 408254721Semaste case eSymbolTypeObjectFile: return eAddressClassDebug; 409254721Semaste case eSymbolTypeCommonBlock: return eAddressClassDebug; 410254721Semaste case eSymbolTypeBlock: return eAddressClassDebug; 411254721Semaste case eSymbolTypeLocal: return eAddressClassData; 412254721Semaste case eSymbolTypeParam: return eAddressClassData; 413254721Semaste case eSymbolTypeVariable: return eAddressClassData; 414254721Semaste case eSymbolTypeVariableType: return eAddressClassDebug; 415254721Semaste case eSymbolTypeLineEntry: return eAddressClassDebug; 416254721Semaste case eSymbolTypeLineHeader: return eAddressClassDebug; 417254721Semaste case eSymbolTypeScopeBegin: return eAddressClassDebug; 418254721Semaste case eSymbolTypeScopeEnd: return eAddressClassDebug; 419254721Semaste case eSymbolTypeAdditional: return eAddressClassUnknown; 420254721Semaste case eSymbolTypeCompiler: return eAddressClassDebug; 421254721Semaste case eSymbolTypeInstrumentation:return eAddressClassDebug; 422254721Semaste case eSymbolTypeUndefined: return eAddressClassUnknown; 423254721Semaste case eSymbolTypeObjCClass: return eAddressClassRuntime; 424254721Semaste case eSymbolTypeObjCMetaClass: return eAddressClassRuntime; 425254721Semaste case eSymbolTypeObjCIVar: return eAddressClassRuntime; 426263363Semaste case eSymbolTypeReExported: return eAddressClassRuntime; 427254721Semaste } 428254721Semaste } 429254721Semaste } 430254721Semaste return eAddressClassUnknown; 431254721Semaste} 432254721Semaste 433254721SemasteDataBufferSP 434254721SemasteObjectFile::ReadMemory (const ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size) 435254721Semaste{ 436254721Semaste DataBufferSP data_sp; 437254721Semaste if (process_sp) 438254721Semaste { 439254721Semaste std::unique_ptr<DataBufferHeap> data_ap (new DataBufferHeap (byte_size, 0)); 440254721Semaste Error error; 441254721Semaste const size_t bytes_read = process_sp->ReadMemory (addr, 442254721Semaste data_ap->GetBytes(), 443254721Semaste data_ap->GetByteSize(), 444254721Semaste error); 445254721Semaste if (bytes_read == byte_size) 446254721Semaste data_sp.reset (data_ap.release()); 447254721Semaste } 448254721Semaste return data_sp; 449254721Semaste} 450254721Semaste 451254721Semastesize_t 452254721SemasteObjectFile::GetData (off_t offset, size_t length, DataExtractor &data) const 453254721Semaste{ 454254721Semaste // The entire file has already been mmap'ed into m_data, so just copy from there 455254721Semaste // as the back mmap buffer will be shared with shared pointers. 456254721Semaste return data.SetData (m_data, offset, length); 457254721Semaste} 458254721Semaste 459254721Semastesize_t 460254721SemasteObjectFile::CopyData (off_t offset, size_t length, void *dst) const 461254721Semaste{ 462254721Semaste // The entire file has already been mmap'ed into m_data, so just copy from there 463263363Semaste // Note that the data remains in target byte order. 464263363Semaste return m_data.CopyData (offset, length, dst); 465254721Semaste} 466254721Semaste 467254721Semaste 468254721Semastesize_t 469254721SemasteObjectFile::ReadSectionData (const Section *section, off_t section_offset, void *dst, size_t dst_len) const 470254721Semaste{ 471254721Semaste // If some other objectfile owns this data, pass this to them. 472254721Semaste if (section->GetObjectFile() != this) 473254721Semaste return section->GetObjectFile()->ReadSectionData (section, section_offset, dst, dst_len); 474254721Semaste 475254721Semaste if (IsInMemory()) 476254721Semaste { 477254721Semaste ProcessSP process_sp (m_process_wp.lock()); 478254721Semaste if (process_sp) 479254721Semaste { 480254721Semaste Error error; 481254721Semaste const addr_t base_load_addr = section->GetLoadBaseAddress (&process_sp->GetTarget()); 482254721Semaste if (base_load_addr != LLDB_INVALID_ADDRESS) 483254721Semaste return process_sp->ReadMemory (base_load_addr + section_offset, dst, dst_len, error); 484254721Semaste } 485254721Semaste } 486254721Semaste else 487254721Semaste { 488254721Semaste const uint64_t section_file_size = section->GetFileSize(); 489254721Semaste if (section_offset < section_file_size) 490254721Semaste { 491254721Semaste const uint64_t section_bytes_left = section_file_size - section_offset; 492254721Semaste uint64_t section_dst_len = dst_len; 493254721Semaste if (section_dst_len > section_bytes_left) 494254721Semaste section_dst_len = section_bytes_left; 495254721Semaste return CopyData (section->GetFileOffset() + section_offset, section_dst_len, dst); 496254721Semaste } 497254721Semaste else 498254721Semaste { 499254721Semaste if (section->GetType() == eSectionTypeZeroFill) 500254721Semaste { 501254721Semaste const uint64_t section_size = section->GetByteSize(); 502254721Semaste const uint64_t section_bytes_left = section_size - section_offset; 503254721Semaste uint64_t section_dst_len = dst_len; 504254721Semaste if (section_dst_len > section_bytes_left) 505254721Semaste section_dst_len = section_bytes_left; 506263363Semaste memset(dst, 0, section_dst_len); 507254721Semaste return section_dst_len; 508254721Semaste } 509254721Semaste } 510254721Semaste } 511254721Semaste return 0; 512254721Semaste} 513254721Semaste 514254721Semaste//---------------------------------------------------------------------- 515254721Semaste// Get the section data the file on disk 516254721Semaste//---------------------------------------------------------------------- 517254721Semastesize_t 518254721SemasteObjectFile::ReadSectionData (const Section *section, DataExtractor& section_data) const 519254721Semaste{ 520254721Semaste // If some other objectfile owns this data, pass this to them. 521254721Semaste if (section->GetObjectFile() != this) 522254721Semaste return section->GetObjectFile()->ReadSectionData (section, section_data); 523254721Semaste 524254721Semaste if (IsInMemory()) 525254721Semaste { 526254721Semaste ProcessSP process_sp (m_process_wp.lock()); 527254721Semaste if (process_sp) 528254721Semaste { 529254721Semaste const addr_t base_load_addr = section->GetLoadBaseAddress (&process_sp->GetTarget()); 530254721Semaste if (base_load_addr != LLDB_INVALID_ADDRESS) 531254721Semaste { 532254721Semaste DataBufferSP data_sp (ReadMemory (process_sp, base_load_addr, section->GetByteSize())); 533254721Semaste if (data_sp) 534254721Semaste { 535254721Semaste section_data.SetData (data_sp, 0, data_sp->GetByteSize()); 536254721Semaste section_data.SetByteOrder (process_sp->GetByteOrder()); 537254721Semaste section_data.SetAddressByteSize (process_sp->GetAddressByteSize()); 538254721Semaste return section_data.GetByteSize(); 539254721Semaste } 540254721Semaste } 541254721Semaste } 542254721Semaste } 543254721Semaste else 544254721Semaste { 545254721Semaste // The object file now contains a full mmap'ed copy of the object file data, so just use this 546254721Semaste return MemoryMapSectionData (section, section_data); 547254721Semaste } 548254721Semaste section_data.Clear(); 549254721Semaste return 0; 550254721Semaste} 551254721Semaste 552254721Semastesize_t 553254721SemasteObjectFile::MemoryMapSectionData (const Section *section, DataExtractor& section_data) const 554254721Semaste{ 555254721Semaste // If some other objectfile owns this data, pass this to them. 556254721Semaste if (section->GetObjectFile() != this) 557254721Semaste return section->GetObjectFile()->MemoryMapSectionData (section, section_data); 558254721Semaste 559254721Semaste if (IsInMemory()) 560254721Semaste { 561254721Semaste return ReadSectionData (section, section_data); 562254721Semaste } 563254721Semaste else 564254721Semaste { 565254721Semaste // The object file now contains a full mmap'ed copy of the object file data, so just use this 566254721Semaste return GetData(section->GetFileOffset(), section->GetFileSize(), section_data); 567254721Semaste } 568254721Semaste section_data.Clear(); 569254721Semaste return 0; 570254721Semaste} 571254721Semaste 572254721Semaste 573254721Semastebool 574254721SemasteObjectFile::SplitArchivePathWithObject (const char *path_with_object, FileSpec &archive_file, ConstString &archive_object, bool must_exist) 575254721Semaste{ 576254721Semaste RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$"); 577254721Semaste RegularExpression::Match regex_match(2); 578254721Semaste if (g_object_regex.Execute (path_with_object, ®ex_match)) 579254721Semaste { 580254721Semaste std::string path; 581254721Semaste std::string obj; 582254721Semaste if (regex_match.GetMatchAtIndex (path_with_object, 1, path) && 583254721Semaste regex_match.GetMatchAtIndex (path_with_object, 2, obj)) 584254721Semaste { 585254721Semaste archive_file.SetFile (path.c_str(), false); 586254721Semaste archive_object.SetCString(obj.c_str()); 587254721Semaste if (must_exist && !archive_file.Exists()) 588254721Semaste return false; 589254721Semaste return true; 590254721Semaste } 591254721Semaste } 592254721Semaste return false; 593254721Semaste} 594254721Semaste 595254721Semastevoid 596254721SemasteObjectFile::ClearSymtab () 597254721Semaste{ 598254721Semaste ModuleSP module_sp(GetModule()); 599254721Semaste if (module_sp) 600254721Semaste { 601254721Semaste lldb_private::Mutex::Locker locker(module_sp->GetMutex()); 602254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 603254721Semaste if (log) 604254721Semaste { 605254721Semaste log->Printf ("%p ObjectFile::ClearSymtab () symtab = %p", 606254721Semaste this, 607254721Semaste m_symtab_ap.get()); 608254721Semaste } 609254721Semaste m_symtab_ap.reset(); 610254721Semaste } 611254721Semaste} 612254721Semaste 613254721SemasteSectionList * 614254721SemasteObjectFile::GetSectionList() 615254721Semaste{ 616254721Semaste if (m_sections_ap.get() == NULL) 617254721Semaste { 618254721Semaste ModuleSP module_sp(GetModule()); 619254721Semaste if (module_sp) 620254721Semaste CreateSections(*module_sp->GetUnifiedSectionList()); 621254721Semaste } 622254721Semaste return m_sections_ap.get(); 623254721Semaste} 624