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

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 "elfdynamicentry.h"
0019 #include "elfdynamicsection.h"
0020 #include "elfstringtablesection.h"
0021 #include <QObject>
0022 
0023 #include <elf.h>
0024 
0025 #include <cassert>
0026 
0027 ElfDynamicEntry::ElfDynamicEntry(const ElfDynamicSection* section) : m_section(section)
0028 {
0029 }
0030 
0031 ElfDynamicEntry::~ElfDynamicEntry()
0032 {
0033 }
0034 
0035 const ElfDynamicSection* ElfDynamicEntry::dynamicSection() const
0036 {
0037     return m_section;
0038 }
0039 
0040 QString ElfDynamicEntry::tagName() const
0041 {
0042     switch (tag()) {
0043         case DT_NULL: return QStringLiteral("<null>");
0044         case DT_NEEDED: return QStringLiteral("Needed library");
0045         case DT_PLTRELSZ: return QStringLiteral("PLT reloc size");
0046         case DT_PLTGOT: return QStringLiteral("PLTGOT");
0047         case DT_HASH: return QStringLiteral("Symbol hash table address");
0048         case DT_STRTAB: return QStringLiteral("String table address");
0049         case DT_SYMTAB: return QStringLiteral("Symbol table address");
0050         case DT_RELA: return QStringLiteral("Rela reloc address");
0051         case DT_RELASZ: return QStringLiteral("Rela reloc size");
0052         case DT_RELAENT: return QStringLiteral("Rela reloc entry size");
0053         case DT_STRSZ: return QStringLiteral("String table size");
0054         case DT_SYMENT: return QStringLiteral("Symbol table entry size");
0055         case DT_INIT: return QStringLiteral("Init function address");
0056         case DT_FINI: return QStringLiteral("Termination function address");
0057         case DT_SONAME: return QStringLiteral("Shared object name");
0058         case DT_RPATH: return QStringLiteral("RPATH");
0059         case DT_SYMBOLIC: return QStringLiteral("Symbol search start");
0060         case DT_REL: return QStringLiteral("Rel reloc address");
0061         case DT_RELSZ: return QStringLiteral("Rel reloc size");
0062         case DT_RELENT: return QStringLiteral("Rel reloc entry size");
0063         case DT_PLTREL: return QStringLiteral("Reloc type in PLT");
0064         case DT_DEBUG: return QStringLiteral("Debug");
0065         case DT_TEXTREL: return QStringLiteral("Reloc might modify .text");
0066         case DT_JMPREL: return QStringLiteral("PLT reloc address");
0067         case DT_BIND_NOW: return QStringLiteral("BIND_NOW");
0068         case DT_INIT_ARRAY: return QStringLiteral("Init function address array");
0069         case DT_FINI_ARRAY: return QStringLiteral("Termination function address array");
0070         case DT_INIT_ARRAYSZ: return QStringLiteral("Init function address array size");
0071         case DT_FINI_ARRAYSZ: return QStringLiteral("Termination function address array size");
0072         case DT_RUNPATH: return QStringLiteral("RUNPATH");
0073         case DT_FLAGS: return QStringLiteral("Flags");
0074         case DT_PREINIT_ARRAY: return QStringLiteral("Preinit function address array");
0075         case DT_PREINIT_ARRAYSZ: return QStringLiteral("Preinit function address array size");
0076 #if 0
0077         #define DT_GNU_PRELINKED 0x6ffffdf5     /* Prelinking timestamp */
0078         #define DT_GNU_CONFLICTSZ 0x6ffffdf6    /* Size of conflict section */
0079         #define DT_GNU_LIBLISTSZ 0x6ffffdf7     /* Size of library list */
0080         #define DT_CHECKSUM     0x6ffffdf8
0081         #define DT_PLTPADSZ     0x6ffffdf9
0082         #define DT_MOVEENT      0x6ffffdfa
0083         #define DT_MOVESZ       0x6ffffdfb
0084         #define DT_FEATURE_1    0x6ffffdfc      /* Feature selection (DTF_*).  */
0085         #define DT_POSFLAG_1    0x6ffffdfd      /* Flags for DT_* entries, effecting the following DT_* entry.  */
0086 #endif
0087         case DT_SYMINSZ: return QStringLiteral("Syminfo table size");
0088         case DT_SYMINENT: return QStringLiteral("Syminfo table entry size");
0089         case DT_GNU_HASH: return QStringLiteral("GNU hash table address");
0090         case DT_TLSDESC_PLT: return QStringLiteral("TLS description PLT");
0091         case DT_TLSDESC_GOT: return QStringLiteral("TLS description GOT");
0092         case DT_GNU_CONFLICT: return QStringLiteral("GNU conflict section");
0093         case DT_GNU_LIBLIST: return QStringLiteral("GNU library list");
0094 #if 0
0095         #define DT_CONFIG       0x6ffffefa      /* Configuration information.  */
0096         #define DT_DEPAUDIT     0x6ffffefb      /* Dependency auditing.  */
0097         #define DT_AUDIT        0x6ffffefc      /* Object auditing.  */
0098         #define DT_PLTPAD       0x6ffffefd      /* PLT padding.  */
0099         #define DT_MOVETAB      0x6ffffefe      /* Move table.  */
0100         #define DT_SYMINFO      0x6ffffeff      /* Syminfo table.  */
0101 #endif
0102         case DT_VERSYM: return QStringLiteral("GNU version symbol");
0103         case DT_RELACOUNT: return QStringLiteral("Rela count");
0104         case DT_RELCOUNT: return QStringLiteral("Rel count");
0105         case DT_FLAGS_1: return QStringLiteral("State flags");
0106         case DT_VERDEF: return QStringLiteral("Address of version definition table");
0107         case DT_VERDEFNUM: return QStringLiteral("Number of version definitions");
0108         case DT_VERNEED: return QStringLiteral("Needed versions table address");
0109         case DT_VERNEEDNUM: return QStringLiteral("Number of needed versions");
0110         default:
0111             return QObject::tr("unknown (%1)").arg(tag());
0112     }
0113 
0114     return QString();
0115 }
0116 
0117 bool ElfDynamicEntry::isStringValue() const
0118 {
0119     return tag() == DT_NEEDED
0120         || tag() == DT_SONAME
0121         || tag() == DT_RPATH
0122         || tag() == DT_RUNPATH
0123     ; // TODO complete
0124 }
0125 
0126 const char* ElfDynamicEntry::stringValue() const
0127 {
0128     assert(isStringValue());
0129     return dynamicSection()->linkedSection<ElfStringTableSection>()->string(value());
0130 }
0131 
0132 bool ElfDynamicEntry::isAddress() const
0133 {
0134     switch (tag()) {
0135         case DT_PLTGOT:
0136         case DT_HASH:
0137         case DT_STRTAB:
0138         case DT_SYMTAB:
0139         case DT_RELA:
0140         case DT_INIT:
0141         case DT_FINI:
0142         case DT_REL:
0143         case DT_JMPREL:
0144         case DT_INIT_ARRAY:
0145         case DT_FINI_ARRAY:
0146         case DT_PREINIT_ARRAY:
0147         case DT_VERSYM:
0148         case DT_VERDEF:
0149         case DT_VERNEED:
0150             return true;
0151     }
0152 
0153     return tag() >= DT_ADDRRNGLO && tag() <= DT_ADDRRNGHI;
0154 }