File indexing completed on 2024-05-12 05:43:31
0001 /* 0002 Copyright (C) 2015 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 "notesectionprinter.h" 0019 #include <elf/elfnoteentry.h> 0020 0021 #include <QByteArray> 0022 0023 #include <elf.h> 0024 0025 #include <cassert> 0026 0027 struct NoteType { 0028 uint32_t type; 0029 const char* name; 0030 }; 0031 0032 #define NT(type) { NT_ ## type, #type } 0033 0034 static const NoteType note_types[] { 0035 NT(GNU_ABI_TAG), 0036 NT(GNU_HWCAP), 0037 NT(GNU_BUILD_ID), 0038 NT(GNU_GOLD_VERSION) 0039 }; 0040 0041 #undef NT 0042 0043 static const int note_types_size = sizeof(note_types) / sizeof(NoteType); 0044 0045 #ifdef Q_OS_FREEBSD 0046 // FreeBSD elf-common.h has no ELF_NOTE_OS_* and those are strings, anyway 0047 0048 static const NoteType os_types[] { 0049 { 0, ELF_NOTE_FREEBSD }, 0050 // TODO: is that a sensible value? 0051 // TODO: there's also NETBSD, SOLARIS and GNU 0052 }; 0053 0054 0055 #else 0056 #define OS(type) { ELF_NOTE_OS_ ## type, #type } 0057 0058 static const NoteType os_types[] { 0059 OS(LINUX), 0060 OS(GNU), 0061 OS(SOLARIS2), 0062 OS(FREEBSD) 0063 }; 0064 0065 #undef OS 0066 #endif 0067 0068 static const int os_types_size = sizeof(note_types) / sizeof(NoteType); 0069 0070 static const NoteType* noteType(uint32_t type, const NoteType *table, int size) 0071 { 0072 for (int i = 0; i < size; ++i) { 0073 if (table[i].type == type) 0074 return &table[i]; 0075 } 0076 return nullptr; 0077 } 0078 0079 const char* NoteSectionPrinter::typeDisplayString(ElfNoteEntry* entry) 0080 { 0081 if (!entry->isGNUVendorNote()) 0082 return entry->name(); 0083 0084 const auto nt = noteType(entry->type(), note_types, note_types_size); 0085 if (!nt) 0086 return entry->name(); 0087 return nt->name; 0088 } 0089 0090 QByteArray NoteSectionPrinter::abi(ElfNoteEntry* entry) 0091 { 0092 assert(entry->isGNUVendorNote()); 0093 assert(entry->type() == NT_GNU_ABI_TAG); 0094 assert(entry->descriptionSize() >= 16); 0095 QByteArray r; 0096 0097 struct ABIDesc { 0098 uint32_t os; 0099 uint32_t major; 0100 uint32_t minor; 0101 uint32_t patch; 0102 }; 0103 const ABIDesc *abiDesc = reinterpret_cast<const ABIDesc*>(entry->descriptionData()); 0104 0105 const auto osType = noteType(abiDesc->os, os_types, os_types_size); 0106 if (osType) { 0107 r += osType->name; 0108 } else { 0109 r += "Unknown OS"; 0110 } 0111 0112 r += ' '; 0113 r += QByteArray::number(abiDesc->major); 0114 r += '.'; 0115 r += QByteArray::number(abiDesc->minor); 0116 r += '.'; 0117 r += QByteArray::number(abiDesc->patch); 0118 0119 return r; 0120 }