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

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 "dwarfcudie.h"
0019 #include "dwarfline.h"
0020 
0021 #include <libdwarf.h>
0022 
0023 #include <QFileInfo>
0024 
0025 DwarfCuDie::DwarfCuDie(Dwarf_Die die, DwarfInfo* info) : DwarfDie(die, info)
0026 {
0027 
0028 }
0029 
0030 DwarfCuDie::~DwarfCuDie()
0031 {
0032     for (int i = 0; i < m_srcFileCount; ++i) {
0033         dwarf_dealloc(dwarfHandle(), m_srcFiles[i], DW_DLA_STRING);
0034     }
0035     dwarf_dealloc(dwarfHandle(), m_srcFiles, DW_DLA_LIST);
0036 
0037     for (int i = 0; i < m_lineCount; ++i) {
0038         dwarf_dealloc(dwarfHandle(), m_lines[i], DW_DLA_LINE);
0039     }
0040     dwarf_dealloc(dwarfHandle(), m_lines, DW_DLA_LIST);
0041 
0042     dwarf_dealloc(dwarfHandle(), m_die, DW_DLA_DIE);
0043 }
0044 
0045 const char* DwarfCuDie::sourceFileForIndex(int sourceIndex) const
0046 {
0047     if (!m_srcFiles) {
0048         auto res = dwarf_srcfiles(m_die, &m_srcFiles, &m_srcFileCount, nullptr);
0049         if (res != DW_DLV_OK)
0050             return nullptr;
0051     }
0052 
0053     Q_ASSERT(sourceIndex >= 0);
0054     Q_ASSERT(sourceIndex < m_srcFileCount);
0055     return m_srcFiles[sourceIndex];
0056 }
0057 
0058 void DwarfCuDie::loadLines() const
0059 {
0060     if (m_lines)
0061         return;
0062 
0063     dwarf_srclines(m_die, &m_lines, &m_lineCount, nullptr);
0064 }
0065 
0066 DwarfLine DwarfCuDie::lineForAddress(Dwarf_Addr addr) const
0067 {
0068     loadLines();
0069     // ### is this sorted in any way?
0070     for (int i = 0; i < m_lineCount; ++i) {
0071         DwarfLine line(m_lines[i]);
0072         if (line.address() == addr)
0073             return line;
0074     }
0075 
0076     return {};
0077 }
0078 
0079 QString DwarfCuDie::sourceFileForLine(DwarfLine line) const
0080 {
0081     char* srcFile = nullptr;
0082     auto res = dwarf_linesrc(line.handle(), &srcFile, nullptr);
0083     if (res != DW_DLV_OK)
0084         return {};
0085     auto fileName = QString::fromUtf8(srcFile);
0086     dwarf_dealloc(dwarfHandle(), srcFile, DW_DLA_STRING);
0087 
0088     QFileInfo fi(fileName);
0089     if (fi.exists())
0090         return fi.canonicalFilePath();
0091     return fileName;
0092 }