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 }