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 "parentvisitor.h" 0019 #include "elfmodel.h" 0020 0021 #include <elf/elffileset.h> 0022 #include <elf/elfgnusymbolversiondefinitionauxiliaryentry.h> 0023 #include <elf/elfgnusymbolversionrequirement.h> 0024 #if HAVE_DWARF 0025 #include <dwarf/dwarfcudie.h> 0026 #endif 0027 0028 #include <elf.h> 0029 0030 #include <cassert> 0031 0032 ParentVisitor::ParentVisitor(const ElfModel* model) : m_model(model) 0033 { 0034 } 0035 0036 ParentVisitor::type ParentVisitor::doVisit(ElfFile* file, int) const 0037 { 0038 int row = 0; 0039 for (; row < m_model->fileSet()->size(); ++row) { 0040 if (m_model->fileSet()->file(row) == file) 0041 break; 0042 } 0043 return makeParent(m_model->fileSet(), ElfNodeVariant::FileSet, row); 0044 } 0045 0046 ParentVisitor::type ParentVisitor::doVisit(ElfSection* section, int) const 0047 { 0048 auto file = section->file(); 0049 if (file->isSeparateDebugFile()) 0050 file = file->contentFile(); 0051 return makeParent(file, ElfNodeVariant::File, section->header()->sectionIndex()); 0052 } 0053 0054 ParentVisitor::type ParentVisitor::doVisit(ElfGNUSymbolVersionDefinition* verDef, int) const 0055 { 0056 int row = -1; 0057 for (uint i = 0; i < verDef->section()->entryCount(); ++i) { 0058 if (verDef->section()->definition(i) == verDef) { 0059 row = i; 0060 break; 0061 } 0062 } 0063 assert(row >= 0); 0064 return makeParent(verDef->section(), ElfNodeVariant::VersionDefinitionSection, row); 0065 } 0066 0067 ParentVisitor::type ParentVisitor::doVisit(ElfGNUSymbolVersionRequirement *verNeed, int) const 0068 { 0069 int row = -1; 0070 for (uint i = 0; i < verNeed->section()->entryCount(); ++i) { 0071 if (verNeed->section()->requirement(i) == verNeed) { 0072 row = i; 0073 break; 0074 } 0075 } 0076 assert(row >= 0); 0077 return makeParent(verNeed->section(), ElfNodeVariant::VersionRequirementsSection, row); 0078 } 0079 0080 ParentVisitor::type ParentVisitor::doVisit(ElfGotEntry* entry, int) const 0081 { 0082 return makeParent(entry->section(), ElfNodeVariant::GotSection, entry->index()); 0083 } 0084 0085 ParentVisitor::type ParentVisitor::doVisit(ElfPltEntry* entry, int) const 0086 { 0087 return makeParent(entry->section(), ElfNodeVariant::PltSection, entry->index()); 0088 } 0089 0090 ParentVisitor::type ParentVisitor::doVisit(ElfSymbolTableEntry *symbol, int) const 0091 { 0092 return makeParent(const_cast<ElfSymbolTableSection*>(symbol->symbolTable()), ElfNodeVariant::SymbolTableSection, symbol->index()); 0093 } 0094 0095 #if HAVE_DWARF 0096 ParentVisitor::type ParentVisitor::doVisit(DwarfInfo* info, int) const 0097 { 0098 return makeParent(info->elfFile(), ElfNodeVariant::File, info->elfFile()->indexOfSection(".debug_info")); 0099 } 0100 0101 ParentVisitor::type ParentVisitor::doVisit(DwarfDie* die, int) const 0102 { 0103 if (die->parentDie()) { 0104 return makeParent(die->parentDie(), ElfNodeVariant::DwarfDie, die->parentDie()->children().indexOf(die)); 0105 } 0106 return makeParent(die->dwarfInfo(), ElfNodeVariant::DwarfInfo, die->dwarfInfo()->compilationUnits().indexOf(static_cast<DwarfCuDie*>(die))); 0107 } 0108 #endif 0109 0110 ParentVisitor::type ParentVisitor::makeParent(void* payload, ElfNodeVariant::Type type, int row) const 0111 { 0112 return qMakePair(m_model->makeVariant(payload, type), row); 0113 }