From 0ec10ac80845fe5ffe3ccf1fc54785036d7b750d Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Wed, 1 Dec 2021 08:34:45 +0000 Subject: [PATCH 01/17] Move error flags to Ripes lib to supress warnings in external projects --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dcbbb22f..58df09371 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ endif() if(MSVC) add_definitions(/bigobj) # Allow big object elseif(MINGW) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj") # Allow big object + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mbig-obj") # Allow big object endif() ###################################################################### diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a31bdf33d..51c16661b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,6 +42,14 @@ function(create_ripes_lib NAME) endif() endfunction() +# Error flags on everything but MSVC +if(NOT MSVC) + set(CMAKE_CXX_FLAGS "-Wextra -Wall \ + -Werror=switch -Werror=return-type \ + -Werror=unreachable-code") +elseif(MINGW) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa") +endif() # Create the parent library. This will include everything in the current directory. create_ripes_lib(${RIPES_LIB} FIXED_NAME EXCLUDE_SRC_INC) From b28dc0d1a8317b852ceb7703272a64bf6f60aca4 Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Wed, 1 Dec 2021 09:17:26 +0000 Subject: [PATCH 02/17] Add libelfin submodule --- .gitmodules | 3 +++ external/libelfin_cmake/libelfin | 1 + 2 files changed, 4 insertions(+) create mode 160000 external/libelfin_cmake/libelfin diff --git a/.gitmodules b/.gitmodules index 7594bfadc..dfd6c0ada 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "external/ELFIO"] path = external/ELFIO url = https://github.com/serge1/ELFIO +[submodule "external/libelfin_cmake/libelfin"] + path = external/libelfin_cmake/libelfin + url = https://github.com/aclements/libelfin diff --git a/external/libelfin_cmake/libelfin b/external/libelfin_cmake/libelfin new file mode 160000 index 000000000..946dde57e --- /dev/null +++ b/external/libelfin_cmake/libelfin @@ -0,0 +1 @@ +Subproject commit 946dde57e5caef8297b9339f3a7971401d540840 From dafd5b15c913ec255a61e15f8fbccca63e229f0d Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Wed, 1 Dec 2021 09:17:53 +0000 Subject: [PATCH 03/17] Add libelfin CMakeLists --- external/CMakeLists.txt | 2 + external/libelfin_cmake/CMakeLists.txt | 64 ++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 external/libelfin_cmake/CMakeLists.txt diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 19b94d0d6..e4e22e045 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -11,3 +11,5 @@ add_subdirectory(fancytabbar) add_subdirectory(VSRTL) set(VSRTL_BUILD_APP OFF) set(VSRTL_BUILD_TESTS OFF) + +add_subdirectory(libelfin_cmake) diff --git a/external/libelfin_cmake/CMakeLists.txt b/external/libelfin_cmake/CMakeLists.txt new file mode 100644 index 000000000..2e8f73cf1 --- /dev/null +++ b/external/libelfin_cmake/CMakeLists.txt @@ -0,0 +1,64 @@ +cmake_minimum_required(VERSION 3.1) +project(libelfin CXX) + +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(PythonInterp 3 REQUIRED) +set(source_subfolder "${CMAKE_CURRENT_SOURCE_DIR}/libelfin") + +file(GLOB_RECURSE elf_sources ${source_subfolder}/elf/*.cc) +set(elf_headers + ${source_subfolder}/elf/common.hh + ${source_subfolder}/elf/data.hh + ${source_subfolder}/elf/elf++.hh) +file(GLOB_RECURSE dwarf_sources ${source_subfolder}/dwarf/*.cc) +set(dwarf_headers + ${source_subfolder}/dwarf/data.hh + ${source_subfolder}/dwarf/dwarf++.hh + ${source_subfolder}/dwarf/small_vector.hh) + +add_custom_command( + OUTPUT ${source_subfolder}/elf/to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '// Automatically generated' > to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '// DO NOT EDIT' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '\#include \"data.hh\"' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '\#include \"to_hex.hh\"' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo 'ELFPP_BEGIN_NAMESPACE' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc + COMMAND ${PYTHON_EXECUTABLE} enum-print.py -u --hex --no-type --mask shf --mask pf -x loos -x hios -x loproc -x hiproc < data.hh >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo 'ELFPP_END_NAMESPACE' >> to_string.cc + DEPENDS ${source_subfolder}/elf/enum-print.py ${source_subfolder}/elf/data.hh + WORKING_DIRECTORY ${source_subfolder}/elf) + +add_custom_command( + OUTPUT ${source_subfolder}/dwarf/to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '// Automatically generated' > to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '// DO NOT EDIT' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo '\#include \"internal.hh\"' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo 'DWARFPP_BEGIN_NAMESPACE' >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc + COMMAND ${PYTHON_EXECUTABLE} ../elf/enum-print.py < dwarf++.hh >> to_string.cc + COMMAND ${PYTHON_EXECUTABLE} ../elf/enum-print.py -s _ -u --hex -x hi_user -x lo_user < data.hh >> to_string.cc + COMMAND ${CMAKE_COMMAND} -E echo 'DWARFPP_END_NAMESPACE' >> to_string.cc + DEPENDS ${source_subfolder}/elf/enum-print.py ${source_subfolder}/dwarf/data.hh + WORKING_DIRECTORY ${source_subfolder}/dwarf) + +# Uncomment this if/when switching to elf++ instead of libelf. +# add_library(elf++ STATIC ${elf_sources} ${source_subfolder}/elf/to_string.cc) +# set_target_properties(elf++ PROPERTIES +# PUBLIC_HEADER "${elf_headers}") + +add_library(dwarf++ STATIC ${dwarf_sources} ${source_subfolder}/dwarf/to_string.cc) +set_target_properties(dwarf++ PROPERTIES + PUBLIC_HEADER "${dwarf_headers}") + +# Make autoMOC and autoUIC happy +set_property(SOURCE ${source_subfolder}/elf/to_string.cc PROPERTY SKIP_AUTOGEN ON) +set_property(SOURCE ${source_subfolder}/dwarf/to_string.cc PROPERTY SKIP_AUTOGEN ON) From 099926da61dde8390b4cb11be571e117981094d1 Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Wed, 1 Dec 2021 09:18:29 +0000 Subject: [PATCH 04/17] Initial commit for C source mapping --- CMakeLists.txt | 1 + src/CMakeLists.txt | 3 ++- src/edittab.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58df09371..a06e9df4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,7 @@ include_directories(${RIPES_LIB} SYSTEM PUBLIC external/VSRTL/external/cereal/in include_directories(${RIPES_LIB} PUBLIC external/VSRTL/external) include_directories(SYSTEM external/ELFIO) include_directories(SYSTEM external/VSRTL/external/Signals) +include_directories(external/libelfin_cmake) include_directories(external) option(RIPES_BUILD_VERILATOR_PROCESSORS "Build verilator processors" OFF) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 51c16661b..db54672a1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -70,5 +70,6 @@ add_subdirectory(version) target_link_libraries(${RIPES_LIB} PUBLIC fancytabbar_lib ${VSRTL_GRAPHICS_LIB} - Qt5::Charts) + Qt5::Charts + dwarf++) diff --git a/src/edittab.cpp b/src/edittab.cpp index d3cca569c..85befc88b 100644 --- a/src/edittab.cpp +++ b/src/edittab.cpp @@ -2,6 +2,7 @@ #include "ui_edittab.h" #include "elfio/elfio.hpp" +#include "libelfin/dwarf/dwarf++.hh" #include #include @@ -367,6 +368,34 @@ bool EditTab::loadSourceFile(Program&, QFile& file) { return true; } +using namespace ELFIO; +class ELFIODwarfLoader : public ::dwarf::loader { +public: + ELFIODwarfLoader(elfio& reader) : reader(reader) {} + + const void* load(::dwarf::section_type section, size_t* size_out) override { + auto sec = reader.sections[::dwarf::elf::section_type_to_name(section)]; + if (sec == nullptr) + return nullptr; + *size_out = sec->get_size(); + return sec->get_data(); + } + +private: + elfio& reader; +}; + +std::shared_ptr createDwarfLoader(elfio& reader) { + return std::make_shared(reader); +} + +static bool isInternalSourceFile(const QString& filename) { + // Returns true if we have reason to believe that this file originated from within the Ripes editor. These will be + // temporary files like /.../Ripes.abc123.c + static QRegularExpression re("Ripes.[a-zA-Z0-9]+.c"); + return re.match(filename).hasMatch(); +} + bool EditTab::loadElfFile(Program& program, QFile& file) { ELFIO::elfio reader; @@ -407,6 +436,39 @@ bool EditTab::loadElfFile(Program& program, QFile& file) { } } + // Load DWARF information into the source mapping of the program. + // We'll only load information from compilation units which originated from a source file that plausibly arrived + // from within the Ripes editor. + QString editorSrcFile; + try { + ::dwarf::dwarf dw(createDwarfLoader(reader)); + for (auto& cu : dw.compilation_units()) { + for (auto& line : cu.get_line_table()) { + if (!line.file) + continue; + QString filePath = QString::fromStdString(line.file->path); + if (editorSrcFile.isEmpty()) { + // Try to see if this compilation unit is from the Ripes editor: + if (isInternalSourceFile(filePath)) + editorSrcFile = filePath; + } + if (editorSrcFile != filePath) + continue; + qDebug() << "Mapping " << line.address << " to " << line.line; + program.sourceMapping[line.address] = line.line; + } + } + + // Finally, we need to generate a hash of the source file that we've loaded source mappings from, so the editor + // knows what editor contents applies to this program. + QFile srcFile(editorSrcFile); + if (srcFile.open(QFile::ReadOnly)) { + program.sourceHash = Program::calculateHash(srcFile.readAll()); + } + } catch (...) { + // Could not load DWARF information for some reason... + } + program.entryPoint = reader.get_entry(); m_ui->curInputSrcLabel->setText("Executable (ELF)"); From 105d1dc73836b4fec588f77173f9f520a012b40a Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Wed, 1 Dec 2021 09:45:07 +0000 Subject: [PATCH 05/17] Allow a PC to map to multiple source lines --- src/assembler/assembler.h | 2 +- src/assembler/program.h | 5 +++-- src/editor/codeeditor.cpp | 27 +++++++++++++++------------ src/edittab.cpp | 3 +-- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/assembler/assembler.h b/src/assembler/assembler.h index e95f688d4..2a00fdd3f 100644 --- a/src/assembler/assembler.h +++ b/src/assembler/assembler.h @@ -370,7 +370,7 @@ class Assembler : public AssemblerBase { std::shared_ptr<_Instruction> assembledWith; runOperation(machineCode, _InstrRes, assembleInstruction, line, assembledWith); assert(assembledWith && "Expected the assembler instruction to be set"); - program.sourceMapping[addr_offset] = line.sourceLine; + program.sourceMapping[addr_offset].insert(line.sourceLine); if (!machineCode.linksWithSymbol.symbol.isEmpty()) { LinkRequest req; diff --git a/src/assembler/program.h b/src/assembler/program.h index 27755bae3..0bf5b5fec 100644 --- a/src/assembler/program.h +++ b/src/assembler/program.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "ripes_types.h" @@ -100,8 +101,8 @@ class DisassembledProgram { */ class Program { public: - // A source mapping is a mapping from {instruction address : source code line} - using SourceMapping = std::map; + // A source mapping is a mapping from {instruction address : source code lines} + using SourceMapping = std::map>; AInt entryPoint = 0; std::map sections; diff --git a/src/editor/codeeditor.cpp b/src/editor/codeeditor.cpp index d60f6e9fd..691110486 100644 --- a/src/editor/codeeditor.cpp +++ b/src/editor/codeeditor.cpp @@ -419,23 +419,26 @@ void CodeEditor::updateHighlighting() { for (unsigned sid = 0; sid < stages; sid++) { const auto stageInfo = proc->stageInfo(sid); + QColor stageColor = colorGenerator(); if (stageInfo.stage_valid) { - auto sourceLine = sourceMapping.find(stageInfo.pc); - if (sourceLine == sourceMapping.end()) { + auto mappingIt = sourceMapping.find(stageInfo.pc); + if (mappingIt == sourceMapping.end()) { // No source line registerred for this PC. continue; } - // Find block - QTextBlock block = document()->findBlockByLineNumber(sourceLine->second); - if (!block.isValid()) - continue; - - // Record the stage name for the highlighted block for later painting - QString stageString = ProcessorHandler::getProcessor()->stageName(sid); - if (!stageInfo.namedState.isEmpty()) - stageString += " (" + stageInfo.namedState + ")"; - highlightBlock(block, colorGenerator(), stageString); + for (auto sourceLine : mappingIt->second) { + // Find block + QTextBlock block = document()->findBlockByLineNumber(sourceLine); + if (!block.isValid()) + continue; + + // Record the stage name for the highlighted block for later painting + QString stageString = ProcessorHandler::getProcessor()->stageName(sid); + if (!stageInfo.namedState.isEmpty()) + stageString += " (" + stageInfo.namedState + ")"; + highlightBlock(block, stageColor, stageString); + } } } } diff --git a/src/edittab.cpp b/src/edittab.cpp index 85befc88b..09ec3c4ec 100644 --- a/src/edittab.cpp +++ b/src/edittab.cpp @@ -454,8 +454,7 @@ bool EditTab::loadElfFile(Program& program, QFile& file) { } if (editorSrcFile != filePath) continue; - qDebug() << "Mapping " << line.address << " to " << line.line; - program.sourceMapping[line.address] = line.line; + program.sourceMapping[line.address].insert(line.line - 1); } } From 9ba169374ab6cd1ac30d00003574c53c3ea88010 Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Wed, 1 Dec 2021 09:56:49 +0000 Subject: [PATCH 06/17] Do not clear block highlighting on non-text changes --- src/editor/highlightabletextedit.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/editor/highlightabletextedit.cpp b/src/editor/highlightabletextedit.cpp index 7cba2ee29..acda7cd37 100644 --- a/src/editor/highlightabletextedit.cpp +++ b/src/editor/highlightabletextedit.cpp @@ -10,7 +10,13 @@ namespace Ripes { HighlightableTextEdit::HighlightableTextEdit(QWidget* parent) : QPlainTextEdit(parent) { - connect(this, &QPlainTextEdit::textChanged, this, &HighlightableTextEdit::clearBlockHighlights); + // Clear block highlighting on text inserted or removed. This avoids clearing block highlightins on formatting + // changes. + connect(this->document(), &QTextDocument::contentsChange, this, [&](int /*pos*/, int charsRemoved, int charsAdded) { + if ((charsRemoved == 0 && charsAdded == 0) || (charsAdded == charsRemoved)) + return; + clearBlockHighlights(); + }); } void HighlightableTextEdit::paintEvent(QPaintEvent* event) { @@ -31,6 +37,7 @@ void HighlightableTextEdit::paintEvent(QPaintEvent* event) { painter.drawText(QRectF(drawAt.x(), drawAt.y(), stageStringRect.width(), stageStringRect.height()), stageString); } + viewport()->update(); painter.end(); } From 2fc0e3d2e50e2885f10f4712852addb47e4c91b7 Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Wed, 1 Dec 2021 10:02:03 +0000 Subject: [PATCH 07/17] Add status message on debug info load error --- src/edittab.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/edittab.cpp b/src/edittab.cpp index 09ec3c4ec..2a513775a 100644 --- a/src/edittab.cpp +++ b/src/edittab.cpp @@ -464,8 +464,12 @@ bool EditTab::loadElfFile(Program& program, QFile& file) { if (srcFile.open(QFile::ReadOnly)) { program.sourceHash = Program::calculateHash(srcFile.readAll()); } + } catch (::dwarf::format_error& e) { + std::string msg = "Could not load debug information: "; + msg += e.what(); + GeneralStatusManager::setStatusTimed(QString::fromStdString(msg), 2500); } catch (...) { - // Could not load DWARF information for some reason... + // Something else went wrong. } program.entryPoint = reader.get_entry(); From 7f228af798c6206b0db5b21ffd4e7cc59e26b626 Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Wed, 1 Dec 2021 10:02:34 +0000 Subject: [PATCH 08/17] Add debug flag (-g) to default C argments --- src/ripessettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ripessettings.cpp b/src/ripessettings.cpp index 5f512b1c8..ae6d7920f 100644 --- a/src/ripessettings.cpp +++ b/src/ripessettings.cpp @@ -15,7 +15,7 @@ const std::map s_defaultSettings = { {RIPES_SETTING_FORMATTER_PATH, "clang-format"}, {RIPES_SETTING_FORMAT_ON_SAVE, false}, {RIPES_SETTING_FORMATTER_ARGS, "--style=file --fallback-style=LLVM"}, - {RIPES_SETTING_CCARGS, "-O0"}, + {RIPES_SETTING_CCARGS, "-O0 -g"}, {RIPES_SETTING_LDARGS, "-static -lm"}, // Ensure statically linked executable + link with math library {RIPES_SETTING_CONSOLEECHO, "true"}, {RIPES_SETTING_CONSOLEBG, QColorConstants::White}, From 9733c5cfcacc86867cf4598e21b3187e51aded30 Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Wed, 1 Dec 2021 10:04:09 +0000 Subject: [PATCH 09/17] Add error message on missing source file --- src/edittab.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/edittab.cpp b/src/edittab.cpp index 2a513775a..f919e0e85 100644 --- a/src/edittab.cpp +++ b/src/edittab.cpp @@ -463,6 +463,8 @@ bool EditTab::loadElfFile(Program& program, QFile& file) { QFile srcFile(editorSrcFile); if (srcFile.open(QFile::ReadOnly)) { program.sourceHash = Program::calculateHash(srcFile.readAll()); + } else { + throw ::dwarf::format_error("Could not find source file " + editorSrcFile.toStdString()); } } catch (::dwarf::format_error& e) { std::string msg = "Could not load debug information: "; From 9ccf4c7e1ae7d039abb8bef5cf02b07efcd80733 Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Sun, 5 Dec 2021 14:19:34 +0100 Subject: [PATCH 10/17] Do not load debug file when filepath is empty --- src/CMakeLists.txt | 2 +- src/edittab.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index db54672a1..079bd0ed0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,7 +44,7 @@ endfunction() # Error flags on everything but MSVC if(NOT MSVC) - set(CMAKE_CXX_FLAGS "-Wextra -Wall \ + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wall \ -Werror=switch -Werror=return-type \ -Werror=unreachable-code") elseif(MINGW) diff --git a/src/edittab.cpp b/src/edittab.cpp index f919e0e85..8822b900c 100644 --- a/src/edittab.cpp +++ b/src/edittab.cpp @@ -457,14 +457,14 @@ bool EditTab::loadElfFile(Program& program, QFile& file) { program.sourceMapping[line.address].insert(line.line - 1); } } - - // Finally, we need to generate a hash of the source file that we've loaded source mappings from, so the editor - // knows what editor contents applies to this program. - QFile srcFile(editorSrcFile); - if (srcFile.open(QFile::ReadOnly)) { - program.sourceHash = Program::calculateHash(srcFile.readAll()); - } else { - throw ::dwarf::format_error("Could not find source file " + editorSrcFile.toStdString()); + if (!editorSrcFile.isEmpty()) { + // Finally, we need to generate a hash of the source file that we've loaded source mappings from, so the + // editor knows what editor contents applies to this program. + QFile srcFile(editorSrcFile); + if (srcFile.open(QFile::ReadOnly)) + program.sourceHash = Program::calculateHash(srcFile.readAll()); + else + throw ::dwarf::format_error("Could not find source file " + editorSrcFile.toStdString()); } } catch (::dwarf::format_error& e) { std::string msg = "Could not load debug information: "; From 59e210ef3507047852082ef6c46eb2ddd25f17db Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Sun, 5 Dec 2021 14:35:31 +0100 Subject: [PATCH 11/17] Try to debug CI --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4a5a04020..f95c6f6de 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -77,6 +77,7 @@ jobs: name: build Ripes run: | cmake -DRIPES_BUILD_TESTS=ON -DVSRTL_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release . + cat external/libelfin_cmake/libelfin/dwarf/to_string.cc make -j $(nproc) - if: contains(matrix.os, 'windows') From cb8ea32038e16267a0282b05d74f2719aec45e1f Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Sun, 5 Dec 2021 14:56:58 +0100 Subject: [PATCH 12/17] Switch libelfin module to fork --- .gitmodules | 6 +++--- external/CMakeLists.txt | 6 +++++- external/libelfin | 1 + external/libelfin_cmake/libelfin | 1 - 4 files changed, 9 insertions(+), 5 deletions(-) create mode 160000 external/libelfin delete mode 160000 external/libelfin_cmake/libelfin diff --git a/.gitmodules b/.gitmodules index dfd6c0ada..967504ccf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,6 @@ [submodule "external/ELFIO"] path = external/ELFIO url = https://github.com/serge1/ELFIO -[submodule "external/libelfin_cmake/libelfin"] - path = external/libelfin_cmake/libelfin - url = https://github.com/aclements/libelfin +[submodule "external/libelfin"] + path = external/libelfin + url = https://github.com/mortbopet/libelfin diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index e4e22e045..ef69b0e28 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -12,4 +12,8 @@ add_subdirectory(VSRTL) set(VSRTL_BUILD_APP OFF) set(VSRTL_BUILD_TESTS OFF) -add_subdirectory(libelfin_cmake) +add_subdirectory(libelfin) +# Make autoMOC and autoUIC happy about the generated libelfin files +set(libelfin_src "${CMAKE_CURRENT_SOURCE_DIR}/libelfin") +set_property(SOURCE "${libelfin_src}/elf/to_string.cc" PROPERTY SKIP_AUTOGEN ON) +set_property(SOURCE "${libelfin_src}/dwarf/to_string.cc" PROPERTY SKIP_AUTOGEN ON) diff --git a/external/libelfin b/external/libelfin new file mode 160000 index 000000000..c2ae04a24 --- /dev/null +++ b/external/libelfin @@ -0,0 +1 @@ +Subproject commit c2ae04a24edb471bffd2f5aff7f0bc16b5da17ed diff --git a/external/libelfin_cmake/libelfin b/external/libelfin_cmake/libelfin deleted file mode 160000 index 946dde57e..000000000 --- a/external/libelfin_cmake/libelfin +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 946dde57e5caef8297b9339f3a7971401d540840 From 06012f84c5e6563e59033fc80ff386c9b537f1dd Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Sun, 5 Dec 2021 18:55:45 +0100 Subject: [PATCH 13/17] Remove unused CMakeLists in old libelfin dir --- external/libelfin | 2 +- external/libelfin_cmake/CMakeLists.txt | 64 -------------------------- 2 files changed, 1 insertion(+), 65 deletions(-) delete mode 100644 external/libelfin_cmake/CMakeLists.txt diff --git a/external/libelfin b/external/libelfin index c2ae04a24..3210ba6bf 160000 --- a/external/libelfin +++ b/external/libelfin @@ -1 +1 @@ -Subproject commit c2ae04a24edb471bffd2f5aff7f0bc16b5da17ed +Subproject commit 3210ba6bfa6c455cd1cedd1b00668f4c20ee6b86 diff --git a/external/libelfin_cmake/CMakeLists.txt b/external/libelfin_cmake/CMakeLists.txt deleted file mode 100644 index 2e8f73cf1..000000000 --- a/external/libelfin_cmake/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -cmake_minimum_required(VERSION 3.1) -project(libelfin CXX) - -if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 11) -endif() -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -find_package(PythonInterp 3 REQUIRED) -set(source_subfolder "${CMAKE_CURRENT_SOURCE_DIR}/libelfin") - -file(GLOB_RECURSE elf_sources ${source_subfolder}/elf/*.cc) -set(elf_headers - ${source_subfolder}/elf/common.hh - ${source_subfolder}/elf/data.hh - ${source_subfolder}/elf/elf++.hh) -file(GLOB_RECURSE dwarf_sources ${source_subfolder}/dwarf/*.cc) -set(dwarf_headers - ${source_subfolder}/dwarf/data.hh - ${source_subfolder}/dwarf/dwarf++.hh - ${source_subfolder}/dwarf/small_vector.hh) - -add_custom_command( - OUTPUT ${source_subfolder}/elf/to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo '// Automatically generated' > to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo '// DO NOT EDIT' >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo '\#include \"data.hh\"' >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo '\#include \"to_hex.hh\"' >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo 'ELFPP_BEGIN_NAMESPACE' >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc - COMMAND ${PYTHON_EXECUTABLE} enum-print.py -u --hex --no-type --mask shf --mask pf -x loos -x hios -x loproc -x hiproc < data.hh >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo 'ELFPP_END_NAMESPACE' >> to_string.cc - DEPENDS ${source_subfolder}/elf/enum-print.py ${source_subfolder}/elf/data.hh - WORKING_DIRECTORY ${source_subfolder}/elf) - -add_custom_command( - OUTPUT ${source_subfolder}/dwarf/to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo '// Automatically generated' > to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo '// DO NOT EDIT' >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo '\#include \"internal.hh\"' >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo 'DWARFPP_BEGIN_NAMESPACE' >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo >> to_string.cc - COMMAND ${PYTHON_EXECUTABLE} ../elf/enum-print.py < dwarf++.hh >> to_string.cc - COMMAND ${PYTHON_EXECUTABLE} ../elf/enum-print.py -s _ -u --hex -x hi_user -x lo_user < data.hh >> to_string.cc - COMMAND ${CMAKE_COMMAND} -E echo 'DWARFPP_END_NAMESPACE' >> to_string.cc - DEPENDS ${source_subfolder}/elf/enum-print.py ${source_subfolder}/dwarf/data.hh - WORKING_DIRECTORY ${source_subfolder}/dwarf) - -# Uncomment this if/when switching to elf++ instead of libelf. -# add_library(elf++ STATIC ${elf_sources} ${source_subfolder}/elf/to_string.cc) -# set_target_properties(elf++ PROPERTIES -# PUBLIC_HEADER "${elf_headers}") - -add_library(dwarf++ STATIC ${dwarf_sources} ${source_subfolder}/dwarf/to_string.cc) -set_target_properties(dwarf++ PROPERTIES - PUBLIC_HEADER "${dwarf_headers}") - -# Make autoMOC and autoUIC happy -set_property(SOURCE ${source_subfolder}/elf/to_string.cc PROPERTY SKIP_AUTOGEN ON) -set_property(SOURCE ${source_subfolder}/dwarf/to_string.cc PROPERTY SKIP_AUTOGEN ON) From 940115478a848873f1dbfe99096d4002513ef228 Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Sun, 5 Dec 2021 20:48:16 +0100 Subject: [PATCH 14/17] Update libelfin tracking commit --- external/CMakeLists.txt | 6 +++--- external/libelfin | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index ef69b0e28..54b93284e 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -14,6 +14,6 @@ set(VSRTL_BUILD_TESTS OFF) add_subdirectory(libelfin) # Make autoMOC and autoUIC happy about the generated libelfin files -set(libelfin_src "${CMAKE_CURRENT_SOURCE_DIR}/libelfin") -set_property(SOURCE "${libelfin_src}/elf/to_string.cc" PROPERTY SKIP_AUTOGEN ON) -set_property(SOURCE "${libelfin_src}/dwarf/to_string.cc" PROPERTY SKIP_AUTOGEN ON) +set(libelfin_src "${CMAKE_CURRENT_BINARY_DIR}/libelfin") +set_property(SOURCE "${libelfin_src}/elf_to_string.cc" PROPERTY SKIP_AUTOGEN ON) +set_property(SOURCE "${libelfin_src}/dwarf_to_string.cc" PROPERTY SKIP_AUTOGEN ON) diff --git a/external/libelfin b/external/libelfin index 3210ba6bf..ec80e3cb7 160000 --- a/external/libelfin +++ b/external/libelfin @@ -1 +1 @@ -Subproject commit 3210ba6bfa6c455cd1cedd1b00668f4c20ee6b86 +Subproject commit ec80e3cb7f4a12a967fd81a923f3f6e79b68d21d From dfd9c2ef11f21e179680a895fbb664367409e0dc Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Sun, 5 Dec 2021 21:30:00 +0100 Subject: [PATCH 15/17] Remove stray cat --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f95c6f6de..4a5a04020 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -77,7 +77,6 @@ jobs: name: build Ripes run: | cmake -DRIPES_BUILD_TESTS=ON -DVSRTL_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release . - cat external/libelfin_cmake/libelfin/dwarf/to_string.cc make -j $(nproc) - if: contains(matrix.os, 'windows') From 9796cbc8a95f6bb2781c5bd6762b11815bc6b2f6 Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Sun, 12 Dec 2021 10:43:24 +0100 Subject: [PATCH 16/17] Update libelfin tracking commit --- external/libelfin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/libelfin b/external/libelfin index ec80e3cb7..49d16531a 160000 --- a/external/libelfin +++ b/external/libelfin @@ -1 +1 @@ -Subproject commit ec80e3cb7f4a12a967fd81a923f3f6e79b68d21d +Subproject commit 49d16531a11f5f288e77795a5c6bdd75b46657f7 From a1d79c4df6aac3ca424ca749f72c78465822f6ae Mon Sep 17 00:00:00 2001 From: Morten Borup Petersen Date: Sun, 12 Dec 2021 11:39:25 +0100 Subject: [PATCH 17/17] Don't store ExtraSelection but always recreate it --- src/editor/highlightabletextedit.cpp | 43 ++++++++++++++-------------- src/editor/highlightabletextedit.h | 10 +++++-- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/editor/highlightabletextedit.cpp b/src/editor/highlightabletextedit.cpp index acda7cd37..a876bbadc 100644 --- a/src/editor/highlightabletextedit.cpp +++ b/src/editor/highlightabletextedit.cpp @@ -43,7 +43,10 @@ void HighlightableTextEdit::paintEvent(QPaintEvent* event) { void HighlightableTextEdit::applyHighlighting() { QList selections; - llvm::transform(m_blockHighlights, std::back_inserter(selections), [](const auto& bh) { return bh.selection; }); + for (auto& bh : m_blockHighlights) { + if (auto selection = getExtraSelection(bh); selection.has_value()) + selections.push_back(selection.value()); + } setExtraSelections(selections); // The block text is drawn on the viewport itself, which is not automatically redrawn when the extra selections @@ -64,24 +67,8 @@ void HighlightableTextEdit::clearBlockHighlights() { update(); } -void HighlightableTextEdit::setBlockGradient(BlockHighlight& highlight) { - auto block = highlight.selection.cursor.block(); - if (!block.isValid()) - return; - const auto bbr = blockBoundingRect(block); - QLinearGradient grad(bbr.topLeft(), bbr.bottomRight()); - grad.setColorAt(0, palette().base().color()); - grad.setColorAt(1, highlight.color); - highlight.selection.format.setBackground(grad); -} - void HighlightableTextEdit::resizeEvent(QResizeEvent* e) { QPlainTextEdit::resizeEvent(e); - - // we need to update the highlighted lines whenever resizing the window to recalculate the highlighting gradient, - // reflecting the new widget size - for (auto& highlight : m_blockHighlights) - setBlockGradient(highlight); applyHighlighting(); } @@ -94,14 +81,28 @@ void HighlightableTextEdit::highlightBlock(const QTextBlock& block, const QColor // Check if we're already highlighting the block. If this is the case, do not set an additional highlight on it. if (m_highlightedBlocks.count(block)) return; - m_blockHighlights.push_back({}); auto& highlight = m_blockHighlights.back(); - highlight.selection.cursor = QTextCursor(block); - highlight.selection.format.setProperty(QTextFormat::FullWidthSelection, true); + highlight.blockNumber = block.blockNumber(); highlight.color = color; - setBlockGradient(highlight); applyHighlighting(); } +std::optional +HighlightableTextEdit::getExtraSelection(const HighlightableTextEdit::BlockHighlight& highlighting) { + auto block = document()->findBlockByNumber(highlighting.blockNumber); + if (!block.isValid()) + return {}; + + QTextEdit::ExtraSelection selection; + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = QTextCursor(block); + const auto bbr = blockBoundingRect(block); + QLinearGradient grad(bbr.topLeft(), bbr.bottomRight()); + grad.setColorAt(0, palette().base().color()); + grad.setColorAt(1, highlighting.color); + selection.format.setBackground(grad); + return {selection}; +} + } // namespace Ripes diff --git a/src/editor/highlightabletextedit.h b/src/editor/highlightabletextedit.h index 62b6042c2..12e26e66d 100644 --- a/src/editor/highlightabletextedit.h +++ b/src/editor/highlightabletextedit.h @@ -6,6 +6,7 @@ #include #include +#include #include namespace Ripes { @@ -18,7 +19,10 @@ class HighlightableTextEdit : public QPlainTextEdit { struct BlockHighlight { // Store the color which the block is highlighted with so that we can rehighlight a selection. QColor color; - QTextEdit::ExtraSelection selection; + // Only store the block number, not the block itself nor a ExtraSelection. After countless of hours of + // debugging, it's deemed that all of this is very unsafe to store outside of the QPlainTextEdit itself, and so + // we just rebuild all of this info whenever needed. + int blockNumber; }; public: @@ -34,7 +38,9 @@ class HighlightableTextEdit : public QPlainTextEdit { void resizeEvent(QResizeEvent* event) override; private: - void setBlockGradient(BlockHighlight& highlight); + /// Creates a new ExtraSelection formatting from the information stored in BlockHighlighting. + std::optional + getExtraSelection(const HighlightableTextEdit::BlockHighlight& highlighting); void applyHighlighting(); /// A list of strings which will be printed at the right-hand side of each block