File indexing completed on 2024-05-12 05:43:30
0001 /* 0002 Copyright (C) 2013-2014 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 "elfsymboltablesection.h" 0019 #include "elfsectionheader.h" 0020 0021 #include <elf.h> 0022 0023 ElfSymbolTableSection::ElfSymbolTableSection(ElfFile* file, ElfSectionHeader *shdr): ElfSection(file, shdr) 0024 { 0025 m_entries.reserve(header()->entryCount()); 0026 m_entriesByValue.reserve(header()->entryCount()); 0027 0028 const uint64_t entryCount = header()->entryCount(); 0029 for (uint64_t i = 0; i < entryCount; ++i) { 0030 m_entries.push_back(ElfSymbolTableEntry(this, i)); 0031 0032 const auto entry = m_entries.data() + i; 0033 if (entry->size() == 0 || entry->value() == 0) { 0034 continue; 0035 } 0036 m_entriesByValue.push_back(entry); 0037 } 0038 0039 std::sort(m_entriesByValue.begin(), m_entriesByValue.end(), [](auto *lhs, auto *rhs) { 0040 return lhs->value() < rhs->value(); 0041 }); 0042 } 0043 0044 ElfSymbolTableSection::~ElfSymbolTableSection() = default; 0045 0046 ElfSymbolTableEntry* ElfSymbolTableSection::entry(uint32_t index) const 0047 { 0048 return const_cast<ElfSymbolTableEntry*>(m_entries.data() + index); 0049 } 0050 0051 int ElfSymbolTableSection::exportCount() const 0052 { 0053 int count = 0; 0054 for (const auto &entry : m_entries) { 0055 if (entry.bindType() == STB_GLOBAL && entry.size() > 0) 0056 ++count; 0057 } 0058 return count; 0059 } 0060 0061 int ElfSymbolTableSection::importCount() const 0062 { 0063 int count = 0; 0064 for (const auto &entry : m_entries) { 0065 if (entry.bindType() == STB_GLOBAL && entry.size() == 0) 0066 ++count; 0067 } 0068 return count; 0069 } 0070 0071 ElfSymbolTableEntry* ElfSymbolTableSection::entryWithValue(uint64_t value) const 0072 { 0073 if (value == 0) 0074 return nullptr; 0075 0076 const auto it = std::lower_bound(m_entriesByValue.begin(), m_entriesByValue.end(), value, [](auto *lhs, uint64_t rhs) { 0077 return lhs->value() < rhs; 0078 }); 0079 if (it != m_entriesByValue.end() && (*it)->value() == value) { 0080 return (*it); 0081 } 0082 return nullptr; 0083 } 0084 0085 0086 ElfSymbolTableEntry* ElfSymbolTableSection::entryContainingValue(uint64_t value) const 0087 { 0088 if (value == 0) 0089 return nullptr; 0090 0091 auto it = std::lower_bound(m_entriesByValue.begin(), m_entriesByValue.end(), value, [](auto *lhs, uint64_t rhs) { 0092 return lhs->value() < rhs; 0093 }); 0094 if (it == m_entriesByValue.end()) { --it; } 0095 0096 while (it != m_entriesByValue.end() && value < (*it)->value() + (*it)->size()) { 0097 if ((*it)->value() <= value) { 0098 return *it; 0099 } 0100 0101 if (it == m_entriesByValue.begin()) { 0102 return nullptr; 0103 } 0104 --it; 0105 } 0106 0107 return nullptr; 0108 }