File indexing completed on 2024-05-19 05:44:09
0001 /* 0002 Copyright (C) 2015 Volker Krause <vkrause@kde.org> 0003 0004 This program is free software; you can redistribute it and/or modify it 0005 under the terms of the GNU Library General Public License as published by 0006 the Free Software Foundation; either version 2 of the License, or (at your 0007 option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, but WITHOUT 0010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0012 License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program. If not, see <https://www.gnu.org/licenses/>. 0016 */ 0017 0018 #include "elfgnusymbolversionrequirement.h" 0019 #include "elfgnusymbolversionrequirementssection.h" 0020 #include "elfgnusymbolversionrequirementauxiliaryentry.h" 0021 #include "elfstringtablesection.h" 0022 0023 #include <cassert> 0024 0025 ElfGNUSymbolVersionRequirement::ElfGNUSymbolVersionRequirement(ElfGNUSymbolVersionRequirementsSection* section, uint32_t offset) : 0026 m_section(section), 0027 m_verNeed(reinterpret_cast<const Elf64_Verneed*>(section->rawData() + offset)) 0028 { 0029 // 32bit and 64bit have exactly the same memory layout 0030 static_assert(sizeof(Elf32_Verneed) == sizeof(Elf64_Verneed), "SHT_GNU_verneed memory layout changed"); 0031 0032 assert(m_verNeed->vn_version == 1); 0033 static_assert(VER_NEED_CURRENT == 1, "SHT_GNU_verneed format changed!"); 0034 0035 uint32_t auxOffset = 0; 0036 m_auxEntries.reserve(auxiliarySize()); 0037 for (int i = 0; i < auxiliarySize(); ++i) { 0038 const auto auxEntry = new ElfGNUSymbolVersionRequirementAuxiliaryEntry(this, auxOffset); 0039 m_auxEntries.push_back(auxEntry); 0040 auxOffset += auxEntry->nextAuxiliaryEntryOffset(); 0041 } 0042 0043 assert(auxiliarySize() == m_auxEntries.size()); 0044 } 0045 0046 ElfGNUSymbolVersionRequirement::~ElfGNUSymbolVersionRequirement() 0047 { 0048 qDeleteAll(m_auxEntries); 0049 } 0050 0051 ElfGNUSymbolVersionRequirementsSection* ElfGNUSymbolVersionRequirement::section() const 0052 { 0053 return m_section; 0054 } 0055 0056 uint16_t ElfGNUSymbolVersionRequirement::auxiliarySize() const 0057 { 0058 return m_verNeed->vn_cnt; 0059 } 0060 0061 const char* ElfGNUSymbolVersionRequirement::fileName() const 0062 { 0063 return section()->linkedSection<ElfStringTableSection>()->string(m_verNeed->vn_file); 0064 } 0065 0066 uint32_t ElfGNUSymbolVersionRequirement::auxiliaryOffset() const 0067 { 0068 return m_verNeed->vn_aux; 0069 } 0070 0071 uint32_t ElfGNUSymbolVersionRequirement::nextOffset() const 0072 { 0073 return m_verNeed->vn_next; 0074 } 0075 0076 ElfGNUSymbolVersionRequirementAuxiliaryEntry* ElfGNUSymbolVersionRequirement::auxiliaryEntry(uint32_t index) const 0077 { 0078 return m_auxEntries.at(index); 0079 } 0080 0081 uint32_t ElfGNUSymbolVersionRequirement::size() const 0082 { 0083 if (nextOffset()) 0084 return nextOffset(); 0085 return section()->size() - (reinterpret_cast<const unsigned char*>(m_verNeed) - section()->rawData()); 0086 } 0087 0088 const unsigned char* ElfGNUSymbolVersionRequirement::rawData() const 0089 { 0090 return reinterpret_cast<const unsigned char*>(m_verNeed); 0091 }