diff --git a/CMakeLists.txt b/CMakeLists.txt index 8fc227d0a..197eb8b2d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,10 +6,16 @@ set(CMAKE_CXX_STANDARD 20) find_package(PkgConfig REQUIRED) pkg_search_module(GLFW REQUIRED glfw3) pkg_search_module(GLM REQUIRED glm) +pkg_search_module(CRYPTO REQUIRED libcrypto) pkg_search_module(CAPSTONE REQUIRED capstone) find_package(OpenGL REQUIRED) +find_package(LLVM REQUIRED CONFIG) + +llvm_map_components_to_libnames(demangler) + +include_directories(include ${GLFW_INCLUDE_DIRS} ${CAPSTONE_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS} libs/ImGui/include libs/glad/include) +add_definitions(${LLVM_DEFINITIONS}) -include_directories(include ${GLFW_INCLUDE_DIRS} ${CAPSTONE_INCLUDE_DIRS} libs/ImGui/include libs/glad/include) SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -DIMGUI_IMPL_OPENGL_LOADER_GLAD") if (WIN32) @@ -58,10 +64,12 @@ add_executable(ImHex resource.rc ) +llvm_map_components_to_libnames(LLVM_LIBRARIES Demangle) + if (WIN32) - target_link_libraries(ImHex libglfw3.a libgcc.a libstdc++.a libmagic.a libgnurx.a libtre.a libintl.a libiconv.a shlwapi.lib libcrypto.a libwinpthread.a libcapstone.a) + target_link_libraries(ImHex libglfw3.a libgcc.a libstdc++.a libmagic.a libgnurx.a libtre.a libintl.a libiconv.a shlwapi.lib libcrypto.a libwinpthread.a libcapstone.a ${LLVM_LIBRARIES}) endif (WIN32) if (UNIX) - target_link_libraries(ImHex libglfw.so libmagic.so libcrypto.so libdl.so libcapstone.so) + target_link_libraries(ImHex libglfw.so libmagic.so libcrypto.so libdl.so libcapstone.so ${LLVM_LIBRARIES}) endif (UNIX) \ No newline at end of file diff --git a/include/utils.hpp b/include/utils.hpp index 246db0e7e..8b3525b2d 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -165,25 +165,6 @@ namespace hex { } } - inline std::string demangleItaniumSymbol(const std::string &mangledSymbol) { - size_t length = 0; - int status = 0; - char *demangledSymbol = abi::__cxa_demangle(mangledSymbol.c_str(), nullptr, &length, &status); - - if (demangledSymbol == nullptr) - return "< ??? >"; - - std::string result = demangledSymbol; - - free(demangledSymbol); - - if (status != 0) - result = "< ??? >"; - - return result; - } - - class ScopeExit { public: ScopeExit(std::function func) : m_func(func) {} diff --git a/include/views/view_strings.hpp b/include/views/view_strings.hpp index e40f592dc..96d0f4633 100644 --- a/include/views/view_strings.hpp +++ b/include/views/view_strings.hpp @@ -30,6 +30,11 @@ namespace hex { std::vector m_foundStrings; int m_minimumLength = 5; char *m_filter; + + std::string m_selectedString; + std::string m_demangledName; + + void createStringContextMenu(const FoundString &foundString); }; } \ No newline at end of file diff --git a/source/views/view_strings.cpp b/source/views/view_strings.cpp index 8f24dc3ef..7dbddc505 100644 --- a/source/views/view_strings.cpp +++ b/source/views/view_strings.cpp @@ -5,6 +5,8 @@ #include +#include + using namespace std::literals::string_literals; namespace hex { @@ -24,15 +26,21 @@ namespace hex { } - static void createStringContextMenu(const FoundString &foundString) { - if (ImGui::TableGetHoveredColumn() == 2 && ImGui::IsMouseReleased(1)) + void ViewStrings::createStringContextMenu(const FoundString &foundString) { + if (ImGui::TableGetHoveredColumn() == 2 && ImGui::IsMouseReleased(1) && ImGui::IsItemHovered()) { ImGui::OpenPopup("StringContextMenu"); + this->m_selectedString = foundString.string; + } if (ImGui::BeginPopup("StringContextMenu")) { - if (ImGui::MenuItem("Copy string")) - ImGui::SetClipboardText(foundString.string.c_str()); + if (ImGui::MenuItem("Copy string")) { + ImGui::SetClipboardText(this->m_selectedString.c_str()); + } ImGui::Separator(); - if (ImGui::MenuItem("Copy demangled string")) - ImGui::SetClipboardText(demangleItaniumSymbol(foundString.string).c_str()); + if (ImGui::MenuItem("Demangle")) { + this->m_demangledName = llvm::demangle(this->m_selectedString); + if (!this->m_demangledName.empty()) + View::doLater([]{ ImGui::OpenPopup("Demangled Name"); }); + } ImGui::EndPopup(); } } @@ -140,16 +148,15 @@ namespace hex { Region selectRegion = { foundString.offset, foundString.size }; View::postEvent(Events::SelectionChangeRequest, &selectRegion); } + ImGui::PushID(i + 1); + createStringContextMenu(foundString); + ImGui::PopID(); ImGui::SameLine(); ImGui::Text("0x%08lx : 0x%08lx", foundString.offset, foundString.offset + foundString.size); ImGui::TableNextColumn(); ImGui::Text("0x%04lx", foundString.size); ImGui::TableNextColumn(); ImGui::Text("%s", foundString.string.c_str()); - - ImGui::PushID(i + 1); - createStringContextMenu(foundString); - ImGui::PopID(); } } clipper.End(); @@ -159,6 +166,19 @@ namespace hex { } } ImGui::End(); + + if (ImGui::BeginPopup("Demangled Name")) { + if (ImGui::BeginChild("##scrolling", ImVec2(500, 150))) { + ImGui::Text("Demangled Name"); + ImGui::Separator(); + ImGui::TextWrapped("%s", this->m_demangledName.c_str()); + ImGui::EndChild(); + ImGui::NewLine(); + if (ImGui::Button("Copy")) + ImGui::SetClipboardText(this->m_demangledName.c_str()); + } + ImGui::EndPopup(); + } } void ViewStrings::createMenu() { diff --git a/source/views/view_tools.cpp b/source/views/view_tools.cpp index 823490402..d7d9c33b6 100644 --- a/source/views/view_tools.cpp +++ b/source/views/view_tools.cpp @@ -1,11 +1,12 @@ #include "views/view_tools.hpp" -#include #include #include #include "utils.hpp" +#include + namespace hex { ViewTools::ViewTools() : View("Tools") { @@ -30,9 +31,9 @@ namespace hex { } void ViewTools::drawDemangler() { - if (ImGui::CollapsingHeader("Itanium demangler")) { + if (ImGui::CollapsingHeader("Itanium/MSVC demangler")) { if (ImGui::InputText("Mangled name", this->m_mangledBuffer, 0xF'FFFF)) { - this->m_demangledName = demangleItaniumSymbol(this->m_mangledBuffer); + this->m_demangledName = llvm::demangle(this->m_mangledBuffer); } ImGui::InputText("Demangled name", this->m_demangledName.data(), this->m_demangledName.size(), ImGuiInputTextFlags_ReadOnly);