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

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 #ifndef ELFNODEVISITOR_H
0019 #define ELFNODEVISITOR_H
0020 
0021 #include "config-elf-dissector.h"
0022 
0023 #include <elf/elfheader.h>
0024 #include <elf/elfsymboltablesection.h>
0025 #include <elf/elfdynamicsection.h>
0026 #include <elf/elfgnudebuglinksection.h>
0027 #include <elf/elfgnusymbolversiondefinition.h>
0028 #include <elf/elfgnusymbolversiondefinitionssection.h>
0029 #include <elf/elfgnusymbolversionrequirementssection.h>
0030 #include <elf/elfgotsection.h>
0031 #include <elf/elfhashsection.h>
0032 #include <elf/elfgnuhashsection.h>
0033 #include <elf/elfnotesection.h>
0034 #include <elf/elfpltsection.h>
0035 #include <elf/elfrelocationsection.h>
0036 #include <elf/elfrelocationentry.h>
0037 
0038 #if HAVE_DWARF
0039 #include <dwarf/dwarfdie.h>
0040 #include <dwarf/dwarfinfo.h>
0041 #endif
0042 
0043 #include "elfnodevariant.h"
0044 
0045 #include <qglobal.h>
0046 
0047 #include <cassert>
0048 
0049 class ElfDynamicEntry;
0050 class ElfFile;
0051 class ElfFileSet;
0052 class ElfGNUSymbolVersionRequirementAuxiliaryEntry;
0053 class ElfPltEntry;
0054 
0055 template <typename T>
0056 class ElfNodeVisitor
0057 {
0058 public:
0059     typedef T type;
0060 
0061     ElfNodeVisitor() = default;
0062     ElfNodeVisitor(const ElfNodeVisitor&) = delete;
0063     virtual ~ElfNodeVisitor() = default;
0064     ElfNodeVisitor& operator=(ElfNodeVisitor&) = delete;
0065 
0066     inline T visit(ElfNodeVariant *node, int arg = 0) const
0067     {
0068         switch (node->type) {
0069             case ElfNodeVariant::Invalid:
0070                 assert(false);
0071                 break;
0072             case ElfNodeVariant::FileSet:
0073                 return doVisit(node->value<ElfFileSet>(), arg);
0074             case ElfNodeVariant::File:
0075                 return doVisit(node->value<ElfFile>(), arg);
0076             case ElfNodeVariant::Section:
0077                 return doVisit(node->value<ElfSection>(), arg);
0078             case ElfNodeVariant::SymbolTableSection:
0079                 return doVisit(node->value<ElfSymbolTableSection>(), arg);
0080             case ElfNodeVariant::SymbolTableEntry:
0081                 return doVisit(node->value<ElfSymbolTableEntry>(), arg);
0082             case ElfNodeVariant::DebugLinkSection:
0083                 return doVisit(node->value<ElfGnuDebugLinkSection>(), arg);
0084             case ElfNodeVariant::DynamicSection:
0085                 return doVisit(node->value<ElfDynamicSection>(), arg);
0086             case ElfNodeVariant::DynamicEntry:
0087                 return doVisit(node->value<ElfDynamicEntry>(), arg);
0088             case ElfNodeVariant::GotSection:
0089                 return doVisit(node->value<ElfGotSection>(), arg);
0090             case ElfNodeVariant::GotEntry:
0091                 return doVisit(node->value<ElfGotEntry>(), arg);
0092             case ElfNodeVariant::HashSection:
0093                 return doVisit(node->value<ElfHashSection>(), arg);
0094             case ElfNodeVariant::NoteSection:
0095                 return doVisit(node->value<ElfNoteSection>(), arg);
0096             case ElfNodeVariant::NoteEntry:
0097                 return doVisit(node->value<ElfNoteEntry>(), arg);
0098             case ElfNodeVariant::PltSection:
0099                 return doVisit(node->value<ElfPltSection>(), arg);
0100             case ElfNodeVariant::PltEntry:
0101                 return doVisit(node->value<ElfPltEntry>(), arg);
0102             case ElfNodeVariant::RelocationSection:
0103                 return doVisit(node->value<ElfRelocationSection>(), arg);
0104             case ElfNodeVariant::RelocationEntry:
0105                 return doVisit(node->value<ElfRelocationEntry>(), arg);
0106             case ElfNodeVariant::VersionDefinitionSection:
0107                 return doVisit(node->value<ElfGNUSymbolVersionDefinitionsSection>(), arg);
0108             case ElfNodeVariant::VersionDefinitionEntry:
0109                 return doVisit(node->value<ElfGNUSymbolVersionDefinition>(), arg);
0110             case ElfNodeVariant::VersionDefinitionAuxiliaryEntry:
0111                 return doVisit(node->value<ElfGNUSymbolVersionDefinitionAuxiliaryEntry>(), arg);
0112             case ElfNodeVariant::VersionRequirementsSection:
0113                 return doVisit(node->value<ElfGNUSymbolVersionRequirementsSection>(), arg);
0114             case ElfNodeVariant::VersionRequirementEntry:
0115                 return doVisit(node->value<ElfGNUSymbolVersionRequirement>(), arg);
0116             case ElfNodeVariant::VersionRequirementAuxiliaryEntry:
0117                 return doVisit(node->value<ElfGNUSymbolVersionRequirementAuxiliaryEntry>(), arg);
0118 #if HAVE_DWARF
0119             case ElfNodeVariant::DwarfInfo:
0120                 return doVisit(node->value<DwarfInfo>(), arg);
0121             case ElfNodeVariant::DwarfDie:
0122                 return doVisit(node->value<DwarfDie>(), arg);
0123 #endif
0124         }
0125 
0126         assert(false);
0127         Q_UNREACHABLE();
0128     }
0129 
0130 protected:
0131     virtual T doVisit(ElfFileSet *fileSet, int arg) const
0132     {
0133         Q_UNUSED(fileSet);
0134         Q_UNUSED(arg);
0135         return T();
0136     }
0137 
0138     virtual T doVisit(ElfFile* file, int arg) const
0139     {
0140         Q_UNUSED(file);
0141         Q_UNUSED(arg);
0142         return T();
0143     }
0144     virtual T doVisit(ElfSection* section, int arg) const
0145     {
0146         Q_UNUSED(section);
0147         Q_UNUSED(arg);
0148         return T();
0149     }
0150     virtual T doVisit(ElfSymbolTableSection *symtab, int arg) const
0151     {
0152         return doVisit(static_cast<ElfSection*>(symtab), arg);
0153     }
0154     virtual T doVisit(ElfSymbolTableEntry *entry, int arg) const
0155     {
0156         Q_UNUSED(entry);
0157         Q_UNUSED(arg);
0158         return T();
0159     }
0160     virtual T doVisit(ElfGnuDebugLinkSection *section, int arg) const
0161     {
0162         return doVisit(static_cast<ElfSection*>(section), arg);
0163     }
0164     virtual T doVisit(ElfDynamicSection* section, int arg) const
0165     {
0166         return doVisit(static_cast<ElfSection*>(section), arg);
0167     }
0168     virtual T doVisit(ElfDynamicEntry*, int) const
0169     {
0170         return T();
0171     }
0172     virtual T doVisit(ElfHashSection *section, int arg) const
0173     {
0174         return doVisit(static_cast<ElfSection*>(section), arg);
0175     }
0176     virtual T doVisit(ElfGNUSymbolVersionDefinitionsSection *section, int arg) const
0177     {
0178         return doVisit(static_cast<ElfSection*>(section), arg);
0179     }
0180     virtual T doVisit(ElfGNUSymbolVersionDefinition*, int) const
0181     {
0182         return T();
0183     }
0184     virtual T doVisit(ElfGNUSymbolVersionDefinitionAuxiliaryEntry*, int) const
0185     {
0186         return T();
0187     }
0188     virtual T doVisit(ElfGNUSymbolVersionRequirementsSection *section, int arg) const
0189     {
0190         return doVisit(static_cast<ElfSection*>(section), arg);
0191     }
0192     virtual T doVisit(ElfGNUSymbolVersionRequirement*, int) const
0193     {
0194         return T();
0195     }
0196     virtual T doVisit(ElfGNUSymbolVersionRequirementAuxiliaryEntry*, int) const
0197     {
0198         return T();
0199     }
0200     virtual T doVisit(ElfGotSection *section, int arg) const
0201     {
0202         return doVisit(static_cast<ElfSection*>(section), arg);
0203     }
0204     virtual T doVisit(ElfGotEntry*, int) const
0205     {
0206         return T();
0207     }
0208     virtual T doVisit(ElfNoteSection* section, int arg) const
0209     {
0210         return doVisit(static_cast<ElfSection*>(section), arg);
0211     }
0212     virtual T doVisit(ElfNoteEntry*, int) const
0213     {
0214         return T();
0215     }
0216     virtual T doVisit(ElfPltSection *section, int arg) const
0217     {
0218         return doVisit(static_cast<ElfSection*>(section), arg);
0219     }
0220     virtual T doVisit(ElfPltEntry*, int) const
0221     {
0222         return T();
0223     }
0224     virtual T doVisit(ElfRelocationSection *section, int arg) const
0225     {
0226         return doVisit(static_cast<ElfSection*>(section), arg);
0227     }
0228     virtual T doVisit(ElfRelocationEntry*, int) const
0229     {
0230         return T();
0231     }
0232 #if HAVE_DWARF
0233     virtual T doVisit(DwarfInfo*, int) const
0234     {
0235         return T();
0236     }
0237     virtual T doVisit(DwarfDie*, int) const
0238     {
0239        return T();
0240     }
0241 #endif
0242 };
0243 
0244 #endif