File indexing completed on 2024-04-14 15:32:43

0001 /******************************************************************
0002  *
0003  * kdbgwin - Helper application for DrKonqi
0004  *
0005  * This file is part of the KDE project
0006  *
0007  * SPDX-FileCopyrightText: 2010 Ilie Halip <lupuroshu@gmail.com>
0008  *
0009  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0010  *****************************************************************/
0011 
0012 #include "mingw_generator.h"
0013 #include <bfd.h>
0014 #include <cxxabi.h>
0015 
0016 MingwGenerator::MingwGenerator(const Process &process)
0017     : AbstractBTGenerator(process)
0018     , file(NULL)
0019     , func(NULL)
0020     , line(0)
0021 {
0022 }
0023 
0024 struct MyBFD {
0025     QString module;
0026     bfd *abfd;
0027     asymbol **syms;
0028     MyBFD()
0029         : abfd(0)
0030         , syms(0)
0031     {
0032     }
0033     MyBFD(const QString &module, bfd *abfd, asymbol **syms)
0034     {
0035         this->module = module;
0036         this->abfd = abfd;
0037         this->syms = syms;
0038     }
0039     bool operator==(const MyBFD &other)
0040     {
0041         return module == other.module;
0042     }
0043 };
0044 
0045 typedef QList<MyBFD> TBFDList;
0046 TBFDList bfds;
0047 
0048 asection *text = NULL;
0049 
0050 bool MingwGenerator::Init()
0051 {
0052     bfd_init();
0053     return true;
0054 }
0055 
0056 void MingwGenerator::UnInit()
0057 {
0058 }
0059 
0060 void MingwGenerator::FrameChanged()
0061 {
0062     QString modPath = GetModulePath();
0063     bool existsSymbol = false;
0064     TSymbolsMap::const_iterator i = m_symbolsMap.constFind(modPath);
0065     if (i == m_symbolsMap.cend()) {
0066         return;
0067     }
0068     MyBFD dummy(modPath, NULL, NULL);
0069     int pos = bfds.indexOf(dummy);
0070     if (pos == -1) {
0071         return;
0072     }
0073     MyBFD bfd = bfds[pos];
0074     text = bfd_get_section_by_name(bfd.abfd, ".text");
0075     long offset = m_currentFrame.AddrPC.Offset - text->vma;
0076     file = DEFAULT_FILE;
0077     func = DEFAULT_FUNC;
0078     line = DEFAULT_LINE;
0079     if (offset > 0) {
0080         bfd_find_nearest_line(bfd.abfd, text, bfd.syms, offset, &file, &func, (unsigned int *)&line);
0081     }
0082 }
0083 
0084 QString MingwGenerator::GetFunctionName()
0085 {
0086     if (func != NULL) {
0087         char *realname = abi::__cxa_demangle(func, NULL, NULL, NULL);
0088         if (realname != NULL) {
0089             QString strReturn = QString::fromLatin1(realname);
0090             free(realname);
0091             return strReturn;
0092         } else {
0093             return QString::fromLatin1(func);
0094         }
0095     }
0096     return QString::fromLatin1(DEFAULT_FUNC);
0097 }
0098 
0099 QString MingwGenerator::GetFile()
0100 {
0101     if (file != NULL) {
0102         return QString::fromLatin1(file);
0103     }
0104     return QString::fromLatin1(DEFAULT_FILE);
0105 }
0106 
0107 int MingwGenerator::GetLine()
0108 {
0109     if (line > 0) {
0110         return line;
0111     }
0112     return -1;
0113 }
0114 
0115 void MingwGenerator::LoadSymbol(const QString &module, DWORD64 dwBaseAddr)
0116 {
0117     QString symbolFile = module;
0118     symbolFile.chop(4);
0119     symbolFile.append(QStringLiteral(".sym"));
0120 
0121     m_symbolsMap[module] = false; // default
0122     QString symbolType;
0123     do {
0124         bfd *abfd = bfd_openr(symbolFile.toLatin1().data(), NULL);
0125         if (abfd == NULL) {
0126             symbolType = QString::fromLatin1("no symbols loaded");
0127             break;
0128         }
0129         bfd_check_format(abfd, bfd_object);
0130         unsigned storage_needed = bfd_get_symtab_upper_bound(abfd);
0131         assert(storage_needed > 4);
0132         if (storage_needed <= 4) {
0133             // i don't know why the minimum value for this var is 4...
0134             symbolType = QString::fromLatin1("no symbols loaded");
0135             break;
0136         }
0137         asymbol **syms = (asymbol **)malloc(storage_needed);
0138         assert(syms);
0139         if (syms == NULL) {
0140             symbolType = QString::fromLatin1("no symbols loaded");
0141             break;
0142         }
0143         symbolType = QString::fromLatin1("symbols loaded");
0144         m_symbolsMap[module] = true;
0145 
0146         bfds.push_back(MyBFD(module, abfd, syms));
0147     } while (0);
0148 
0149     QString strOutput = QString::fromLatin1("Loaded %1 (%2)").arg(module).arg(symbolType);
0150     Q_EMIT DebugLine(strOutput);
0151 }