├── .gitignore
├── data
├── icons
│ ├── form.png
│ ├── info.png
│ ├── import.png
│ ├── settings.png
│ ├── search-property.png
│ ├── import.svg
│ ├── export.svg
│ ├── mine-cart.svg
│ ├── file-explorer.svg
│ ├── save.svg
│ ├── settings.svg
│ ├── create-document.svg
│ ├── microscope.svg
│ └── open-archive.svg
├── fonts
│ ├── VICTORMONO-BOLD.TTF
│ ├── VICTORMONO-THIN.TTF
│ ├── VICTORMONO-ITALIC.TTF
│ ├── VICTORMONO-LIGHT.TTF
│ ├── VICTORMONO-MEDIUM.TTF
│ ├── VICTORMONO-OBLIQUE.TTF
│ ├── VICTORMONO-REGULAR.TTF
│ ├── VICTORMONO-SEMIBOLD.TTF
│ ├── VICTORMONO-BOLDITALIC.TTF
│ ├── VICTORMONO-BOLDOBLIQUE.TTF
│ ├── VICTORMONO-EXTRALIGHT.TTF
│ ├── VICTORMONO-LIGHTITALIC.TTF
│ ├── VICTORMONO-MEDIUMITALIC.TTF
│ ├── VICTORMONO-THINITALIC.TTF
│ ├── VICTORMONO-SEMIBOLDITALIC.TTF
│ ├── VICTORMONO-EXTRALIGHTITALIC.TTF
│ └── load.css
├── tab-content
│ ├── home.html
│ ├── share.css
│ ├── vtable.html
│ └── search.html
├── common
│ ├── vlist.css
│ ├── font.css
│ ├── plus-routes.css
│ ├── base.css
│ ├── lib.tis
│ ├── folder-tree.css
│ ├── animate.tis
│ ├── plus.css
│ ├── plus-routes.tis
│ ├── folder-tree.tis
│ ├── frame.css
│ ├── controls.css
│ ├── sqlite3.tis
│ ├── virtual-tree.tis
│ └── controls.tis
├── settings.html
├── wizard
│ ├── share.css
│ ├── index.html
│ ├── export.html
│ ├── import.html
│ └── process.html
├── menu.html
├── main.htm
├── wizard.html
├── explorer.html
└── browser.html
├── common
├── CMakeLists.txt
├── dumpcommon.h
└── windowscommon.h
├── TaskPool
├── CMakeLists.txt
├── TaskPool.h
└── TaskPool.cpp
├── BedrockExt
├── version.h.in
├── UI.manifest
├── CMakeLists.txt
├── version.rc.in
└── main.cpp
├── CLI
├── CMakeLists.txt
└── ostream_joiner.h
├── ELF
├── CMakeLists.txt
├── elf.cpp
└── include
│ └── elf.h
├── Adapter
├── CMakeLists.txt
├── include
│ └── adapter.h
├── itanium.cpp
└── msvc.cpp
├── sqlite3
├── SymbolTokenizer.h
├── sciter-sqlite.cpp
├── CMakeLists.txt
├── sciter-sqlite.h
├── sciter-sqlite-db.cpp
├── sciter-sqlite-rs.cpp
└── SymbolTokenizer.cpp
├── WindowExt
├── CMakeLists.txt
├── hiddenapi.h
└── main.cpp
├── PDB
├── include
│ └── pdb.h
├── CMakeLists.txt
└── pdb.cpp
├── Demangler
├── CMakeLists.txt
├── Demangler.cpp
└── include
│ ├── DemangleConfig.h
│ ├── StringView.h
│ ├── Demangle.h
│ ├── Utility.h
│ └── MicrosoftDemangle.h
├── .clang-format
└── CMakeLists.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs
2 | .vscode
3 | build
4 | out
5 | CMakeSettings.json
--------------------------------------------------------------------------------
/data/icons/form.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/icons/form.png
--------------------------------------------------------------------------------
/data/icons/info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/icons/info.png
--------------------------------------------------------------------------------
/data/icons/import.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/icons/import.png
--------------------------------------------------------------------------------
/data/icons/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/icons/settings.png
--------------------------------------------------------------------------------
/common/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_library (common INTERFACE)
2 | target_include_directories (common INTERFACE .)
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-BOLD.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-BOLD.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-THIN.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-THIN.TTF
--------------------------------------------------------------------------------
/data/icons/search-property.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/icons/search-property.png
--------------------------------------------------------------------------------
/TaskPool/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_library (TaskPool TaskPool.cpp)
2 | target_include_directories (TaskPool PUBLIC .)
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-ITALIC.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-ITALIC.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-LIGHT.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-LIGHT.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-MEDIUM.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-MEDIUM.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-OBLIQUE.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-OBLIQUE.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-REGULAR.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-REGULAR.TTF
--------------------------------------------------------------------------------
/BedrockExt/version.h.in:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define BDSDVERSION L"@BDSD_NUMBER@.@BDSD_VERSION@.@BDSD_BUILD_NUMBER@"
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-SEMIBOLD.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-SEMIBOLD.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-BOLDITALIC.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-BOLDITALIC.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-BOLDOBLIQUE.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-BOLDOBLIQUE.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-EXTRALIGHT.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-EXTRALIGHT.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-LIGHTITALIC.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-LIGHTITALIC.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-MEDIUMITALIC.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-MEDIUMITALIC.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-THINITALIC.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-THINITALIC.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-SEMIBOLDITALIC.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-SEMIBOLDITALIC.TTF
--------------------------------------------------------------------------------
/data/fonts/VICTORMONO-EXTRALIGHTITALIC.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codehz/BDSD/HEAD/data/fonts/VICTORMONO-EXTRALIGHTITALIC.TTF
--------------------------------------------------------------------------------
/data/tab-content/home.html:
--------------------------------------------------------------------------------
1 |
7 |
8 | home
9 |
--------------------------------------------------------------------------------
/CLI/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_executable (symutils "main.cpp" "ostream_joiner.h")
2 | target_link_libraries (symutils elf pdb Demangler adapter sqlite3 SymbolTokenizer)
--------------------------------------------------------------------------------
/ELF/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_library (elf "elf.cpp" "include/elf.h")
2 | target_link_libraries (elf PUBLIC common)
3 | target_include_directories (elf INTERFACE include)
--------------------------------------------------------------------------------
/data/common/vlist.css:
--------------------------------------------------------------------------------
1 | vlist {
2 | display: block;
3 | overflow: scroll-indicator;
4 | prototype: VList url(vlist.tis);
5 | }
6 |
7 | vlist > li {
8 | display:block;
9 | }
--------------------------------------------------------------------------------
/data/settings.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
--------------------------------------------------------------------------------
/data/common/font.css:
--------------------------------------------------------------------------------
1 | @import url(../fonts/load.css);
2 |
3 | html {
4 | font-family: 'Victor Mono';
5 | font-rendering-mode: sub-pixel;
6 | font-size: 14dip;
7 | color: black;
8 | }
--------------------------------------------------------------------------------
/Adapter/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_library (adapter "itanium.cpp" "include/adapter.h" "msvc.cpp")
2 | target_link_libraries (adapter PRIVATE Demangler)
3 | target_include_directories (adapter INTERFACE include)
--------------------------------------------------------------------------------
/data/common/plus-routes.css:
--------------------------------------------------------------------------------
1 | @import url(plus.css);
2 |
3 | /*main - sandbox for views*/
4 | main {
5 | aspect: "Plus.Application" url(plus-routes.tis);
6 | size:*;
7 | overflow:auto;
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/data/common/base.css:
--------------------------------------------------------------------------------
1 | html {
2 | var(real-accent-color): rgb(0, 120, 210);
3 | var(accent-color): rgb(0, 0, 0);
4 | var(back-color): rgb(128, 128, 128);
5 | }
6 | html:owns-focus {
7 | var(accent-color): color(real-accent-color);
8 | }
--------------------------------------------------------------------------------
/sqlite3/SymbolTokenizer.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | struct sqlite3;
4 | struct sqlite3_api_routines;
5 |
6 | extern "C" __declspec(dllimport) int sqlite3_symboltokenizer_init(
7 | sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi);
--------------------------------------------------------------------------------
/WindowExt/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_library (WindowExt SHARED main.cpp "hiddenapi.h")
2 | target_link_libraries (WindowExt PRIVATE Dwmapi)
3 | target_include_directories (WindowExt PRIVATE ${SCITERSDK}/include)
4 | target_include_directories (WindowExt PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
--------------------------------------------------------------------------------
/PDB/include/pdb.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include
8 |
9 | namespace pdb {
10 |
11 | using namespace common;
12 |
13 | ISymbolDumper &GetDumper();
14 |
15 | } // namespace pdb
--------------------------------------------------------------------------------
/data/common/lib.tis:
--------------------------------------------------------------------------------
1 | try {
2 | include library "BedrockExt";
3 | include library "WindowExt";
4 | include library "DatabaseExt";
5 | include "sqlite3.tis";
6 | } catch (e) {
7 | view.msgbox(#alert, String.$(Failed to load library, please re-install: {"\n"}{e}));
8 | view.close();
9 | }
--------------------------------------------------------------------------------
/data/wizard/share.css:
--------------------------------------------------------------------------------
1 | @import url(../common/font.css);
2 | @import url(../common/controls.css);
3 | @import url(../common/plus.css);
4 |
5 | :root {
6 | background: none;
7 | padding: 16dip;
8 | flow: horizontal;
9 | border-spacing: 16dip;
10 | }
11 |
12 | .pad {
13 | size: *;
14 | }
15 |
16 | .bottom {
17 | flow: horizontal;
18 | border-spacing: 8dip;
19 | }
--------------------------------------------------------------------------------
/Demangler/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_library (Demangler
2 | "MicrosoftDemangle.cpp"
3 | "MicrosoftDemangleNodes.cpp"
4 | "ItaniumDemangle.cpp"
5 | "include/StringView.h"
6 | "include/Demangle.h"
7 | "include/DemangleConfig.h"
8 | "include/MicrosoftDemangle.h"
9 | "include/MicrosoftDemangleNodes.h"
10 | "include/ItaniumDemangle.h"
11 | "include/Utility.h" "Demangler.cpp" )
12 | target_include_directories (Demangler INTERFACE "include")
--------------------------------------------------------------------------------
/TaskPool/TaskPool.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | class TaskPool {
10 | bool stop = false;
11 | std::mutex mtx;
12 | std::thread thread;
13 | std::condition_variable cv;
14 | std::queue> tasks;
15 |
16 | void Worker();
17 |
18 | public:
19 | TaskPool();
20 | ~TaskPool();
21 | void AddTask(std::function &&);
22 | };
--------------------------------------------------------------------------------
/BedrockExt/UI.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/BedrockExt/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_library (BedrockExt SHARED main.cpp UI.manifest)
2 | target_link_libraries (BedrockExt PRIVATE Demangler elf pdb adapter sqlite3 TaskPool)
3 | target_include_directories (BedrockExt PRIVATE ${SCITERSDK}/include)
4 | target_include_directories (BedrockExt PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
5 |
6 | configure_file (
7 | ${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in
8 | ${CMAKE_CURRENT_BINARY_DIR}/version.rc
9 | @ONLY)
10 | configure_file (
11 | ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in
12 | ${CMAKE_CURRENT_BINARY_DIR}/version.h
13 | @ONLY)
14 |
15 | target_sources (BedrockExt PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
--------------------------------------------------------------------------------
/.clang-format:
--------------------------------------------------------------------------------
1 | BasedOnStyle: LLVM
2 | IndentWidth: 2
3 | ColumnLimit: 120
4 | AlignConsecutiveAssignments: true
5 | AlignAfterOpenBracket: AlwaysBreak
6 | AlignTrailingComments: true
7 | AllowAllParametersOfDeclarationOnNextLine: false
8 | AllowShortBlocksOnASingleLine: true
9 | AllowShortCaseLabelsOnASingleLine: true
10 | AllowShortIfStatementsOnASingleLine: true
11 | AllowShortLoopsOnASingleLine: true
12 | AlwaysBreakBeforeMultilineStrings: true
13 | BinPackArguments: true
14 | BinPackParameters: true
15 | IndentPPDirectives: AfterHash
16 | PointerAlignment: Right
17 | SpaceAfterCStyleCast: true
18 | SpacesBeforeTrailingComments: 1
19 | IncludeBlocks: Preserve
20 | SortIncludes: false
--------------------------------------------------------------------------------
/data/wizard/index.html:
--------------------------------------------------------------------------------
1 |
14 |
15 | In order to create a new project,
16 | you need to provide the bedrock_server file and bedrock_server.pdb file
17 | from official website
18 | (link ).
19 |
20 | Now click next button.
21 |
22 |
23 |
24 | Next
25 | Cancel
26 |
--------------------------------------------------------------------------------
/sqlite3/sciter-sqlite.cpp:
--------------------------------------------------------------------------------
1 | #include "sciter-sqlite.h"
2 | #include "sqlite3.h"
3 | #include "SymbolTokenizer.h"
4 |
5 | extern "C" {
6 |
7 | #ifndef WINDOWS
8 | __attribute__((visibility("default")))
9 | #else
10 | __declspec(dllexport)
11 | #endif
12 | BOOL SCAPI
13 | SciterLibraryInit(ISciterAPI *psapi, SCITER_VALUE *plibobject) {
14 | _SAPI(psapi);
15 | sqlite3_initialize();
16 | sqlite3_auto_extension((void (*)()) sqlite3_symboltokenizer_init);
17 | static sciter::om::hasset sqlite_root = new sqlite::SQLite(); // invloked once (C++ static convention)
18 | *plibobject = sciter::value::wrap_asset(sqlite_root);
19 | return TRUE;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/data/common/folder-tree.css:
--------------------------------------------------------------------------------
1 | widget[type="folder-tree"] { style-set: std-folder-tree; }
2 |
3 | @set std-folder-tree < std-tree {
4 | :root {
5 | prototype: FolderTree url(folder-tree.tis);
6 | border-spacing: 4dip;
7 | overflow: scroll-indicator;
8 | }
9 |
10 | option {
11 | border-spacing: 4dip;
12 | }
13 |
14 | option:not(:node) {
15 | padding: 0;
16 | }
17 |
18 | option > text {
19 | behavior: file-icon;
20 | line-height: 18dip;
21 | padding: 1dip 3dip 1dip 20dip;
22 | foreground-repeat: no-repeat;
23 | foreground-position: 0 50%;
24 | min-width: 4em;
25 | }
26 |
27 | option > text:rtl {
28 | padding: 1dip 20dip 1dip 3dip;
29 | foreground-position: 100% 50%;
30 | }
31 | }
--------------------------------------------------------------------------------
/data/icons/import.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/common/dumpcommon.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | namespace common {
8 |
9 | class DumpError : std::runtime_error {
10 | using runtime_error::runtime_error;
11 | };
12 |
13 | struct Symbol {
14 | std::string Name;
15 | uint64_t Offset;
16 | };
17 |
18 | class ISymbolIterator {
19 | public:
20 | virtual ~ISymbolIterator() {}
21 | virtual Symbol Get() = 0;
22 | virtual bool Next() = 0;
23 | };
24 |
25 | class IDumpSource {
26 | public:
27 | virtual ~IDumpSource() {}
28 | virtual std::unique_ptr GetIterator() = 0;
29 | };
30 |
31 | class ISymbolDumper {
32 | public:
33 | virtual ~ISymbolDumper() {}
34 | virtual std::unique_ptr Open(std::filesystem::path const &path) = 0;
35 | };
36 |
37 | } // namespace common
--------------------------------------------------------------------------------
/data/icons/export.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/data/wizard/export.html:
--------------------------------------------------------------------------------
1 |
21 |
22 | save
23 |
24 |
25 | Now click next to build project database
26 |
27 |
28 |
29 | Prev
30 | Build Database
31 | Cancel
32 |
--------------------------------------------------------------------------------
/TaskPool/TaskPool.cpp:
--------------------------------------------------------------------------------
1 | #include "TaskPool.h"
2 |
3 | TaskPool::TaskPool() : thread{std::bind_front(&TaskPool::Worker, this)} {}
4 |
5 | TaskPool::~TaskPool() {
6 | {
7 | std::lock_guard lock{mtx};
8 | stop = true;
9 | }
10 | cv.notify_all();
11 | if (thread.joinable()) thread.join();
12 | }
13 |
14 | void TaskPool::AddTask(std::function &&fn) {
15 | std::unique_lock lock{mtx};
16 | auto may_wait = tasks.empty();
17 | tasks.emplace(std::move(fn));
18 | lock.unlock();
19 | cv.notify_all();
20 | }
21 |
22 | void TaskPool::Worker() {
23 | while (true) {
24 | std::unique_lock lock{mtx};
25 | if (!tasks.empty()) {
26 | auto task = std::move(tasks.front());
27 | tasks.pop();
28 | lock.unlock();
29 | task();
30 | } else if (stop)
31 | return;
32 | else
33 | cv.wait(lock);
34 | }
35 | }
--------------------------------------------------------------------------------
/data/wizard/import.html:
--------------------------------------------------------------------------------
1 |
17 |
18 | ELF
19 |
20 |
21 |
22 | PDB
23 |
24 |
25 |
26 |
27 |
28 | Prev
29 | Next
30 | Cancel
31 |
--------------------------------------------------------------------------------
/data/tab-content/share.css:
--------------------------------------------------------------------------------
1 | @import url(../common/controls.css);
2 |
3 | :root {
4 | background: none;
5 | color: black;
6 | }
7 |
8 | toolbar {
9 | display: block;
10 | flow: horizontal;
11 | width: *;
12 | height: 32dip;
13 | padding: 0 16dip;
14 | border-spacing: 16dip;
15 | background: morph(color(accent-color), opacity: 28%);
16 | }
17 | toolbar > .pad {
18 | size: *;
19 | }
20 | toolbar > #stat {
21 | font-size: 12dip;
22 | margin: * 0;
23 | }
24 | vlist {
25 | display: block;
26 | padding: 16dip 0;
27 | padding-top: 0;
28 | size: *;
29 | overflow-x: hidden;
30 | overflow-y: scroll-indicator;
31 | }
32 | #error-output:empty {
33 | display: none;
34 | }
35 | #error-output:not(:empty) {
36 | display: block;
37 | size: *;
38 | padding: 32dip 16dip;
39 | // font-size: 20dip;
40 | vertical-align: middle;
41 | white-space: pre-wrap;
42 | word-break: break-all;
43 | overflow-wrap: break-word;
44 | overflow: hidden;
45 | }
46 | #error-output:not(:empty) + vlist {
47 | display: none;
48 | }
--------------------------------------------------------------------------------
/sqlite3/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_library (sqlite3 "sqlite3.c")
2 | target_compile_definitions (sqlite3 PUBLIC
3 | -DSQLITE_ENABLE_FTS5
4 | -DSQLITE_DQS=0
5 | -DSQLITE_DEFAULT_MEMSTATUS=0
6 | -DSQLITE_LIKE_DOESNT_MATCH_BLOBS
7 | -DSQLITE_MAX_EXPR_DEPTH=0
8 | -DSQLITE_OMIT_DEPRECATED
9 | -DSQLITE_ENABLE_COLUMN_METADATA
10 | -DSQLITE_OMIT_PROGRESS_CALLBACK
11 | -DSQLITE_OMIT_SHARED_CACHE
12 | -DSQLITE_USE_ALLOCA
13 | -DSQLITE_OMIT_AUTOINIT)
14 | target_include_directories (sqlite3 INTERFACE .)
15 |
16 | add_library (SymbolTokenizer SHARED "SymbolTokenizer.cpp" "SymbolTokenizer.h")
17 |
18 | add_executable (sqlite3cli "shell.c")
19 | target_link_libraries (sqlite3cli PRIVATE sqlite3)
20 | set_target_properties (sqlite3cli PROPERTIES OUTPUT_NAME "sqlite3")
21 |
22 | add_library (DatabaseExt SHARED "sciter-sqlite.cpp" "sciter-sqlite-db.cpp" "sciter-sqlite-rs.cpp")
23 | target_link_libraries (DatabaseExt PRIVATE sqlite3 SymbolTokenizer TaskPool)
24 | target_include_directories (DatabaseExt PRIVATE ${SCITERSDK}/include)
25 | target_include_directories (DatabaseExt PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
--------------------------------------------------------------------------------
/PDB/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | set(MSVC_DIA_SDK_DIR "$ENV{VSINSTALLDIR}DIA SDK" CACHE PATH
2 | "Path to the DIA SDK")
3 |
4 | if (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL AMD64)
5 | set (DIAARCH "/amd64")
6 | elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l OR CMAKE_SYSTEM_PROCESSOR STREQUAL arm)
7 | set(DIAARCH "/arm")
8 | elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
9 | set(DIAARCH "/arm64")
10 | else ()
11 | set(DIAARCH "")
12 | endif ()
13 |
14 | add_library (DIA STATIC IMPORTED)
15 | set_target_properties (DIA PROPERTIES IMPORTED_LOCATION ${MSVC_DIA_SDK_DIR}/lib${DIAARCH}/diaguids.lib)
16 | target_include_directories (DIA INTERFACE ${MSVC_DIA_SDK_DIR}/include)
17 | target_link_directories (DIA INTERFACE ${MSVC_DIA_SDK_DIR}/lib${DIAARCH})
18 |
19 | add_library (pdb "include/pdb.h" "pdb.cpp")
20 | target_link_libraries (pdb PRIVATE DIA common)
21 | target_include_directories (pdb INTERFACE include)
22 |
23 | add_custom_command (TARGET pdb POST_BUILD
24 | COMMAND ${CMAKE_COMMAND} -E copy_if_different
25 | ${MSVC_DIA_SDK_DIR}/bin${DIAARCH}/msdia140.dll
26 | ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
27 |
--------------------------------------------------------------------------------
/data/common/animate.tis:
--------------------------------------------------------------------------------
1 | function abs(a) {
2 | return a < (a * 0) ? -a : a;
3 | }
4 |
5 | export default class Animation {
6 | this var state = false;
7 |
8 | function this(element, applyFn, current, speed, epsilon) {
9 | this.element = element;
10 | this.applyFn = applyFn;
11 | this.current = current;
12 | this.target = target;
13 | this.speed = speed;
14 | this.epsilon = epsilon;
15 | }
16 |
17 | function to(target) {
18 | this.target = target;
19 | if (!this.state) {
20 | this.state = true;
21 | this.element.animate(||this.next());
22 | }
23 | }
24 |
25 | function next() {
26 | if (abs(this.current - this.target) >= this.epsilon) {
27 | this.current = Length.morph(this.current, this.target, this.speed);
28 | this.applyFn.call(this.element, this.current);
29 | } else {
30 | this.current = this.target;
31 | this.applyFn.call(this.element, this.current);
32 | this.state = false;
33 | }
34 | return this.state;
35 | }
36 | }
37 |
38 | export function @animate(applyFn, element, current, speed, epsilon) {
39 | return new Animation(element, applyFn, current, speed, epsilon)
40 | }
--------------------------------------------------------------------------------
/data/wizard/process.html:
--------------------------------------------------------------------------------
1 |
20 |
35 |
36 |
37 |
38 | Done
39 | Cancel
40 |
--------------------------------------------------------------------------------
/data/icons/mine-cart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/data/common/plus.css:
--------------------------------------------------------------------------------
1 |
2 | /* principal handlers */
3 | [model] {aspect:"Plus.Model" url(plus.tis); }
4 | [model] [each], [model][each] { aspect:"Plus.EachRepeater"; } /* note repeater shall come first before [model] [name] for */
5 | [model] [repeat] { aspect:"Plus.RepeatRepeater"; } /* note repeater shall come first before [model] [name] for */
6 | [model] [name], [model][name] { aspect:"Plus.Terminal"; }
7 | [model] [class*='{{'], [model][class*='{{'] { aspect:"Plus.ClassTerminal"; }
8 | [model] [value*='{{'], [model][value*='{{'] { aspect:"Plus.valAttrTerminal"; }
9 | [model] [href*='{{'], [model][href*='{{'] { aspect:"Plus.hrefAttrTerminal"; }
10 | [model] [src*='{{'], [model][src*='{{'] { aspect:"Plus.srcAttrTerminal"; }
11 |
12 | /* any attribute with the name starting from '@' is considered as bound: */
13 | [model] *:has-bound-attributes { aspect:"Plus.boundAttributesTerminal"; }
14 |
15 | /* auxiliary event handlers */
16 | [model] [click] { aspect:"Plus.Click"; }
17 | [model] [dblclick] { aspect:"Plus.DblClick"; }
18 | [model] [change] { aspect:"Plus.Change"; }
19 | [model] [enter] { aspect:"Plus.Enter"; }
20 | [model] [escape] { aspect:"Plus.Escape"; }
21 | [model] [focusin] { aspect:"Plus.FocusIn"; }
22 | [model] [focusout] { aspect:"Plus.FocusOut"; }
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Demangler/Demangler.cpp:
--------------------------------------------------------------------------------
1 | //===-- Demangle.cpp - Common demangling functions ------------------------===//
2 | //
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 | // See https://llvm.org/LICENSE.txt for license information.
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 | //
7 | //===----------------------------------------------------------------------===//
8 | ///
9 | /// \file This file contains definitions of common demangling functions.
10 | ///
11 | //===----------------------------------------------------------------------===//
12 |
13 | #include "include/Demangle.h"
14 | #include
15 |
16 | static bool isItaniumEncoding(const std::string &MangledName) {
17 | size_t Pos = MangledName.find_first_not_of('_');
18 | // A valid Itanium encoding requires 1-4 leading underscores, followed by 'Z'.
19 | return Pos > 0 && Pos <= 4 && MangledName[Pos] == 'Z';
20 | }
21 |
22 | std::string llvm::demangle(const std::string &MangledName) {
23 | char *Demangled;
24 | if (isItaniumEncoding(MangledName))
25 | Demangled = itaniumDemangle(MangledName.c_str(), nullptr, nullptr, nullptr);
26 | else
27 | Demangled = microsoftDemangle(MangledName.c_str(), nullptr, nullptr, nullptr, nullptr);
28 |
29 | if (!Demangled) return MangledName;
30 |
31 | std::string Ret = Demangled;
32 | std::free(Demangled);
33 | return Ret;
34 | }
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 3.14)
2 |
3 | project (BDSD)
4 |
5 | set (CMAKE_CXX_STANDARD 20)
6 | set (CMAKE_CXX_STANDARD_REQUIRED ON)
7 |
8 | set (BDSD_NUMBER 0)
9 | set (BDSD_VERSION 1)
10 | set (BDSD_BUILD_NUMBER 0)
11 |
12 | add_compile_options (/wd26812)
13 | add_definitions (/DWINDOWS /DNOMINMAX /D_CRT_SECURE_NO_WARNINGS /DUNICODE /DWIN32_LEAN_AND_MEAN)
14 |
15 | set (SCITERSDK $ENV{SCITERSDK} CACHE PATH "Sciter SDK Path")
16 | if (NOT IS_DIRECTORY "${SCITERSDK}")
17 | message (FATAL_ERROR "ENV:SCITERSDK NOT FOUND")
18 | endif ()
19 |
20 | if (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL AMD64)
21 | set (SCITERATCH "x64")
22 | elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l OR CMAKE_SYSTEM_PROCESSOR STREQUAL arm)
23 | message (FATAL_ERROR "ARCH NOT SUPPORT")
24 | elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
25 | set (SCITERATCH "arm64")
26 | else ()
27 | set (SCITERATCH "x32")
28 | endif ()
29 |
30 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
31 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
32 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
33 |
34 | add_subdirectory ("common")
35 | add_subdirectory ("TaskPool")
36 | add_subdirectory ("Demangler")
37 | add_subdirectory ("PDB")
38 | add_subdirectory ("ELF")
39 | add_subdirectory ("Adapter")
40 | add_subdirectory ("sqlite3")
41 | add_subdirectory ("BedrockExt")
42 | add_subdirectory ("WindowExt")
43 | add_subdirectory ("CLI")
--------------------------------------------------------------------------------
/data/icons/file-explorer.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/data/common/plus-routes.tis:
--------------------------------------------------------------------------------
1 | include "plus.tis";
2 |
3 | // the routes thing
4 | function Plus.Application() {
5 |
6 | assert !Plus.app : "only one instance allowed!";
7 |
8 | var main = $(main);
9 | assert main : " shall exist";
10 |
11 | var routes = []; // [{path:"/xxx", url:"..." }]
12 | var path = "";
13 | var param = null;
14 |
15 | function go(topath, andparam = null) {
16 | for (var route in routes)
17 | if (route.path like topath) {
18 | if (path == topath && param == andparam)
19 | main.postEvent("reset");
20 | else if (path != topath) {
21 | path = route.path;
22 | param = andparam;
23 | main.update(::main.load(self.url(route.url))); // do transactional update to reduce visual effects
24 | main.postEvent("routechange");
25 | var (total,free,used) = gc();
26 | //stdout.println("gc", total,free,used);
27 | } else {
28 | main.postEvent("paramchange");
29 | }
30 | return;
31 | }
32 | throw "Plus.app: unknown path:" + path;
33 | }
34 |
35 | var app = { go:go };
36 |
37 | // anything clickable with href works like hyperlink
38 | self << event click $([href]) {
39 | var param = this.attributes["param"] || null;
40 | go( this.attributes["href"], param );
41 | return true;
42 | }
43 |
44 | Plus.app = app;
45 |
46 | app.routes = property(v) {
47 | get return routes;
48 | set { routes = v; }
49 | }
50 |
51 | app.path = property(v) {
52 | get return path;
53 | set { throw "use app.go() to navigate to path"; }
54 | }
55 |
56 | app.param = property(v) {
57 | get return param;
58 | set { param = v; }
59 | }
60 |
61 | // Voulez vous danser ?
62 | main.post(:: go(routes[0].path));
63 | }
64 |
--------------------------------------------------------------------------------
/data/icons/save.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/data/icons/settings.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/BedrockExt/version.rc.in:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #define VER_FILEVERSION @BDSD_NUMBER@,@BDSD_VERSION@,@BDSD_BUILD_NUMBER@,0
4 | #define VER_FILEVERSION_STR "@BDSD_NUMBER@.@BDSD_VERSION@.@BDSD_BUILD_NUMBER@.0\0"
5 |
6 | #define VER_PRODUCTVERSION @BDSD_NUMBER@,@BDSD_VERSION@,@BDSD_BUILD_NUMBER@,0
7 | #define VER_PRODUCTVERSION_STR "@BDSD_NUMBER@.@BDSD_VERSION@.@BDSD_BUILD_NUMBER@\0"
8 |
9 | #define VER_PRIVATEBUILD 0
10 | #define VER_PRERELEASE 0
11 |
12 | #define VER_COMPANYNAME_STR "codehz.one"
13 | #define VER_FILEDESCRIPTION_STR "Bedrock Dedicated Server Symbol Dumper"
14 | #define VER_INTERNALNAME_STR "BDSD"
15 | #define VER_LEGALCOPYRIGHT_STR "Created by CodeHz"
16 | #define VER_ORIGINALFILENAME_STR "BedrockExt.dll"
17 | #define VER_PRODUCTNAME_STR "Bedrock Dedicated Server Symbol Dumper"
18 |
19 | #ifndef DEBUG
20 | #define VER_DEBUG 0
21 | #else
22 | #define VER_DEBUG VS_FF_DEBUG
23 | #endif
24 |
25 | VS_VERSION_INFO VERSIONINFO
26 | FILEVERSION VER_FILEVERSION
27 | PRODUCTVERSION VER_PRODUCTVERSION
28 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
29 | FILEFLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG)
30 | FILEOS VOS__WINDOWS32
31 | FILETYPE VFT_APP
32 | FILESUBTYPE VFT2_UNKNOWN
33 | BEGIN
34 | BLOCK "StringFileInfo"
35 | BEGIN
36 | BLOCK "040904E4"
37 | BEGIN
38 | VALUE "CompanyName", VER_COMPANYNAME_STR
39 | VALUE "FileDescription", VER_FILEDESCRIPTION_STR
40 | VALUE "FileVersion", VER_FILEVERSION_STR
41 | VALUE "InternalName", VER_INTERNALNAME_STR
42 | VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
43 | VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
44 | VALUE "ProductName", VER_PRODUCTNAME_STR
45 | VALUE "ProductVersion", VER_PRODUCTVERSION_STR
46 | END
47 | END
48 |
49 | BLOCK "VarFileInfo"
50 | BEGIN
51 | VALUE "Translation", 0x409, 1252
52 | END
53 | END
--------------------------------------------------------------------------------
/data/icons/create-document.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/data/menu.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
32 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/data/common/folder-tree.tis:
--------------------------------------------------------------------------------
1 | import { VirtualTree } from "virtual-tree.tis";
2 |
3 | export class FolderTree : VirtualTree {
4 | function attached() {
5 | this.filters = (this.@#filter || "*").split(";");
6 | this.folderonly = this.attributes.exists("folder-only");
7 | }
8 |
9 | function eachRoot(cb) {
10 | var drives = [];
11 |
12 | function w(name, flags, caption) {
13 | if(flags & (System.IS_HIDDEN | System.IS_SYSTEM)) return true; // skip it
14 | if((flags & System.IS_DIR) != 0)
15 | drives.push({name:name,caption:caption});
16 | return true;
17 | }
18 | System.scanFiles("/*.*", w);
19 |
20 | drives.sort(:a,b: a.name.lexicalCompare(b.name));
21 |
22 | if( System.PLATFORM == #Windows ) // on Windows FS is a forest
23 | for(var n in drives)
24 | cb(n.caption + " ("+ n.name +")",n.name, true);
25 | else // on Posix FS is a tree
26 | for(var n in drives)
27 | cb(n.caption,"/" + n.name, true);
28 | }
29 |
30 | function eachChild(path, cb)
31 | {
32 | var folders = [];
33 | var files = [];
34 | var filters = this.filters;
35 |
36 | function accept(name) {
37 | for(var filter in filters)
38 | if(name like filter) return true;
39 | return false;
40 | }
41 |
42 | function w(name, flags) {
43 | //stdout.println("scan fn",name);
44 | if(name == "." || name == "..") return true; // skip it
45 | if(flags & (System.IS_HIDDEN | System.IS_SYSTEM)) return true; // skip it
46 | if((flags & System.IS_DIR) != 0)
47 | folders.push(name);
48 | else {
49 | if((this super).folderonly || !accept(name)) return true; // skip it
50 | files.push(name);
51 | }
52 | return true;
53 | }
54 | System.scanFiles(path + "/*.*", w);
55 |
56 | folders.sort(:a,b: a.lexicalCompare(b));
57 | files.sort(:a,b: a.lexicalCompare(b));
58 | for(var n in folders)
59 | cb(n,path + "/" + n, true);
60 | for(var n in files)
61 | cb(n,path + "/" + n, false);
62 | }
63 |
64 | function show(path = "",filters = null) {
65 | this.filters = filters || this.filters;
66 | super.show(path);
67 | }
68 | }
--------------------------------------------------------------------------------
/data/main.htm:
--------------------------------------------------------------------------------
1 |
2 |
3 |
20 |
59 | Bedrock Dedicated Server Dumper
60 |
61 |
62 | Bedrock Dedicated Server Dumper
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | Open Project
71 | New Project
72 |
73 |
74 |
--------------------------------------------------------------------------------
/data/wizard.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
74 | New project
75 |
76 |
77 | New project
78 |
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/data/common/frame.css:
--------------------------------------------------------------------------------
1 | @import url(base.css);
2 |
3 | html {
4 | background: rgba(0, 0, 0, 0);
5 | border: window-frame-width solid color(accent-color);
6 | padding-top: 28dip;
7 | }
8 | @media win7 {
9 | html {
10 | border-width: 2px;
11 | background: rgba(255, 255, 255, 0.8);
12 | }
13 | }
14 | html > header {
15 | position: fixed;
16 | z-index: 1;
17 | top: 0;
18 | left: 0;
19 | right: 0;
20 | height: 28dip;
21 | flow: horizontal;
22 | height: 28dip;
23 | margin: 0;
24 | font-family: inherit;
25 | font-size: 12dip;
26 | font-weight: 600;
27 | }
28 | html > header.overlay {
29 | left: *;
30 | }
31 | html > header.shade {
32 | background: morph(color(accent-color), opacity: 10%);
33 | }
34 | window-caption {
35 | display: block;
36 | line-height: 28dip;
37 | width: *;
38 | color: rgba(0, 0, 0, 0.5);
39 | padding: 0 1em;
40 | }
41 | html:owns-focus window-caption {
42 | color: black;
43 | }
44 | window-buttons {
45 | display: block;
46 | flow: horizontal;
47 | width: max-content;
48 | height: 2em;
49 | }
50 | window-buttons > window-button {
51 | behavior: clickable;
52 | display: block;
53 | height: 28dip;
54 | width: 48dip;
55 | foreground-size: 10dip;
56 | foreground-repeat: no-repeat;
57 | foreground-position: 50% 50%;
58 | fill: none;
59 | stroke: black;
60 | stroke-width: 1.1dip;
61 | transition: background-color linear 100ms, color linear 100ms;
62 | }
63 |
64 | window-buttons > window-button:hover {
65 | background: morph(color(accent-color), opacity: 50%);
66 | }
67 | window-buttons > window-button[role="window-settings"] {
68 | foreground-image: url(path: M5 6 L6 6 L6 5 L4 3 L4 1 L3 0 L2 0 L1.5 0.5 L2.5 1.5 L2.5 2.5 L1.5 2.5 L0.5 1.5 L0 2 L0 3 L1 4 L3 4 Z);
69 | }
70 | window-buttons > window-button[role="window-close"] {
71 | foreground-image: url(path: M0 0 L10 10 M10 0 L0 10);
72 | }
73 | window-buttons > window-button[role="window-close"]:hover {
74 | background: rgb(232,17,35);
75 | stroke: white;
76 | }
77 | window-buttons > window-button[role="window-maximize"] {
78 | foreground-image: url(path: M0 0 H9 V9 H0 Z);
79 | }
80 | html[state="maximized"] > header > window-buttons > window-button[role="window-maximize"] {
81 | foreground-image: url(path: M0 2 h8 v8 h-8 Z M2 2 v-2 h8 v8 h-2);
82 | }
83 | window-buttons > window-button[role="window-minimize"] {
84 | foreground-image: url(path: M0 0 M0 4.5 H9 M9 9);
85 | }
--------------------------------------------------------------------------------
/data/fonts/load.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Victor Mono';
3 | font-style: normal;
4 | font-weight: 100;
5 | src: url(VICTORMONO-THIN.TTF);
6 | }
7 | @font-face {
8 | font-family: 'Victor Mono';
9 | font-style: italic;
10 | font-weight: 100;
11 | src: url(VICTORMONO-THINITALIC.TTF);
12 | }
13 | @font-face {
14 | font-family: 'Victor Mono';
15 | font-style: normal;
16 | font-weight: 200;
17 | src: url(VICTORMONO-EXTRALIGHT.TTF);
18 | }
19 | @font-face {
20 | font-family: 'Victor Mono';
21 | font-style: italic;
22 | font-weight: 200;
23 | src: url(VICTORMONO-EXTRALIGHTITALIC.TTF);
24 | }
25 | @font-face {
26 | font-family: 'Victor Mono';
27 | font-style: normal;
28 | font-weight: 300;
29 | src: url(VICTORMONO-LIGHT.TTF);
30 | }
31 | @font-face {
32 | font-family: 'Victor Mono';
33 | font-style: italic;
34 | font-weight: 300;
35 | src: url(VICTORMONO-LIGHTITALIC.TTF);
36 | }
37 | @font-face {
38 | font-family: 'Victor Mono';
39 | font-style: normal;
40 | font-weight: 400;
41 | src: url(VICTORMONO-REGULAR.TTF);
42 | }
43 | @font-face {
44 | font-family: 'Victor Mono';
45 | font-style: italic;
46 | font-weight: 400;
47 | src: url(VICTORMONO-ITALIC.TTF);
48 | }
49 | @font-face {
50 | font-family: 'Victor Mono';
51 | font-style: oblique;
52 | font-weight: 400;
53 | src: url(VICTORMONO-OBLIQUE.TTF);
54 | }
55 | @font-face {
56 | font-family: 'Victor Mono';
57 | font-style: normal;
58 | font-weight: 500;
59 | src: url(VICTORMONO-MEDIUM.TTF);
60 | }
61 | @font-face {
62 | font-family: 'Victor Mono';
63 | font-style: italic;
64 | font-weight: 500;
65 | src: url(VICTORMONO-MEDIUMITALIC.TTF);
66 | }
67 | @font-face {
68 | font-family: 'Victor Mono';
69 | font-style: normal;
70 | font-weight: 600;
71 | src: url(VICTORMONO-SEMIBOLD.TTF);
72 | }
73 | @font-face {
74 | font-family: 'Victor Mono';
75 | font-style: italic;
76 | font-weight: 600;
77 | src: url(VICTORMONO-SEMIBOLDITALIC.TTF);
78 | }
79 | @font-face {
80 | font-family: 'Victor Mono';
81 | font-style: normal;
82 | font-weight: 700;
83 | src: url(VICTORMONO-BOLD.TTF);
84 | }
85 | @font-face {
86 | font-family: 'Victor Mono';
87 | font-style: italic;
88 | font-weight: 700;
89 | src: url(VICTORMONO-BOLDITALIC.TTF);
90 | }
91 | @font-face {
92 | font-family: 'Victor Mono';
93 | font-style: oblique;
94 | font-weight: 700;
95 | src: url(VICTORMONO-BOLDOBLIQUE.TTF);
96 | }
--------------------------------------------------------------------------------
/data/common/controls.css:
--------------------------------------------------------------------------------
1 | button {
2 | aspect: UX.button(color: color(accent-color)) url(controls.tis);
3 | display: block;
4 | height: 32dip;
5 | color: black;
6 | font-family: inherit;
7 | font-size: inherit;
8 | border: none;
9 | border-radius: none;
10 | border-width: 0;
11 | background: morph(color(accent-color), opacity: 10%);
12 | padding: * 16dip;
13 | }
14 |
15 | button[type="link"] {
16 | behavior: hyperlink;
17 | }
18 |
19 | button.big-icon {
20 | foreground-position: 50%;
21 | foreground-repeat: no-repeat;
22 | padding-bottom: 0;
23 | }
24 |
25 | button.icon {
26 | foreground-position: 8dip 50%;
27 | foreground-repeat: no-repeat;
28 | foreground-size: 24dip;
29 | padding-left: 40dip;
30 | }
31 |
32 | button>text {
33 | padding: 0;
34 | }
35 |
36 | button:active {
37 | background: morph(color(accent-color), opacity: 20%);
38 | }
39 |
40 | button:disabled {
41 | background: morph(color(accent-color), opacity: 5%);
42 | }
43 |
44 | input {
45 | display: inline-block;
46 | height: 32dip;
47 | background: none;
48 | padding: * 8dip;
49 | overflow-x: scroll-indicator;
50 | border-radius: 0;
51 | box-shadow: inset 0 -2.4dip 0 morph(color(accent-color), opacity: 50%);
52 | border: 0;
53 | color: inherit;
54 | font-family: inherit;
55 | font-size: inherit;
56 | text-selection-caret-color: black;
57 | text-selection-background-color: black;
58 | text-selection-color: white;
59 | context-menu: unset;
60 | aspect: UX.input url(controls.tis);
61 | }
62 | input:hover {
63 | background: morph(color(accent-color), opacity: 10%);
64 | box-shadow: inset 0 -2.4dip 0 morph(color(accent-color), opacity: 100%);
65 | }
66 | input:focus, input:busy {
67 | background: morph(color(accent-color), opacity: 20%);
68 | box-shadow: inset 0 -2.4dip 0 morph(color(accent-color), opacity: 100%);
69 | }
70 | input::marker {
71 | content: attr(placeholder);
72 | size: *;
73 | text-align: center;
74 | vertical-align: middle;
75 | opacity: 0.5;
76 | transition: opacity linear 0.2s;
77 | }
78 | input:not(:empty)::marker {
79 | opacity: 0;
80 | }
81 | popup[role=tooltip] {
82 | background: rgba(240, 240, 240, 0.9);
83 | border: 1px solid rgba(120, 120, 120, 1);
84 | font-family: inherit;
85 | color: black;
86 | font-size: 16dip;
87 | }
88 | progress {
89 | size: *;
90 | border-radius: 0;
91 | background: morph(color(accent-color), opacity: 10%);
92 | border: none;
93 | padding: 4dip;
94 | foreground: rgba(0, 0, 0, 0.5);
95 | }
96 | a[target="browser"] {
97 | aspect: UX.link url(controls.tis);
98 | }
--------------------------------------------------------------------------------
/data/common/sqlite3.tis:
--------------------------------------------------------------------------------
1 | function SQLite.isRecordset(rs) {
2 | return rs && (rs instanceof Asset) && (Asset.typeOf(rs) == #Recordset);
3 | }
4 |
5 | function SQLite.isDatabase(db) {
6 | return db && (db instanceof Asset) && (Asset.typeOf(db) == #DB);
7 | }
8 |
9 | function SQLite.tablesIn(db) {
10 | assert SQLite.isDatabase(db);
11 | var rs = db.exec("SELECT name,sql FROM sqlite_master WHERE type='table' ORDER BY name;" );
12 | var names = {};
13 | if (SQLite.isRecordset(rs))
14 | do names[rs["name"]] = rs["sql"] while( rs.next() );
15 | return names;
16 | }
17 | // returns map of indexes found in the DB
18 | function SQLite.indexesIn(db) {
19 | assert SQLite.isDatabase(db);
20 | var rs = db.exec("SELECT name,sql FROM sqlite_master WHERE type='index' ORDER BY name;" );
21 | var names = {};
22 | if (SQLite.isRecordset(rs))
23 | do names[rs["name"]] = rs["sql"] while( rs.next() );
24 | return names;
25 | }
26 |
27 | // fills the table DOM element by data from the Recordset:
28 |
29 | function SQLite.tableFrom(rs) {
30 | var headers = [];
31 | for (var n in rs.length) {
32 | const title = String.printf("%s:%s:%s", rs.name(n,#database), rs.name(n,#table), rs.name(n,#field));
33 | headers.push({rs.name(n)} );
34 | }
35 |
36 | var rows = [];
37 |
38 | function cells() {
39 | var list = [];
40 | for (var v in rs)
41 | list.push({v} );
42 | return list;
43 | }
44 |
45 | do { rows.push({cells()} ); } while(rs.next());
46 |
47 | return
48 | {headers}
49 | {rows}
50 |
;
51 | }
52 |
53 | // Returns object constructed from current row as { field1: value1, field2: value2, etc. }
54 | // Not too much effective but someone may need it
55 | function SQLite.rowAsObject(rs) {
56 | var names = [];
57 | for (var n in rs.length)
58 | names.push(rs.name(n));
59 | var obj = {};
60 | var n = 0;
61 | for (var v in rs)
62 | obj[names[n++]] = v;
63 | return obj;
64 | }
65 |
66 | function SQLite.rowsAsArray(rs) {
67 | var data = [];
68 | do {
69 | var row = [];
70 | for (var v in rs) row.push(v);
71 | data.push(row);
72 | } while( rs.next() );
73 | return data;
74 | }
75 |
76 | function SQLite.rowsAsObjectArray(rs) {
77 | var names = [];
78 | for (var n in rs.length)
79 | names.push(rs.name(n));
80 | var list = [];
81 | do {
82 | var row = {};
83 | var n = 0;
84 | for (var v in rs) row[names[n++]] = v;
85 | list.push(row);
86 | } while (rs.next());
87 | return list;
88 | }
89 |
90 | function @asyncSql(func, db, sql, params...) {
91 | db.execCallback(sql, params, func)
92 | }
--------------------------------------------------------------------------------
/BedrockExt/main.cpp:
--------------------------------------------------------------------------------
1 | #undef WIN32_LEAN_AND_MEAN
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #ifndef BDSDVERSION
12 | # define BDSDVERSION L"0.0.0"
13 | #endif
14 |
15 | EXTERN_C IMAGE_DOS_HEADER __ImageBase;
16 |
17 | struct extension : sciter::om::asset {
18 | sciter::string version = BDSDVERSION;
19 | TaskPool pool;
20 |
21 | extension() {}
22 |
23 | SOM_PASSPORT_BEGIN_EX(bedrock, extension)
24 | SOM_FUNCS(SOM_FUNC(demangleVtableFunction))
25 | SOM_PROPS(SOM_RO_PROP(version), SOM_RO_VIRTUAL_PROP(symutils, getPath))
26 | SOM_PASSPORT_END
27 |
28 | SCITER_VALUE getPath() {
29 | static std::filesystem::path cached = ([] {
30 | WCHAR DllPath[MAX_PATH] = {0};
31 | GetModuleFileNameW((HINSTANCE) &__ImageBase, DllPath, _countof(DllPath));
32 | std::filesystem::path raw{DllPath};
33 | raw = raw.parent_path() / "symutils.exe";
34 | return raw;
35 | })();
36 | return sciter::value::make_string(cached.c_str());
37 | }
38 |
39 | SCITER_VALUE demangleVtableFunction(sciter::string inp, sciter::value cb) {
40 | pool.AddTask([=, this] {
41 | try {
42 | aux::w2a dat{inp};
43 | auto str = llvm::microsoftDemangle(
44 | dat.c_str(), nullptr, nullptr, nullptr, nullptr,
45 | (llvm::MSDemangleFlags)(llvm::MSDF_NoCallingConvention | llvm::MSDF_NoAccessSpecifier));
46 | if (!str) return sciter::value::make_error((L"failed to demangle: " + inp).c_str());
47 | std::string buf{str};
48 | free(str);
49 | static std::regex re_string{
50 | "class std::basic_string, class std::allocator>"};
51 | static std::regex re_vector{R"raw(class std::vector<(.*), class std::allocator<\1>>)raw"};
52 | static std::regex re_unique{R"raw(class std::unique_ptr<(.*), struct std::default_delete<\1>>)raw"};
53 | buf = std::regex_replace(buf, re_string, "std::string");
54 | buf = std::regex_replace(buf, re_vector, "std::vector<$1>");
55 | buf = std::regex_replace(buf, re_unique, "std::unique_ptr<$1>");
56 | auto ret = sciter::value::make_string(buf.c_str());
57 | cb.call(ret);
58 | } catch (...) { cb.call({}); }
59 | });
60 | return {};
61 | }
62 | };
63 |
64 | extern "C" __declspec(dllexport) BOOL SCAPI SciterLibraryInit(ISciterAPI *psapi, SCITER_VALUE *plibobject) {
65 | _SAPI(psapi);
66 | static sciter::om::hasset root = new extension();
67 |
68 | *plibobject = sciter::value::wrap_asset(root);
69 | return TRUE;
70 | }
--------------------------------------------------------------------------------
/data/common/virtual-tree.tis:
--------------------------------------------------------------------------------
1 | export class VirtualTree : Element {
2 | // overridables:
3 | // notifications:
4 | function optionExpanded(option) {}
5 | function optionCollapsed(option) {}
6 | function selectionChanged() {}
7 |
8 | // workers, must be implemented:
9 | // toCall = function(caption, path, isFolder);
10 | function eachChild(ofPath,toCall) { assert false: "must be implemented"; }
11 | // toCall = function(caption, path, isFolder);
12 | function eachRoot(toCall) { assert false: "must be implemented"; }
13 |
14 | // implementation:
15 | function appendOption(parentOpt, caption, path, nodeState) {
16 | const el = Element.create({caption} )
17 | parentOpt.append(el);
18 | if (nodeState === true) el.state.expanded = true;
19 | else if (nodeState === false) el.state.collapsed = true;
20 | el.sendMouseEvent {
21 | type: Event.MOUSE_MOVE,
22 | x: 0,
23 | y: 0,
24 | };
25 | return el;
26 | }
27 |
28 | function expandOption(opt) {
29 | function appendChild(caption, path, isFolder) { (this super).appendOption(opt, caption, path, isFolder? false: undefined); }
30 | this.eachChild(opt.attributes["filename"], appendChild);
31 | opt.state.expanded = true;
32 | }
33 |
34 | function collapseOption(opt) {
35 | while(opt.length > 1)
36 | opt.last.remove();
37 | opt.state.collapsed = true;
38 | opt.state.current = true;
39 | opt.state.checked = true;
40 | this.postEvent("item-activate", opt.attributes["filename"]);
41 | }
42 |
43 | event expand(evt) {
44 | this.expandOption(evt.target);
45 | this.optionExpanded(evt.target);
46 | return true;
47 | }
48 | event collapse(evt) {
49 | this.collapseOption(evt.target);
50 | this.optionCollapsed(evt.target);
51 | return true;
52 | }
53 |
54 | event change() {
55 | this.postEvent("item-activate", this.value);
56 | return true;
57 | }
58 |
59 | event dblclick $(option:not(:node)) (evt,option) {
60 | this.postEvent("item-activate", option.attributes["filename"]);
61 | }
62 | event keydown $(option:not(:node)) (evt,option) {
63 | if(evt.keyCode == Event.VK_ENTER) this.postEvent("item-activate", option.attributes["filename"]);
64 | }
65 |
66 | function appendRoot(caption, path, isFolder) {
67 | var rn = this.appendOption(this, caption, path, isFolder? true: undefined);
68 | if(isFolder)
69 | this.expandOption(rn);
70 | }
71 |
72 | function show(path = "") {
73 | this.clear();
74 | function rootAppender(caption, path, isFolder) { (this super).appendRoot(caption, path, isFolder); }
75 | if(path)
76 | this.eachChild(path,rootAppender);
77 | else
78 | this.eachRoot(rootAppender);
79 | }
80 | }
--------------------------------------------------------------------------------
/CLI/ostream_joiner.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // This file allows me to use std::experimental::ostream_joiner without waiting for Microsoft to create it.
4 | // Reference: http://en.cppreference.com/w/cpp/experimental/ostream_joiner
5 |
6 | #if !defined(HAS_OSTREAM_JOINER_H)
7 | # if defined(__has_include)
8 | # if __has_include()
9 | # define HAS_OSTREAM_JOINER_H
10 | # endif /* __has_include() */
11 | # endif /* __has_include */
12 | #endif /* HAS_OSTREAM_JOINER_H */
13 |
14 | #if !defined(HAS_OSTREAM_JOINER_H)
15 | # include
16 |
17 | namespace std::experimental {
18 | template > class ostream_joiner {
19 | public:
20 | using char_type = CharT;
21 | using traits_type = Traits;
22 | using ostream_type = basic_ostream;
23 |
24 | using value_type = void;
25 | using difference_type = void;
26 | using pointer = void;
27 | using reference = void;
28 | using iterator_category = output_iterator_tag;
29 |
30 | // ReSharper disable once CppRedundantAccessSpecifier
31 | public:
32 | ostream_joiner(ostream_type &stream, const DelimT &delimiter)
33 | : m_bFirst(true), m_pStream(addressof(stream)), m_Delimiter(delimiter) {}
34 | ostream_joiner(ostream_type &stream, DelimT &&delimiter)
35 | : m_bFirst(true), m_pStream(addressof(stream)), m_Delimiter(forward(delimiter)) {}
36 | ostream_joiner(const ostream_joiner &other) = default;
37 | ostream_joiner(ostream_joiner &&other) = default;
38 | ~ostream_joiner() = default;
39 |
40 | // ReSharper disable once CppRedundantAccessSpecifier
41 | public:
42 | template ostream_joiner &operator=(const T &value) {
43 | if (!m_bFirst) *m_pStream << m_Delimiter;
44 |
45 | m_bFirst = false;
46 | *m_pStream << value;
47 |
48 | return *this;
49 | }
50 | ostream_joiner &operator=(const ostream_joiner &other) = default;
51 | ostream_joiner &operator=(ostream_joiner &&other) = default;
52 |
53 | // ReSharper disable once CppRedundantAccessSpecifier
54 | public:
55 | ostream_joiner &operator*() noexcept { return *this; }
56 | ostream_joiner &operator++() noexcept { return *this; }
57 | ostream_joiner &operator++(int) noexcept { return *this; }
58 |
59 | private:
60 | bool m_bFirst;
61 | ostream_type *m_pStream;
62 | DelimT m_Delimiter;
63 | };
64 |
65 | // ReSharper disable once CppRedundantInlineSpecifier
66 | template
67 | ostream_joiner, charT, traits> static inline make_ostream_joiner(
68 | basic_ostream &os, DelimT &&delimiter) {
69 | return ostream_joiner, charT, traits>(os, forward(delimiter));
70 | }
71 | } // namespace std::experimental
72 | #else
73 | # include
74 | #endif
--------------------------------------------------------------------------------
/data/common/controls.tis:
--------------------------------------------------------------------------------
1 | namespace UX {
2 | namespace details {
3 | function showMenu(parameters) {
4 | view.window {
5 | type: View.FRAME_WINDOW,
6 | url: view.root.url("menu.html"),
7 | parameters: parameters
8 | };
9 | }
10 |
11 | function createCommand(target, name, title) {
12 | return
13 | }
14 | }
15 |
16 | function @contextmenu(func, target) {
17 | target.on("contextmenu", func);
18 | }
19 |
20 | function input() {
21 | @contextmenu (this) | {
22 | this.state.busy = true;
23 | var (cx, cy) = view.cursorLocation();
24 | var (vx, vy) = view.box(#position, #client, #screen);
25 | details.showMenu {
26 | position: {
27 | x: cx + vx,
28 | y: cy + vy
29 | },
30 | list: [
31 | details.createCommand(this, "edit:undo", "Undo"),
32 | details.createCommand(this, "edit:copy", "Copy"),
33 | details.createCommand(this, "edit:cut", "Cut"),
34 | details.createCommand(this, "edit:paste", "Paste"),
35 | details.createCommand(this, "edit:selectall", "Select All"),
36 | ],
37 | close: || this.state.busy = false
38 | }
39 | };
40 | }
41 |
42 | function button(obj) {
43 | const color = obj.color;
44 | var step = 0;
45 | var state = 0;
46 | var last = 0;
47 | this.paintContent = | gfx {
48 | const (x1, y1, x2, y2) = this.box(#rectw,#border,#self);
49 | const base = this.toPixels(1.4dip);
50 | if (this.state.disabled) return;
51 | gfx.pushLayer(#background-area, [opacity: Float.morph(0.5, 0.1, step)]);
52 | gfx.fillColor(color);
53 | gfx.rectangle(x1, Float.morph(y1 + y2 - base, y1, step * step), x2 + 1, y2 + 1);
54 | gfx.popLayer();
55 | }
56 | const update = | {
57 | const now = System.ticks;
58 | const changed = (now - last) / 150.0;
59 | last = now;
60 | step += state == 1 ? changed : -changed;
61 | if (step <= 0) {
62 | state = 0.;
63 | step = 0.;
64 | this.refresh();
65 | return false;
66 | } else if (step >= 1) {
67 | state = 2;
68 | step = 1.;
69 | this.refresh();
70 | return false;
71 | }
72 | this.refresh();
73 | return true;
74 | };
75 |
76 | this << event mouseenter {
77 | if (state == 0) {
78 | last = System.ticks - 1;
79 | state = 1;
80 | this.animate(update);
81 | } else if (state = 3) state = 1;
82 | }
83 | this << event mouseleave {
84 | if (state == 2) {
85 | last = System.ticks - 1;
86 | state = 3;
87 | this.animate(update);
88 | } else if (state == 1) state = 3;
89 | }
90 | }
91 |
92 | function link() {
93 | this << event click {
94 | const href = this.attributes["href"];
95 | Sciter.launch(href);
96 | return true;
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/Demangler/include/DemangleConfig.h:
--------------------------------------------------------------------------------
1 | //===--- DemangleConfig.h ---------------------------------------*- C++ -*-===//
2 | //
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 | // See https://llvm.org/LICENSE.txt for license information.
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 | //
7 | //===----------------------------------------------------------------------===//
8 | //
9 | // This file contains a variety of feature test macros copied from
10 | // include/llvm/Support/Compiler.h so that LLVMDemangle does not need to take
11 | // a dependency on LLVMSupport.
12 | //
13 | //===----------------------------------------------------------------------===//
14 |
15 | #pragma once
16 |
17 | #ifndef __has_feature
18 | #define __has_feature(x) 0
19 | #endif
20 |
21 | #ifndef __has_cpp_attribute
22 | #define __has_cpp_attribute(x) 0
23 | #endif
24 |
25 | #ifndef __has_attribute
26 | #define __has_attribute(x) 0
27 | #endif
28 |
29 | #ifndef __has_builtin
30 | #define __has_builtin(x) 0
31 | #endif
32 |
33 | #ifndef DEMANGLE_GNUC_PREREQ
34 | #if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
35 | #define DEMANGLE_GNUC_PREREQ(maj, min, patch) \
36 | ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \
37 | ((maj) << 20) + ((min) << 10) + (patch))
38 | #elif defined(__GNUC__) && defined(__GNUC_MINOR__)
39 | #define DEMANGLE_GNUC_PREREQ(maj, min, patch) \
40 | ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10))
41 | #else
42 | #define DEMANGLE_GNUC_PREREQ(maj, min, patch) 0
43 | #endif
44 | #endif
45 |
46 | #if __has_attribute(used) || DEMANGLE_GNUC_PREREQ(3, 1, 0)
47 | #define DEMANGLE_ATTRIBUTE_USED __attribute__((__used__))
48 | #else
49 | #define DEMANGLE_ATTRIBUTE_USED
50 | #endif
51 |
52 | #if __has_builtin(__builtin_unreachable) || DEMANGLE_GNUC_PREREQ(4, 5, 0)
53 | #define DEMANGLE_UNREACHABLE __builtin_unreachable()
54 | #elif defined(_MSC_VER)
55 | #define DEMANGLE_UNREACHABLE __assume(false)
56 | #else
57 | #define DEMANGLE_UNREACHABLE
58 | #endif
59 |
60 | #if __has_attribute(noinline) || DEMANGLE_GNUC_PREREQ(3, 4, 0)
61 | #define DEMANGLE_ATTRIBUTE_NOINLINE __attribute__((noinline))
62 | #elif defined(_MSC_VER)
63 | #define DEMANGLE_ATTRIBUTE_NOINLINE __declspec(noinline)
64 | #else
65 | #define DEMANGLE_ATTRIBUTE_NOINLINE
66 | #endif
67 |
68 | #if !defined(NDEBUG)
69 | #define DEMANGLE_DUMP_METHOD DEMANGLE_ATTRIBUTE_NOINLINE DEMANGLE_ATTRIBUTE_USED
70 | #else
71 | #define DEMANGLE_DUMP_METHOD DEMANGLE_ATTRIBUTE_NOINLINE
72 | #endif
73 |
74 | #if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
75 | #define DEMANGLE_FALLTHROUGH [[fallthrough]]
76 | #elif __has_cpp_attribute(gnu::fallthrough)
77 | #define DEMANGLE_FALLTHROUGH [[gnu::fallthrough]]
78 | #elif !__cplusplus
79 | // Workaround for llvm.org/PR23435, since clang 3.6 and below emit a spurious
80 | // error when __has_cpp_attribute is given a scoped attribute in C mode.
81 | #define DEMANGLE_FALLTHROUGH
82 | #elif __has_cpp_attribute(clang::fallthrough)
83 | #define DEMANGLE_FALLTHROUGH [[clang::fallthrough]]
84 | #else
85 | #define DEMANGLE_FALLTHROUGH
86 | #endif
--------------------------------------------------------------------------------
/ELF/elf.cpp:
--------------------------------------------------------------------------------
1 | #include "include/elf.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | namespace elf {
11 |
12 | struct SymbolIterator : public ISymbolIterator {
13 | MappingView syms;
14 | MappingView strtab;
15 | symbol_data *it{};
16 | virtual Symbol Get() override { return Symbol{.Name = &strtab[it->st_name], .Offset = it->st_value}; }
17 | virtual bool Next() override { return ++it < syms.end(); }
18 | };
19 |
20 | constexpr int ELFMAG0 = 0x7f;
21 | constexpr int ELFMAG1 = 'E';
22 | constexpr int ELFMAG2 = 'L';
23 | constexpr int ELFMAG3 = 'F';
24 |
25 | constexpr char magic_numbers[] = {ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3};
26 |
27 | struct DumpSource : public IElfDumpSource {
28 | friend class SymbolDumper;
29 | WindowsFileMapping map;
30 | MappingView header;
31 | MappingView sections;
32 | MappingView shstrtab;
33 |
34 | DumpSource(std::filesystem::path const &path) : map(path) {
35 | MappingView header{map, 0};
36 | if (std::memcmp(header->e_ident, &magic_numbers, sizeof magic_numbers) != 0) throw DumpError{"Not a elf"};
37 | MappingView sections{map, (DWORD) header->e_shoff, (DWORD) header->e_shnum};
38 | auto str = sections[header->e_shstrndx];
39 | shstrtab = {map, (DWORD) str.sh_offset, str.sh_size};
40 | this->header = std::move(header);
41 | this->sections = std::move(sections);
42 | }
43 | virtual std::unique_ptr GetIterator() override {
44 | auto ret = std::make_unique();
45 | for (auto §ion : sections) {
46 | if (section.sh_type != SHT::SHT_DYNSYM) continue;
47 | unsigned long num = section.sh_size / section.sh_entsize;
48 | MappingView syms{map, (DWORD) section.sh_offset, num};
49 | auto &strsec = sections[section.sh_link];
50 | MappingView strtab{map, (DWORD) strsec.sh_offset, strsec.sh_size};
51 |
52 | ret->syms = std::move(syms);
53 | ret->strtab = std::move(strtab);
54 | ret->it = ret->syms.begin();
55 | return ret;
56 | }
57 | return nullptr;
58 | }
59 |
60 | virtual std::vector GetSectionHeaders() override {
61 | std::vector ret;
62 | for (auto §ion : sections)
63 | ret.emplace_back(&shstrtab[section.sh_name], section.sh_addr, section.sh_offset, section.sh_size);
64 | return ret;
65 | }
66 |
67 | virtual std::optional GetSection(std::string const &name) override {
68 | for (auto §ion : sections) {
69 | if (name == &shstrtab[section.sh_name]) {
70 | return SectionData{MappingView{map, (DWORD) section.sh_offset, (DWORD) section.sh_size}, section.sh_addr};
71 | }
72 | }
73 | return std::nullopt;
74 | }
75 | };
76 |
77 | class SymbolDumper : public ISymbolDumper {
78 | public:
79 | virtual std::unique_ptr Open(std::filesystem::path const &path) override {
80 | return std::make_unique(path);
81 | }
82 | };
83 |
84 | ISymbolDumper &elf::GetDumper() {
85 | static SymbolDumper ret;
86 | return ret;
87 | }
88 |
89 | } // namespace elf
--------------------------------------------------------------------------------
/WindowExt/hiddenapi.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | typedef enum _WINDOWCOMPOSITIONATTRIB {
9 | WCA_UNDEFINED = 0,
10 | WCA_NCRENDERING_ENABLED = 1,
11 | WCA_NCRENDERING_POLICY = 2,
12 | WCA_TRANSITIONS_FORCEDISABLED = 3,
13 | WCA_ALLOW_NCPAINT = 4,
14 | WCA_CAPTION_BUTTON_BOUNDS = 5,
15 | WCA_NONCLIENT_RTL_LAYOUT = 6,
16 | WCA_FORCE_ICONIC_REPRESENTATION = 7,
17 | WCA_EXTENDED_FRAME_BOUNDS = 8,
18 | WCA_HAS_ICONIC_BITMAP = 9,
19 | WCA_THEME_ATTRIBUTES = 10,
20 | WCA_NCRENDERING_EXILED = 11,
21 | WCA_NCADORNMENTINFO = 12,
22 | WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
23 | WCA_VIDEO_OVERLAY_ACTIVE = 14,
24 | WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
25 | WCA_DISALLOW_PEEK = 16,
26 | WCA_CLOAK = 17,
27 | WCA_CLOAKED = 18,
28 | WCA_ACCENT_POLICY = 19,
29 | WCA_FREEZE_REPRESENTATION = 20,
30 | WCA_EVER_UNCLOAKED = 21,
31 | WCA_VISUAL_OWNER = 22,
32 | WCA_HOLOGRAPHIC = 23,
33 | WCA_EXCLUDED_FROM_DDA = 24,
34 | WCA_PASSIVEUPDATEMODE = 25,
35 | WCA_USEDARKMODECOLORS = 26,
36 | WCA_LAST = 27
37 | } WINDOWCOMPOSITIONATTRIB;
38 |
39 | typedef struct _WINDOWCOMPOSITIONATTRIBDATA {
40 | WINDOWCOMPOSITIONATTRIB Attrib;
41 | PVOID pvData;
42 | SIZE_T cbData;
43 | } WINDOWCOMPOSITIONATTRIBDATA;
44 |
45 | typedef enum _ACCENT_STATE {
46 | ACCENT_DISABLED = 0,
47 | ACCENT_ENABLE_GRADIENT = 1,
48 | ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
49 | ACCENT_ENABLE_BLURBEHIND = 3,
50 | ACCENT_ENABLE_ACRYLICBLURBEHIND = 4, // RS4 1803
51 | ACCENT_ENABLE_HOSTBACKDROP = 5, // RS5 1809
52 | ACCENT_INVALID_STATE = 6
53 | } ACCENT_STATE;
54 |
55 | typedef struct _ACCENT_POLICY {
56 | ACCENT_STATE AccentState;
57 | DWORD AccentFlags;
58 | DWORD GradientColor;
59 | DWORD AnimationId;
60 | } ACCENT_POLICY;
61 |
62 | typedef BOOL(WINAPI *pfnGetWindowCompositionAttribute)(HWND, WINDOWCOMPOSITIONATTRIBDATA *);
63 |
64 | typedef BOOL(WINAPI *pfnSetWindowCompositionAttribute)(HWND, WINDOWCOMPOSITIONATTRIBDATA *);
65 |
66 | inline void make_blur(HWND win) {
67 | if (IsWindows10OrGreater()) {
68 | static HMODULE user32 = GetModuleHandle(L"user32.dll");
69 | static pfnSetWindowCompositionAttribute setWindowCompositionAttribute =
70 | (pfnSetWindowCompositionAttribute) GetProcAddress(user32, "SetWindowCompositionAttribute");
71 | if (setWindowCompositionAttribute) {
72 | ACCENT_POLICY accent = {ACCENT_ENABLE_ACRYLICBLURBEHIND, 0, 0xA0FFFFFF, 0};
73 | WINDOWCOMPOSITIONATTRIBDATA data;
74 | data.Attrib = WCA_ACCENT_POLICY;
75 | data.pvData = &accent;
76 | data.cbData = sizeof(accent);
77 | setWindowCompositionAttribute(win, &data);
78 | return;
79 | }
80 | }
81 | MARGINS margins = {-1};
82 | DwmExtendFrameIntoClientArea(win, &margins);
83 | LONG_PTR style = GetWindowLongPtr(win, GWL_STYLE);
84 | SetWindowLongPtr(win, GWL_STYLE, style & ~WS_SYSMENU);
85 | SciterSetMediaType(win, L"win7");
86 | }
--------------------------------------------------------------------------------
/data/icons/microscope.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/data/explorer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
96 |
117 |
118 |
119 | File Explorer
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | select
134 | cancel
135 |
136 |
137 |
--------------------------------------------------------------------------------
/common/windowscommon.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | namespace common {
6 |
7 | struct SysHandle {
8 | HANDLE handle{INVALID_HANDLE_VALUE};
9 | char const *desc;
10 | SysHandle(char const *desc) : desc(desc) {}
11 |
12 | void operator=(HANDLE rhs) {
13 | if (rhs == INVALID_HANDLE_VALUE) throw std::system_error{(int) GetLastError(), std::system_category(), desc};
14 | handle = rhs;
15 | }
16 |
17 | ~SysHandle() {
18 | if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle);
19 | }
20 |
21 | operator HANDLE() const { return handle; }
22 | };
23 |
24 | class WindowsFileMapping {
25 | SysHandle file{"Failed to open file"};
26 | SysHandle mapping{"Failed to map file"};
27 | template friend class MappingView;
28 |
29 | public:
30 | WindowsFileMapping(WindowsFileMapping const &) = delete;
31 | WindowsFileMapping(std::filesystem::path const &path) {
32 | file = CreateFile(path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
33 | DWORD high, low;
34 | low = GetFileSize(file, &high);
35 | mapping = CreateFileMapping(file, NULL, PAGE_READONLY, high, low, NULL);
36 | }
37 | WindowsFileMapping &operator=(WindowsFileMapping const &) = delete;
38 | };
39 |
40 | template class MappingView {
41 | template friend class MappingView;
42 | void *raw{};
43 | T *ptr{};
44 | size_t num{};
45 |
46 | static DWORD GetSysGran() {
47 | SYSTEM_INFO SysInfo;
48 | GetSystemInfo(&SysInfo);
49 | return SysInfo.dwAllocationGranularity;
50 | }
51 |
52 | public:
53 | MappingView() {}
54 | MappingView(MappingView const &rhs) = delete;
55 | MappingView(MappingView &&rhs) noexcept : raw(rhs.raw), ptr(rhs.ptr), num(rhs.num) {
56 | rhs.raw = nullptr;
57 | rhs.ptr = nullptr;
58 | }
59 | template
60 | MappingView(MappingView &&rhs) noexcept : raw(rhs.raw), ptr((T *) rhs.ptr), num(rhs.num * sizeof(R) / sizeof(T)) {
61 | rhs.raw = nullptr;
62 | rhs.ptr = nullptr;
63 | }
64 | MappingView(WindowsFileMapping const &map) : num(0) {
65 | raw = MapViewOfFile(map.mapping, FILE_MAP_READ, 0, 0, 0);
66 | if (raw == nullptr) throw std::system_error{(int) GetLastError(), std::system_category(), "Failed to map view"};
67 | ptr = (T *) raw;
68 | }
69 | MappingView(WindowsFileMapping const &map, DWORD offset, size_t num = 1) : num(num) {
70 | static DWORD SysGram = GetSysGran();
71 | DWORD FileMapStart = (offset / SysGram) * SysGram;
72 | DWORD MapViewSize = (offset % SysGram) + num * sizeof(T);
73 | DWORD Delta = offset - FileMapStart;
74 |
75 | raw = MapViewOfFile(map.mapping, FILE_MAP_READ, 0, FileMapStart, MapViewSize);
76 | if (raw == nullptr) throw std::system_error{(int) GetLastError(), std::system_category(), "Failed to map view"};
77 | ptr = (T *) ((char *) raw + Delta);
78 | }
79 |
80 | MappingView &operator=(MappingView &&rhs) noexcept {
81 | if (raw) UnmapViewOfFile(raw);
82 | raw = rhs.raw;
83 | ptr = rhs.ptr;
84 | num = rhs.num;
85 | rhs.raw = nullptr;
86 | rhs.ptr = nullptr;
87 | return *this;
88 | }
89 | MappingView &operator=(MappingView const &rhs) = delete;
90 |
91 | ~MappingView() {
92 | if (raw) UnmapViewOfFile(raw);
93 | }
94 |
95 | T &operator*() { return *ptr; }
96 | T *operator->() { return ptr; }
97 | T &operator[](size_t idx) { return ptr[idx]; }
98 | T *begin() { return ptr; }
99 | T *end() { return ptr + num; }
100 | };
101 |
102 | } // namespace common
--------------------------------------------------------------------------------
/sqlite3/sciter-sqlite.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "sqlite3.h"
4 |
5 | #include "../include/sciter-x.h"
6 | #include
7 |
8 | extern const char sqlite3_version[];
9 |
10 | namespace sqlite {
11 |
12 | class DB : public sciter::om::asset {
13 | sqlite3 *pDb = nullptr;
14 | TaskPool pool;
15 |
16 | public:
17 | DB(sqlite3 *p) : pDb(p) {}
18 | ~DB();
19 |
20 | static DB *open(sciter::string path);
21 |
22 | int close();
23 | int lastRowId();
24 |
25 | sciter::value exec(sciter::string sql, std::vector params);
26 | sciter::value execCallback(sciter::string sql, std::vector params, sciter::value cb);
27 |
28 | SOM_PASSPORT_BEGIN(DB)
29 | SOM_FUNCS(SOM_FUNC(exec), SOM_FUNC(execCallback), SOM_FUNC(close), SOM_FUNC(lastRowId))
30 | SOM_PASSPORT_END
31 | };
32 |
33 | // namespace object
34 |
35 | class SQLite : public sciter::om::asset {
36 | public:
37 | sciter::string version = WSTR(SQLITE_VERSION);
38 |
39 | SQLite() {}
40 |
41 | sciter::value open(sciter::string path) {
42 | sqlite::DB *pdb = DB::open(path);
43 | if (pdb)
44 | return sciter::value::wrap_asset(pdb);
45 | else
46 | return sciter::value();
47 | }
48 | sciter::astring errstr(int code) { return sqlite3_errstr(code); }
49 |
50 | SOM_PASSPORT_BEGIN(SQLite)
51 | SOM_PASSPORT_FLAGS(SOM_EXTENDABLE_OBJECT) // allow SQLite to be extended as a namespace
52 | SOM_FUNCS(SOM_FUNC(open), SOM_FUNC(errstr))
53 | SOM_PROPS(SOM_RO_PROP(version))
54 | SOM_PASSPORT_END
55 | };
56 |
57 | class Recordset : public sciter::om::asset {
58 |
59 | sqlite3_stmt *pst;
60 |
61 | public:
62 | Recordset(sqlite3_stmt *pstatement);
63 |
64 | ~Recordset();
65 |
66 | // function rs.next() : true | false
67 | // - advances recordset to the next record.
68 | // - returns 'true' if operation is successfull and so record buffer is valid.
69 | // If end-of-set reached than RS will be auto-finalized (closed).
70 | bool next();
71 |
72 | // function rs.close()
73 | // - finalizes this thing.
74 | bool close();
75 |
76 | // function rs.name( colno:int [,which: #logical | #field | #table | #database ] ):string
77 | // - returns requested name of the field.
78 | sciter::string name(int column_no, sciter::string which);
79 |
80 | // property
81 | // rs.length : int
82 | // - reports number of columns in the result set
83 | int get_length() const;
84 |
85 | // rs.valid() : true | false
86 | // - reports true if the buffer contains valid row.
87 | bool isValid() const;
88 |
89 | // [] accessor implementation
90 | // - supported cases:
91 | // var cv = rs["columnname"]; - by string
92 | // var cv = rs[no]; - by ordinal number
93 | bool get_item(sciter::value key_or_index, sciter::value &val);
94 |
95 | // .propName accessor implementation
96 | // - supported cases:
97 | // var cv = rs.columnname;
98 | bool get_prop(const std::string &field_name, sciter::value &val);
99 |
100 | // iterator, handler of for( var v in rs ) calls
101 | bool get_next(sciter::value &index, sciter::value &val);
102 |
103 | SOM_PASSPORT_BEGIN(Recordset)
104 | SOM_FUNCS(SOM_FUNC(next), SOM_FUNC(name), SOM_FUNC(isValid), SOM_FUNC(close))
105 | SOM_PROPS(SOM_RO_VIRTUAL_PROP(length, get_length))
106 | SOM_ITEM_GET(get_item)
107 | SOM_PROP_GET(get_prop)
108 | SOM_ITEM_NEXT(get_next)
109 | SOM_PASSPORT_END
110 |
111 | private:
112 | sciter::value field_to_value(int n);
113 | };
114 |
115 | } // namespace sqlite
116 |
--------------------------------------------------------------------------------
/PDB/pdb.cpp:
--------------------------------------------------------------------------------
1 | #include "include/pdb.h"
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | using pDllGetClassObject = HRESULT (*)(REFCLSID rclsid, REFIID riid, LPVOID ppv);
8 |
9 | namespace pdb {
10 |
11 | class HResultCollector {
12 | public:
13 | void operator=(HRESULT res) {
14 | if (FAILED(res)) throw DumpError(std::system_category().message(res));
15 | }
16 | };
17 |
18 | class BStrHelper {
19 | BSTR value;
20 |
21 | public:
22 | ~BStrHelper() {
23 | if (value) SysFreeString(value);
24 | }
25 | operator std::wstring() { return {value}; }
26 | operator std::string() {
27 | std::string ret;
28 | auto len = WideCharToMultiByte(CP_ACP, 0, value, SysStringLen(value), NULL, 0, NULL, NULL);
29 | ret.resize(len);
30 | WideCharToMultiByte(CP_ACP, 0, value, SysStringLen(value), ret.data(), len, NULL, NULL);
31 | return ret;
32 | }
33 | BSTR *operator&() { return &value; }
34 | };
35 |
36 | class SymbolIterator : public ISymbolIterator {
37 | friend class DumpSource;
38 | CComPtr byaddr;
39 | CComPtr psym;
40 |
41 | public:
42 | virtual Symbol Get() override {
43 | BStrHelper cache;
44 | DWORD offset;
45 | psym->get_name(&cache);
46 | psym->get_addressOffset(&offset);
47 | return Symbol{.Name = cache, .Offset = offset};
48 | }
49 |
50 | virtual bool Next() override {
51 | HResultCollector hr;
52 | ULONG celt = 0;
53 | psym = 0;
54 | hr = byaddr->Next(1, &psym, &celt);
55 | DWORD Tag = 0;
56 | psym->get_symTag(&Tag);
57 | if(celt && Tag == 10) //SymTagPublicSymbol
58 | return Next();
59 | return celt;
60 | }
61 | };
62 |
63 | class DumpSource : public IDumpSource {
64 | friend class PDBDump;
65 | CComPtr source;
66 | CComPtr session;
67 | void Load(std::filesystem::path const &path) {
68 | HResultCollector hr;
69 | hr = source->loadDataFromPdb(path.c_str());
70 | hr = source->openSession(&session);
71 | }
72 |
73 | public:
74 | virtual std::unique_ptr GetIterator() override {
75 | HResultCollector hr;
76 | auto ret = std::make_unique();
77 | hr = session->getSymbolsByAddr(&ret->byaddr);
78 | hr = ret->byaddr->symbolByAddr(1, 0, &ret->psym);
79 | return ret;
80 | }
81 | };
82 |
83 | class PDBDump : public ISymbolDumper {
84 | CComPtr ClassFactory;
85 |
86 | public:
87 | PDBDump() {
88 | HResultCollector hr;
89 | CoInitialize(nullptr);
90 | WCHAR exe[MAX_PATH];
91 | GetModuleFileName(NULL, exe, MAX_PATH);
92 |
93 | std::filesystem::path path{exe};
94 | path = path.parent_path() / "msdia140.dll";
95 | auto handle = LoadLibrary(path.c_str());
96 | if (handle == 0) throw DumpError{"Failed to load msdia140.dll"};
97 | auto getClassObj = (pDllGetClassObject) GetProcAddress(handle, "DllGetClassObject");
98 | if (getClassObj == 0) throw DumpError{"Failed to load DllGetClassObject from msdia140.dll"};
99 | hr = getClassObj(CLSID_DiaSource, IID_IClassFactory, &ClassFactory);
100 | }
101 | virtual std::unique_ptr Open(std::filesystem::path const &path) override {
102 | HResultCollector hr;
103 | auto ret = std::make_unique();
104 | hr = ClassFactory->CreateInstance(0, IID_IDiaDataSource, (void **) &ret->source);
105 | ret->Load(path);
106 | return std::move(ret);
107 | }
108 | };
109 |
110 | ISymbolDumper &GetDumper() {
111 | static PDBDump ret;
112 | return ret;
113 | }
114 |
115 | } // namespace pdb
116 |
--------------------------------------------------------------------------------
/sqlite3/sciter-sqlite-db.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "sciter-sqlite.h"
4 | #include "aux-cvt.h"
5 | #include "sqlite3.h"
6 |
7 | namespace sqlite {
8 |
9 | DB *DB::open(sciter::string path) {
10 | sqlite3 *pDb;
11 | if (SQLITE_OK != sqlite3_open16(path.c_str(), &pDb)) return nullptr; // undefined
12 | return new DB(pDb);
13 | }
14 |
15 | // function DB.close() - closes the DB
16 | int DB::close() {
17 | if (pDb) {
18 | int result = sqlite3_close(pDb);
19 | pDb = nullptr;
20 | }
21 | return 0;
22 | }
23 |
24 | int DB::lastRowId() {
25 | if (pDb)
26 | return (int) sqlite3_last_insert_rowid(pDb);
27 | else {
28 | throw sciter::om::exception("DB is already closed");
29 | }
30 | }
31 |
32 | bool bind_value(sqlite3_stmt *pst, int n, sciter::value arg) {
33 | if (arg.is_array())
34 | for (int i = 0; i < arg.length(); ++i) {
35 | if (!bind_value(pst, n, arg.get_item(i))) return false;
36 | }
37 | else if (arg.is_int())
38 | sqlite3_bind_int(pst, n, arg.get());
39 | else if (arg.is_float())
40 | sqlite3_bind_double(pst, n, arg.get());
41 | else if (arg.is_string()) {
42 | sciter::string s = arg.get();
43 | sqlite3_bind_text16(pst, n, s.c_str(), (int) s.length() * sizeof(sciter::string::value_type), SQLITE_TRANSIENT);
44 | } else if (arg.is_null())
45 | sqlite3_bind_null(pst, n);
46 | else if (arg.is_bool())
47 | sqlite3_bind_int(pst, n, arg.get());
48 | else if (arg.is_bytes()) {
49 | auto bytes = arg.get_bytes();
50 | sqlite3_bind_blob(pst, n, bytes.start, (int) bytes.length, SQLITE_STATIC);
51 | } else
52 | return false;
53 |
54 | return true;
55 | }
56 |
57 | bool bind_params(sqlite3_stmt *pst, aux::slice params) {
58 | for (int n = 1; n <= int(params.length); ++n) {
59 | if (!bind_value(pst, n, params[n - 1])) return false;
60 | }
61 | return true;
62 | }
63 |
64 | // function DB.exec(sql [,param1,param2,...]): [int,int] | recordset - executes SQL statement on the DB.
65 |
66 | sciter::value DB::exec(sciter::string sql, std::vector params) {
67 | if (!pDb) {
68 | throw sciter::om::exception("DB is already closed");
69 | return sciter::value();
70 | }
71 |
72 | sqlite3_stmt *pst = 0;
73 |
74 | auto statement = aux::chars_of(sql);
75 | WCHAR *end = 0;
76 |
77 | int r = sqlite3_prepare16(
78 | pDb, statement.start, (int) statement.length * sizeof(statement[0]), &pst, (const void **) &end);
79 | if (r != SQLITE_OK) throw sciter::om::exception(sqlite3_errmsg(pDb));
80 |
81 | if (!bind_params(pst, aux::elements_of(params))) {
82 | sqlite3_finalize(pst);
83 | throw sciter::om::exception("wrong type of SQL parameter value");
84 | }
85 |
86 | r = sqlite3_step(pst);
87 | if (r && r != SQLITE_ROW && r != SQLITE_DONE && r != SQLITE_MISUSE) {
88 | // SQLITE_MISUSE may mean that something is wrong with the sql, but we should continue anyway
89 | sqlite3_finalize(pst);
90 | throw sciter::om::exception(sqlite3_errmsg(pDb));
91 | }
92 |
93 | // last statement could be select
94 | if (r == SQLITE_ROW) return sciter::value::wrap_asset(new Recordset(pst));
95 |
96 | sqlite3_finalize(pst);
97 |
98 | int numrows_affected = sqlite3_changes(pDb);
99 | return sciter::value::make_array({r, numrows_affected});
100 | }
101 |
102 | sciter::value DB::execCallback(sciter::string sql, std::vector params, sciter::value cb) {
103 | pool.AddTask([=, this] {
104 | try {
105 | auto res = exec(sql, params);
106 | cb.call(res, {});
107 | } catch (std::exception const &e) {
108 | cb.call({}, sciter::value::make_error(e.what()));
109 | }
110 | });
111 | return {};
112 | }
113 |
114 | DB::~DB() {
115 | if (pDb) sqlite3_close(pDb);
116 | }
117 |
118 | } // namespace sqlite
--------------------------------------------------------------------------------
/data/icons/open-archive.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Demangler/include/StringView.h:
--------------------------------------------------------------------------------
1 | //===--- StringView.h -------------------------------------------*- C++ -*-===//
2 | //
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 | // See https://llvm.org/LICENSE.txt for license information.
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 | //
7 | //===----------------------------------------------------------------------===//
8 | //
9 | // FIXME: Use std::string_view instead when we support C++17.
10 | //
11 | //===----------------------------------------------------------------------===//
12 |
13 | #pragma once
14 |
15 | #include "DemangleConfig.h"
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 |
22 | namespace llvm {
23 |
24 | class StringView {
25 | const char *First;
26 | const char *Last;
27 |
28 | public:
29 | static const size_t npos = ~size_t(0);
30 |
31 | template StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
32 | StringView(const char *First_, const char *Last_) : First(First_), Last(Last_) {}
33 | StringView(const char *First_, size_t Len) : First(First_), Last(First_ + Len) {}
34 | StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {}
35 | StringView() : First(nullptr), Last(nullptr) {}
36 |
37 | StringView substr(size_t From) const { return StringView(begin() + From, size() - From); }
38 |
39 | size_t find(char C, size_t From = 0) const {
40 | size_t FindBegin = std::min(From, size());
41 | // Avoid calling memchr with nullptr.
42 | if (FindBegin < size()) {
43 | // Just forward to memchr, which is faster than a hand-rolled loop.
44 | if (const void *P = ::memchr(First + FindBegin, C, size() - FindBegin))
45 | return size_t(static_cast(P) - First);
46 | }
47 | return npos;
48 | }
49 |
50 | StringView substr(size_t From, size_t To) const {
51 | if (To >= size()) To = size() - 1;
52 | if (From >= size()) From = size() - 1;
53 | return StringView(First + From, First + To);
54 | }
55 |
56 | StringView dropFront(size_t N = 1) const {
57 | if (N >= size()) N = size();
58 | return StringView(First + N, Last);
59 | }
60 |
61 | StringView dropBack(size_t N = 1) const {
62 | if (N >= size()) N = size();
63 | return StringView(First, Last - N);
64 | }
65 |
66 | char front() const {
67 | assert(!empty());
68 | return *begin();
69 | }
70 |
71 | char back() const {
72 | assert(!empty());
73 | return *(end() - 1);
74 | }
75 |
76 | char popFront() {
77 | assert(!empty());
78 | return *First++;
79 | }
80 |
81 | bool consumeFront(char C) {
82 | if (!startsWith(C)) return false;
83 | *this = dropFront(1);
84 | return true;
85 | }
86 |
87 | bool consumeFront(StringView S) {
88 | if (!startsWith(S)) return false;
89 | *this = dropFront(S.size());
90 | return true;
91 | }
92 |
93 | bool startsWith(char C) const { return !empty() && *begin() == C; }
94 |
95 | bool startsWith(StringView Str) const {
96 | if (Str.size() > size()) return false;
97 | return std::equal(Str.begin(), Str.end(), begin());
98 | }
99 |
100 | const char &operator[](size_t Idx) const { return *(begin() + Idx); }
101 |
102 | const char *begin() const { return First; }
103 | const char *end() const { return Last; }
104 | size_t size() const { return static_cast(Last - First); }
105 | bool empty() const { return First == Last; }
106 |
107 | std::string toString() const { return {First, (uint64_t)(Last - First)}; }
108 | std::string_view toStd() const { return {First, (uint64_t)(Last - First)}; }
109 |
110 | friend std::ostream &operator<<(std::ostream &os, StringView const &self) {
111 | return os << std::string_view{self.First, (uint64_t)(self.Last - self.First)};
112 | }
113 | };
114 |
115 | inline bool operator==(const StringView &LHS, const StringView &RHS) {
116 | return LHS.size() == RHS.size() && std::equal(LHS.begin(), LHS.end(), RHS.begin());
117 | }
118 |
119 | } // namespace llvm
--------------------------------------------------------------------------------
/ELF/include/elf.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #include
8 | #include
9 |
10 | namespace elf {
11 |
12 | using namespace common;
13 |
14 | using elf_half_t = uint16_t;
15 | using elf_word_t = uint32_t;
16 | using elf_qword_t = uint64_t;
17 | using elf_long_t = int64_t;
18 |
19 | struct SectionData {
20 | MappingView data;
21 | elf_qword_t diff{};
22 |
23 | SectionData(MappingView &&data, elf_qword_t diff) : data(std::move(data)), diff(diff) {}
24 | inline char *GetMapped(uint64_t va) {
25 | auto ret = data.begin() + va - diff;
26 | if (ret >= data.end()) return nullptr;
27 | return ret;
28 | }
29 |
30 | inline uint64_t GetOffset(char *ptr) {
31 | if (ptr < data.begin() || ptr >= data.end()) return 0;
32 | return ptr + diff - data.begin();
33 | }
34 | };
35 |
36 | struct SectionHeader {
37 | std::string name;
38 | uint64_t address, offset, size;
39 |
40 | SectionHeader(std::string name, uint64_t address, uint64_t offset, uint64_t size)
41 | : name(std::move(name)), address(address), offset(offset), size(size) {}
42 | };
43 |
44 | struct IElfDumpSource : IDumpSource {
45 | virtual std::vector GetSectionHeaders() = 0;
46 | virtual std::optional GetSection(std::string const &name) = 0;
47 | };
48 |
49 | ISymbolDumper &GetDumper();
50 |
51 | constexpr int EI_NIDENT = 16;
52 |
53 | struct elf_header {
54 | // [0-3] Magic numbers
55 | // [4] either 1 or 2, 32-bit or 64-bit
56 | // [5] either 1 or 2, little endian or big endian
57 | // [6] Version of ELF
58 | // [7] Target operating system
59 | // [8] Specifies ABI version
60 | // [9-16] Not used
61 | char e_ident[EI_NIDENT] = {};
62 |
63 | // Type of object file
64 | elf_half_t e_type{};
65 |
66 | // Target ISA
67 | // 0x3E is x86-64
68 | elf_half_t e_machine{};
69 |
70 | // Usually just 1 for the original ELF version
71 | elf_word_t e_version{};
72 |
73 | // Memory address for the entry point of the process
74 | elf_qword_t e_entry{};
75 |
76 | // Points to the start of the program header table
77 | // 0x34 for 32-bit or 0x40 for 64-bit offset
78 | elf_qword_t e_phoff{};
79 |
80 | // Points to the start of the section header table
81 | elf_qword_t e_shoff{};
82 |
83 | // Interpretation of this field depends on the target architecture.
84 | elf_word_t e_flags{};
85 |
86 | // Contains the size of this header, normally 64 Bytes for 64-bit and 52 Bytes
87 | // for 32-bit format.
88 | elf_half_t e_ehsize{};
89 |
90 | // Contains the size of a program header table entry.
91 | elf_half_t e_phentsize{};
92 |
93 | // Contains the number of entries in the program header table.
94 | elf_half_t e_phnum{};
95 |
96 | // Contains the size of a section header table entry.
97 | elf_half_t e_shentsize{};
98 |
99 | // Contains the number of entries in the section header table.
100 | elf_half_t e_shnum{};
101 |
102 | // Contains index of the section header table entry that contains the section
103 | // names.
104 | elf_half_t e_shstrndx{};
105 | };
106 |
107 | struct section_header {
108 | // Offset to a string in the .shstrtab section
109 | elf_word_t sh_name;
110 |
111 | // Identifies the type of this header
112 | elf_word_t sh_type;
113 |
114 | // Identfies the attributes of the section
115 | elf_qword_t sh_flags;
116 |
117 | // Virtual address of the section in memory, for sectino that are loaded
118 | elf_qword_t sh_addr;
119 |
120 | // Offset of the section in the file image
121 | elf_qword_t sh_offset;
122 |
123 | // Size in bytes of the section in the file image, can be 0
124 | elf_qword_t sh_size;
125 |
126 | // Contains the section index of an associated section
127 | elf_word_t sh_link;
128 |
129 | // Contains extra information about the section
130 | elf_word_t sh_info;
131 |
132 | // Contains the required alignment of the section
133 | elf_qword_t sh_addralign;
134 |
135 | // Contains the size, in bytes, of each entry, for sections that contain
136 | // fixed-size entries
137 | elf_qword_t sh_entsize;
138 | };
139 |
140 | struct symbol_data {
141 | // Index into the string table of the name of the symbol, or 0 for scratch
142 | // register
143 | elf_word_t st_name;
144 |
145 | // Register number
146 | char st_info;
147 |
148 | // Unused
149 | char st_other;
150 |
151 | // Bind is typically `STB_GLobal`
152 | elf_half_t st_shndx;
153 |
154 | elf_qword_t st_value;
155 | elf_qword_t st_size;
156 | };
157 |
158 | struct elf_rela {
159 | elf_qword_t offset;
160 | elf_word_t r_type;
161 | elf_word_t r_sym;
162 | elf_long_t r_addend;
163 | };
164 |
165 | enum SHT { SHT_DYNSYM = 11 };
166 |
167 | static constexpr int elf_header_size = sizeof(elf_header);
168 | static constexpr int section_header_size = sizeof(section_header);
169 |
170 | } // namespace elf
--------------------------------------------------------------------------------
/sqlite3/sciter-sqlite-rs.cpp:
--------------------------------------------------------------------------------
1 | // Recordset class, TBD.
2 |
3 | #include "sciter-sqlite.h"
4 | #include "aux-cvt.h"
5 |
6 | namespace sqlite {
7 |
8 | // used by DB.exec() to create an RS object
9 |
10 | Recordset::Recordset(sqlite3_stmt *pstatement) : pst(pstatement) {}
11 |
12 | Recordset::~Recordset() {
13 | if (pst) sqlite3_finalize(pst);
14 | }
15 |
16 | int Recordset::get_length() const {
17 | if (!pst) throw sciter::om::exception("Recordset is already closed");
18 | return sqlite3_column_count(pst);
19 | }
20 |
21 | // function rs.next() : true | false
22 | // - advances recordset to the next record.
23 | // returns 'true' if operation is successfull and so record buffer is valid.
24 | // If end-of-set reached than RS is getting finalized (closed).
25 |
26 | bool Recordset::next() {
27 | if (!pst) throw sciter::om::exception("Recordset is already closed");
28 | int r = sqlite3_step(pst);
29 |
30 | if (r == SQLITE_ROW)
31 | return true;
32 | else {
33 | close();
34 | return false;
35 | }
36 | }
37 |
38 | // function rs.close()
39 | // - finalizes this thing.
40 | bool Recordset::close() {
41 | if (!pst) return false;
42 |
43 | sqlite3_finalize(pst);
44 | pst = nullptr;
45 | return true;
46 | }
47 |
48 | // function rs.name( colno:int [,which: #logical | #field | #table | #database ] ):string
49 | // - returns requested name of the field.
50 | sciter::string Recordset::name(int colno, sciter::string which) {
51 | if (!pst) throw sciter::om::exception("Recordset is already closed");
52 |
53 | auto sym = aux::chars_of(which);
54 |
55 | if (sym == const_wchars("logical") || sym.length == 0)
56 | return (const WCHAR *) sqlite3_column_name16(pst, colno);
57 | else if (sym == const_wchars("field"))
58 | return (const WCHAR *) sqlite3_column_origin_name16(pst, colno);
59 | else if (sym == const_wchars("table"))
60 | return (const WCHAR *) sqlite3_column_table_name16(pst, colno);
61 | else if (sym == const_wchars("database"))
62 | return (const WCHAR *) sqlite3_column_database_name16(pst, colno);
63 | else
64 | throw sciter::om::exception("Unknown type of name");
65 | return sciter::string();
66 | }
67 |
68 | // - reports true if the buffer contains valid row.
69 | bool Recordset::isValid() const { return pst != nullptr; }
70 |
71 | sciter::value Recordset::field_to_value(int n) {
72 | int total = sqlite3_column_count(pst);
73 | if (n >= 0 && n < total) switch (sqlite3_column_type(pst, n)) {
74 | case SQLITE_INTEGER: return sciter::value(sqlite3_column_int(pst, n));
75 | case SQLITE_FLOAT: return sciter::value(sqlite3_column_double(pst, n));
76 | case SQLITE_TEXT:
77 | return sciter::value::make_string(
78 | (const WCHAR *) sqlite3_column_text16(pst, n), sqlite3_column_bytes16(pst, n) / sizeof(WCHAR));
79 | case SQLITE_BLOB:
80 | return sciter::value::make_bytes(
81 | (const unsigned char *) sqlite3_column_blob(pst, n), sqlite3_column_bytes(pst, n));
82 | case SQLITE_NULL: return sciter::value::null();
83 | default: throw sciter::om::exception("Unknown type of field");
84 | }
85 | return sciter::value::nothing(); // exactly nothing
86 | }
87 |
88 | // [] accessor implementation
89 | // - supported cases:
90 | // var cv = rs["columnname"]; - by string
91 | // var cv = rs#columnname; - by symbol
92 | // var cv = rs[no]; - by ordinal number
93 |
94 | bool Recordset::get_item(sciter::value key_or_index, sciter::value &val) {
95 | int n = 0;
96 | int total = sqlite3_column_count(pst);
97 |
98 | if (key_or_index.is_string()) // var cv = rs#columnname;
99 | {
100 | sciter::string name = key_or_index.get();
101 | for (n = 0; n < total; ++n) {
102 | aux::wchars cn = aux::chars_of((const WCHAR *) sqlite3_column_name16(pst, n));
103 | if (aux::chars_of(name) == cn) {
104 | val = field_to_value(n);
105 | return true;
106 | }
107 | }
108 | } else if (key_or_index.is_int()) // var cv = rs[0];
109 | {
110 | n = key_or_index.get();
111 | val = field_to_value(n);
112 | return true;
113 | }
114 | return false;
115 | }
116 |
117 | // iterator, handler of for( var v in rs ) calls
118 | bool Recordset::get_next(sciter::value &index, sciter::value &val) {
119 | int n = 0;
120 | if (!index.is_int()) {
121 | // initial invocation of the iterator
122 | index = n;
123 | } else {
124 | n = index.get() + 1;
125 | index = n;
126 | }
127 |
128 | if (n < get_length()) {
129 | index = n;
130 | val = field_to_value(n);
131 | return true;
132 | } else
133 | return false;
134 | }
135 |
136 | bool Recordset::get_prop(const std::string &field_name, sciter::value &val) {
137 | int n = 0;
138 | int total = sqlite3_column_count(pst);
139 |
140 | for (n = 0; n < total; ++n) {
141 | aux::chars cn = aux::chars_of((const CHAR *) sqlite3_column_name(pst, n));
142 | if (aux::chars_of(field_name) == cn) {
143 | val = field_to_value(n);
144 | return true;
145 | }
146 | }
147 | return false;
148 | }
149 |
150 | } // namespace sqlite
--------------------------------------------------------------------------------
/Demangler/include/Demangle.h:
--------------------------------------------------------------------------------
1 | //===--- Demangle.h ---------------------------------------------*- C++ -*-===//
2 | //
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 | // See https://llvm.org/LICENSE.txt for license information.
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 | //
7 | //===----------------------------------------------------------------------===//
8 |
9 | #pragma once
10 |
11 | #include
12 | #include
13 |
14 | namespace llvm {
15 | /// This is a llvm local version of __cxa_demangle. Other than the name and
16 | /// being in the llvm namespace it is identical.
17 | ///
18 | /// The mangled_name is demangled into buf and returned. If the buffer is not
19 | /// large enough, realloc is used to expand it.
20 | ///
21 | /// The *status will be set to a value from the following enumeration
22 | enum : int {
23 | demangle_unknown_error = -4,
24 | demangle_invalid_args = -3,
25 | demangle_invalid_mangled_name = -2,
26 | demangle_memory_alloc_failure = -1,
27 | demangle_success = 0,
28 | };
29 |
30 | char *itaniumDemangle(const char *mangled_name, char *buf, size_t *n, int *status);
31 |
32 | enum MSDemangleFlags {
33 | MSDF_None = 0,
34 | MSDF_DumpBackrefs = 1 << 0,
35 | MSDF_NoAccessSpecifier = 1 << 1,
36 | MSDF_NoCallingConvention = 1 << 2,
37 | MSDF_NoReturnType = 1 << 3,
38 | MSDF_NoMemberType = 1 << 4,
39 | };
40 |
41 | /// Demangles the Microsoft symbol pointed at by mangled_name and returns it.
42 | /// Returns a pointer to the start of a null-terminated demangled string on
43 | /// success, or nullptr on error.
44 | /// If n_read is non-null and demangling was successful, it receives how many
45 | /// bytes of the input string were consumed.
46 | /// buf can point to a *n_buf bytes large buffer where the demangled name is
47 | /// stored. If the buffer is too small, it is grown with realloc(). If buf is
48 | /// nullptr, then this malloc()s memory for the result.
49 | /// *n_buf stores the size of buf on input if buf is non-nullptr, and it
50 | /// receives the size of the demangled string on output if n_buf is not nullptr.
51 | /// status receives one of the demangle_ enum entries above if it's not nullptr.
52 | /// Flags controls various details of the demangled representation.
53 | char *microsoftDemangle(
54 | const char *MangledName, size_t *NMangled, char *Buf, size_t *N, int *Status, MSDemangleFlags Flags = MSDF_None);
55 |
56 | /// Attempt to demangle a string using different demangling schemes.
57 | /// The function uses heuristics to determine which demangling scheme to use.
58 | /// \param MangledName - reference to string to demangle.
59 | /// \returns - the demangled string, or a copy of the input string if no
60 | /// demangling occurred.
61 | std::string demangle(const std::string &MangledName);
62 |
63 | /// "Partial" demangler. This supports demangling a string into an AST
64 | /// (typically an intermediate stage in itaniumDemangle) and querying certain
65 | /// properties or partially printing the demangled name.
66 | struct ItaniumPartialDemangler {
67 | ItaniumPartialDemangler();
68 |
69 | ItaniumPartialDemangler(ItaniumPartialDemangler &&Other);
70 | ItaniumPartialDemangler &operator=(ItaniumPartialDemangler &&Other);
71 |
72 | /// Demangle into an AST. Subsequent calls to the rest of the member functions
73 | /// implicitly operate on the AST this produces.
74 | /// \return true on error, false otherwise
75 | bool partialDemangle(const char *MangledName);
76 |
77 | /// Just print the entire mangled name into Buf. Buf and N behave like the
78 | /// second and third parameters to itaniumDemangle.
79 | char *finishDemangle(char *Buf, size_t *N) const;
80 |
81 | /// Get the base name of a function. This doesn't include trailing template
82 | /// arguments, ie for "a::b" this function returns "b".
83 | char *getFunctionBaseName(char *Buf, size_t *N) const;
84 |
85 | /// Get the context name for a function. For "a::b::c", this function returns
86 | /// "a::b".
87 | char *getFunctionDeclContextName(char *Buf, size_t *N) const;
88 |
89 | /// Get the entire name of this function.
90 | char *getFunctionName(char *Buf, size_t *N) const;
91 |
92 | /// Get the parameters for this function.
93 | char *getFunctionParameters(char *Buf, size_t *N) const;
94 | char *getFunctionReturnType(char *Buf, size_t *N) const;
95 |
96 | /// If this function has any any cv or reference qualifiers. These imply that
97 | /// the function is a non-static member function.
98 | bool hasFunctionQualifiers() const;
99 |
100 | /// If this symbol describes a constructor or destructor.
101 | bool isCtorOrDtor() const;
102 |
103 | /// If this symbol describes a function.
104 | bool isFunction() const;
105 |
106 | /// If this symbol describes a variable.
107 | bool isData() const;
108 |
109 | /// If this symbol is a . These are generally implicitly
110 | /// generated by the implementation, such as vtables and typeinfo names.
111 | bool isSpecialName() const;
112 |
113 | ~ItaniumPartialDemangler();
114 |
115 | private:
116 | void *RootNode;
117 | void *Context;
118 | };
119 |
120 | } // namespace llvm
--------------------------------------------------------------------------------
/Demangler/include/Utility.h:
--------------------------------------------------------------------------------
1 | //===--- Utility.h ----------------------------------------------*- C++ -*-===//
2 | //
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 | // See https://llvm.org/LICENSE.txt for license information.
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 | //
7 | //===----------------------------------------------------------------------===//
8 | //
9 | // Provide some utility classes for use in the demangler(s).
10 | //
11 | //===----------------------------------------------------------------------===//
12 |
13 | #pragma once
14 |
15 | #include "StringView.h"
16 |
17 | namespace llvm {
18 |
19 | // Stream that AST nodes write their string representation into after the AST
20 | // has been parsed.
21 | class OutputStream {
22 | char *Buffer = nullptr;
23 | size_t CurrentPosition = 0;
24 | size_t BufferCapacity = 0;
25 |
26 | // Ensure there is at least n more positions in buffer.
27 | void grow(size_t N) {
28 | if (N + CurrentPosition >= BufferCapacity) {
29 | BufferCapacity *= 2;
30 | if (BufferCapacity < N + CurrentPosition) BufferCapacity = N + CurrentPosition;
31 | Buffer = static_cast(std::realloc(Buffer, BufferCapacity));
32 | if (Buffer == nullptr) std::terminate();
33 | }
34 | }
35 |
36 | void writeUnsigned(uint64_t N, bool isNeg = false) {
37 | // Handle special case...
38 | if (N == 0) {
39 | *this << '0';
40 | return;
41 | }
42 |
43 | char Temp[21];
44 | char *TempPtr = std::end(Temp);
45 |
46 | while (N) {
47 | *--TempPtr = '0' + char(N % 10);
48 | N /= 10;
49 | }
50 |
51 | // Add negative sign...
52 | if (isNeg) *--TempPtr = '-';
53 | this->operator<<(StringView(TempPtr, std::end(Temp)));
54 | }
55 |
56 | public:
57 | OutputStream(char *StartBuf, size_t Size) : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
58 | OutputStream() = default;
59 | void reset(char *Buffer_, size_t BufferCapacity_) {
60 | CurrentPosition = 0;
61 | Buffer = Buffer_;
62 | BufferCapacity = BufferCapacity_;
63 | }
64 |
65 | /// If a ParameterPackExpansion (or similar type) is encountered, the offset
66 | /// into the pack that we're currently printing.
67 | unsigned CurrentPackIndex = std::numeric_limits::max();
68 | unsigned CurrentPackMax = std::numeric_limits::max();
69 |
70 | OutputStream &operator+=(StringView R) {
71 | size_t Size = R.size();
72 | if (Size == 0) return *this;
73 | grow(Size);
74 | std::memmove(Buffer + CurrentPosition, R.begin(), Size);
75 | CurrentPosition += Size;
76 | return *this;
77 | }
78 |
79 | OutputStream &operator+=(char C) {
80 | grow(1);
81 | Buffer[CurrentPosition++] = C;
82 | return *this;
83 | }
84 |
85 | OutputStream &operator<<(StringView R) { return (*this += R); }
86 |
87 | OutputStream &operator<<(char C) { return (*this += C); }
88 |
89 | OutputStream &operator<<(long long N) {
90 | if (N < 0)
91 | writeUnsigned(static_cast(-N), true);
92 | else
93 | writeUnsigned(static_cast(N));
94 | return *this;
95 | }
96 |
97 | OutputStream &operator<<(unsigned long long N) {
98 | writeUnsigned(N, false);
99 | return *this;
100 | }
101 |
102 | OutputStream &operator<<(long N) { return this->operator<<(static_cast(N)); }
103 |
104 | OutputStream &operator<<(unsigned long N) { return this->operator<<(static_cast(N)); }
105 |
106 | OutputStream &operator<<(int N) { return this->operator<<(static_cast(N)); }
107 |
108 | OutputStream &operator<<(unsigned int N) { return this->operator<<(static_cast(N)); }
109 |
110 | size_t getCurrentPosition() const { return CurrentPosition; }
111 | void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; }
112 |
113 | char back() const { return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0'; }
114 |
115 | bool empty() const { return CurrentPosition == 0; }
116 |
117 | char *getBuffer() { return Buffer; }
118 | char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
119 | size_t getBufferCapacity() const { return BufferCapacity; }
120 | };
121 |
122 | template class SwapAndRestore {
123 | T &Restore;
124 | T OriginalValue;
125 | bool ShouldRestore = true;
126 |
127 | public:
128 | SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {}
129 |
130 | SwapAndRestore(T &Restore_, T NewVal) : Restore(Restore_), OriginalValue(Restore) { Restore = std::move(NewVal); }
131 | ~SwapAndRestore() {
132 | if (ShouldRestore) Restore = std::move(OriginalValue);
133 | }
134 |
135 | void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; }
136 |
137 | void restoreNow(bool Force) {
138 | if (!Force && !ShouldRestore) return;
139 |
140 | Restore = std::move(OriginalValue);
141 | ShouldRestore = false;
142 | }
143 |
144 | SwapAndRestore(const SwapAndRestore &) = delete;
145 | SwapAndRestore &operator=(const SwapAndRestore &) = delete;
146 | };
147 |
148 | inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S, size_t InitSize) {
149 | size_t BufferSize;
150 | if (Buf == nullptr) {
151 | Buf = static_cast(std::malloc(InitSize));
152 | if (Buf == nullptr) return false;
153 | BufferSize = InitSize;
154 | } else
155 | BufferSize = *N;
156 |
157 | S.reset(Buf, BufferSize);
158 | return true;
159 | }
160 |
161 | } // namespace llvm
--------------------------------------------------------------------------------
/data/browser.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
100 | Bedrock Dedicated Server Dumper
101 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
BDS Dumper
213 |
214 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
--------------------------------------------------------------------------------
/WindowExt/main.cpp:
--------------------------------------------------------------------------------
1 | #undef WIN32_LEAN_AND_MEAN
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include "hiddenapi.h"
9 |
10 | static ITaskbarList *taskbar;
11 |
12 | namespace sciter {
13 |
14 | HINSTANCE application::hinstance() { return GetModuleHandle(NULL); }
15 |
16 | LRESULT window::on_message(HWINDOW hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL &pHandled) { return 0; }
17 |
18 | LRESULT SC_CALLBACK
19 | window::msg_delegate(HWINDOW hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LPVOID pParam, BOOL *pHandled) {
20 | window *win = static_cast(pParam);
21 | return win->on_message(hwnd, msg, wParam, lParam, *pHandled);
22 | }
23 |
24 | void window::collapse() {
25 | if (_hwnd) ::ShowWindow(_hwnd, SW_MINIMIZE);
26 | }
27 | void window::expand(bool maximize) {
28 | if (_hwnd) ::ShowWindow(_hwnd, maximize ? SW_MAXIMIZE : SW_NORMAL);
29 | }
30 | void window::dismiss() {
31 | if (_hwnd) ::PostMessage(_hwnd, WM_CLOSE, 0, 0);
32 | }
33 |
34 | window::window(UINT creationFlags, RECT frame) : _hwnd(NULL) {
35 | asset_add_ref();
36 | _hwnd = ::SciterCreateWindow(creationFlags, &frame, &msg_delegate, this, NULL);
37 | }
38 |
39 | } // namespace sciter
40 |
41 | struct basewin : sciter::window {
42 | basewin(UINT flags) : window(flags) {}
43 |
44 | bool show() {
45 | expand();
46 | return true;
47 | }
48 | };
49 |
50 | struct winext : sciter::om::asset {
51 | winext() {}
52 |
53 | SOM_PASSPORT_BEGIN(winext)
54 | SOM_FUNCS(
55 | SOM_FUNC(openFile), SOM_FUNC(saveFile), SOM_FUNC(menu), SOM_FUNC(create), SOM_FUNC(blur), SOM_FUNC(maximize),
56 | SOM_FUNC(restore))
57 | SOM_PASSPORT_END
58 |
59 | SCITER_VALUE openFile(sciter::string filter, sciter::string title, sciter::value el) {
60 | HWND hwnd = 0;
61 | SciterGetElementHwnd((HELEMENT) el.get_object_data(), &hwnd, TRUE);
62 | if (hwnd == 0) return sciter::value(false);
63 | std::replace(filter.begin(), filter.end(), L'|', L'\0');
64 | filter += L'\0';
65 | wchar ret[MAX_PATH]{};
66 | OPENFILENAME param{
67 | .lStructSize = sizeof(OPENFILENAME),
68 | .hwndOwner = hwnd,
69 | .hInstance = sciter::application::hinstance(),
70 | .lpstrFilter = filter.c_str(),
71 | .nFilterIndex = 0,
72 | .lpstrFile = ret,
73 | .nMaxFile = MAX_PATH,
74 | .lpstrTitle = title.c_str(),
75 | .Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST,
76 | };
77 | GetOpenFileName(¶m);
78 | return sciter::value::from_string(ret);
79 | }
80 |
81 | SCITER_VALUE saveFile(sciter::string filter, sciter::string defext, sciter::string title, sciter::value el) {
82 | HWND hwnd = 0;
83 | SciterGetElementHwnd((HELEMENT) el.get_object_data(), &hwnd, TRUE);
84 | if (hwnd == 0) return sciter::value(false);
85 | std::replace(filter.begin(), filter.end(), L'|', L'\0');
86 | filter += L'\0';
87 | wchar ret[MAX_PATH]{};
88 | OPENFILENAME param{
89 | .lStructSize = sizeof(OPENFILENAME),
90 | .hwndOwner = hwnd,
91 | .hInstance = sciter::application::hinstance(),
92 | .lpstrFilter = filter.c_str(),
93 | .nFilterIndex = 0,
94 | .lpstrFile = ret,
95 | .nMaxFile = MAX_PATH,
96 | .lpstrTitle = title.c_str(),
97 | .Flags = OFN_NOCHANGEDIR | OFN_EXTENSIONDIFFERENT | OFN_OVERWRITEPROMPT,
98 | .lpstrDefExt = defext.c_str(),
99 | };
100 | GetSaveFileName(¶m);
101 | return sciter::value::from_string(ret);
102 | }
103 |
104 | SCITER_VALUE create(sciter::string address, SCITER_VALUE args) {
105 | struct context : basewin {
106 | SCITER_VALUE value;
107 | context(SCITER_VALUE value)
108 | : basewin(SW_GLASSY | SW_CONTROLS | SW_RESIZEABLE | SW_TITLEBAR | SW_ENABLE_DEBUG), value(value) {}
109 |
110 | SOM_PASSPORT_BEGIN(context)
111 | SOM_PROPS(SOM_PROP(value))
112 | SOM_FUNCS(SOM_FUNC(show))
113 | SOM_PASSPORT_END
114 | };
115 | sciter::om::hasset win = new context(args);
116 |
117 | auto hwnd = win->get_hwnd();
118 | win->load(address.c_str());
119 | make_blur(hwnd);
120 | return sciter::value::wrap_asset(win);
121 | }
122 |
123 | SCITER_VALUE menu(sciter::string address, SCITER_VALUE args) {
124 | struct menuctx : basewin {
125 | SCITER_VALUE value;
126 | menuctx(SCITER_VALUE value) : basewin(SW_GLASSY | SW_TOOL | SW_ENABLE_DEBUG), value(value) {}
127 |
128 | SOM_PASSPORT_BEGIN_EX(menu, menuctx)
129 | SOM_PROPS(SOM_PROP(value))
130 | SOM_FUNCS(SOM_FUNC(show))
131 | SOM_PASSPORT_END
132 | };
133 | sciter::om::hasset win = new menuctx(args);
134 |
135 | auto hwnd = win->get_hwnd();
136 | win->load(address.c_str());
137 | make_blur(hwnd);
138 | taskbar->DeleteTab(hwnd);
139 | return sciter::value::wrap_asset(win);
140 | }
141 |
142 | bool blur(sciter::value el) {
143 | HWND hwnd = 0;
144 | SciterGetElementHwnd((HELEMENT) el.get_object_data(), &hwnd, TRUE);
145 | if (hwnd == 0) return false;
146 | make_blur(hwnd);
147 | return true;
148 | }
149 |
150 | bool maximize(sciter::value el) {
151 | HWND hwnd = 0;
152 | SciterGetElementHwnd((HELEMENT) el.get_object_data(), &hwnd, TRUE);
153 | if (hwnd == 0) return false;
154 | ShowWindow(hwnd, SW_MAXIMIZE);
155 | return true;
156 | }
157 |
158 | bool restore(sciter::value el) {
159 | HWND hwnd = 0;
160 | SciterGetElementHwnd((HELEMENT) el.get_object_data(), &hwnd, TRUE);
161 | if (hwnd == 0) return false;
162 | ShowWindow(hwnd, SW_RESTORE);
163 | return true;
164 | }
165 | };
166 |
167 | extern "C" __declspec(dllexport) BOOL SCAPI SciterLibraryInit(ISciterAPI *psapi, SCITER_VALUE *plibobject) {
168 | CoInitialize(0);
169 | CoCreateInstance(CLSID_TaskbarList, 0, CLSCTX_INPROC_SERVER, IID_ITaskbarList, (void **) &taskbar);
170 | taskbar->HrInit();
171 |
172 | _SAPI(psapi);
173 | static sciter::om::hasset root = new winext();
174 |
175 | *plibobject = sciter::value::wrap_asset(root);
176 | return TRUE;
177 | }
--------------------------------------------------------------------------------
/sqlite3/SymbolTokenizer.cpp:
--------------------------------------------------------------------------------
1 | #include "sqlite3ext.h"
2 | #include
3 | #include
4 |
5 | SQLITE_EXTENSION_INIT1
6 |
7 | static fts5_api *fts5_api_from_db(sqlite3 *db) {
8 | fts5_api *pRet = 0;
9 | sqlite3_stmt *pStmt = 0;
10 |
11 | if (SQLITE_OK == sqlite3_prepare(db, "SELECT fts5(?1)", -1, &pStmt, 0)) {
12 | sqlite3_bind_pointer(pStmt, 1, (void *) &pRet, "fts5_api_ptr", NULL);
13 | sqlite3_step(pStmt);
14 | }
15 | sqlite3_finalize(pStmt);
16 | return pRet;
17 | }
18 |
19 | static fts5_api *fts5 = nullptr;
20 |
21 | static int symbol_xCreate(void *, const char **azArg, int nArg, Fts5Tokenizer **ppOut) {
22 | *ppOut = (Fts5Tokenizer *) "fake";
23 | return SQLITE_OK;
24 | }
25 | static void symbol_xDelete(Fts5Tokenizer *self) {}
26 |
27 | inline bool isTokenChar(char ch) { return ch == '$' || ch == '_' || 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z'; }
28 |
29 | inline bool isAlpha(char ch) { return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z'; }
30 |
31 | inline bool isUpperCase(char ch) { return 'A' <= ch && ch <= 'Z'; }
32 |
33 | inline bool isNum(char ch) { return '0' <= ch && ch <= '9'; }
34 |
35 | inline bool isSep(char ch) { return !isTokenChar(ch) && !isNum(ch); }
36 |
37 | #if 1 && !defined(NDEBUG)
38 | # define iemit oemit
39 | # define DEBUG_EMIT
40 | #else
41 | # define iemit emit
42 | #endif
43 |
44 | static int symbol_tokenize(
45 | Fts5Tokenizer *, void *ctx, int flags, const char *text, int len,
46 | int (*iemit)(void *pCtx, int tflags, const char *pToken, int nToken, int iStart, int iEnd)) {
47 | int rc = SQLITE_OK;
48 | if (text == NULL) return rc;
49 | int rec0 = 0, rec1 = 0;
50 | enum struct State { None, Alpha, Number, Seprator, Operator } state{};
51 |
52 | #ifdef DEBUG_EMIT
53 | auto emit = [&](void *pCtx, int tflags, const char *pToken, int nToken, int iStart, int iEnd) -> int {
54 | std::cout << "token " << (tflags ? "-" : "+") << " (" << std::string_view{pToken, (size_t) nToken} << "), "
55 | << iStart << ", " << iEnd << std::endl;
56 | return oemit(pCtx, tflags, pToken, nToken, iStart, iEnd);
57 | };
58 | #endif
59 |
60 | for (int i = 0; i < len; i++) {
61 | auto const &cur = text[i];
62 | switch (state) {
63 | case State::None:
64 | rec0 = rec1 = i;
65 | if (isTokenChar(cur))
66 | state = State::Alpha;
67 | else if (isNum(cur))
68 | state = State::Number;
69 | break;
70 | case State::Alpha:
71 | if (isSep(cur)) {
72 | state = cur == ':' ? State::Seprator : State::None;
73 | emit(ctx, 0, text + rec0, i - rec0, rec0, i);
74 | if (rec0 != rec1)
75 | emit(ctx, 0, text + rec1, i - rec1, rec1, i);
76 | else if (std::string_view{text + rec0, (size_t) i - rec0} == "operator") {
77 | rec1 = i;
78 | state = State::Operator;
79 | }
80 | rec0 = i;
81 | } else if (isUpperCase(cur) || isNum(cur)) {
82 | emit(ctx, 0, text + rec1, i - rec1, rec1, i);
83 | rec1 = i;
84 | } else if (cur == '_' && text[rec0] != '$') {
85 | emit(ctx, 0, text + rec1, i - rec1, rec1, i);
86 | rec1 = ++i;
87 | }
88 | break;
89 | case State::Number:
90 | if (isNum(cur)) continue;
91 | if (isTokenChar(cur)) {
92 | emit(ctx, 0, text + rec1, i - rec1, rec1, i);
93 | rec1 = i;
94 | state = State::Alpha;
95 | } else if (isSep(cur)) {
96 | emit(ctx, 0, text + rec0, i - rec0, rec0, i);
97 | if (rec0 != rec1) emit(ctx, 0, text + rec1, i - rec1, rec1, i);
98 | state = cur == ':' ? State::Seprator : State::None;
99 | rec0 = i;
100 | }
101 | break;
102 | case State::Seprator:
103 | if (cur == ':') emit(ctx, 0, text + rec0, i - rec0 + 1, rec0, i + 1);
104 | state = State::None;
105 | break;
106 | case State::Operator:
107 | if (cur == '(') {
108 | emit(ctx, 0, text + rec0, i - rec0, rec0, i);
109 | state = State::None;
110 | }
111 | break;
112 | default: return SQLITE_MISUSE;
113 | }
114 | }
115 | switch (state) {
116 | case State::None: break;
117 | case State::Alpha:
118 | case State::Number:
119 | emit(ctx, 0, text + rec0, len - rec0, rec0, len);
120 | if (rec0 != rec1) emit(ctx, 0, text + rec1, len - rec1, rec1, len);
121 | break;
122 | case State::Operator: emit(ctx, 0, text + rec0, len - rec0, rec0, len); break;
123 | default: break;
124 | }
125 | return rc;
126 | }
127 |
128 | static fts5_tokenizer tokenizer{
129 | .xCreate = symbol_xCreate,
130 | .xDelete = symbol_xDelete,
131 | .xTokenize = symbol_tokenize,
132 | };
133 |
134 | void symprefix(sqlite3_context *ctx, int, sqlite3_value **values) {
135 | auto str = sqlite3_value_text(values[0]);
136 | auto len = sqlite3_value_bytes(values[0]);
137 |
138 | std::string buf;
139 | buf.reserve(len);
140 | auto level = 0, skiplvl = 0;
141 |
142 | for (int i = 0; i < len; i++) {
143 | auto cur = str[i];
144 | if (skiplvl == 0) {
145 | if (cur == '<') {
146 | buf += ' ';
147 | level++;
148 | } else if (cur == '>') {
149 | buf += ' ';
150 | level--;
151 | } else if (cur == '(') {
152 | if (buf.ends_with("operator"))
153 | buf += cur;
154 | else if (level == 0)
155 | break;
156 | skiplvl++;
157 | } else if (cur != '-'){
158 | buf += cur;
159 | }
160 | } else {
161 | if (cur == '(' && !buf.ends_with("operator")) {
162 | skiplvl++;
163 | } else if (cur == ')' && !buf.ends_with("operator(")) {
164 | skiplvl--;
165 | }
166 | }
167 | }
168 | sqlite3_result_text(ctx, buf.c_str(), (int) buf.size(), SQLITE_TRANSIENT);
169 | }
170 |
171 | extern "C" __declspec(dllexport) int sqlite3_symboltokenizer_init(
172 | sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi) {
173 | int rc = SQLITE_OK;
174 | SQLITE_EXTENSION_INIT2(pApi);
175 | fts5 = fts5_api_from_db(db);
176 | fts5->xCreateTokenizer(fts5, "symbol", nullptr, &tokenizer, nullptr);
177 | sqlite3_create_function(db, "symprefix", 1, SQLITE_UTF8 | SQLITE_DIRECTONLY, nullptr, symprefix, nullptr, nullptr);
178 | return rc;
179 | }
--------------------------------------------------------------------------------
/data/tab-content/vtable.html:
--------------------------------------------------------------------------------
1 |
66 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
--------------------------------------------------------------------------------
/data/tab-content/search.html:
--------------------------------------------------------------------------------
1 |
113 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 | reload
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
--------------------------------------------------------------------------------
/Adapter/include/adapter.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | namespace adapter {
12 |
13 | enum struct RootKind : int {
14 | Unknown = 0,
15 | Variable = 1,
16 | Function = 2,
17 | SpecialName = 3,
18 | LocalName = 4,
19 | };
20 |
21 | namespace Enum {
22 | enum Qualifier { None = 0, Const = 1, Volatile = 2, Restrict = 4 };
23 |
24 | inline Qualifier operator|(Qualifier lhs, Qualifier rhs) { return (Qualifier)(((int) lhs) | ((int) rhs)); }
25 | inline Qualifier &operator|=(Qualifier &lhs, Qualifier rhs) {
26 | lhs = lhs | rhs;
27 | return lhs;
28 | }
29 |
30 | inline std::ostream &operator<<(std::ostream &os, Qualifier q) {
31 | if (q & Const) os << "const ";
32 | if (q & Volatile) os << "volatile ";
33 | if (q & Restrict) os << "restrict ";
34 | return os;
35 | }
36 |
37 | } // namespace Enum
38 |
39 | enum class PointerKind { Pointer, Reference, RValueReference };
40 |
41 | inline std::ostream &operator<<(std::ostream &os, PointerKind k) {
42 | switch (k) {
43 | case adapter::PointerKind::Pointer: os << "* "; break;
44 | case adapter::PointerKind::Reference: os << "& "; break;
45 | case adapter::PointerKind::RValueReference: os << "&& "; break;
46 | default: break;
47 | }
48 | return os;
49 | }
50 |
51 | enum class FunctionReferenceKind { None, Reference, RValueReference };
52 |
53 | inline std::ostream &operator<<(std::ostream &os, FunctionReferenceKind k) {
54 | switch (k) {
55 | case adapter::FunctionReferenceKind::None: break;
56 | case adapter::FunctionReferenceKind::Reference: os << "& "; break;
57 | case adapter::FunctionReferenceKind::RValueReference: os << "&& "; break;
58 | default: break;
59 | }
60 | return os;
61 | }
62 |
63 | struct Node {
64 | virtual ~Node() {}
65 | virtual void Print(std::ostream &os) const = 0;
66 |
67 | friend std::ostream &operator<<(std::ostream &os, const Node &node) {
68 | node.Print(os);
69 | return os;
70 | }
71 |
72 | std::string ToString() {
73 | std::ostringstream oss;
74 | oss << *this;
75 | return oss.str();
76 | }
77 | };
78 |
79 | struct RootNode : Node {
80 | RootKind Kind;
81 | RootNode(RootKind Kind) : Kind(Kind) {}
82 | };
83 | struct TypeNode : Node {};
84 |
85 | template struct NodeArray {
86 | std::vector> Elements;
87 |
88 | void Print(std::ostream &os, std::string_view del = ", ") const {
89 | bool first = true;
90 | for (auto &element : Elements) {
91 | if (first)
92 | first = false;
93 | else
94 | os << del;
95 | os << *element;
96 | }
97 | }
98 |
99 | void append(std::unique_ptr &&r) { Elements.emplace_back(std::move(r)); }
100 | };
101 |
102 | struct SkippedRoot : RootNode {
103 | SkippedRoot() : RootNode(RootKind::Unknown) {}
104 | virtual void Print(std::ostream &os) const override { os << "$SKIP_ROOT"; }
105 | };
106 | struct SkippedType : TypeNode {
107 | virtual void Print(std::ostream &os) const override { os << "$SKIP_TYPE"; }
108 | };
109 |
110 | struct NamePiece : Node {
111 | virtual std::string &GetRaw() = 0;
112 | virtual std::optional> &GetTemplate() = 0;
113 | };
114 |
115 | struct SimpleNamePiece : NamePiece {
116 | std::string Raw;
117 | std::optional> TemplateParameters;
118 |
119 | SimpleNamePiece(std::string Raw, std::optional> TemplateParameters = std::nullopt)
120 | : Raw(std::move(Raw)), TemplateParameters(std::move(TemplateParameters)) {}
121 |
122 | std::string &GetRaw() override { return Raw; }
123 | std::optional> &GetTemplate() override { return TemplateParameters; }
124 |
125 | virtual void Print(std::ostream &os) const override {
126 | os << Raw;
127 | if (TemplateParameters) {
128 | os << "<";
129 | TemplateParameters->Print(os);
130 | os << ">";
131 | }
132 | }
133 | };
134 |
135 | struct NameNode : Node {
136 | NodeArray Pieces;
137 |
138 | virtual void Print(std::ostream &os) const override { Pieces.Print(os, "::"); }
139 | };
140 |
141 | struct SpecialType : TypeNode {
142 | std::string Name;
143 |
144 | SpecialType(std::string Name) : Name(std::move(Name)) {}
145 |
146 | virtual void Print(std::ostream &os) const override { os << "$$" << Name; }
147 | };
148 |
149 | struct SimpleType : TypeNode {
150 | std::unique_ptr Name;
151 |
152 | SimpleType(std::unique_ptr Name) : Name(std::move(Name)) {}
153 |
154 | virtual void Print(std::ostream &os) const override { os << *Name; }
155 | };
156 |
157 | struct QualType : TypeNode {
158 | std::unique_ptr Child;
159 | Enum::Qualifier Qualifier;
160 |
161 | QualType(std::unique_ptr Child, Enum::Qualifier Qualifier)
162 | : Child(std::move(Child)), Qualifier(Qualifier) {}
163 |
164 | virtual void Print(std::ostream &os) const override { os << Qualifier << *Child; }
165 | };
166 |
167 | struct PointerType : TypeNode {
168 | std::unique_ptr Child;
169 | PointerKind Type;
170 |
171 | PointerType(std::unique_ptr Child, PointerKind Type) : Child(std::move(Child)), Type(Type) {}
172 |
173 | virtual void Print(std::ostream &os) const override { os << Type << *Child; }
174 | };
175 |
176 | struct FunctionType : TypeNode {
177 | NodeArray Params;
178 | std::unique_ptr ReturnType;
179 | Enum::Qualifier Qualifier;
180 | FunctionReferenceKind FuncReference;
181 |
182 | FunctionType(
183 | NodeArray Params, std::unique_ptr ReturnType, Enum::Qualifier Qualifier,
184 | FunctionReferenceKind FuncReference = FunctionReferenceKind::None)
185 | : Params(std::move(Params)), ReturnType(std::move(ReturnType)), Qualifier(Qualifier),
186 | FuncReference(FuncReference) {}
187 |
188 | virtual void Print(std::ostream &os) const override {
189 | os << "(";
190 | Params.Print(os);
191 | os << ") ";
192 | os << Qualifier << FuncReference;
193 | os << "-> ";
194 | if (ReturnType)
195 | os << *ReturnType;
196 | else
197 | os << "unknown";
198 | }
199 | };
200 |
201 | struct FunctionRootNode : RootNode {
202 | std::unique_ptr Name;
203 | std::unique_ptr Signature;
204 |
205 | FunctionRootNode(std::unique_ptr Name, std::unique_ptr Signature)
206 | : RootNode(RootKind::Function), Name(std::move(Name)), Signature(std::move(Signature)) {}
207 |
208 | virtual void Print(std::ostream &os) const override { os << *Name << *Signature; }
209 | };
210 |
211 | struct VariableRootNode : RootNode {
212 | std::unique_ptr Name;
213 | std::unique_ptr Type;
214 |
215 | VariableRootNode(std::unique_ptr Name, std::unique_ptr Type)
216 | : RootNode(RootKind::Variable), Name(std::move(Name)), Type(std::move(Type)) {}
217 |
218 | virtual void Print(std::ostream &os) const override {
219 | os << *Name << " -> ";
220 | if (Type)
221 | os << *Type;
222 | else
223 | os << "$unknown";
224 | }
225 | };
226 |
227 | enum struct SpecialNameKind { vtable, type_info, type_info_name, complete_object_locator };
228 |
229 | struct SpecialNameNode : RootNode {
230 | SpecialNameKind Kind;
231 | std::unique_ptr Type;
232 |
233 | SpecialNameNode(SpecialNameKind Kind, std::unique_ptr Type)
234 | : RootNode(RootKind::SpecialName), Kind(Kind), Type(std::move(Type)) {}
235 |
236 | virtual void Print(std::ostream &os) const override {
237 | if (Kind == SpecialNameKind::vtable) {
238 | os << *Type << "::$vtable";
239 | } else if (Kind == SpecialNameKind::complete_object_locator) {
240 | os << *Type << "::$complete_object_locator";
241 | } else {
242 | os << *Type << " <- ";
243 | switch (Kind) {
244 | case SpecialNameKind::type_info: os << "$type_info"; break;
245 | case SpecialNameKind::type_info_name: os << "$type_info_name"; break;
246 | default: os << "$unknow_special"; break;
247 | }
248 | }
249 | }
250 | };
251 |
252 | struct LocalNameNode : RootNode {
253 | std::unique_ptr Root;
254 | std::unique_ptr Name;
255 | std::unique_ptr Type;
256 |
257 | LocalNameNode(std::unique_ptr Root, std::unique_ptr Name, std::unique_ptr Type)
258 | : RootNode(RootKind::LocalName), Root(std::move(Root)), Name(std::move(Name)), Type(std::move(Type)) {}
259 |
260 | virtual void Print(std::ostream &os) const override {
261 | os << *Root << " | " << *Name << " -> ";
262 | if (Type)
263 | os << *Type;
264 | else
265 | os << "$unknown";
266 | }
267 | };
268 |
269 | struct LocalNameTypeNode : TypeNode {
270 | std::unique_ptr LocalName;
271 |
272 | LocalNameTypeNode(std::unique_ptr LocalName) : LocalName(std::move(LocalName)) {}
273 |
274 | virtual void Print(std::ostream &os) const override { os << *LocalName; }
275 | };
276 |
277 | template std::unique_ptr Adapt(T const &node) { return nullptr; }
278 |
279 | } // namespace adapter
280 |
281 | namespace llvm {
282 | namespace itanium_demangle {
283 | class Node;
284 | }
285 | namespace ms_demangle {
286 | struct SymbolNode;
287 | }
288 | } // namespace llvm
289 |
290 | template <> std::unique_ptr adapter::Adapt<>(llvm::itanium_demangle::Node const &node);
291 | template <> std::unique_ptr adapter::Adapt<>(llvm::ms_demangle::SymbolNode const &node);
--------------------------------------------------------------------------------
/Demangler/include/MicrosoftDemangle.h:
--------------------------------------------------------------------------------
1 | //===------------------------- MicrosoftDemangle.h --------------*- C++ -*-===//
2 | //
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 | // See https://llvm.org/LICENSE.txt for license information.
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 | //
7 | //===----------------------------------------------------------------------===//
8 |
9 | #pragma once
10 |
11 | #include "Demangle.h"
12 | #include "DemangleConfig.h"
13 | #include "Utility.h"
14 | #include "StringView.h"
15 | #include "MicrosoftDemangleNodes.h"
16 |
17 | #include
18 | #include
19 |
20 | namespace llvm::ms_demangle {
21 |
22 | // This memory allocator is extremely fast, but it doesn't call dtors
23 | // for allocated objects. That means you can't use STL containers
24 | // (such as std::vector) with this allocator. But it pays off --
25 | // the demangler is 3x faster with this allocator compared to one with
26 | // STL containers.
27 | constexpr size_t AllocUnit = 4096;
28 |
29 | class ArenaAllocator {
30 | struct AllocatorNode {
31 | uint8_t *Buf = nullptr;
32 | size_t Used = 0;
33 | size_t Capacity = 0;
34 | AllocatorNode *Next = nullptr;
35 | };
36 |
37 | void addNode(size_t Capacity) {
38 | AllocatorNode *NewHead = new AllocatorNode;
39 | NewHead->Buf = new uint8_t[Capacity];
40 | NewHead->Next = Head;
41 | NewHead->Capacity = Capacity;
42 | Head = NewHead;
43 | NewHead->Used = 0;
44 | }
45 |
46 | public:
47 | ArenaAllocator() { addNode(AllocUnit); }
48 |
49 | ~ArenaAllocator() {
50 | while (Head) {
51 | assert(Head->Buf);
52 | delete[] Head->Buf;
53 | AllocatorNode *Next = Head->Next;
54 | delete Head;
55 | Head = Next;
56 | }
57 | }
58 |
59 | char *allocUnalignedBuffer(size_t Size) {
60 | assert(Head && Head->Buf);
61 |
62 | uint8_t *P = Head->Buf + Head->Used;
63 |
64 | Head->Used += Size;
65 | if (Head->Used <= Head->Capacity) return reinterpret_cast(P);
66 |
67 | addNode(std::max(AllocUnit, Size));
68 | Head->Used = Size;
69 | return reinterpret_cast(Head->Buf);
70 | }
71 |
72 | template T *allocArray(size_t Count) {
73 | size_t Size = Count * sizeof(T);
74 | assert(Head && Head->Buf);
75 |
76 | size_t P = (size_t) Head->Buf + Head->Used;
77 | uintptr_t AlignedP = (((size_t) P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
78 | uint8_t *PP = (uint8_t *) AlignedP;
79 | size_t Adjustment = AlignedP - P;
80 |
81 | Head->Used += Size + Adjustment;
82 | if (Head->Used <= Head->Capacity) return new (PP) T[Count]();
83 |
84 | addNode(std::max(AllocUnit, Size));
85 | Head->Used = Size;
86 | return new (Head->Buf) T[Count]();
87 | }
88 |
89 | template T *alloc(Args &&... ConstructorArgs) {
90 | constexpr size_t Size = sizeof(T);
91 | assert(Head && Head->Buf);
92 |
93 | size_t P = (size_t) Head->Buf + Head->Used;
94 | uintptr_t AlignedP = (((size_t) P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
95 | uint8_t *PP = (uint8_t *) AlignedP;
96 | size_t Adjustment = AlignedP - P;
97 |
98 | Head->Used += Size + Adjustment;
99 | if (Head->Used <= Head->Capacity) return new (PP) T(std::forward(ConstructorArgs)...);
100 |
101 | static_assert(Size < AllocUnit, "");
102 | addNode(AllocUnit);
103 | Head->Used = Size;
104 | return new (Head->Buf) T(std::forward(ConstructorArgs)...);
105 | }
106 |
107 | private:
108 | AllocatorNode *Head = nullptr;
109 | };
110 |
111 | struct BackrefContext {
112 | static constexpr size_t Max = 10;
113 |
114 | TypeNode *FunctionParams[Max];
115 | size_t FunctionParamCount = 0;
116 |
117 | // The first 10 BackReferences in a mangled name can be back-referenced by
118 | // special name @[0-9]. This is a storage for the first 10 BackReferences.
119 | IdentifierNode *Names[Max];
120 | size_t NamesCount = 0;
121 | };
122 |
123 | enum class QualifierMangleMode { Drop, Mangle, Result };
124 |
125 | enum NameBackrefBehavior : uint8_t {
126 | NBB_None = 0, // don't save any names as backrefs.
127 | NBB_Template = 1 << 0, // save template instanations.
128 | NBB_Simple = 1 << 1, // save simple names.
129 | };
130 |
131 | enum class FunctionIdentifierCodeGroup { Basic, Under, DoubleUnder };
132 |
133 | // Demangler class takes the main role in demangling symbols.
134 | // It has a set of functions to parse mangled symbols into Type instances.
135 | // It also has a set of functions to convert Type instances to strings.
136 | class Demangler {
137 | public:
138 | Demangler() = default;
139 | virtual ~Demangler() = default;
140 |
141 | // You are supposed to call parse() first and then check if error is true. If
142 | // it is false, call output() to write the formatted name to the given stream.
143 | SymbolNode *parse(StringView &MangledName);
144 |
145 | TagTypeNode *parseTagUniqueName(StringView &MangledName);
146 |
147 | // True if an error occurred.
148 | bool Error = false;
149 |
150 | void dumpBackReferences();
151 |
152 | private:
153 | SymbolNode *demangleEncodedSymbol(StringView &MangledName, QualifiedNameNode *QN);
154 | SymbolNode *demangleDeclarator(StringView &MangledName);
155 | SymbolNode *demangleMD5Name(StringView &MangledName);
156 | SymbolNode *demangleTypeinfoName(StringView &MangledName);
157 |
158 | VariableSymbolNode *demangleVariableEncoding(StringView &MangledName, StorageClass SC);
159 | FunctionSymbolNode *demangleFunctionEncoding(StringView &MangledName);
160 |
161 | Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
162 |
163 | // Parser functions. This is a recursive-descent parser.
164 | TypeNode *demangleType(StringView &MangledName, QualifierMangleMode QMM);
165 | PrimitiveTypeNode *demanglePrimitiveType(StringView &MangledName);
166 | CustomTypeNode *demangleCustomType(StringView &MangledName);
167 | TagTypeNode *demangleClassType(StringView &MangledName);
168 | PointerTypeNode *demanglePointerType(StringView &MangledName);
169 | PointerTypeNode *demangleMemberPointerType(StringView &MangledName);
170 | FunctionSignatureNode *demangleFunctionType(StringView &MangledName, bool HasThisQuals);
171 |
172 | ArrayTypeNode *demangleArrayType(StringView &MangledName);
173 |
174 | NodeArrayNode *demangleFunctionParameterList(StringView &MangledName, bool &IsVariadic);
175 | NodeArrayNode *demangleTemplateParameterList(StringView &MangledName);
176 |
177 | std::pair demangleNumber(StringView &MangledName);
178 | uint64_t demangleUnsigned(StringView &MangledName);
179 | int64_t demangleSigned(StringView &MangledName);
180 |
181 | void memorizeString(StringView s);
182 | void memorizeIdentifier(IdentifierNode *Identifier);
183 |
184 | /// Allocate a copy of \p Borrowed into memory that we own.
185 | StringView copyString(StringView Borrowed);
186 |
187 | QualifiedNameNode *demangleFullyQualifiedTypeName(StringView &MangledName);
188 | QualifiedNameNode *demangleFullyQualifiedSymbolName(StringView &MangledName);
189 |
190 | IdentifierNode *demangleUnqualifiedTypeName(StringView &MangledName, bool Memorize);
191 | IdentifierNode *demangleUnqualifiedSymbolName(StringView &MangledName, NameBackrefBehavior NBB);
192 |
193 | QualifiedNameNode *demangleNameScopeChain(StringView &MangledName, IdentifierNode *UnqualifiedName);
194 | IdentifierNode *demangleNameScopePiece(StringView &MangledName);
195 |
196 | IdentifierNode *demangleBackRefName(StringView &MangledName);
197 | IdentifierNode *demangleTemplateInstantiationName(StringView &MangledName, NameBackrefBehavior NBB);
198 | IntrinsicFunctionKind translateIntrinsicFunctionCode(char CH, FunctionIdentifierCodeGroup Group);
199 | IdentifierNode *demangleFunctionIdentifierCode(StringView &MangledName);
200 | IdentifierNode *demangleFunctionIdentifierCode(StringView &MangledName, FunctionIdentifierCodeGroup Group);
201 | StructorIdentifierNode *demangleStructorIdentifier(StringView &MangledName, bool IsDestructor);
202 | ConversionOperatorIdentifierNode *demangleConversionOperatorIdentifier(StringView &MangledName);
203 | LiteralOperatorIdentifierNode *demangleLiteralOperatorIdentifier(StringView &MangledName);
204 |
205 | SymbolNode *demangleSpecialIntrinsic(StringView &MangledName);
206 | SpecialTableSymbolNode *demangleSpecialTableSymbolNode(StringView &MangledName, SpecialIntrinsicKind SIK);
207 | LocalStaticGuardVariableNode *demangleLocalStaticGuard(StringView &MangledName, bool IsThread);
208 | VariableSymbolNode *demangleUntypedVariable(ArenaAllocator &Arena, StringView &MangledName, StringView VariableName);
209 | VariableSymbolNode *demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena, StringView &MangledName);
210 | FunctionSymbolNode *demangleInitFiniStub(StringView &MangledName, bool IsDestructor);
211 |
212 | NamedIdentifierNode *demangleSimpleName(StringView &MangledName, bool Memorize);
213 | NamedIdentifierNode *demangleAnonymousNamespaceName(StringView &MangledName);
214 | NamedIdentifierNode *demangleLocallyScopedNamePiece(StringView &MangledName);
215 | EncodedStringLiteralNode *demangleStringLiteral(StringView &MangledName);
216 | FunctionSymbolNode *demangleVcallThunkNode(StringView &MangledName);
217 |
218 | StringView demangleSimpleString(StringView &MangledName, bool Memorize);
219 |
220 | FuncClass demangleFunctionClass(StringView &MangledName);
221 | CallingConv demangleCallingConvention(StringView &MangledName);
222 | StorageClass demangleVariableStorageClass(StringView &MangledName);
223 | bool demangleThrowSpecification(StringView &MangledName);
224 | wchar_t demangleWcharLiteral(StringView &MangledName);
225 | uint8_t demangleCharLiteral(StringView &MangledName);
226 |
227 | std::pair demangleQualifiers(StringView &MangledName);
228 |
229 | // Memory allocator.
230 | ArenaAllocator Arena;
231 |
232 | // A single type uses one global back-ref table for all function params.
233 | // This means back-refs can even go "into" other types. Examples:
234 | //
235 | // // Second int* is a back-ref to first.
236 | // void foo(int *, int*);
237 | //
238 | // // Second int* is not a back-ref to first (first is not a function param).
239 | // int* foo(int*);
240 | //
241 | // // Second int* is a back-ref to first (ALL function types share the same
242 | // // back-ref map.
243 | // using F = void(*)(int*);
244 | // F G(int *);
245 | BackrefContext Backrefs;
246 | };
247 | } // namespace llvm::ms_demangle
--------------------------------------------------------------------------------
/Adapter/itanium.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "include/adapter.h"
4 |
5 | #include
6 |
7 | using namespace adapter;
8 | using namespace llvm;
9 | namespace SRC = llvm::itanium_demangle;
10 |
11 | namespace itanium {
12 |
13 | template struct BaseContext {
14 | std::unique_ptr output{};
15 |
16 | BaseContext(SRC::Node const *node) { process(node); }
17 |
18 | void process(SRC::Node const *node) { node->visit((XType &) *this); }
19 |
20 | operator std::unique_ptr() { return std::move(output); }
21 | };
22 |
23 | struct NameContext {
24 | std::unique_ptr name;
25 | std::vector> &output() { return name->Pieces.Elements; }
26 | std::optional> temp;
27 | NameContext(SRC::Node const *node) : name(std::make_unique()) { process(node); }
28 |
29 | void process(SRC::Node const *node) { node->visit(*this); }
30 |
31 | template void operator()(T node) {}
32 |
33 | operator std::unique_ptr() {
34 | if (output().size() >= 2 && output()[0]->GetRaw() == "std") {
35 | if (output()[1]->GetRaw() == "__cxx11") { output().erase(++output().begin()); }
36 | auto &key = *output()[1];
37 | if (output().size() == 2 && key.GetRaw() == "basic_string") {
38 | auto &temp = output()[1]->GetTemplate()->Elements;
39 | auto chtype = temp[0]->ToString();
40 | auto trtype = temp[1]->ToString();
41 | auto altype = temp[2]->ToString();
42 | if (chtype == "char" && trtype == "std::char_traits" && altype == "std::allocator") {
43 | output()[1] = std::make_unique("string");
44 | } else if (chtype == "wchar" && trtype == "std::char_traits" && altype == "std::allocator") {
45 | output()[1] = std::make_unique("wstring");
46 | }
47 | } else if (key.GetRaw() == "vector" || key.GetRaw() == "initializer_list") {
48 | auto &temp = key.GetTemplate()->Elements;
49 | if (temp.size() != 2) goto end;
50 | auto &base = temp[0];
51 | auto &alloc = temp[1];
52 | if (auto st = dynamic_cast(alloc.get())) {
53 | auto &sp = st->Name->Pieces.Elements;
54 | if (sp[0]->GetRaw() == "std" && sp[1]->GetRaw() == "allocator") {
55 | if (sp[1]->GetTemplate()->Elements[0]->ToString() == base->ToString()) {
56 | temp.resize(1); //
57 | }
58 | }
59 | }
60 | } else if (key.GetRaw() == "unique_ptr") {
61 | auto &temp = key.GetTemplate()->Elements;
62 | auto &base = temp[0];
63 | auto &alloc = temp[1];
64 | if (auto st = dynamic_cast(alloc.get())) {
65 | auto &sp = st->Name->Pieces.Elements;
66 | if (sp[0]->GetRaw() == "std" && sp[1]->GetRaw() == "default_delete") {
67 | if (sp[1]->GetTemplate()->Elements[0]->ToString() == base->ToString()) {
68 | temp.resize(1); //
69 | }
70 | }
71 | }
72 | }
73 | }
74 | end:
75 | return std::move(name);
76 | }
77 | };
78 |
79 | struct RootContext : BaseContext {
80 | using BaseContext::BaseContext;
81 | template