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