File indexing completed on 2024-05-12 05:43:33

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 "indexvisitor.h"
0019 
0020 #include <elf/elffile.h>
0021 #include <elf/elffileset.h>
0022 #include <elf/elfgnusymbolversionrequirement.h>
0023 #if HAVE_DWARF
0024 #include <dwarf/dwarfcudie.h>
0025 #endif
0026 
0027 #include <elf.h>
0028 
0029 IndexVisitor::type IndexVisitor::doVisit(ElfFileSet* fileSet, int row) const
0030 {
0031     return qMakePair<void*, ElfNodeVariant::Type>(fileSet->file(row), ElfNodeVariant::File);
0032 }
0033 
0034 IndexVisitor::type IndexVisitor::doVisit(ElfFile* file, int row) const
0035 {
0036     ElfSection *section = file->section<ElfSection>(row);
0037     void *internalPointer = section;
0038     ElfNodeVariant::Type type;
0039     switch (section->header()->type()) {
0040         case SHT_SYMTAB:
0041         case SHT_DYNSYM:
0042             type = ElfNodeVariant::SymbolTableSection;
0043             break;
0044         case SHT_DYNAMIC:
0045             type = ElfNodeVariant::DynamicSection;
0046             break;
0047         case SHT_NOTE:
0048             type = ElfNodeVariant::NoteSection;
0049             break;
0050         case SHT_REL:
0051         case SHT_RELA:
0052             type = ElfNodeVariant::RelocationSection;
0053             break;
0054         case SHT_GNU_verdef:
0055             type = ElfNodeVariant::VersionDefinitionSection;
0056             break;
0057         case SHT_GNU_verneed:
0058             type = ElfNodeVariant::VersionRequirementsSection;
0059             break;
0060         case SHT_HASH:
0061         case SHT_GNU_HASH:
0062             type = ElfNodeVariant::HashSection;
0063             break;
0064         case SHT_PROGBITS:
0065             if (strcmp(section->header()->name(), ".plt") == 0) {
0066                 type = ElfNodeVariant::PltSection;
0067                 break;
0068             } else if ((section->header()->flags() & SHF_WRITE) && strncmp(section->header()->name(), ".got", 4) == 0) {
0069                 type = ElfNodeVariant::GotSection;
0070                 break;
0071             } else if (strcmp(section->header()->name(), ".gnu_debuglink") == 0) {
0072                 type = ElfNodeVariant::DebugLinkSection;
0073                 break;
0074             }
0075             // else fallthrough
0076         default:
0077             if (strcmp(section->header()->name(), ".debug_info") == 0) {
0078 #if HAVE_DWARF
0079                 type = ElfNodeVariant::DwarfInfo;
0080                 internalPointer = file->dwarfInfo();
0081 #else
0082                 type = ElfNodeVariant::Section;
0083 #endif
0084             } else {
0085                 type = ElfNodeVariant::Section;
0086             }
0087     }
0088     return qMakePair(internalPointer, type);
0089 }
0090 
0091 IndexVisitor::type IndexVisitor::doVisit(ElfSymbolTableSection* symtab, int row) const
0092 {
0093     const auto entry = symtab->entry(row);
0094     return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::SymbolTableEntry);
0095 }
0096 
0097 IndexVisitor::type IndexVisitor::doVisit(ElfDynamicSection* section, int row) const
0098 {
0099     const auto entry = section->entry(row);
0100     return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::DynamicEntry);
0101 }
0102 
0103 IndexVisitor::type IndexVisitor::doVisit(ElfGNUSymbolVersionDefinitionsSection *section, int row) const
0104 {
0105     const auto entry = section->definition(row);
0106     return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::VersionDefinitionEntry);
0107 }
0108 
0109 IndexVisitor::type IndexVisitor::doVisit(ElfGNUSymbolVersionDefinition *verDef, int row) const
0110 {
0111     const auto auxEntry = verDef->auxiliaryEntry(row);
0112     return qMakePair<void*, ElfNodeVariant::Type>(auxEntry, ElfNodeVariant::VersionDefinitionAuxiliaryEntry);
0113 }
0114 
0115 IndexVisitor::type IndexVisitor::doVisit(ElfGNUSymbolVersionRequirementsSection *section, int row) const
0116 {
0117     const auto entry = section->requirement(row);
0118     return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::VersionRequirementEntry);
0119 }
0120 
0121 IndexVisitor::type IndexVisitor::doVisit(ElfGNUSymbolVersionRequirement *verNeed, int row) const
0122 {
0123     const auto auxEntry = verNeed->auxiliaryEntry(row);
0124     return qMakePair<void*, ElfNodeVariant::Type>(auxEntry, ElfNodeVariant::VersionRequirementAuxiliaryEntry);
0125 }
0126 
0127 IndexVisitor::type IndexVisitor::doVisit(ElfGotSection *section, int row) const
0128 {
0129     const auto entry = section->entry(row);
0130     return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::GotEntry);
0131 }
0132 
0133 IndexVisitor::type IndexVisitor::doVisit(ElfNoteSection *section, int row) const
0134 {
0135     const auto entry = section->entry(row);
0136     return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::NoteEntry);
0137 }
0138 
0139 IndexVisitor::type IndexVisitor::doVisit(ElfPltSection *section, int row) const
0140 {
0141     const auto entry = section->entry(row);
0142     return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::PltEntry);
0143 }
0144 
0145 IndexVisitor::type IndexVisitor::doVisit(ElfRelocationSection* section, int row) const
0146 {
0147     const auto entry = section->entry(row);
0148     return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::RelocationEntry);
0149 }
0150 
0151 #if HAVE_DWARF
0152 IndexVisitor::type IndexVisitor::doVisit(DwarfInfo* info, int row) const
0153 {
0154     auto cuDie = info->compilationUnits().at(row);
0155     return qMakePair<void*, ElfNodeVariant::Type>(cuDie, ElfNodeVariant::DwarfDie);
0156 }
0157 
0158 QPair< void*, ElfNodeVariant::Type > IndexVisitor::doVisit(DwarfDie* die, int row) const
0159 {
0160     DwarfDie *childDie = die->children().at(row);
0161     return qMakePair<void*, ElfNodeVariant::Type>(childDie, ElfNodeVariant::DwarfDie);
0162 }
0163 #endif