File indexing completed on 2024-05-19 05:44:10
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 "config-elf-dissector.h" 0019 #include "dwarfprinter.h" 0020 0021 #if HAVE_DWARF 0022 #include <dwarf/dwarfexpression.h> 0023 #include <dwarf/dwarfranges.h> 0024 #include <dwarf/dwarfdie.h> 0025 0026 #include <libdwarf.h> 0027 #endif 0028 0029 #include <QMetaType> 0030 #include <QString> 0031 0032 #include <cassert> 0033 #include <type_traits> 0034 0035 const char* DwarfPrinter::virtuality(DwarfVirtuality v) 0036 { 0037 #if HAVE_DWARF 0038 const char *str = nullptr; 0039 const auto res = dwarf_get_VIRTUALITY_name(static_cast<int>(v), &str); 0040 if (res != DW_DLV_OK) 0041 return nullptr; 0042 return str; 0043 #else 0044 return nullptr; 0045 #endif 0046 } 0047 0048 QByteArray DwarfPrinter::ranges(const DwarfRanges& ranges) 0049 { 0050 #if HAVE_DWARF 0051 QByteArray b; 0052 for (int i = 0; i < ranges.size(); ++i) { 0053 const auto r = ranges.entry(i); 0054 static_assert(std::is_same< decltype(r->dwr_addr1), Dwarf_Addr >::value, "Incompatible DWARFs"); 0055 static_assert(std::is_same< decltype(r->dwr_addr2), Dwarf_Addr >::value, "Incompatible DWARFs"); 0056 static_assert( std::is_convertible<Dwarf_Addr, qulonglong>::value, "Incompatible DWARFs" ); 0057 if (r->dwr_type == DW_RANGES_ADDRESS_SELECTION) { 0058 if (r->dwr_addr2 != 0) 0059 b += "base address: 0x" + QByteArray::number(static_cast<qulonglong>(r->dwr_addr2), 16) + ' '; 0060 } else { 0061 b += "[0x" + QByteArray::number(static_cast<qulonglong>(r->dwr_addr1), 16); 0062 b += ", 0x" + QByteArray::number(static_cast<qulonglong>(r->dwr_addr2), 16); 0063 b += "]\n"; 0064 } 0065 } 0066 return b; 0067 #else 0068 return {}; 0069 #endif 0070 } 0071 0072 void DwarfPrinter::registerConverterFunctions() 0073 { 0074 #if HAVE_DWARF 0075 QMetaType::registerConverter<DwarfExpression, QString>(&DwarfExpression::displayString); 0076 QMetaType::registerConverter<DwarfVirtuality, QString>([](DwarfVirtuality v){ 0077 return QString::fromLatin1(DwarfPrinter::virtuality(v)); 0078 }); 0079 QMetaType::registerConverter<DwarfRanges, QString>([](const DwarfRanges &r){ 0080 return QString::fromLatin1(DwarfPrinter::ranges(r)); 0081 }); 0082 #endif 0083 } 0084 0085 QString DwarfPrinter::dieRichText(DwarfDie* die) 0086 { 0087 #if HAVE_DWARF 0088 assert(die); 0089 QString s; 0090 s += "TAG: " + QLatin1String(die->tagName()) + "<br/>"; 0091 s += "Name: " + QString::fromUtf8(die->name()).toHtmlEscaped() + "<br/>"; 0092 s += "Offset: " + QString::number(die->offset()) + "<br/>"; 0093 foreach (const auto attrType, die->attributes()) { 0094 const QVariant attrValue = die->attribute(attrType); 0095 QString attrValueStr; 0096 if (DwarfDie *die = attrValue.value<DwarfDie*>()) 0097 attrValueStr = die->displayName(); 0098 else 0099 attrValueStr = attrValue.toString(); 0100 s += QLatin1String(die->attributeName(attrType)) + ": " + attrValueStr.toHtmlEscaped() + "<br/>"; 0101 } 0102 return s; 0103 #else 0104 return {}; 0105 #endif 0106 }