File indexing completed on 2024-05-12 05:43:30
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 "elfreverserelocator.h" 0019 #include "elfrelocationsection.h" 0020 0021 #include <cassert> 0022 0023 int ElfReverseRelocator::size() const 0024 { 0025 indexRelocations(); 0026 return m_relocations.size(); 0027 } 0028 0029 ElfRelocationEntry* ElfReverseRelocator::find(uint64_t vaddr) const 0030 { 0031 indexRelocations(); 0032 0033 const auto it = std::lower_bound(m_relocations.cbegin(), m_relocations.cend(), vaddr, [](ElfRelocationEntry *entry, uint64_t vaddr) { 0034 return entry->offset() < vaddr; 0035 }); 0036 0037 if (it == m_relocations.cend() || (*it)->offset() != vaddr) 0038 return nullptr; 0039 0040 return *it; 0041 } 0042 0043 int ElfReverseRelocator::relocationCount(uint64_t beginVAddr, uint64_t length) const 0044 { 0045 indexRelocations(); 0046 0047 const auto beginIt = std::lower_bound(m_relocations.cbegin(), m_relocations.cend(), beginVAddr, [](ElfRelocationEntry *entry, uint64_t vaddr) { 0048 return entry->offset() < vaddr; 0049 }); 0050 0051 if (beginIt == m_relocations.cend()) 0052 return 0; 0053 0054 const auto endIt = std::lower_bound(m_relocations.cbegin(), m_relocations.cend(), beginVAddr + length, [](ElfRelocationEntry *entry, uint64_t vaddr) { 0055 return entry->offset() < vaddr; 0056 }); 0057 0058 return std::distance(beginIt, endIt); 0059 } 0060 0061 void ElfReverseRelocator::addRelocationSection(ElfRelocationSection* section) 0062 { 0063 assert(m_relocations.isEmpty()); 0064 m_relocSections.push_back(section); 0065 } 0066 0067 void ElfReverseRelocator::indexRelocations() const 0068 { 0069 if (!m_relocations.isEmpty()) 0070 return; 0071 0072 int totalSize = 0; 0073 std::for_each(m_relocSections.constBegin(), m_relocSections.constEnd(), [&totalSize](ElfRelocationSection* section) { 0074 totalSize += section->header()->entryCount(); 0075 }); 0076 0077 m_relocations.resize(totalSize); 0078 auto oit = m_relocations.begin(); 0079 for (const auto sec : m_relocSections) { 0080 for (uint64_t i = 0; i < sec->header()->entryCount(); ++i) { 0081 *oit++ = sec->entry(i); 0082 } 0083 } 0084 0085 std::sort(m_relocations.begin(), m_relocations.end(), [](ElfRelocationEntry *lhs, ElfRelocationEntry *rhs) { 0086 return lhs->offset() < rhs->offset(); 0087 }); 0088 }