File indexing completed on 2025-04-20 10:55:33
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 }