Index: lldb/source/Symbol/ObjectFile.cpp =================================================================== --- lldb/source/Symbol/ObjectFile.cpp +++ lldb/source/Symbol/ObjectFile.cpp @@ -31,6 +31,30 @@ char ObjectFile::ID; +// RAII Utility to reset the data buffer and data offset. +class DataReset { +public: + DataReset(DataBufferSP &data_sp, lldb::offset_t &data_offset) + : data_sp(data_sp), data_sp_ref(data_sp), data_offset(data_offset), + data_offset_ref(data_offset) {} + + ~DataReset() { + if (!reset) + return; + data_sp_ref = data_sp; + data_offset_ref = data_offset; + } + + void Release() { reset = false; } + +private: + bool reset = true; + DataBufferSP data_sp; + DataBufferSP data_sp_ref; + lldb::offset_t data_offset; + lldb::offset_t &data_offset_ref; +}; + static ObjectFileSP CreateObjectFromContainer(const lldb::ModuleSP &module_sp, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t file_size, @@ -40,10 +64,33 @@ (callback = PluginManager::GetObjectContainerCreateCallbackAtIndex( idx)) != nullptr; ++idx) { + DataReset data_reset(data_sp, data_offset); std::unique_ptr object_container_up(callback( module_sp, data_sp, data_offset, file, file_offset, file_size)); - if (object_container_up) + if (object_container_up) { + data_reset.Release(); return object_container_up->GetObjectFile(file); + } + } + return {}; +} + +static ObjectFileSP +CreateObject(const lldb::ModuleSP &module_sp, const FileSpec *file, + lldb::offset_t file_offset, lldb::offset_t file_size, + DataBufferSP &data_sp, lldb::offset_t &data_offset) { + ObjectFileCreateInstance callback; + for (uint32_t idx = 0; + (callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != + nullptr; + ++idx) { + DataReset data_reset(data_sp, data_offset); + ObjectFileSP object_file_sp(callback(module_sp, data_sp, data_offset, file, + file_offset, file_size)); + if (object_file_sp.get()) { + data_reset.Release(); + return object_file_sp; + } } return {}; } @@ -71,9 +118,8 @@ // a static archive (.a file). Try and see if we have a cached archive // first without reading any data first if (file_exists && module_sp->GetObjectName()) { - ObjectFileSP object_file_sp = CreateObjectFromContainer( - module_sp, file, file_offset, file_size, data_sp, data_offset); - if (object_file_sp) + if (ObjectFileSP object_file_sp = CreateObjectFromContainer( + module_sp, file, file_offset, file_size, data_sp, data_offset)) return object_file_sp; } // Ok, we didn't find any containers that have a named object, now lets @@ -108,9 +154,8 @@ // ANY data in case there is data cached in the container plug-ins // (like BSD archives caching the contained objects within an // file). - ObjectFileSP object_file_sp = CreateObjectFromContainer( - module_sp, file, file_offset, file_size, data_sp, data_offset); - if (object_file_sp) + if (ObjectFileSP object_file_sp = CreateObjectFromContainer( + module_sp, file, file_offset, file_size, data_sp, data_offset)) return object_file_sp; // We failed to find any cached object files in the container plug- // ins, so lets read the first 512 bytes and try again below... @@ -121,25 +166,17 @@ } if (data_sp && data_sp->GetByteSize() > 0) { - // Check if this is a normal object file by iterating through all - // object file plugin instances. - ObjectFileCreateInstance callback; - for (uint32_t idx = 0; - (callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != - nullptr; - ++idx) { - ObjectFileSP object_file_sp(callback(module_sp, data_sp, data_offset, - file, file_offset, file_size)); - if (object_file_sp.get()) - return object_file_sp; - } + // Check if this is a normal object file by iterating through all object + // file plugin instances. + if (ObjectFileSP object_file_sp = CreateObject( + module_sp, file, file_offset, file_size, data_sp, data_offset)) + return object_file_sp; // Check if this is a object container by iterating through all object // container plugin instances and then trying to get an object file // from the container. - ObjectFileSP object_file_sp = CreateObjectFromContainer( - module_sp, file, file_offset, file_size, data_sp, data_offset); - if (object_file_sp) + if (ObjectFileSP object_file_sp = CreateObjectFromContainer( + module_sp, file, file_offset, file_size, data_sp, data_offset)) return object_file_sp; }