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 "elfsymboltableentry.h"
0019 #include "elfsymboltablesection.h"
0020 #include "elfstringtablesection.h"
0021 #include "elffile.h"
0022 #include "elfheader.h"
0023 
0024 
0025 #include <elf.h>
0026 
0027 ElfSymbolTableEntry::ElfSymbolTableEntry(): m_section(nullptr)
0028 {
0029     m_symbol.sym32 = nullptr;
0030 }
0031 
0032 ElfSymbolTableEntry::ElfSymbolTableEntry(const ElfSymbolTableSection* section, uint32_t index) :
0033     m_section(section)
0034 {
0035     // sym64 will contain the right pointer as well
0036     m_symbol.sym32 = reinterpret_cast<Elf32_Sym*>(section->rawData() + index * section->header()->entrySize());
0037 }
0038 
0039 uint32_t ElfSymbolTableEntry::nameIndex() const
0040 {
0041     if (m_section->file()->type() == ELFCLASS64)
0042         return m_symbol.sym64->st_name;
0043     return m_symbol.sym32->st_name;
0044 }
0045 
0046 uint8_t ElfSymbolTableEntry::info() const
0047 {
0048     if (m_section->file()->type() == ELFCLASS64)
0049         return m_symbol.sym64->st_info;
0050     return m_symbol.sym32->st_info;
0051 }
0052 
0053 uint8_t ElfSymbolTableEntry::other() const
0054 {
0055     if (m_section->file()->type() == ELFCLASS64)
0056         return m_symbol.sym64->st_other;
0057     return m_symbol.sym32->st_other;
0058 }
0059 
0060 uint16_t ElfSymbolTableEntry::sectionIndex() const
0061 {
0062     if (m_section->file()->type() == ELFCLASS64)
0063         return m_symbol.sym64->st_shndx;
0064     return m_symbol.sym32->st_shndx;
0065 }
0066 
0067 uint64_t ElfSymbolTableEntry::value() const
0068 {
0069     if (m_section->file()->type() == ELFCLASS64)
0070         return m_symbol.sym64->st_value;
0071     return m_symbol.sym32->st_value;
0072 }
0073 
0074 uint64_t ElfSymbolTableEntry::size() const
0075 {
0076     if (m_section->file()->type() == ELFCLASS64)
0077         return m_symbol.sym64->st_size;
0078     return m_symbol.sym32->st_size;
0079 }
0080 
0081 uint32_t ElfSymbolTableEntry::index() const
0082 {
0083     return (reinterpret_cast<const unsigned char*>(m_symbol.sym32) - symbolTable()->rawData()) / symbolTable()->header()->entrySize();
0084 }
0085 
0086 const ElfSymbolTableSection* ElfSymbolTableEntry::symbolTable() const
0087 {
0088     return m_section;
0089 }
0090 
0091 const char* ElfSymbolTableEntry::name() const
0092 {
0093     return m_section->linkedSection<ElfStringTableSection>()->string(nameIndex());
0094 }
0095 
0096 bool ElfSymbolTableEntry::hasValidSection() const
0097 {
0098     const auto index = sectionIndex();
0099     if (index >= symbolTable()->file()->header()->sectionHeaderCount())
0100         return false;
0101     return symbolTable()->file()->sectionHeaders().at(index)->type() != SHT_NULL;
0102 }
0103 
0104 ElfSectionHeader* ElfSymbolTableEntry::sectionHeader() const
0105 {
0106     return symbolTable()->file()->sectionHeaders().at(sectionIndex());
0107 }
0108 
0109 ElfSection* ElfSymbolTableEntry::section() const
0110 {
0111     return symbolTable()->file()->section<ElfSection>(sectionIndex());
0112 }
0113 
0114 uint8_t ElfSymbolTableEntry::bindType() const
0115 {
0116     // same as 64
0117     return ELF32_ST_BIND(info());
0118 }
0119 
0120 uint8_t ElfSymbolTableEntry::type() const
0121 {
0122     // same as 64
0123     return ELF32_ST_TYPE(info());
0124 }
0125 
0126 uint8_t ElfSymbolTableEntry::visibility() const
0127 {
0128     // same as 64
0129     return ELF32_ST_VISIBILITY(other());
0130 }
0131 
0132 const unsigned char* ElfSymbolTableEntry::data() const
0133 {
0134     const auto targetSection = m_section->file()->section<ElfSection>(sectionIndex());
0135     return targetSection->rawData() + value() - targetSection->header()->virtualAddress();
0136 }