1 /*
2 Copyright (C) 2013-2014 Volker Krause <vkrause@kde.org>
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 #include "elfdefinitions.h" // must come first before <elf.h>
19 #define _ELF_H_
20 #include "indexvisitor.h"
21
22 #include <elf/elffile.h>
23 #include <elf/elffileset.h>
24 #include <elf/elfgnusymbolversionrequirement.h>
25 #include <dwarf/dwarfcudie.h>
26
27 #include <elf.h>
28
doVisit(ElfFileSet * fileSet,int row) const29 IndexVisitor::type IndexVisitor::doVisit(ElfFileSet* fileSet, int row) const
30 {
31 return qMakePair<void*, ElfNodeVariant::Type>(fileSet->file(row), ElfNodeVariant::File);
32 }
33
doVisit(ElfFile * file,int row) const34 IndexVisitor::type IndexVisitor::doVisit(ElfFile* file, int row) const
35 {
36 ElfSection *section = file->section<ElfSection>(row);
37 void *internalPointer = section;
38 ElfNodeVariant::Type type;
39 switch (section->header()->type()) {
40 case SHT_SYMTAB:
41 case SHT_DYNSYM:
42 type = ElfNodeVariant::SymbolTableSection;
43 break;
44 case SHT_DYNAMIC:
45 type = ElfNodeVariant::DynamicSection;
46 break;
47 case SHT_NOTE:
48 type = ElfNodeVariant::NoteSection;
49 break;
50 case SHT_REL:
51 case SHT_RELA:
52 type = ElfNodeVariant::RelocationSection;
53 break;
54 case SHT_GNU_verdef:
55 type = ElfNodeVariant::VersionDefinitionSection;
56 break;
57 case SHT_GNU_verneed:
58 type = ElfNodeVariant::VersionRequirementsSection;
59 break;
60 case SHT_HASH:
61 case SHT_GNU_HASH:
62 type = ElfNodeVariant::HashSection;
63 break;
64 case SHT_PROGBITS:
65 if (strcmp(section->header()->name(), ".plt") == 0) {
66 type = ElfNodeVariant::PltSection;
67 break;
68 } else if ((section->header()->flags() & SHF_WRITE) && strncmp(section->header()->name(), ".got", 4) == 0) {
69 type = ElfNodeVariant::GotSection;
70 break;
71 } else if (strcmp(section->header()->name(), ".gnu_debuglink") == 0) {
72 type = ElfNodeVariant::DebugLinkSection;
73 break;
74 }
75 // else fallthrough
76 default:
77 if (strcmp(section->header()->name(), ".debug_info") == 0) {
78 type = ElfNodeVariant::DwarfInfo;
79 internalPointer = file->dwarfInfo();
80 } else {
81 type = ElfNodeVariant::Section;
82 }
83 }
84 return qMakePair(internalPointer, type);
85 }
86
doVisit(ElfSymbolTableSection * symtab,int row) const87 IndexVisitor::type IndexVisitor::doVisit(ElfSymbolTableSection* symtab, int row) const
88 {
89 const auto entry = symtab->entry(row);
90 return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::SymbolTableEntry);
91 }
92
doVisit(ElfDynamicSection * section,int row) const93 IndexVisitor::type IndexVisitor::doVisit(ElfDynamicSection* section, int row) const
94 {
95 const auto entry = section->entry(row);
96 return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::DynamicEntry);
97 }
98
doVisit(ElfGNUSymbolVersionDefinitionsSection * section,int row) const99 IndexVisitor::type IndexVisitor::doVisit(ElfGNUSymbolVersionDefinitionsSection *section, int row) const
100 {
101 const auto entry = section->definition(row);
102 return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::VersionDefinitionEntry);
103 }
104
doVisit(ElfGNUSymbolVersionDefinition * verDef,int row) const105 IndexVisitor::type IndexVisitor::doVisit(ElfGNUSymbolVersionDefinition *verDef, int row) const
106 {
107 const auto auxEntry = verDef->auxiliaryEntry(row);
108 return qMakePair<void*, ElfNodeVariant::Type>(auxEntry, ElfNodeVariant::VersionDefinitionAuxiliaryEntry);
109 }
110
doVisit(ElfGNUSymbolVersionRequirementsSection * section,int row) const111 IndexVisitor::type IndexVisitor::doVisit(ElfGNUSymbolVersionRequirementsSection *section, int row) const
112 {
113 const auto entry = section->requirement(row);
114 return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::VersionRequirementEntry);
115 }
116
doVisit(ElfGNUSymbolVersionRequirement * verNeed,int row) const117 IndexVisitor::type IndexVisitor::doVisit(ElfGNUSymbolVersionRequirement *verNeed, int row) const
118 {
119 const auto auxEntry = verNeed->auxiliaryEntry(row);
120 return qMakePair<void*, ElfNodeVariant::Type>(auxEntry, ElfNodeVariant::VersionRequirementAuxiliaryEntry);
121 }
122
doVisit(ElfGotSection * section,int row) const123 IndexVisitor::type IndexVisitor::doVisit(ElfGotSection *section, int row) const
124 {
125 const auto entry = section->entry(row);
126 return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::GotEntry);
127 }
128
doVisit(ElfNoteSection * section,int row) const129 IndexVisitor::type IndexVisitor::doVisit(ElfNoteSection *section, int row) const
130 {
131 const auto entry = section->entry(row);
132 return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::NoteEntry);
133 }
134
doVisit(ElfPltSection * section,int row) const135 IndexVisitor::type IndexVisitor::doVisit(ElfPltSection *section, int row) const
136 {
137 const auto entry = section->entry(row);
138 return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::PltEntry);
139 }
140
doVisit(ElfRelocationSection * section,int row) const141 IndexVisitor::type IndexVisitor::doVisit(ElfRelocationSection* section, int row) const
142 {
143 const auto entry = section->entry(row);
144 return qMakePair<void*, ElfNodeVariant::Type>(entry, ElfNodeVariant::RelocationEntry);
145 }
146
doVisit(DwarfInfo * info,int row) const147 IndexVisitor::type IndexVisitor::doVisit(DwarfInfo* info, int row) const
148 {
149 auto cuDie = info->compilationUnits().at(row);
150 return qMakePair<void*, ElfNodeVariant::Type>(cuDie, ElfNodeVariant::DwarfDie);
151 }
152
doVisit(DwarfDie * die,int row) const153 QPair< void*, ElfNodeVariant::Type > IndexVisitor::doVisit(DwarfDie* die, int row) const
154 {
155 DwarfDie *childDie = die->children().at(row);
156 return qMakePair<void*, ElfNodeVariant::Type>(childDie, ElfNodeVariant::DwarfDie);
157 }
158