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 }