Compare commits

...

627 Commits

Author SHA1 Message Date
refractionpcsx2
f6675808fc GS/Runner: Set the screenshot compression low to stop slow dump times 2025-03-20 14:19:47 +00:00
PCSX2 Bot
aa64712354 [ci skip] Qt: Update Base Translation. 2025-03-20 11:14:07 +01:00
chaoticgd
f6e2185c9c Debugger: Don't jump to PC if the breakpoint code paused the core 2025-03-18 22:04:41 -04:00
JordanTheToaster
08edc8dfab Deps: Update Mac to Qt 6.7.3 2025-03-18 19:43:20 -04:00
chaoticgd
ec0760c03e Deps: Add an extra include path for KDDockWidgets 2025-03-18 11:50:12 -04:00
PCSX2 Bot
b53dfed032 [ci skip] PAD: Update to latest controller database. 2025-03-17 12:02:04 -04:00
refractionpcsx2
96599f26a5 GS/HW: Fix width prediction on texture shuffles 2025-03-17 15:44:46 +00:00
JordanTheToaster
c049a7ac76 Docs: Update thirdpartylicenses 2025-03-16 17:30:45 -04:00
JordanTheToaster
34dabc77c1 Deps: Swap to libjpeg-turbo 3.1.0 2025-03-16 17:30:45 -04:00
JordanTheToaster
b4deb6a4e2 VMManager: Actually enable file logging by default for real this time 2025-03-16 16:22:42 -04:00
Ty
dd91c0aac2 CI: Pin some third-party actions to a full length commit SHA 2025-03-16 14:50:27 -04:00
TheLastRar
fd983946f5 Qt: Fix display of LED colours on Windows native themes 2025-03-16 12:12:40 -04:00
JordanTheToaster
fb18fdf5b7 VMManager: Enable file logging by default 2025-03-16 11:59:09 -04:00
refractionpcsx2
bc7670aa3b GameDB: Add IBit hack to Killzone and Shellshock - Nam '67 2025-03-15 15:11:46 +00:00
refractionpcsx2
fe76a4575c VU: Expand IBit hack to work for immediates on several instructions 2025-03-15 15:11:46 +00:00
PCSX2 Bot
6addc7cf5f [ci skip] Qt: Update Base Translation. 2025-03-14 20:05:38 -04:00
JordanTheToaster
eb8b6f4fb5 3rdparty: Fix Apple Silicon detection with cpuinfo 2025-03-14 15:06:52 -04:00
Mrlinkwii
e2a60b7280 add KDDockWidgets to Third-Party Licenses 2025-03-14 19:35:34 +01:00
Dakota Smith
fe2d0cb514 Revert "Debugger: Set default breakpoint size to 4"
This reverts commit 92b9390c51.
2025-03-14 08:46:03 -04:00
TellowKrinkle
3362ca25be GHActions:MacOS: Don't use cmake --parallel without specifying job count
That ends up allowing infinite jobs on the makefile backend for some reason
2025-03-14 08:43:16 -04:00
PCSX2 Bot
c919c2a6fd [ci skip] Qt: Update Base Translation. 2025-03-14 00:08:58 -05:00
Silent
5a70075169 GameDB: Add memcard filters for Midnight Club 3 - DUB Edition Remix
Save data from Midnight Club 3 - DUB Edition (non-Remix)
can be imported into Remix.
2025-03-13 10:58:14 +01:00
TheLastRar
42c576cf99 FSUI: More formatting 2025-03-13 10:56:09 +01:00
PCSX2 Bot
1fd26c919b [ci skip] Qt: Update Base Translation. 2025-03-12 20:40:15 -04:00
TheLastRar
c957b558e0 FSUI: Automatic "Swap OK/Cancel" will now swap with switch controllers 2025-03-12 17:22:32 -04:00
JordanTheToaster
ec047c5972 GS: Change GetValidSize warning to DevCon 2025-03-12 17:21:52 -04:00
JordanTheToaster
08388d12d1 Config: Default to higher compression 2025-03-12 17:21:52 -04:00
lightningterror
850aeaf05e Misc: More warning fixes. 2025-03-12 17:20:56 -04:00
chaoticgd
6195f4b40e Debugger: Fix breakpoints and saved addresses lists 2025-03-12 17:20:35 -04:00
chaoticgd
92baf77509 Debugger: Add custom drop indicators and some user interface settings 2025-03-12 17:20:35 -04:00
chaoticgd
ab1cdb4c9d Debugger: Make various improvements to the UI 2025-03-12 17:20:35 -04:00
chaoticgd
4f4ff00ecf Debugger: Add System toolbar with shutdown and reset actions 2025-03-12 17:20:35 -04:00
chaoticgd
6fe97b42c3 Debugger: Allow having multiple dock widgets of the same type 2025-03-12 17:20:35 -04:00
chaoticgd
c9ac4960bc Debugger: Hook up all the debugger widgets again
New event system, context menus, and more.
2025-03-12 17:20:35 -04:00
chaoticgd
e4d7d22e78 Debugger: Hook up breakpoints and stepping again 2025-03-12 17:20:35 -04:00
chaoticgd
eb83cb70ea Debugger: Save and restore the state of the toolbars for each layout 2025-03-12 17:20:35 -04:00
chaoticgd
59210dffa9 Debugger: Add support for multiple UI layouts 2025-03-12 17:20:35 -04:00
chaoticgd
c76cca874b Debugger: Redesign UI based on KDDockWidgets 2025-03-12 17:20:35 -04:00
chaoticgd
d989ce5b44 Deps: Add KDDockWidgets 2025-03-12 17:20:35 -04:00
PCSX2 Bot
fbc95f2c86 [ci skip] PAD: Update to latest controller database. 2025-03-10 21:52:10 +01:00
TheLastRar
9fb8dacadb Input: Fix incorrect string conversion of motor binds 2025-03-09 17:42:31 +01:00
TheLastRar
d332aee542 Qt: Fix vibration binding window 2025-03-09 17:42:31 +01:00
refractionpcsx2
f2c97fc2c3 GS/HW: Tweak offsets for textures using ATN WTO 2025-03-09 16:41:36 +00:00
Ty
5ab84aaa29 CI: Flatten symbols for upload-artifact 2025-03-07 12:47:07 -05:00
JordanTheToaster
9842b11815 Deps: Update to SDL3 3.2.8 2025-03-07 09:58:04 -05:00
Ty
083fb5a1e6 CI: Generate Breakpad symbols for Linux / OSX Windows debugging ease 2025-03-06 17:38:46 -05:00
lightningterror
98cdd3446b GS/HW: Properly check PABE with source alpha for blends that check for PABE. 2025-03-06 19:18:29 +01:00
lightningterror
9bcbf43695 GS/HW: Check if pabe sw is actually enabled for ate second pass.
No need to check for PABE if it's not enabled on sw blend.
In fact on ICO flag is enabled even if ABE is disabled which is pointless.
2025-03-06 19:18:29 +01:00
TheLastRar
e3c988aa8b FileSystem: Improve handling of relative paths in RealPath() 2025-03-06 13:08:32 -05:00
TheLastRar
06be543d32 FileSystem: Don't pass file access mode into GetWin32Path() 2025-03-06 13:08:32 -05:00
Ty
1fd22dcc1c Windows: Make PCSX2 long path aware 2025-03-04 09:14:25 -05:00
refractionpcsx2
e3afdde981 GSDumpRunner: Fix compilation 2025-03-04 13:28:42 +00:00
lightningterror
698df49e5e Qt: Fix -Wsign-compare warnings. 2025-03-04 13:29:13 +01:00
TheLastRar
ff5c90ec5e SDLInputSource: Correct joystick types 2025-03-04 05:07:56 +01:00
TheLastRar
1e075d23b2 Input: Fix warnings 2025-03-04 05:07:56 +01:00
PCSX2 Bot
2b172903b9 [ci skip] Qt: Update Base Translation. 2025-03-04 01:04:44 +01:00
TheLastRar
4654a3ef6c FSUI: Formatting 2025-03-04 00:34:14 +01:00
Ty
9996061f74 SIO: Bump savestate warning from 1 hour to 2 hours 2025-03-03 12:19:09 -05:00
Ty
247a4c40d1 SIO: Remove a debugging include I somehow missed 2025-03-03 12:19:09 -05:00
PCSX2 Bot
1ffbdd9c08 [ci skip] PAD: Update to latest controller database. 2025-03-03 17:30:19 +01:00
TheLastRar
f67c0cbd2e Input: Fix migration of input profiles 2025-03-03 13:38:55 +01:00
PCSX2 Bot
ff7cc0867b [ci skip] Qt: Update Base Translation. 2025-03-03 01:36:07 +01:00
TheLastRar
ac1a6d3348 Deps: Update to SDL3 (#12311)
Co-authored-by: TheTechnician27 <TheTechnician27@users.noreply.github.com>
2025-03-02 18:04:19 -05:00
TellowKrinkle
582bba6c91 microVU: Accurate CLIP 2025-03-02 18:19:52 +00:00
TellowKrinkle
aaf156478e Interpreter: Accurate CLIP 2025-03-02 18:19:52 +00:00
TellowKrinkle
0539c177ab x86emitter: Add pblend 2025-03-02 18:19:52 +00:00
TellowKrinkle
fb1323b72f MicroVU: Declare constants inline 2025-03-02 18:19:52 +00:00
TellowKrinkle
dc557dd0e5 Interpreter: Merge broadcast min/max into one implementation 2025-03-02 18:19:08 +00:00
TellowKrinkle
2d0cfc9c2c Interpreter: Merge MAC ops into a few template functions 2025-03-02 18:19:08 +00:00
TellowKrinkle
625a25cd50 Interpreter: Merge broadcast ops into one implementation each 2025-03-02 18:19:08 +00:00
TellowKrinkle
b8a29d1cd8 Interpreter: Accurate FTOI
Plus some ITOF cleanup
2025-03-02 18:17:36 +00:00
TellowKrinkle
0fabdf9a01 Interpreter: Accurate ABS 2025-03-02 18:17:36 +00:00
refractionpcsx2
9c3ae795c8 COP2/Int: Propagate CLIP_FLAG writes to the VU0.clipflag variable for use in COP2
This value was being updated then COP2 running VCLIP would have the wrong original clip flag value to work from.
2025-03-02 18:17:05 +00:00
refractionpcsx2
de26226fa1 Core: Delete constant regs when flushing to interpreter 2025-03-02 18:17:05 +00:00
KamFretoZ
121920c074 FSUI: Add Themes 2025-03-02 11:48:29 -05:00
TellowKrinkle
05e19470b2 FileSystem: Don't leak on directory scan cancel
Fixes: 7587581d1f
2025-03-02 09:41:51 -05:00
TheLastRar
b6680e4aca FSUI: Formatting 2025-03-02 09:36:07 -05:00
TheLastRar
f9d70af841 FSUI: Auto detect when to use circle as confirm 2025-03-02 09:36:07 -05:00
TellowKrinkle
7587581d1f GameList: Allow recursive scans to be cancelled 2025-03-02 04:20:01 +01:00
PCSX2 Bot
8f19976c10 [ci skip] Qt: Update Base Translation. 2025-03-02 01:43:09 +01:00
GovanifY
8567d68433 VMManager: initialize PINE with config-provided slot
Sten broke it during the port to Qt...
2025-03-02 00:01:18 +01:00
Glebux
6542301566 Input/PAD: Make macro chords work 2025-03-01 14:38:00 -05:00
refractionpcsx2
a359f77cf6 GameDB/Link: Fix validation limit for Half Pixel Offset to allow new option 2025-03-01 02:01:46 +00:00
PCSX2 Bot
4c9a81f3d8 [ci skip] Qt: Update Base Translation. 2025-02-28 19:54:36 -05:00
refractionpcsx2
9234b493a3 Testing further tweaks to bring it closer to SW 2025-02-28 21:59:19 +00:00
refractionpcsx2
f84425b67c GS/HW: Add new HPO - Align to Native With Texture Offset 2025-02-28 21:59:19 +00:00
PCSX2 Bot
8a0c1874dd [ci skip] Qt: Update Base Translation. 2025-02-27 01:05:14 +01:00
Light
fa23628ae2 Qt: Allow recording on game boot 2025-02-26 17:17:39 -05:00
Loy2up
8a594e673d Debugger: Fix 8 byte searches (#12362) 2025-02-26 14:41:49 -05:00
Loy2up
92b9390c51 Debugger: Set default breakpoint size to 4 2025-02-25 19:07:19 -05:00
PCSX2 Bot
c5c5b2a7b9 [ci skip] Qt: Update Base Translation. 2025-02-26 01:06:43 +01:00
refractionpcsx2
32a9d0e48b GameDB: Also add Tekken 5 CRC to Taiko No Tatsujin 9 2025-02-25 18:22:38 +01:00
refractionpcsx2
80a961bb25 GameDB: Add Tekken 5 CRC (Yes really) To Tales of the Abyss 2025-02-25 18:22:38 +01:00
TheLastRar
d4e227286e FSUI: Correct description of the "Swap OK/Cancel" option 2025-02-25 10:00:18 -05:00
github-actions[bot]
ba705c8c24 Qt: Update Base Translation (#12354)
Co-authored-by: PCSX2 Bot <PCSX2Bot@users.noreply.github.com>
2025-02-24 19:11:57 -05:00
dependabot[bot]
b6ae4b173e CI: Update dependencies in /.github/workflows/scripts/releases/generate-release-notes (#12315)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-24 17:54:41 -05:00
TJnotJT
23a28be346 GS/UI: Rename dumping variables and UI labels to be more consistent/clear. 2025-02-24 17:53:01 -05:00
TJnotJT
a0e24dd36f UI: Add debug UI options for new dumping options. 2025-02-24 17:53:01 -05:00
TheLastRar
a2cde5e17b FSUI: Add a config option to swap OK/Cancel within BPM 2025-02-24 17:45:46 -05:00
JordanTheToaster
ecc46e9294 Deps: Update ZSTD to 1.5.7 2025-02-24 17:44:22 -05:00
dreamsyntax
20b1190d47 Achievements: Fix leaderboard timers persisting
Removes setting the leaderboard timer to active on receiving an update
event. This fixes having multiple timers stuck on the screen.
2025-02-24 14:05:03 -05:00
Silent
29b736bcf7 GameDB: Add TOCA Race Driver 3 memcard filters 2025-02-24 12:04:05 -05:00
Silent
a48bc76ca6 GameDB: Add NFS Undercover memcard filters
Checks from NFS Carbon (incl. a bugged check for MW BE)
are in the code, but unused.
2025-02-24 12:04:05 -05:00
Silent
305c01cdfa GameDB: Add NFS ProStreet memcard filters 2025-02-24 12:04:05 -05:00
Silent
88bbdf4696 GameDB: Add NFS Carbon memcard filters 2025-02-24 12:04:05 -05:00
Silent
afc11279a9 GameDB: Improve NFS Most Wanted memcard filters 2025-02-24 12:04:05 -05:00
Silent
a3fb2a84d5 GameDB: SCUS-21494 doesn't exist 2025-02-24 12:04:05 -05:00
Ty
4db23e6677 Debugger Assembler: BC1(t|f) 24 bit immediates to 16 bit immediates 2025-02-24 11:39:30 -05:00
PCSX2 Bot
5dd36a7969 [ci skip] PAD: Update to latest controller database. 2025-02-24 17:02:04 +01:00
RedPanda4552
35a3d0027e Memcard: Apply filtering when checking all possible memcard options
Prevents log being flooded with warnings when large folder memcards exceed 8 MB size
2025-02-24 16:08:00 +01:00
refractionpcsx2
02789ebd86 GS/HW: Increase Merge Sprite paving sensitivity to avoid mismerges 2025-02-23 03:33:39 +00:00
JordanTheToaster
dfd1846b93 GameDB: Various fixes 2025-02-23 01:12:43 +00:00
refractionpcsx2
872205abc6 GS/HW: Maintain scale on subsequent downscale draws 2025-02-23 01:12:07 +00:00
PCSX2 Bot
c52cebd20a [ci skip] Qt: Update Base Translation. 2025-02-22 01:04:56 +01:00
GovanifY
f449b54f87 CI: enable wayland by default 2025-02-21 12:28:28 +01:00
GovanifY
ffcb6e2f6f QT/MainWindow: disable native window rendering in wayland
This is a workaround for QTBUG-133919
2025-02-21 12:28:28 +01:00
PCSX2 Bot
5daa1aa115 [ci skip] Qt: Update Base Translation. 2025-02-21 01:09:05 +01:00
GovanifY
1dc009f752 pcsx2/SIO: correctly detect whether format status of folder mcd 2025-02-20 16:00:40 +01:00
GovanifY
009b4ff5e7 QT/Settings: ensure that a memory card is formatted before conversion 2025-02-20 16:00:40 +01:00
PCSX2 Bot
f1a947af92 [ci skip] Qt: Update Base Translation. 2025-02-19 21:00:23 -05:00
Ty Lamontagne
97c098b1ff QT: Adjust mouse grab help text 2025-02-19 11:18:17 -05:00
Ty
e252cb6643 HostSys: Implement platform Specific mouse lock osx/windows/x11 2025-02-19 11:18:17 -05:00
Gonzalosilvalde
75c0236e1e Qt: Add mouse grab/lock feature when PCSX2 is in focus 2025-02-19 11:18:17 -05:00
KamFretoZ
9c4a98bc25 Qt: Add AMOLED Theme 2025-02-19 10:34:44 -05:00
GovanifY
9cba11cde5 appimage: revert #11667 , switch back to upstream appimagetool 2025-02-19 01:44:18 +01:00
GovanifY
fac5512b04 flatpak: misc additions to the metainfo 2025-02-19 01:44:18 +01:00
GovanifY
ed9bf05971 bin: update icons to be centered 2025-02-18 20:44:43 +01:00
GovanifY
19d0f3bdc5 flatpak: add branding colors 2025-02-18 20:44:43 +01:00
GovanifY
2abe53de43 flatpak: remove wild caps in summary 2025-02-18 20:44:43 +01:00
GovanifY
37a25750d7 flatpak: update default screenshots
This fixes a few issues in our flathub review report
2025-02-18 20:44:43 +01:00
lightningterror
d3e288447f GS/HW: Cleanup gl and vk shaders.
gl: Rename fetch_rt to sample_from_rt to match vk shaders, remove old atst call.

vk: Make sure shuffle values have correct unsigned type.
2025-02-17 21:27:34 +01:00
Ziemas
4a44d2668c SDL Audio: Set app name hint 2025-02-16 16:41:51 -05:00
Ty
752b1420a3 CI: Increase flatpak cron job timeout to 3 hours instead of 1
[ci skip]
2025-02-16 16:17:11 -05:00
PCSX2 Bot
71705fc91f [ci skip] Qt: Update Base Translation. 2025-02-16 22:12:45 +01:00
Ty
645efc7520 CI: Skip macos signing on forks 2025-02-16 12:03:14 -05:00
Ty
b6ee0e5219 CI: Bump our ccache size from 100M to 500M 2025-02-16 12:03:14 -05:00
Ty
7acf32debc CI: Sign and notarize our macos binaries 2025-02-16 12:03:14 -05:00
Ty
13397f68a3 CI: Update the node version for announce-release try #2 2025-02-16 11:39:54 -05:00
Ty
79250722d6 CI: Update the node version for announce-release 2025-02-16 11:30:47 -05:00
Ty
04b8748a8f CI: Update the announce-release script to use node-fetch (#12310) 2025-02-15 15:14:28 -05:00
dependabot[bot]
2dab8053ea CI: Bump deps in announce-release (#12308)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-02-15 11:03:07 -05:00
refractionpcsx2
f8bab2e465 Build/VS: Fix change in latest VS 2022 update with std::chrono
For more information see: https://learn.microsoft.com/en-us/cpp/overview/what-s-new-for-visual-cpp-in-visual-studio?view=msvc-170#:~:text=Moved%20system_clock%2C%20high_resolution_clock%2C%20and%20chrono_literals%20from%20a%20commonly%20included%20internal%20header%20to%20%3Cchrono%3E.%20If%20you%20see%20compiler%20errors%20that%20types%20like%20system_clock%20or%20user%2Ddefined%20literals%20like%201729ms%20aren%27t%20recognized%2C%20include%20%3Cchrono%3E.
2025-02-14 02:40:24 +00:00
TJnotJT
46221a8500 Tools: Fix typos in GS dump runner help. 2025-02-12 17:40:49 -05:00
TJnotJT
8b0e61af8c Tools: Remove debug preprocessor check around dumping of HW renderer frames. 2025-02-12 17:40:49 -05:00
TJnotJT
2b0a78811a Tools: Add additional options for dumping in GS runner. Other formatting fixes. 2025-02-12 17:40:49 -05:00
TheTechnician27
5798cd7176 Qt: End memcard conversion progress at 100% instead of 99% 2025-02-12 17:40:17 -05:00
JordanTheToaster
5c25637381 GameDB: Knights of the Temple 2 fixes 2025-02-12 17:39:56 -05:00
TheLastRar
8316228771 iR5900: Reset manual protection counters 2025-02-12 12:12:05 -05:00
JordanTheToaster
695250155e GameDB: Even more fixes 2025-02-12 12:09:05 -05:00
PCSX2 Bot
545e606c11 [ci skip] PAD: Update to latest controller database. 2025-02-10 17:26:03 +01:00
refractionpcsx2
52771fdb17 GS/HW: Add CRC fixes for DT Carnage/Racer/Axel Impact 2025-02-10 15:06:29 +00:00
JordanTheToaster
de631a1052 PerformanceMetrics: Increase update rate
Increases update rate of OSD stats from 0.5 per poll to 0.25 seconds per poll.
2025-02-09 12:29:54 -05:00
JordanTheToaster
605398db67 GameDB: Various fixes 2025-02-09 12:29:54 -05:00
TheLastRar
407c989860 Vif: Fixes to non-volatile SSE backup and restore logic 2025-02-09 12:28:04 -05:00
lightningterror
9b4b112a97 GS/HW: Adjust max valid tex size.
Account for index 0.
2025-02-08 23:56:42 +01:00
PCSX2 Bot
865b75bcbb [ci skip] Qt: Update Base Translation. 2025-02-07 19:04:10 -05:00
Ty
795b0813cc Debugger: Only validate memory search value when needed 2025-02-07 13:40:13 -05:00
Ty
3e1f2b8b9d Debugger: Support 'unknown initial value' search types 2025-02-07 13:40:13 -05:00
Ty
1f0d6f0ac7 VMManager: Avoid use-after-move conditions 2025-02-05 10:25:24 -05:00
JordanTheToaster
4ab4f4a67c GameDB: Various fixes 2025-02-04 14:58:40 -05:00
Mrlinkwii
5dbdd5e5e4 CI : fix artifact name on linux builds 2025-02-04 14:49:36 -05:00
JordanTheToaster
f03cddf674 Deps: Update to Qt 6.8.2 on Windows and Linux 2025-02-04 12:22:17 +01:00
PCSX2 Bot
726e908a49 [ci skip] Qt: Update Base Translation. 2025-02-03 19:08:22 -05:00
Jordan
043cd673b8 3rdparty: Update ImGui to v1.91.8 (#12258) 2025-02-03 17:22:32 -05:00
KamFretoZ
f84173e5cc Qt: Add Portable Mode launch argument (#12230) 2025-02-03 17:20:32 -05:00
Jordan
bef7ae7f6c Deps: Update SDL to 2.30.12 (#12263) 2025-02-03 16:54:24 -05:00
TheTechnician27
33aed95a6c Controllers: Make restore defaults restore controller LED (#12264) 2025-02-03 16:53:55 -05:00
Ty
282317c46e Debugger: Add opcodes and fixes to the assembler (#12267) 2025-02-03 16:52:27 -05:00
refractionpcsx2
2d6a42ac06 GS/HW: Reduce number of copies for HDR 2025-02-03 16:48:47 -05:00
PCSX2 Bot
cd98f72f10 [ci skip] PAD: Update to latest controller database. 2025-02-03 20:21:41 +01:00
TheLastRar
29a98f317e Vif: Don't reserve regs for unused columns
We can reuse those for other purposes
2025-02-02 18:02:24 -05:00
TheLastRar
6334082e6f Vif: Don't use non-volatile register in simple unpack
The Vif normally reserves Xmm3-Xmm6 for the columns and row.
However, code emitted for simple unpacks never used them.
Instead, lets use Xmm3 to avoid clobbering a non-volatile register.
2025-02-02 18:02:24 -05:00
TheLastRar
bd4a6a10f9 Vif: Backup and restore non-volatile SSE registers 2025-02-02 18:02:24 -05:00
lightningterror
ea4d988082 GS/HW: Check for null when source is either target or depth. 2025-02-01 22:53:21 +01:00
PCSX2 Bot
bf8693a7e8 [ci skip] Qt: Update Base Translation. 2025-01-29 19:07:07 -05:00
TheTechnician27
32a67c48e0 Qt: Add Wiki and Documentation to 'Help' menu 2025-01-29 10:10:44 -05:00
PCSX2 Bot
e93f81ca7a [ci skip] Qt: Update Base Translation. 2025-01-28 21:35:04 +01:00
PCSX2 Bot
8f107f5345 [ci skip] PAD: Update to latest controller database. 2025-01-27 17:01:51 +01:00
Ziemas
741046079c DebugInterface: isValidAddres on physical
Mask off the segment bits
2025-01-25 09:56:35 -05:00
PCSX2 Bot
df7646fd34 [ci skip] Qt: Update Base Translation. 2025-01-22 19:34:24 -05:00
TheTechnician27
d350408161 Settings: Allow user to manually set RTC per-game 2025-01-22 15:54:17 +01:00
JordanTheToaster
bde55a6fe2 GameDB: Various fixes 2025-01-21 17:30:00 -05:00
JimScript
83c1bed868 GameDB: Add Nicktoons Cross-Save Feature
re-added current GameDB
2025-01-21 11:57:25 -05:00
JimScript
6845f026bc GameDB: Add Nicktoons Cross-Save Feature
Revised commit name
2025-01-21 11:57:25 -05:00
PCSX2 Bot
f2c796bcc5 [ci skip] Qt: Update Base Translation. 2025-01-20 19:10:40 -05:00
chaoticgd
a930daf575 Debugger: Wait for the entry point to run before scanning from memory 2025-01-20 15:18:33 -05:00
TheTechnician27
36d8e5f295 ImGui: Avoid frame count display race condition for input recording and display correct value 2025-01-20 15:17:06 -05:00
Ty
71100679a3 R5900: Implement ARM NEON intrinsics for the EE cache 2025-01-20 15:14:25 -05:00
nassau-tk
e3b61b5b1f Fix Raksuho Pachi-slot series glitch 2025-01-20 15:13:07 -05:00
PCSX2 Bot
42a5e7422c [ci skip] PAD: Update to latest controller database. 2025-01-20 15:12:20 -05:00
Mrlinkwii
24782950e4 Docs: update Gamedb documentation
[ci skip]
2025-01-20 15:12:07 -05:00
TheTechnician27
e5639102cb Sounds: Use freely licensed orchestra hit for achievement unlock 2025-01-20 15:11:47 -05:00
lightningterror
b74d05603d GS/HW: Limit GetValidSize height and width.
Max texture size limit is 2048.
This should never happen but if it does clamp it
2025-01-20 05:14:50 +01:00
TheTechnician27
23fd57f641 Copyright: Change year from 2002-2024 to 2002-2025 2025-01-20 05:07:26 +01:00
TheLastRar
53ae93751c Deps: Fix incorrect hashes in Windows Arm64 script 2025-01-19 11:51:44 -05:00
TheLastRar
ec8736107c 3rdparty/vixl: Define VIXL_CODE_BUFFER_* in cmake 2025-01-19 11:51:44 -05:00
PCSX2 Bot
9e21ee1bc4 [ci skip] Qt: Update Base Translation. 2025-01-19 09:06:41 +01:00
TheLastRar
31497c2b86 3rdparty: Sync vixl to commit e6076e92c416422ea1fbde815e8e327f68658ac1 2025-01-18 15:17:47 -05:00
TheLastRar
0600832ddb 3rdparty: Update ImGui to v1.91.7 2025-01-18 15:17:33 -05:00
Ty
4a57bd7fd4 VMManager / vuJIT: Fix save state loading and saving on ARM64 2025-01-17 18:00:07 -05:00
shockdude
fbe0c8b9cc USB: Fix DJ Hero Turntable automatic mapping & turntable multiplier 2025-01-17 10:44:52 -05:00
Ziemas
2e3501366f iR3000A/iR5900: Partial revert of 8c98f5d928 ("Remove mid block jumping") 2025-01-17 10:42:48 -05:00
Ziemas
ef7169dbbf host: fix gcc build 2025-01-17 10:42:13 -05:00
TheLastRar
de9d08075e Misc: Don't use deprecated fmt/core.h header 2025-01-17 04:35:29 +01:00
TheLastRar
c58f6f2f70 3rdparty: Update fmt to v11.1.2 2025-01-17 04:35:29 +01:00
TheLastRar
56aa5d9657 SmallString: Prep for fmt update 2025-01-17 04:35:29 +01:00
Penguino
754057b496 GameDB: Add Ougon no Kaze VU1 clamping, JoJo romanization consistency
- Added VU1 Clamping (Extra + Preserve Sign) to Ougon no Kaze (SLPM-65140, SLPM-66853, SLPM-61030) to fix the shading of the enemy's Stand in Chapter 11-2
- Changed "Jojo" romanization to "JoJo" (SLPM-66853, SLPS-25686)
- Changed "Kimyouna" to "Kimyou na" in Ougon no Kaze [Best Price] (SLPM-66853)
2025-01-17 04:31:31 +01:00
lightningterror
513c44f07f DumpRunner: Fix compare when frames are missing. 2025-01-17 04:29:37 +01:00
nassau-tk
0090655899 GameDB: Fix Japanese Game Titles. (#12158) 2025-01-15 22:40:52 +01:00
JordanTheToaster
7103e9be1e 3rdparty: Sync cpuinfo to commit 8a1772a0c5c447df2d18edf33ec4603a8c9c04a6 2025-01-15 22:17:59 +01:00
JordanTheToaster
b04906c3e9 3rdparty: Update promptfont with new icons 2025-01-15 22:17:59 +01:00
JordanTheToaster
fc5fe8b48c Deps: Update webp to 1.5.0 2025-01-15 22:17:59 +01:00
JordanTheToaster
e32e91af5c Deps: Update libpng to 1.6.45 2025-01-15 22:17:59 +01:00
JordanTheToaster
aa5b026d4a SDLInputSource: Halve default LED brightness 2025-01-15 22:16:39 +01:00
PCSX2 Bot
9568f3305b [ci skip] PAD: Update to latest controller database. 2025-01-13 17:03:58 +01:00
TheLastRar
f33064a1e2 x86emitter: Backup and restore non-volatile SSE registers
XMM6-XMM15 are non-volatile on Windows
2025-01-13 10:12:57 -05:00
lightningterror
6c9a2e96e1 iR3000A/iR5900: Fix dev/debug build compile.
Remove JITCompileInBlock leftovers.
2025-01-13 03:22:44 +01:00
JordanTheToaster
8c98f5d928 iR5900: Remove mid block jumping 2025-01-12 17:40:36 -05:00
refractionpcsx2
19f0cfcf06 GS/HW: Fix misdetection of draw as clear with fog effect 2025-01-12 23:18:38 +01:00
refractionpcsx2
4f42d95d3c GS/HW: If HW Move is outside of target, make a new target instead 2025-01-12 23:18:38 +01:00
refractionpcsx2
68823c524f GS/HW: Backport target expansion change from RT in RT PR 2025-01-12 23:18:38 +01:00
refractionpcsx2
05917796a5 GS/HW: Backported fixes from RT in RT PR 2025-01-12 23:18:38 +01:00
refractionpcsx2
d64da07b7d DumpRunner: Fix "missing" messages to not break the image cycler 2025-01-12 23:18:38 +01:00
PCSX2 Bot
27074a809c [ci skip] Qt: Update Base Translation. 2025-01-12 01:34:23 +01:00
Silent
33b366180e Qt/Patches, Cheats: Reload lists if serial changes 2025-01-11 09:04:51 -05:00
Silent
d8e310e7bf Qt/Patches: Use the game list serial when populating patches for the ELF
This makes the Game Properties window match the behaviour of the VM
when booting into a game.

Fixes #11533
2025-01-11 09:04:51 -05:00
Silent
534ddd80ae Patch: When serial is empty, don't match files on empty serial
Fixes a bug where _crc.pnach files matched the regex if serial
was not set. Also grey out "All CRCs" when serial is not set,
as the option is then meaningless.
2025-01-11 09:04:51 -05:00
chaoticgd
d34f2ec142 Debugger: Add disassembler toggle to go to the PC address on pause 2025-01-11 09:03:24 -05:00
TheTechnician27
7381a02dae SIO: Fix save state OSD warning formatting 2025-01-11 09:02:45 -05:00
RedPanda4552
333c7ef61b Memcard: Track file size globally at open
Prevents FSeek64 hits on every retrieval of memcard attributes
2025-01-09 15:47:56 +01:00
RedPanda4552
77d5a04aa4 Memcard: Remove support for legacy PSX card types with headers
Supporting legacy PSX cards with headers required constant size checks, thrashing IOP performance.
2025-01-09 15:47:56 +01:00
TheLastRar
d3effdb176 CI/Windows: Use LLVM 19 with MSBuild and CMake
Now using the Chocolatey install of LLVM
2025-01-09 15:46:34 +01:00
JordanTheToaster
d7e1350b95 CI/Windows: Use Windows Server 2025 2025-01-09 15:46:34 +01:00
PCSX2 Bot
14ac653e45 [ci skip] Qt: Update Base Translation. 2025-01-09 15:45:02 +01:00
spixi
a5e4274cd2 common: Add support for MATE Desktop. (#12174)
This extends the screensaver inhibition function to MATE Desktop,
2025-01-09 15:07:09 +01:00
Ty Lamontagne
16b1095a7b EE Cache: Shrink tag size by 4 bytes 2025-01-08 18:34:30 -05:00
Silent
3b5b3ffa91 Patch: Re-run PPT_ONCE_ON_LOAD patches when enabling them as the game is running 2025-01-08 18:30:51 -05:00
Silent
7ebcca36d2 Patch: Actually apply type 2 patches on the entry point
Type 2 patches were supposed to be "Type 0 + Type 1",
but in reality they only executed on vblank, making them equivalent
to Type 1.
2025-01-08 18:30:51 -05:00
PCSX2 Bot
501c543d1b [ci skip] Qt: Update Base Translation. 2025-01-08 19:46:56 +01:00
lightningterror
4dafea65f2 GS/HW: Adjust need_aem_color and req_color conditions.
Improves LookupSource to not use dirty data when it shouldn't.
2025-01-06 18:09:34 +01:00
PCSX2 Bot
e7cdd89577 [ci skip] PAD: Update to latest controller database. 2025-01-06 17:01:53 +01:00
lightningterror
1a508439b3 GameDB: Rename Dynasty Warriors 3 and 4.
SLES-51441: Dynasty Warriors 3 - Extreme Legends -> Dynasty Warriors 3 - Xtreme Legends

SLUS-20812: Dynasty Warriors 4 - Extreme Edition -> Dynasty Warriors 4 - Xtreme Legends
2025-01-06 15:22:07 +01:00
JordanTheToaster
3548d103f4 3rdparty: Update vkmemoryallocator to v3.2.0 2025-01-06 13:55:39 +01:00
JordanTheToaster
b1d4101490 Deps: Update SDL to 2.30.11 2025-01-06 13:53:18 +01:00
Florin9doi
a714582c1c Memcard: Support for MemCardPro2/.mc2 files. (#12157) 2025-01-06 13:31:04 +01:00
chaoticgd
0e7da0f1a8 Debugger: Fix AST node ownership confusion bug 2025-01-06 13:28:21 +01:00
TheTechnician27
4f7c8a77f6 Tools: Fix typo in compression tool 2025-01-04 17:17:39 -05:00
Ty Lamontagne
1842fe6db8 EE Cache: Make the SIMD path x86 only to support ARM interpreters 2025-01-03 14:17:24 -05:00
Mrlinkwii
1feb31498d GameDB: fix some names 2025-01-02 21:19:35 +01:00
nassau-tk
f3632c44c8 GameDB: Fix&Add few Japanese Game Titles 2024-12-31 21:14:13 -06:00
PCSX2 Bot
32a6e62212 [ci skip] Qt: Update Base Translation. 2025-01-01 01:27:00 +01:00
Jordan
575ec07553 3rdparty: Update xxHash to v0.8.3 (#12137) 2024-12-31 18:14:47 -05:00
lightningterror
18308b6525 GS/GL: Properly name logs with GL prefix. 2024-12-31 20:11:25 +01:00
lightningterror
d52f29dcd7 GS/D3D12: Properly name logs with D3D12 prefix. 2024-12-31 20:11:25 +01:00
lightningterror
288d8047ae GS/VK: Properly name logs with VK prefix. 2024-12-31 20:11:25 +01:00
lightningterror
26b232292c GS/D3D11: Properly name logs with D3D11 prefix. 2024-12-31 20:11:25 +01:00
Tyler Wilding
1fff69b0aa translations: Syncing Crowdin translations (#12141)
* New translations pcsx2-qt_en.ts (Romanian)
[ci skip]

* New translations pcsx2-qt_en.ts (French)
[ci skip]

* New translations pcsx2-qt_en.ts (Spanish)
[ci skip]

* New translations pcsx2-qt_en.ts (Afrikaans)
[ci skip]

* New translations pcsx2-qt_en.ts (Arabic)
[ci skip]

* New translations pcsx2-qt_en.ts (Bulgarian)
[ci skip]

* New translations pcsx2-qt_en.ts (Catalan)
[ci skip]

* New translations pcsx2-qt_en.ts (Czech)
[ci skip]

* New translations pcsx2-qt_en.ts (Danish)
[ci skip]

* New translations pcsx2-qt_en.ts (German)
[ci skip]

* New translations pcsx2-qt_en.ts (Greek)
[ci skip]

* New translations pcsx2-qt_en.ts (Finnish)
[ci skip]

* New translations pcsx2-qt_en.ts (Hebrew)
[ci skip]

* New translations pcsx2-qt_en.ts (Hungarian)
[ci skip]

* New translations pcsx2-qt_en.ts (Italian)
[ci skip]

* New translations pcsx2-qt_en.ts (Japanese)
[ci skip]

* New translations pcsx2-qt_en.ts (Georgian)
[ci skip]

* New translations pcsx2-qt_en.ts (Korean)
[ci skip]

* New translations pcsx2-qt_en.ts (Lithuanian)
[ci skip]

* New translations pcsx2-qt_en.ts (Dutch)
[ci skip]

* New translations pcsx2-qt_en.ts (Norwegian)
[ci skip]

* New translations pcsx2-qt_en.ts (Polish)
[ci skip]

* New translations pcsx2-qt_en.ts (Portuguese)
[ci skip]

* New translations pcsx2-qt_en.ts (Russian)
[ci skip]

* New translations pcsx2-qt_en.ts (Serbian (Cyrillic))
[ci skip]

* New translations pcsx2-qt_en.ts (Swedish)
[ci skip]

* New translations pcsx2-qt_en.ts (Turkish)
[ci skip]

* New translations pcsx2-qt_en.ts (Ukrainian)
[ci skip]

* New translations pcsx2-qt_en.ts (Chinese Simplified)
[ci skip]

* New translations pcsx2-qt_en.ts (Chinese Traditional)
[ci skip]

* New translations pcsx2-qt_en.ts (Vietnamese)
[ci skip]

* New translations pcsx2-qt_en.ts (Portuguese, Brazilian)
[ci skip]

* New translations pcsx2-qt_en.ts (Indonesian)
[ci skip]

* New translations pcsx2-qt_en.ts (Persian)
[ci skip]

* New translations pcsx2-qt_en.ts (Croatian)
[ci skip]

* New translations pcsx2-qt_en.ts (Latvian)
[ci skip]

* New translations pcsx2-qt_en.ts (Hindi)
[ci skip]

* New translations pcsx2-qt_en.ts (Quechua)
[ci skip]

* New translations pcsx2-qt_en.ts (Guarani)
[ci skip]

* New translations pcsx2-qt_en.ts (Spanish, Latin America)
[ci skip]
2024-12-30 19:19:40 -05:00
PCSX2 Bot
4d347305b5 [ci skip] PAD: Update to latest controller database. 2024-12-30 17:03:52 +01:00
PCSX2 Bot
2fd6f8e4ac [ci skip] Qt: Update Base Translation. 2024-12-29 19:02:05 -05:00
Silent
97f316eca7 Qt/Patches: Gracefully migrate old per-game widescreen/no-interlace toggles to Patches
This old upgrade path telling users that the setting has been deprecated
can now be changed to perform the upgrade seamlessly for the user,
because the behaviour of the old per-game setting is identical to
the new behaviour of the Patches tab.
2024-12-29 14:03:56 -05:00
Silent
f7ba355697 Qt/Patches: Make WS/NI patches tri-state in the Patches screen, so disabling them per-game is possible
This solves a long-standing issue where globally enabled
widescreen/no-interlace patches visually appeared as disabled
on the patches list, but they were in fact enabled and could NOT be
disabled per-game.
2024-12-29 14:03:56 -05:00
Silent
c334040a96 Partially revert "Qt/Patches: Get rid of the global WS/NI toggle"
This reverts commit cc9f7e723a.
2024-12-29 14:03:56 -05:00
TheTechnician27
b01359e06f Tools: Port refraction's bulk compression script to Python 2024-12-28 12:09:19 -05:00
PCSX2 Bot
905f9431a5 [ci skip] Qt: Update Base Translation. 2024-12-28 11:30:16 -05:00
KamFretoZ
424951e1bb Logging: Adjust the formatting to be more consistent 2024-12-28 11:25:26 -05:00
KamFretoZ
2167d9e4f5 Settings/Log: Print advanced settings warning on the log
Warns the user through the log if they have advanced options enabled.
2024-12-28 11:25:26 -05:00
rtavarez98
82a38a7124 changed indentation from tab to space 2024-12-28 11:22:50 -05:00
Rain
eb6a52c55c replaced recursive_directory_iterator w/ FindFiles() 2024-12-28 11:22:50 -05:00
Rain
234b8f6abf Added rename input profile function 2024-12-28 11:22:50 -05:00
lightningterror
843566eb49 Qt: Properly disable all dumping options if draw dumping is disabled.
Also move around sone options.
2024-12-28 17:04:33 +01:00
nassau-tk
d63733830f GameDB: Disable MTVU for some games 2024-12-27 23:43:51 -06:00
nassau-tk
3ebd496c37 GameDB: Fix titles for Japanese games 2024-12-27 23:43:51 -06:00
Mrlinkwii
f0f2b013fc Redump: update database 2024-12-27 14:30:23 -05:00
Ty Lamontagne
9a75509614 EE Cache: Fix up TLB related register fetching 2024-12-27 14:18:32 -05:00
Ty Lamontagne
c513a29bcf EE Cache: Freeze cached entries in sstates
[SAVEVERSION+]
2024-12-27 14:18:32 -05:00
Ty Lamontagne
5d39c884b5 R5900: Improve the EE cache performance with SIMD 2024-12-27 14:18:32 -05:00
TheLastRar
6a0f811812 Build: Always set EnhancedInstructionSet for AVX2 configs
Replaces the march arguments for clang-cl
2024-12-24 22:05:50 -05:00
TheLastRar
f509fb6950 CI/Appimage: Suppress error when no tags are present 2024-12-24 12:00:56 -05:00
Ziemas
33a475a456 DebugTools: Fix GCC build, missing include 2024-12-24 13:47:49 +01:00
JordanTheToaster
d2fb90a700 GameDB: Various fixes 2024-12-23 19:40:29 -05:00
PCSX2 Bot
a34467dccd [ci skip] PAD: Update to latest controller database. 2024-12-23 17:58:45 +01:00
Hallkezz
c6d0f5e3cd GameDB: Change recommended blending level 2 to 4 for Twisted Metal: Head-On [Extra Twisted Edition]. (#12107)
Fixes menu text brightness in Twisted Metal: Head-On [Extra Twisted Edition].
2024-12-22 13:03:40 +01:00
PCSX2 Bot
34c9590cf1 [ci skip] Qt: Update Base Translation. 2024-12-18 19:06:27 -05:00
Ty Lamontagne
a2c7542e48 Savestates: Warn on savestate load and saves without mcd activity
[SAVEVERSION+]
2024-12-18 18:01:30 -05:00
TheLastRar
72a9f18456 3rdparty: Sync libchdr to commit cb077337d53392454e7100a0fd07139ca678e527 2024-12-18 17:58:44 -05:00
TheLastRar
7f59757eea 3rdparty/libchdr: Purge almost all remaining patches
Leaving only the chd_read_header_* functions, of which exists an equivalent in later libchdr versions
2024-12-18 17:58:44 -05:00
TheLastRar
3b89020082 3rdparty/libchdr: Purge now unused patches 2024-12-18 16:23:49 -05:00
TheLastRar
a7b07eb53f ChdReader: Use core_file to implement precaching 2024-12-18 16:23:49 -05:00
TheLastRar
58d13dac34 FileSystem: Add ReadFileWithPartialProgress for multiple files 2024-12-18 16:23:49 -05:00
Ty Lamontagne
5a8921dd22 IOPBios: Defer to iopMemSafeReadBytes when HLEing writes 2024-12-18 16:15:07 -05:00
Ty Lamontagne
f964dfaa5e IOPBios: Defer to iopMemSafeWriteBytes when HLEing reads 2024-12-18 16:15:07 -05:00
PCSX2 Bot
17274eb397 [ci skip] Qt: Update Base Translation. 2024-12-17 20:54:52 -05:00
TheLastRar
2f0b00a7a1 ChdFileReader: Migrate libchdr patch into PCSX2
Added function didn't need to be in libchdr
2024-12-17 13:35:10 -05:00
Mrlinkwii
260380abec CI: disable builds on controller database update 2024-12-17 19:22:03 +01:00
KamFretoZ
57fc87061d Cheats: Update notes on how PNACH 2.0 works
Co-Authored-By: Mrlinkwii <Mrlinkwii@users.noreply.github.com>
2024-12-17 11:27:45 -05:00
KamFretoZ
cc9f7e723a Qt/Patches: Get rid of the global WS/NI toggle 2024-12-17 11:27:45 -05:00
PCSX2 Bot
6a41e05694 PAD: Update to latest controller database. 2024-12-16 11:06:52 -05:00
TheLastRar
c8e1dc5328 ChdFileReader: Use core_file instead of modifing chd_open_file 2024-12-16 09:39:46 -05:00
lightningterror
c2ee5a0234 GS/HW: Get the proper context for the next draw if it's a split texture shuffle.
Draw might switch the context so make sure we get the correct one.
2024-12-16 08:37:39 +01:00
nassau-tk
3cafd2dc69 GameDB: Japanese game updates 2024-12-15 01:33:40 -06:00
JordanTheToaster
4b8890c438 3rdparty: Sync vkmemoryallocator to commit 5a53a198945ba8260fbc58fadb788745ce6aa263 2024-12-14 13:41:32 -05:00
JordanTheToaster
19882dc160 3rdparty: Sync d3d12memalloc to commit da380f69bd4547cd776c525ae225bb9d13df94e2 2024-12-14 13:41:32 -05:00
chaoticgd
0c21023bb2 Path: Prevent Path::RealPath from returning '.' and '..' components 2024-12-14 13:41:01 -05:00
chaoticgd
68e6ede47e Path: Add tests for Path::RealPath 2024-12-14 13:41:01 -05:00
chaoticgd
1ed3001358 FileSystem: Add CreateSymLink function 2024-12-14 13:41:01 -05:00
chaoticgd
b8ff171127 FileSystem: Improve directory deletion test slightly 2024-12-14 13:41:01 -05:00
lightningterror
7d16a915ed GS/HW: Adjust how we handle dithering on blend mix.
Allow dither adjust regardless of alpha. usually it is clamed to 1 anyway so we can expand it if alpha max is higher than 128.

Expand dither adjust to work in rev subtract conditions.
2024-12-13 08:27:00 +01:00
lightningterror
ecc24ce2e9 GS/TC: Use proper alpha min max for palettes.
If it's an old source made from target make sure it isn't a palette, alphas need to be used from the palette then.
2024-12-13 08:27:00 +01:00
TheLastRar
65748351c7 ChdFileReader: Correct extension check 2024-12-12 08:39:28 -05:00
Ty Lamontagne
a60489b6fd FileSystem: Add a case-insensitive match for nvm and mec file loading. 2024-12-12 08:37:16 -05:00
TheLastRar
e8dbcc31aa SaveState: Fix comparison warning 2024-12-10 21:26:14 +01:00
PCSX2 Bot
5dbaf194c5 PAD: Update to latest controller database. 2024-12-09 12:14:31 -05:00
JordanTheToaster
affdb78a65 GameDB: Change LSW 2 fixes 2024-12-09 12:14:24 -05:00
Ty Lamontagne
313ddb7879 EE Cache: Writeback dirty cache entries when exiting the interpreter. 2024-12-08 17:49:33 -05:00
JordanTheToaster
046b416f61 Deps: Update SDL to 2.30.10 2024-12-08 11:06:01 -05:00
JordanTheToaster
2cb311dd24 3rdparty: Update googletest to v1.15.2 2024-12-08 11:04:38 -05:00
JordanTheToaster
ba36d4b0c8 GameDB: Fix incorrect field order in Silent Hill 3 FMVs 2024-12-08 10:16:12 -05:00
TheLastRar
5de1c60d50 DEV9: Apply const within in PacketReader 2024-12-07 09:22:26 +01:00
TheLastRar
a8a170ebe6 DEV9: Apply const to basic payload types
Propagate const into PacketReader classes as needed
Provide non-const editor version for pcap
2024-12-07 09:22:26 +01:00
PCSX2 Bot
d7937943b0 [ci skip] Qt: Update Base Translation. 2024-12-06 19:14:30 -05:00
JordanTheToaster
3f1df0ea92 3rdparty: Update WIL to v1.0.240803.1 2024-12-06 16:59:34 -05:00
JordanTheToaster
caaa3519ad 3rdparty: Update Vulkan-Headers to v1.4.303 2024-12-06 16:59:34 -05:00
JordanTheToaster
58ab271fc1 Deps: Update to libzip 1.11.2 2024-12-06 16:59:34 -05:00
JordanTheToaster
981fedfdd1 3rdparty/rcheevos: Bump to v11.6.0 2024-12-06 16:59:34 -05:00
JordanTheToaster
ac968f9a6a OSD: Fix status view regression 2024-12-06 16:59:15 -05:00
JordanTheToaster
ac15b77f89 Deps: Update to Qt 6.8.1 on Windows and Linux 2024-12-06 16:59:15 -05:00
chaoticgd
6e4dc1e8ab FileSystem: Don't follow symlinks when recursively deleting directories 2024-12-05 11:52:40 -05:00
chaoticgd
46d17fcb20 FileSystem: Add a test for deleting directories with symlinks 2024-12-05 11:52:40 -05:00
TheLastRar
f91f39afcd DEV9: Fix race-condition while handling closed connection 2024-12-05 11:32:24 -05:00
TheLastRar
f317ba327c DEV9: Correct alignment calculation in Sockets 2024-12-05 11:32:24 -05:00
TheLastRar
00f4cd5252 DEV9: Prevent out of bounds reads in ICMP fix 2024-12-05 11:32:24 -05:00
TheLastRar
0a44e20c34 DEV9: Correct function definitions 2024-12-05 11:32:24 -05:00
TheLastRar
abeb1ca49d DEV9: Skip over invalid gateways 2024-12-05 11:32:24 -05:00
PCSX2 Bot
ee3abe745c [ci skip] Qt: Update Base Translation. 2024-12-03 19:03:20 -05:00
KamFretoZ
a024c25019 Achievements: Fix progression overlay stacking 2024-12-03 17:39:17 +01:00
KamFretoZ
5bf3166832 Qt: Fix Verbose Status Formatting 2024-12-03 17:39:17 +01:00
KamFretoZ
7ef293744a Qt: Move video capture option from Tools to System 2024-12-03 17:39:17 +01:00
TheLastRar
07df874603 DEV9: Avoid iterating over modified vector in UDP_FixedPort 2024-12-03 11:10:31 -05:00
TheLastRar
687c587d19 DEV9: Always bind UDP ports 2024-12-03 11:10:31 -05:00
PCSX2 Bot
671255c684 PAD: Update to latest controller database. 2024-12-02 23:27:24 +01:00
PCSX2 Bot
c31f324853 [ci skip] Qt: Update Base Translation. 2024-11-29 01:30:06 +01:00
lightningterror
5b7122bd30 GS/TC: Remove no longer needed asserts in PreloadTarget.
Asserts are no longer needed as we check for width offset and adjust width accordingly using the offset.
2024-11-28 23:59:52 +01:00
TheLastRar
4a04100207 [SAVEVERSION+] HostFS: Always write savestate tag 2024-11-28 15:47:52 -05:00
TheLastRar
93652a3115 SaveState: Bounds check FreezeMem loads 2024-11-28 15:47:52 -05:00
chaoticgd
4ad1355af3 Debugger: Make sure the colours of functions are consistent across runs 2024-11-28 12:59:24 -05:00
chaoticgd
2501d87840 Console: Fix newline logging regression 2024-11-28 12:53:42 -05:00
Ty Lamontagne
4eae1b7127 Deps: Fix zlib patch hash 2024-11-27 15:13:57 -05:00
TellowKrinkle
a71ea9917a Vulkan: Re-add shaderc status strings to error messages 2024-11-27 14:57:16 -05:00
KamFretoZ
500e2c43b1 Shaderc: Make non-semantic debug optional
Don't you hate it when you come up with more ideas just minutes AFTER the PR has been merged?
2024-11-27 14:57:16 -05:00
KamFretoZ
e6a4cee86c CI: Ensure dependency cache key reflects all state 2024-11-27 14:57:16 -05:00
Dreadmoth
5a94f6819d GameDB: Champions of Norrath & Champions: Return to Arms (PAL) (#11976)
Add Half Pixel Offset Special (Texture) and Round Sprite Half to Champions of Norrath.
Add Show Overscan to Champions of Norrath and Champions: Return to Arms.
2024-11-27 17:39:40 +01:00
chaoticgd
132e3e507d 3rdparty/ccc: Fix some bounds checks and other error handling logic 2024-11-27 17:37:36 +01:00
chaoticgd
ffa06fbb09 3rdparty/ccc: Make CCC_ASSERT macro call abort instead of exit 2024-11-27 17:37:36 +01:00
TheLastRar
028e6cd8a8 CDVD: Fix DevCon log typo 2024-11-26 19:09:07 -05:00
chaoticgd
719063e996 Console: Limit buffer size in ConsoleLogFromVM::Write 2024-11-26 22:44:00 +01:00
PCSX2 Bot
5d40f36fa8 [ci skip] Qt: Update Base Translation. 2024-11-26 19:33:00 +01:00
PCSX2 Bot
31ffcfc920 PAD: Update to latest controller database. 2024-11-25 17:06:11 +01:00
Ty Lamontagne
c9642b70f6 CDVD: Only take ADR and track index/num from host IOCTL SUBQ
Fixes the OSDSYS CD player minute:second counter
2024-11-25 10:02:23 -05:00
Ty Lamontagne
849fa57bf6 CDVD: Adjust register logging 2024-11-25 10:02:23 -05:00
Ty Lamontagne
2c95ef76f1 CDVD: Minor cleanup and fix off-by-one TOC filling issue 2024-11-25 10:02:23 -05:00
Ty Lamontagne
4d9cb885b2 CDVD: Use disc track indexes for our track array. 2024-11-25 10:02:23 -05:00
Ty Lamontagne
e375f98f7a CDVD: Fix OSDSYS Audio CD regression.
There is still an existing issue with the tracks.
2024-11-25 10:02:23 -05:00
lightningterror
1b80f3aea2 Vif: Cleanup code a bit.
Const, casts, nullptr.
2024-11-25 14:02:59 +01:00
Jordan
b0496645f1 GameDB: Various fixes (#12030)
Fixes texture flickering in mission screens on PTO IV Pacific Theater of Operations and corrupted textures banding lighting in levels and bloom misalignment in MOH European Assault.
2024-11-24 19:39:05 +01:00
lightningterror
235cb13647 Vif: Replace some asserts with logs.
The conditions need hardware testing.
Use logs instead so the games don't crash and are still playable.
2024-11-23 13:13:19 +01:00
lightningterror
504dd9f513 Vif: Rename/remove new prefix from files. 2024-11-23 13:13:19 +01:00
Ty Lamontagne
e3fedf1676 QT: Use SetStatusText instead of passing a formatted string as a fmt
This caused crashes when file names had percent signs in them because we passed the file name as the format to SetFormattedStatusText. I opted to continue to use fmt for consistency.
2024-11-22 19:28:55 -05:00
lightningterror
f113a51783 DEV9: Code cleanup.
Casts, constants, unused functions, switch cases.
2024-11-23 00:21:41 +01:00
chaoticgd
f69d5835b8 PINE: Fix stack buffer overflow for long XDG_RUNTIME_DIR paths 2024-11-22 14:10:32 -05:00
PCSX2 Bot
8e8277c0c9 [ci skip] Qt: Update Base Translation. 2024-11-21 01:42:41 +01:00
secondsabre
c6c4eaf31c GameDB: Atelier Iris (SLUS-21113) fixes (#12021) 2024-11-20 15:33:34 -05:00
KamFretoZ
6324722b65 Qt: Add Volume indicator to verbose status 2024-11-20 15:56:15 +01:00
KamFretoZ
efd8c9ec69 OSD: Move VU stats above SW threads. 2024-11-20 15:56:15 +01:00
TellowKrinkle
9858aa1aa5 CMake: Try to put /usr/local/include last 2024-11-18 02:22:30 -06:00
PCSX2 Bot
256a946f96 [ci skip] Qt: Update Base Translation. 2024-11-17 14:43:32 +01:00
chaoticgd
a507964f33 Debugger: Generate a name map for label symbols 2024-11-16 11:50:19 -05:00
chaoticgd
7584a6bb29 Debugger: Allow symbols starting with an underscore in expressions 2024-11-16 11:50:19 -05:00
chaoticgd
ce6103be30 Debugger: Improve function scanner performance for unmapped addresses 2024-11-16 11:50:19 -05:00
chaoticgd
9da4459ab3 Debugger: Run the function scanner on the main symbol database 2024-11-16 11:50:19 -05:00
chaoticgd
3b9b9a84cd Debugger: Use expressions for the function scanner address range 2024-11-16 11:50:19 -05:00
chaoticgd
cce0ae4369 Debugger: Allow loading symbols conditionally and with a base address 2024-11-16 11:50:19 -05:00
chaoticgd
efb43ac7f9 Debugger: Make the expression parser thread safe 2024-11-16 11:50:19 -05:00
lightningterror
8132a8a7f8 USB: Cleanup eyetoy code a bit.
Types, casts, consts.
2024-11-15 15:58:23 +01:00
PCSX2 Bot
9c753cb692 [ci skip] Qt: Update Base Translation. 2024-11-15 14:26:08 +01:00
Berylskid
514e6675c4 GameDB: Fix Enemies Stuck in Armored Core Nine Breaker 2024-11-14 11:22:00 -05:00
Chromaryu
18454fd5d0 GameDB: Add TexInRT on SLPM-62482 2024-11-14 11:20:03 -05:00
chaoticgd
eeb919325e Misc: Minimise the amount of work done when svnrev.h is updated 2024-11-12 09:14:39 -05:00
Julien Reichardt
959be142ed Deps: Update Flatpak dependencies 2024-11-12 08:36:52 -05:00
PCSX2 Bot
42be91d48d PAD: Update to latest controller database. 2024-11-11 14:20:57 -05:00
Bobby Smith
908f916656 GameDB: NBA 2K6 fix hangs on PAL version 2024-11-11 11:52:44 -05:00
Ty Lamontagne
5441c7ed59 Debugger: Use native separators when using external symbol files 2024-11-06 17:06:37 -05:00
chaoticgd
bea471a0e3 Debugger: Fix loading symbols from ELF files other than the boot ELF 2024-11-06 16:58:07 -05:00
chaoticgd
4dafee17e0 Debugger: Refactor nocash symbol importer 2024-11-06 14:23:22 -05:00
PCSX2 Bot
af10be9036 [ci skip] Qt: Update Base Translation. 2024-11-05 19:06:39 -05:00
KamFretoZ
1a4e3ab581 OSD: Fix Pause indicator not showing up 2024-11-05 10:38:49 -05:00
lightningterror
d9e9cf8967 workflows: Fix commit name for daily translations.
Also keep [ci skip] at the start of the commit name as some workflows may require it at the start.
2024-11-05 14:38:58 +01:00
PCSX2 Bot
041b0cb561 PAD: Update to latest controller database. 2024-11-04 17:37:11 +01:00
JordanTheToaster
4ad5dde780 3rdparty: Sync cpuinfo to commit 8df44962d437a0477f07ba6b8843d0b6a48646a4 2024-11-04 12:41:54 +01:00
JordanTheToaster
0bc043a0bb 3rdparty: Update LZMA/7zipSDK to 24.08 2024-11-04 12:41:54 +01:00
JordanTheToaster
c936b7db29 Deps: Update SDL to 2.30.9 2024-11-04 12:41:54 +01:00
JordanTheToaster
2793c49694 Deps: Update Freetype to 2.13.3
a
2024-11-04 12:41:54 +01:00
JordanTheToaster
c578859122 3rdparty: Update xbyak to 7.21 2024-11-04 12:41:54 +01:00
JordanTheToaster
43e6f06a9e Deps: Update libpng to 1.6.44 2024-11-04 12:41:54 +01:00
JordanTheToaster
cf8e9f773e Deps: Update Harfbuzz to 10.0.1 2024-11-04 12:41:54 +01:00
PCSX2 Bot
ed3bdc61f4 Qt: Update Base Translation 2024-11-04 12:40:42 +01:00
TheLastRar
e57f7d92c3 FSUI: Don't move IMGUI cursor unnecessarily in DrawGameGrid() 2024-11-04 12:40:31 +01:00
Gd7
b95eb5cd74 GameDB: Final Fantasy X Optimal FPU config. (#11958)
Fixes the vast majority of FFX's FPU glitches as well as fixing a major cutscene bug without breaking anything more than what the current config already breaks.

EE clamping fixes reverse controls and characters and enemies facing the wrong way during battles, everything else is affected by EE rounding and EE division rounding.

VU0 clamping affects nothing.
2024-11-04 12:40:16 +01:00
KamFretoZ
b865bbb0d3 CI: Add ci skip to base translation update workflow 2024-11-04 12:39:04 +01:00
KamFretoZ
ca6e1c9a46 Qt: Cleanup Unused InputRec Menu 2024-11-04 12:39:04 +01:00
KamFretoZ
ea8a2deae6 Qt: Icon Tweaks 2024-11-04 12:39:04 +01:00
KamFretoZ
c67237672c Qt/Savestate: Add option to disable savestate selector UI 2024-11-04 12:39:04 +01:00
Ty Lamontagne
2d5faa627f CI: Default to flatpak beta branch 2024-10-31 09:22:11 -04:00
Tyler Wilding
1562ba4ca0 translations: Syncing Crowdin translations (#11970) 2024-10-31 09:21:06 -04:00
Ty Lamontagne
a5d94ac454 Patches: Fix a regression that broke gamedb dynpatches 2024-10-30 17:07:07 -04:00
Ty Lamontagne
943fbd8719 Dis5900asm: Fix an out of bounds access on invalid pmfhl formats 2024-10-30 09:15:17 -04:00
Ty Lamontagne
eea1d57e7e PAD: Fix negon and jogcon BPM crash 2024-10-29 18:52:44 -04:00
PCSX2 Bot
74645aa1b7 PAD: Update to latest controller database. 2024-10-28 17:56:47 +01:00
PCSX2 Bot
dfd23d9a25 Qt: Update Base Translation 2024-10-27 20:07:36 -04:00
KamFretoZ
27cf16a09c CI: Fix Translation Workflow Scripts Order of Operation
[ci skip]
2024-10-27 10:20:02 -04:00
PCSX2 Bot
0dee9e3ff1 Qt: Update Base Translation 2024-10-26 21:06:14 -04:00
KamFretoZ
9b47dc0ee3 OSD: Fix Input Overlay Clipping 2024-10-26 11:20:49 -04:00
KamFretoZ
c7b9ee92b7 Qt: Properly Grey Out Checkboxes When Perf OSD is Disabled 2024-10-26 11:20:49 -04:00
KamFretoZ
ac32e6ca92 FSUI: Fix and Tweak BPM Buttons and Legends 2024-10-26 11:20:49 -04:00
TheLastRar
0c204c3ebb Qt: Hackfix settings icon stretching on Windows themes 2024-10-24 12:23:36 -04:00
PCSX2 Bot
016b871734 Qt: Update Base Translation 2024-10-23 20:04:03 -04:00
lightningterror
22413b8e7f GS/OGL: Only paste all available extensions in dev/debug build. 2024-10-23 10:11:06 -04:00
lightningterror
1b50057764 GS/Qt: Adjust how we handle Default adapter.
Try to resolve it again since it annoys me.

Treat is as empty.

Also do NOT translate Default adapter,
it messes with the ini config.
2024-10-23 10:11:06 -04:00
lightningterror
9e15058634 GS/D3D12: Disable DX12 if feature level is not detected.
Intel Haswell doesn't actually support DX12 even tho the device is created which results in a crash,
to get around this check if device can be created using feature level 12 (skylake+).
2024-10-23 10:11:06 -04:00
lightningterror
2a81a7af9e GS: Check feature level 12 as a requirement when selecting auto renderer on intel.
Just to be on the safe side when selecting OpenGL.
2024-10-23 10:11:06 -04:00
chaoticgd
6d3d5ebdc5 Qt: Fix symbol sources list in per-game settings dialog 2024-10-23 09:58:59 -04:00
chaoticgd
7d63a9e51c Debugger: Avoid resetting symbol trees while single stepping 2024-10-23 09:58:02 -04:00
JordanTheToaster
56a2b3b5ad VMManager: Add renderer selection warning 2024-10-23 09:55:36 -04:00
badfontkeming
f46f788d80 USB: Fix FFB quality and dropouts for most wheels, make workaround optional
The original workaround for FFB issues simply restarted the constant force
each time it was updated. Turns out that a lot of wheels don't behave
perfectly during this. A better fix was found, which is to set the effect
duration to infinite. However, some wheels are so bugged that they don't even
respect THAT, so the workaround needs to stick around in some capacity.
2024-10-23 08:40:47 -04:00
TheLastRar
a044b7cf6e DEV9: Set/Clear SEEK bit in all relevent commands (#11931)
* DEV9: Set SEEK on all successful seeks

* DEV9: Complete HDD_Flush immediately when write queue is empty

Also set SEEK when write queue isn't empty

* DEV9: Lock reported value of SEEK when errored
2024-10-23 08:36:16 -04:00
Rares-Alexandru Fodor
8afd29e1a2 Qt: Add search bar for cheats 2024-10-23 08:34:47 -04:00
Rares-Alexandru Fodor
d89b051e6d Qt: Replace QTreeWidget with QTreeView for cheat list 2024-10-23 08:34:47 -04:00
Ty Lamontagne
47cf69d2b3 TraceLogging: Fix SIF trace logging 2024-10-23 08:30:37 -04:00
PCSX2 Bot
35c3c912e7 PAD: Update to latest controller database. 2024-10-21 12:02:59 -04:00
Ziemas
67c5f0229b EE: vtlb handler for writes to IOP mem 2024-10-21 11:14:29 -04:00
github-actions[bot]
5dcc79555d Qt: Update Base Translation (#11932)
Co-authored-by: PCSX2 Bot <PCSX2Bot@users.noreply.github.com>
2024-10-20 20:04:11 -04:00
TheLastRar
82f741e1dc DEV9: Add ATA commands used by PS2 Linux (#11925) 2024-10-19 20:05:34 -04:00
Ty Lamontagne
ab21d22514 Misc: wire up and refactor trace logging 2024-10-19 20:04:02 -04:00
PCSX2 Bot
0a599e7337 Qt: Update Base Translation 2024-10-18 20:26:49 -04:00
chaoticgd
f77bf1ec6b Debugger: Be smarter about deciding when functions should be hashed 2024-10-18 13:57:05 -04:00
chaoticgd
ed4fbb4f5a Debugger: Hash functions scanned in by the MIPS analyst 2024-10-18 13:57:05 -04:00
chaoticgd
f963291970 Debugger: Cache hash match results on symbol tree nodes 2024-10-18 13:57:05 -04:00
chaoticgd
2c3abe33d5 Debugger: Add settings to control the analysis passes 2024-10-18 13:57:05 -04:00
chaoticgd
0fd7e1d7c2 Debugger: Split out SymbolImporter into its own class 2024-10-18 13:57:05 -04:00
TheLastRar
1e23e7efc4 DEV9: Add note regarding IF_CTRL bit 3 2024-10-17 16:10:38 -04:00
TheLastRar
46d5d24fcd DEV9: Correct SPD_XFR_DMAEN define 2024-10-17 16:10:38 -04:00
TheLastRar
3276c0db9c DEV9: Correct implementation of SPD_R_DBUF_STAT reset 2024-10-17 16:10:38 -04:00
TheLastRar
1bdd53a6c5 DEV9: Don't fake the FIFO 2024-10-17 16:10:38 -04:00
TheLastRar
1f2d9ab4e5 IOP: Seperate completing DMA8 to a seperate function 2024-10-17 16:10:38 -04:00
TheLastRar
0806ca442a DEV9: Use ReceivedPayload more in TCP_Session
Instead of shuffling a unique_ptr around
Fixes handling of connection failure in ConnectTCPComplete()
2024-10-15 08:51:09 -04:00
TheLastRar
e3a666bfe4 DEV9: Move adapter detection hack 2024-10-15 08:37:21 -04:00
TheLastRar
6b2dc7a68c DEV9: Move call to network backend reset
SMAP_R_EMAC3_TxMODE1_L is unrelated to resetting the adapter
2024-10-15 08:37:21 -04:00
PCSX2 Bot
18c492d9da Qt: Update Base Translation 2024-10-15 12:28:13 +02:00
TheLastRar
6065caaf19 DEV9: Allow writes to ATA_R_CONTROL while busy 2024-10-15 12:22:03 +02:00
TheLastRar
bb4c456f35 DEV9: Disable interrupts on reset 2024-10-15 12:22:03 +02:00
TheLastRar
078a10dcdb DEV9: Implement ATA pending interrupts 2024-10-15 12:22:03 +02:00
TheLastRar
a8a0c5c0bf DEV9: Rewrite suppression of diagnostics IRQ during reset 2024-10-15 12:22:03 +02:00
TheLastRar
1a95bd3088 DEV9: Support 8bit reads/writes for most ATA regs 2024-10-15 12:22:03 +02:00
PCSX2 Bot
cf157fd2d7 PAD: Update to latest controller database. 2024-10-14 18:12:02 +02:00
Ziemas
35ada362d4 IOP/EE: Add SBUS interrupts
Lets the CPUs trigger an interrupt on the other.
2024-10-14 09:15:42 -04:00
KamFretoZ
444b110411 GSDevice11: Don't try to get the adapter name twice 2024-10-14 14:42:01 +02:00
KamFretoZ
1b82fac70e OSD: Clarify Min/Avg/Max label to Frametime counter 2024-10-14 14:42:01 +02:00
badfontkeming
dafca1e264 USB: Work around FFB dropouts with modern wheels
Certain modern direct-drive wheels such as the Moza R5, R9, etc. implement
timeouts for FFB constant forces, and expect the forces to be re-run
rather than updated in order to refresh these timeouts.
2024-10-13 17:58:52 -04:00
lightningterror
69de95df8b GS: Default to OpenGL on intel GPUs that support it.
Feature level 12 requirement.
2024-10-13 23:15:22 +02:00
JordanTheToaster
ca9f64a08b GameDB: Various fixes 2024-10-13 11:03:22 -04:00
PCSX2 Bot
3b3e35beb7 Qt: Update Base Translation 2024-10-13 00:05:55 +02:00
TheLastRar
c087fc430b DEV9: Allow 8bit reads/writes to all SPEED regs 2024-10-11 19:13:06 -04:00
TheLastRar
d1a4733939 DEV9: Replace incorrect SPD_R_20 behaviour 2024-10-11 19:13:06 -04:00
Bobby Smith
5845109b75 Qt: Call 'map_text_to_keycode()' only when Shift modifier is being used 2024-10-10 18:35:36 -04:00
Ty Lamontagne
7dd2ebdf49 Translations: hotfix a translation mistake causing fmt to crash 2024-10-09 19:24:08 -04:00
TheLastRar
3e78322ea4 DEV9: Rework tx_process based on HW tests 2024-10-09 10:37:54 -04:00
Chromaryu
8d6633fcf9 OSD: Update OSD Text on SW mode so no overlap keyword appears (#11881) 2024-10-09 08:25:30 -04:00
Ty Lamontagne
1c1f67c091 IOP HLE: Only track handles to valid files.
Bonus check for file validity when saving states.
2024-10-08 18:01:11 -04:00
PCSX2 Bot
324b1464e4 Qt: Update Base Translation 2024-10-08 22:13:02 +02:00
JordanTheToaster
1e9a248a0c Deps: Update to Qt 6.8.0 on Windows and Linux 2024-10-08 16:00:37 -04:00
TheLastRar
4319094b02 QT: Clear m_status_verbose_widget text on VM stop 2024-10-08 15:44:59 -04:00
chaoticgd
60abebb3a5 Debugger: Fix crash in symbol tree menu code 2024-10-08 09:47:41 -04:00
PCSX2 Bot
62f20a4809 PAD: Update to latest controller database. 2024-10-07 18:06:16 +02:00
Ty Lamontagne
924326460c Debugger: Destroy and re-create the debugger on theme change 2024-10-07 11:24:09 -04:00
pips3
bba85dc08f HostFS: Retain File Handles in Save States
[SAVEVERSION+]
Save file handle information in save states, and reopen handles when states are loaded.
2024-10-07 09:56:31 -04:00
KamFretoZ
68678ac4ec CI: Add other translations related scripts script to the daily workflow
[ci skip]
2024-10-06 09:31:31 -04:00
PCSX2 Bot
7f9f383324 Qt: Update Base Translation 2024-10-05 20:06:55 -04:00
wxvu
1239c94fba GameDB: Add hwfixes to Armored Core 3 and Sandlot titles. (#11873)
Adds Merge Sprite to Armored Core 3 and adds HPO Native + Autoflush to all Sandlot titles.
2024-10-06 00:38:34 +02:00
KamFretoZ
2ab24bbf28 Qt: Move savestate related options to its new home 2024-10-05 11:04:39 -04:00
KamFretoZ
a304959933 OSD/Savestate: Add close menu hint to the selector
Don't you hate it when you come up with more ideas just minutes AFTER the PR has been merged?
2024-10-05 11:04:39 -04:00
lightningterror
5f0bc729d7 GS/TC: Clamp TW/TH to 11 in source flush.
Clamp TW/TH to 11, as GS memory loops around 2048, anything higher than 12 causes a crash when texture mapping isn't supported like in Direct3D11.
2024-10-03 17:25:23 +02:00
JordanTheToaster
e2421bf3c6 Deps: Update to SDL 2.30.8 2024-10-02 12:53:27 -04:00
JordanTheToaster
9b4b21887f 3rdparty: Update Vulkan-Headers to v1.3.296 2024-10-02 09:52:13 -04:00
PCSX2 Bot
cc9eaef477 Qt: Update Base Translation 2024-10-01 20:18:11 -04:00
KamFretoZ
c1eecb3512 Savestate: Make selector dismissible by opening pause menu 2024-10-01 19:05:51 -04:00
KamFretoZ
58a26dbca4 Qt: Update Glyph Ranges 2024-10-01 19:05:51 -04:00
KamFretoZ
d06700276f Tools: Add shebang to generate fs translation script 2024-10-01 19:05:51 -04:00
KamFretoZ
ab5b622d70 Qt: Fix VPS Counter 2024-10-01 19:05:51 -04:00
KamFretoZ
60e21e2530 SaveState: Add configurable compression type and level 2024-10-01 19:05:51 -04:00
Ty Lamontagne
a694c1bd26 Debugger: Use safe VTLB functions for memory reading and writing 2024-09-29 10:23:00 -04:00
Ty Lamontagne
84d16802a3 iop/hostfs: don't replace back slashes with forward slashes on Windows 2024-09-29 10:20:31 -04:00
JordanTheToaster
02fda478ea Deps: Update to libzip 1.11.1 2024-09-29 10:17:43 -04:00
chaoticgd
31dcda05b7 DebugTools: Scan for functions from the ELF instead of from memory 2024-09-28 12:17:55 -04:00
PCSX2 Bot
5479ab1b8a Qt: Update Base Translation 2024-09-26 20:24:43 -04:00
Ty Lamontagne
cc9c0f9b12 Patches: Implement dynamic patching support in pnaches 2024-09-26 17:15:31 -04:00
Tyler Wilding
aa5a94df5a translations: Syncing Crowdin translations (#11849) 2024-09-26 16:42:42 -04:00
PCSX2 Bot
d9b7f413ff Qt: Update Base Translation 2024-09-26 02:47:57 +02:00
crashGG
6c3cf12df6 GS: Add a 10:7 pixel ration option 2024-09-25 11:46:09 -04:00
lightningterror
13e0546f56 GS/HW: Make sure it's not a channel shuffle when the alpha of a target is used as source.
The alpha of a target used a source is meaningless to us,
since it's not really an indexed texture.
2024-09-23 23:57:09 +02:00
PCSX2 Bot
c01dc20284 Qt: Update Base Translation 2024-09-23 23:56:16 +02:00
PCSX2 Bot
3faf22256e PAD: Update to latest controller database. 2024-09-23 18:01:50 +02:00
Matthew
ac4d827a9c Qt: Add a permission error dialog when converting memorycards in a R/O directory 2024-09-22 14:15:22 -04:00
weirdbeardgame
95201409e3 CDVD: 0 index into tracks array 2024-09-21 10:49:26 -04:00
weirdbeardgame
89cd474278 CDVD: Added cdvdTrack, cdvdTrackIndex
used IOCtl SubQ reads to get proper control register
Added Checks for Control fields.
2024-09-21 10:49:26 -04:00
Joe Wagner
fc715d58f0 Qt: Fix keyboard SHIFT for non-alpha characters 2024-09-20 03:01:33 +02:00
Stuart Kenny
217e1c8fae GS: Update lottes crt shader. 2024-09-19 17:51:29 +02:00
lightningterror
5486eed151 GS/HW: Merge blend ad a mask separate conditions in to one.
Duplicate code.
2024-09-19 00:19:05 +02:00
Ty Lamontagne
d1721360ff DebugInterface: Fix formatting 2024-09-18 16:57:20 -04:00
Ty Lamontagne
0a0f99dd1b DebugInterface: Try to show the kernel memory mappings, again 2024-09-18 12:50:48 -04:00
PCSX2 Bot
eb5ea6f64e Qt: Update Base Translation 2024-09-18 17:38:09 +02:00
lightningterror
1d449e9675 FullscreenUI: Remove unused function.
CopyGlobalControllerSettingsToGame.
2024-09-17 23:19:00 +02:00
Ty Lamontagne
c82671fce4 microVU: fix block clearing regression 2024-09-16 16:46:23 -04:00
oltolm
4c267c4206 microvu: fix ASAN container-overflow in mVUsetupRange 2024-09-16 13:48:00 -04:00
PCSX2 Bot
158e67cf6d Qt: Update Base Translation 2024-09-16 18:41:23 +02:00
Pyra Drake
1afff1a064 GameDB: Pro Race Driver fixes
Pro Race Driver fixes for upscaling lines.
2024-09-16 18:41:05 +02:00
JordanTheToaster
904874d959 OSD: Improve main window stat spacing 2024-09-16 18:40:20 +02:00
PCSX2 Bot
d33168d31f PAD: Update to latest controller database. 2024-09-16 18:39:49 +02:00
Ty
2b7c4ae438 gh: update the feature request template labels
We are trying out a new feature request labelling system.
2024-09-15 14:40:05 -04:00
lightningterror
6483565d47 GS/HW: Fix/cleanup pabe optimization condition.
We should check only if As max is 128, also make sure we are checking the original Alpha C value as it could have been modified for an optimization.
2024-09-15 20:39:41 +02:00
JordanTheToaster
11704f7f0c GameDB: Various fixes 2024-09-15 14:38:38 -04:00
chaoticgd
8d3f4fac23 Debugger: Prevent flicker when resetting symbol tree node children 2024-09-15 08:57:12 -04:00
chaoticgd
93b18412f5 Debugger: Make check box widgets in the symbol tree more responsive 2024-09-15 08:57:12 -04:00
JordanTheToaster
d9c5f22d1e OSD: Rename various fields 2024-09-15 08:41:12 -04:00
KamFretoZ
d12ef2b17c OSD: Add GPU Info (#11808)
* OSD: Add GPU Info

* Qt: More Translatable Strings
2024-09-15 08:24:05 -04:00
lightningterror
e8e0b97f6d GS/HW: Reduce sw/hdr colclip in more cases.
When doing `Cs*Alpha + Cd*(1 - Alpha)` or `Cd*Alpha + Cs*(1 - Alpha)` with an alpha of 128 or lower
we don't really need to hdr or sw colclip blend it because colour range of the result will be
between 0-1 (0-255) without it overflowing.

Also update previous optimizations to include Ad cases when RTA is already scaled.
2024-09-15 01:09:28 +02:00
PCSX2 Bot
f50083e47a Qt: Update Base Translation 2024-09-14 18:07:20 +02:00
Farran666
461ee350c2 GameDB: Add Skip MPEG Hack to Never7 2024-09-13 16:45:43 -04:00
TheLastRar
0cf4b76876 Common: Fix Recursive CreateDirectoryPath() on Windows 2024-09-12 15:45:45 -04:00
KamFretoZ
4e1979427d Qt: Make Settings List Word Wrapped 2024-09-12 15:42:00 -04:00
KamFretoZ
110426ac9f DiscordRPC: Further improve icon url call 2024-09-12 15:42:00 -04:00
OctopusButtons
4565a62634 UI: Update mipmapping help description
Added mipmapping description similar to the help/hover text of other items. Wording is my own phrasing.
2024-09-12 15:36:19 -04:00
JordanTheToaster
f75da73fca 3rdparty/ffmpeg: Bump headers to version 7.0.2 2024-09-12 11:19:05 -04:00
Ziemas
5c83edb7b2 ExpressionParser: Add missing include in header 2024-09-11 09:09:38 -04:00
Ty Lamontagne
bb1162f6cc Achievements: Reset client state on system reset 2024-09-10 16:58:58 -04:00
Martino Fontana
a4d2332f9c Config: Set {ntsc,pal}FrameRate bounds to 10-300 Hz 2024-09-10 11:58:42 -04:00
Nenderus
4963ea9b11 CMake: Install translations in PACKAGE MODE 2024-09-09 20:11:21 -04:00
PCSX2 Bot
11caae46c1 Qt: Update Base Translation 2024-09-09 20:10:18 -04:00
dependabot[bot]
bfaad9f9bf Bump peter-evans/create-pull-request from 6 to 7 in the ci-deps group
Bumps the ci-deps group with 1 update: [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request).


Updates `peter-evans/create-pull-request` from 6 to 7
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v6...v7)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: ci-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-09 20:03:17 -04:00
RedPanda4552
0792ceb21a Config: Prevent pad settings lingering in game properties blocking profiles 2024-09-09 15:06:28 -04:00
smasimar@gmail.com
2886f825aa Added "SaveStateAndSelectNextSlot" hotkey for alternative save slot cycling functionality. 2024-09-09 14:58:15 -04:00
smasimar@gmail.com
22c9b70ca3 Flipped the order of "SaveStateAndSelectNextSlot" to "SelectNextSlotAndSaveState" 2024-09-09 14:58:15 -04:00
PCSX2 Bot
6dbbebeafb PAD: Update to latest controller database. 2024-09-09 18:28:55 +02:00
KamFretoZ
f54eeca1fd FSUI: Move Texture Preloading to Advanced 2024-09-08 14:37:28 -04:00
PCSX2 Bot
7d6f74083b Qt: Update Base Translation 2024-09-06 18:59:17 +02:00
KamFretoZ
28e4b10fda Translation: Remove excess double quote (#11777)
* Translation: Remove excess double quote on the train controller

* Qt: Add Train Controller Icon

* Qt: Expand controller input list

* FSUI: Base Translation Update

* Qt: Update Base Translations
2024-09-03 12:09:54 -04:00
JordanTheToaster
b8405ef7a6 Deps: Update to SDL 2.30.7 2024-09-03 10:26:12 +02:00
PCSX2 Bot
d178bb3904 Qt: Update Base Translation 2024-09-03 10:24:50 +02:00
KamFretoZ
1ea512655a FileSystem: Fix handling of symlinks
Revert of c8a3e5a9ec
2024-09-02 16:18:01 -04:00
chaoticgd
90463a4a6c Debugger: Bring back the expression parser 2024-09-02 16:16:05 -04:00
PCSX2 Bot
f340b5ebd0 Qt: Update Base Translation 2024-09-01 19:07:18 +02:00
Joe Stringer
ab2d18ebf0 USB: Add passthrough support to DenshaCon
Enable an option to use native Densha De Go! controllers and pass the axis inputs from the controller directly through to the game.
2024-08-31 20:47:29 +02:00
Joe Stringer
8d3bb1ad80 Settings: Add DenshaCon bindings UI 2024-08-31 20:47:29 +02:00
Joe Stringer
ed3405b5a9 USB: Add support for Ryojouhen DenshaCon
Add support for TCPP20014 controllers, datasheets courtesy of Marc Riera. Tested with a One Handle MasCon for Nintendo Switch as the controller device.

Link: https://marcriera.github.io/ddgo-controller-docs/controllers/usb/tcpp20014/
2024-08-31 20:47:29 +02:00
Joe Stringer
904d6b9c78 USB: Add support for Shinkansen DenshaCon
Add support for TCPP20011 controllers, datasheets courtesy of Marc Riera. Tested with a One Handle MasCon for Nintendo Switch as the controller device.

Link: https://marcriera.github.io/ddgo-controller-docs/controllers/usb/tcpp20011
2024-08-31 20:47:29 +02:00
Joe Stringer
edcd1d0f9f USB: Add support for Type 2 DenshaCon
Add support for TCPP20009 controllers, datasheets courtesy of Marc Riera. Tested with a One Handle MasCon for Nintendo Switch as the controller device.

Link: https://marcriera.github.io/ddgo-controller-docs/controllers/usb/tcpp20009/
2024-08-31 20:47:29 +02:00
Ty Lamontagne
a8ce6a9f0e UI: Enable "System" and toolbar savestate options in OSDSYS
Saving state in OSDSYS was supported and worked fine with hotkeys, the UI just didn't reflect that.
2024-08-29 11:40:20 -04:00
chaoticgd
42e4a47bfc DebugTools: Fix some compiler warnings 2024-08-28 23:29:35 +02:00
Jordan
e423fd10c6 Misc: Minor text and settings changes (#11751)
* VMManager: Update CPU detection text

* Settings: Move texture preload to advanced

* Settings: Move spin during readback to advanced

* Translations: Add extra comment to mailbox presentation

Update GraphicsSettingsWidget.ui
2024-08-28 16:08:49 -04:00
PCSX2 Bot
f73a9e89f6 Qt: Update Base Translation 2024-08-28 01:02:56 +02:00
chaoticgd
48de49b85d DebugTools: Fix iterator invalidation bug in IopBios.cpp 2024-08-27 18:13:25 -04:00
lightningterror
da1ee3a3b9 GS/HW: Add afix to alphas log. 2024-08-27 19:35:19 +02:00
chaoticgd
79dbc272b8 Debugger: Add symbol tree widgets for functions and variables
This adds three new tabs in the debugger: The Globals tab, the Locals
tab and the Parameters tab. In addition, it rewrites the Functions tab.

All four of these tabs use the new symbol tree widgets and the
associated model. This allows the user the inspect complex data
structures in memory with full type information.

Lastly, new dialogs have been added for creating symbols.
2024-08-27 12:48:40 -04:00
chaoticgd
c83cca1d87 Debugger: Add GNU demangler
This code is taken from GCC 13.2.0 with a number of modifications
applied. See the included readme for more information.
2024-08-27 12:48:40 -04:00
chaoticgd
44b50bee26 Debugger: Replace SymbolMap class with new SymbolGuardian class
This new class uses the CCC library I added in the last commit and
parses the symbol tables on a worker thread.
2024-08-27 12:48:40 -04:00
chaoticgd
87b03fdc28 3rdparty: Add CCC v2.1
This is the symbol table parser that I'm replacing the existing ELF
symbol table parser with. It supports STABS symbols in .mdebug sections
as well as ELF symbols and SNDLL symbols.

It includes its own symbol database, and an AST which facilitates
debugging tools that let the user inspect complex data structures with
full type information.

More information is provided in the included readme.
2024-08-27 12:48:40 -04:00
chaoticgd
b43e05a8fc Debugger: Remove the Avast demangler
This library doesn't support the demangling scheme used by GCC 2.x
compilers and hence doesn't work in lots of cases.
2024-08-27 12:48:40 -04:00
lightningterror
67d7744f7f GS/HW: Further expand blend multipass.
For formulas:
Cs*Alpha + Cd*(1 - Alpha).
Cd*Alpha + Cs*(1 - Alpha).
Where Alpha is higher than 1 and is either As or Af.
2024-08-27 13:38:44 +02:00
RedPanda4552
27fb7dc26e Big Picture: Remove ability to make per-game controls
Replace with profile selector instead
2024-08-26 19:36:25 -04:00
PCSX2 Bot
04168a0359 PAD: Update to latest controller database. 2024-08-26 18:42:50 +02:00
deanff
1131db784f Qt: Set focus to Game Library for improved keyboard navigation (#11719)
Improved keyboard navigation. Users can navigate the Library and play/exit games with just the arrow keys and Enter/Esc.
2024-08-24 18:00:34 +02:00
Florin9doi
517fba3686 USB: Fix CaptureEye corruption on dark images 2024-08-24 17:28:17 +02:00
KamFretoZ
64e17fce3f Qt: Fix a couple of instances of inconsistent sorting
Backport from 7927ec647f
2024-08-24 17:27:39 +02:00
KamFretoZ
518728ca36 Qt: Center type icon in game list
Backport from: 93836636a1
2024-08-24 17:27:39 +02:00
KamFretoZ
d1a7430f80 Qt: Fix incorrect sort indicator on loading
Backport from: a56ebf24b2
2024-08-24 17:27:39 +02:00
KamFretoZ
973c522756 Qt: Ensure fullscreen UI is stopped on exiting
Backport from: 533022bb7d
2024-08-24 17:27:39 +02:00
KamFretoZ
5536342f9d ImGuiManager: Fix stutter when multiple OSD messages lapse
fe55446c25
2024-08-24 17:27:39 +02:00
KamFretoZ
d9ddab1a33 ImGuiFullscreen: Fix incorrect notification width
Backport from: e455a5e371
2024-08-24 17:27:39 +02:00
KamFretoZ
c915aac1fa FileSystem: Correctly use lstat() on Linux
Backport from: 81295c8a7d
2024-08-24 17:27:39 +02:00
KamFretoZ
a3c2a4db5f GSTextureVK: Fix download inside render pass
Backport from: 5f8082734e
2024-08-24 17:27:39 +02:00
KamFretoZ
aebebf5115 Qt: Work around theme switching bug
backport from: b2577ef8bd
2024-08-24 17:27:39 +02:00
KamFretoZ
9a50218400 Image: Fix crash loading corrupted/invalid JPEG files
Backport from: afea18f65e
2024-08-24 17:27:39 +02:00
TellowKrinkle
fd5a652270 Vk: Don't try to transition present source during present 2024-08-23 20:59:26 -05:00
Farran666
c647a30aa9 GameDB: Add multiple fixes 2024-08-23 15:22:51 +02:00
lightningterror
40d5c78573 GS/HW: Implement PABE(Per pixel alpha blending) on accumulation blend and add optimizations.
PABE accumulation blend:
Idea is to achieve final output Cs when As < 1, we do this with manipulating Cd using the src1 output.
This can't be done with reverse subtraction as we want Cd to be 0 when As < 1.
Blend mix is excluded as no games were found, otherwise it can be added.

PABE Disable blending:
We can disable blending here as an optimization since alpha max is 128
which if alpha is 1 in the formula Cs*Alpha + Cd*(1 - Alpha) will give us a result of Cs.
2024-08-22 21:39:19 +02:00
xperia64
fe2a9fc2cd GameDB: Correct two Phoenix Games title names 2024-08-22 11:34:51 -04:00
squidbus
83f9add68b Config: Allow specifying portable directory relative path in portable.txt 2024-08-21 12:32:10 -04:00
KamFretoZ
ffe8d16df4 DiscordRPC: Add game icon support. 2024-08-21 12:28:56 -04:00
PCSX2 Bot
31b5672870 Qt: Update Base Translation 2024-08-20 10:11:20 +02:00
Florin9doi
777fc444ae USB: Rename singstar to usb_mic 2024-08-20 10:09:21 +02:00
Florin9doi
cd5c961dc4 USB: Konami ON-SAY microphone emulation 2024-08-20 10:09:21 +02:00
Florin9doi
c2ea8c4eab USB: Audio support for EyeToy 2024-08-20 10:09:21 +02:00
Florin9doi
d6507a945b USB: Merge Singstar and Logitech mics in a single device with 2 subtypes 2024-08-20 10:09:21 +02:00
PCSX2 Bot
f1abee5d0b Qt: Update Base Translation 2024-08-19 09:15:02 +02:00
Jordan
e4dccc237c Misc: Minor cleanup. (#11717)
Changes video max bitrate to 200,000kbps default audio from 160kbps to 192kbps and adds a missing name I forgot to add previously.
2024-08-19 09:14:27 +02:00
KamFretoZ
92d8c740d4 Qt: Fix a couple of theme switching glitches
Backport from: 6f9e8efee5
2024-08-19 08:54:35 +02:00
KamFretoZ
b6eddade00 Qt: Slightly increase game list title size 2024-08-19 08:54:35 +02:00
KamFretoZ
04fdd09d1e ImGuiFullscreen: Display checkmark on right of choice dialog
Backport from: f5815f3183
2024-08-19 08:54:35 +02:00
KamFretoZ
69574aecc6 ImGuiFullscreen: Fix choice popup selected drawing over border
Backport from 05f9f33ec6
2024-08-19 08:54:35 +02:00
KamFretoZ
c72d98d4cd FullscreenUI: Fix popup close resetting window scroll
Backport from 13a37418e6
2024-08-19 08:54:35 +02:00
Florin9doi
4f405adea9 USB: Store unique disk images for MSD and PictureParadise 2024-08-18 19:29:09 +02:00
Florin9doi
5217ec375d USB: Fix Konami Capture Eye assert 2024-08-18 19:27:48 +02:00
JordanTheToaster
10b264b9ec 3rdparty/imgui: Disable the nav menu
Courtesy to Fobes for figuring this out because I was not getting anywhere.
2024-08-16 11:27:24 -04:00
JordanTheToaster
dc741e95bd 3rdparty/imgui: General cleanup
Clean up and replacing obsolete functions.
2024-08-16 11:27:24 -04:00
PCSX2 Bot
a1ca0a9a02 Qt: Update Base Translation 2024-08-15 19:14:14 +02:00
lightningterror
c076c50b68 GS/DX11: Fix feedback write 1 null pointer crash.
We were using the wrong texture as the source, should be dTex when copying.
2024-08-15 10:26:27 +02:00
lightningterror
c688db8f08 GS/HW: Rename blend second pass to blend multi pass.
Easier if I want to add more passes.
2024-08-14 12:35:52 +02:00
PCSX2 Bot
469053de9b Qt: Update Base Translation 2024-08-13 19:42:38 +02:00
squidbus
185b85f86a Config: Use directory containing bundle as AppRoot on macOS. 2024-08-12 22:50:49 -04:00
PCSX2 Bot
11096a520e PAD: Update to latest controller database. 2024-08-12 19:01:26 -04:00
Florin9doi
07fd035aa2 USB: Set actual_length value for Get HID descriptor 2024-08-12 19:01:08 -04:00
seta-san
6bedcd768f Qt: Update Trilinear Filtering Description 2024-08-12 19:00:28 -04:00
weirdbeardgame
0c949db506 CMake: Added PACKAGE_MODE option
Set paths, add check in SetResourcesDir
2024-08-12 11:33:02 -04:00
PCSX2 Bot
4c5253c0f5 Qt: Update Base Translation 2024-08-11 07:46:00 +02:00
Mrlinkwii
325133e54c GameDB: add missing serial 2024-08-11 00:50:33 +02:00
JordanTheToaster
4113ac574d GameDB: ATV Offroad Fury 2 Fixes
Adds bilinear upscale nearest to fix garbage textures.
2024-08-11 00:47:48 +02:00
JordanTheToaster
2d6c687913 GSTextureCache: Extend Bilinear Upscale to dirty depth 2024-08-11 00:47:48 +02:00
lightningterror
f9fbecc783 GS: Match data types in shaders to be the same when doing bitwise operations. 2024-08-11 00:35:42 +02:00
seta-san
c5ceba35b6 Qt: Update Texture Filtering Description
Qt: Update Texture Filtering Description
2024-08-10 18:25:44 -04:00
1902 changed files with 407945 additions and 211984 deletions

View File

@@ -2,7 +2,7 @@
name: Feature request
description: Suggest a new feature or improve an existing one
title: "[Feature Request]: "
labels: ["Enhancement / Feature Request"]
labels: ["Enhancement / Feature Request", "FR: Awaiting Consideration"]
# assignees:
# - octocat
body:

View File

@@ -10,6 +10,7 @@ jobs:
if: github.repository == 'PCSX2/pcsx2'
name: "Check if release is needed"
runs-on: ubuntu-latest
timeout-minutes: 180
outputs:
PCSX2_RELEASE: ${{ steps.getinfo.outputs.PCSX2_RELEASE }}
FLATHUB_RELEASE: ${{ steps.getinfo.outputs.FLATHUB_RELEASE }}
@@ -43,7 +44,7 @@ jobs:
compiler: clang
cmakeflags: ""
publish: true
branch: stable
fetchTags: true
stableBuild: false
secrets: inherit

View File

@@ -17,10 +17,10 @@ jobs:
run: ./.github/workflows/scripts/common/update_base_translation.sh
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79
with:
title: "Qt: Update Base Translation"
commit-message: "Qt: Update Base Translation"
commit-message: "[ci skip] Qt: Update Base Translation."
committer: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
author: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
body: "Daily update of base translation sources."

View File

@@ -19,10 +19,10 @@ jobs:
mv ./game_controller_db.txt ${{github.workspace}}/bin/resources/game_controller_db.txt
- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79
with:
title: "PAD: Update to latest controller database"
commit-message: "PAD: Update to latest controller database."
commit-message: "[ci skip] PAD: Update to latest controller database."
committer: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
author: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
body: "Weekly automatic update of SDL Controller DB."

View File

@@ -23,10 +23,6 @@ on:
cmakeflags:
required: true
type: string
branch:
required: false
type: string
default: "stable"
publish:
required: false
type: boolean
@@ -98,7 +94,8 @@ jobs:
run: |
flatpak-builder-lint manifest .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.json
- name: Build Flatpak
- name: Build Flatpak (beta)
if: ${{ inputs.stableBuild == false || inputs.stableBuild == 'false' }}
uses: flathub-infra/flatpak-github-actions/flatpak-builder@23796715b3dfa4c86ddf50cf29c3cc8b3c82dca8
with:
bundle: ${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak
@@ -108,17 +105,33 @@ jobs:
build-bundle: true
verbose: true
mirror-screenshots-url: https://dl.flathub.org/media
branch: ${{ inputs.branch }}
branch: beta
cache: true
restore-cache: true
cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json', '.github/workflows/scripts/common/*.patch') }}
- name: Build Flatpak (stable)
if: ${{ inputs.stableBuild == true || inputs.stableBuild == 'true' }}
uses: flathub-infra/flatpak-github-actions/flatpak-builder@23796715b3dfa4c86ddf50cf29c3cc8b3c82dca8
with:
bundle: ${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak
upload-artifact: false
manifest-path: .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.json
arch: x86_64
build-bundle: true
verbose: true
mirror-screenshots-url: https://dl.flathub.org/media
branch: stable
cache: true
restore-cache: true
cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json') }}
#- name: Validate build
# run: |
# flatpak-builder-lint repo repo
- name: Push to Flathub beta
if: inputs.publish == true && inputs.branch == 'beta'
- name: Push to Flathub (beta)
if: ${{ inputs.publish == true && (inputs.stableBuild == false || inputs.stableBuild == 'false') }}
uses: flathub-infra/flatpak-github-actions/flat-manager@23796715b3dfa4c86ddf50cf29c3cc8b3c82dca8
with:
flat-manager-url: https://hub.flathub.org/
@@ -126,8 +139,8 @@ jobs:
token: ${{ secrets.FLATHUB_BETA_TOKEN }}
build-log-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
- name: Push to Flathub stable
if: inputs.publish == true && inputs.branch == 'stable'
- name: Push to Flathub (stable)
if: ${{ inputs.publish == true && (inputs.stableBuild == true || inputs.stableBuild == 'true') }}
uses: flathub-infra/flatpak-github-actions/flat-manager@23796715b3dfa4c86ddf50cf29c3cc8b3c82dca8
with:
flat-manager-url: https://hub.flathub.org/

View File

@@ -15,7 +15,7 @@ jobs:
uses: ./.github/workflows/linux_build_qt.yml
with:
jobName: "AppImage Build"
artifactPrefixName: "PCSX2-linux-Qt-x64-appimage-sse4"
artifactPrefixName: "PCSX2-linux-Qt-x64-appimage"
compiler: clang
cmakeflags: ""
buildAppImage: true
@@ -26,7 +26,7 @@ jobs:
uses: ./.github/workflows/linux_build_flatpak.yml
with:
jobName: "Flatpak Build"
artifactPrefixName: "PCSX2-linux-Qt-x64-flatpak-sse4"
artifactPrefixName: "PCSX2-linux-Qt-x64-flatpak"
compiler: clang
cmakeflags: ""
publish: false

View File

@@ -55,7 +55,7 @@ jobs:
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_COMPRESS: true
CCACHE_COMPRESSLEVEL: 9
CCACHE_MAXSIZE: 100M
CCACHE_MAXSIZE: 500M
steps:
- name: Checkout Repository
@@ -117,7 +117,7 @@ jobs:
uses: actions/cache@v4
with:
path: ~/deps
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/linux/build-dependencies-qt.sh') }}
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/linux/build-dependencies-qt.sh', '.github/workflows/scripts/common/*.patch') }}
- name: Build Dependencies
if: steps.cache-deps.outputs.cache-hit != 'true'

View File

@@ -25,20 +25,26 @@ on:
required: false
type: boolean
default: false
sign_and_notarize:
required: false
type: boolean
default: false
jobs:
build_macos:
name: ${{ inputs.jobName }}
runs-on: ${{ inputs.os }}
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
timeout-minutes: 90
timeout-minutes: 120
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
CCACHE_BASEDIR: ${{ github.workspace }}
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_COMPRESS: true
CCACHE_COMPRESSLEVEL: 9
CCACHE_MAXSIZE: 100M
CCACHE_MAXSIZE: 500M
# Only way to use a secret in an if statement
SIGN_KEY: ${{ secrets.APPLE_SIGN_P12_B64 }}
steps:
- name: Checkout Repository
@@ -85,7 +91,7 @@ jobs:
uses: actions/cache@v4
with:
path: ~/deps
key: ${{ inputs.os }} deps ${{ hashFiles('.github/workflows/scripts/macos/build-dependencies.sh') }}
key: ${{ inputs.os }} deps ${{ hashFiles('.github/workflows/scripts/macos/build-dependencies.sh', '.github/workflows/scripts/common/*.patch') }}
- name: Build Dependencies
if: steps.cache-deps.outputs.cache-hit != 'true'
@@ -143,6 +149,38 @@ jobs:
run: make -j$(getconf _NPROCESSORS_ONLN) unittests
- name: Prepare Build Artifacts
run: |
mv build/pcsx2*/PCSX2.app PCSX2.app
- name: Pull the Signing Keys and Notarization Credentials
if: ${{ inputs.sign_and_notarize == true && env.SIGN_KEY }}
run: |
echo "${{ secrets.APPLE_SIGN_P12_B64 }}" | base64 -d > cert.p12
echo "${{ secrets.APPLE_APPSTORECONNECT_CFG }}" | base64 -d > key.json
- name: Sign the Application
if: ${{ inputs.sign_and_notarize == true && env.SIGN_KEY }}
uses: indygreg/apple-code-sign-action@44d0985b7f4363198e80b6fea63ac3e9dd3e9957
with:
input_path: 'PCSX2.app'
p12_file: cert.p12
p12_password: "${{ secrets.APPLE_SIGN_P12_PASS }}"
sign_args: |
--for-notarization
--code-signature-flags=runtime
--entitlements-xml-file=pcsx2/Resources/PCSX2.entitlements
notarize: true
# max_wait_seconds is only present on my fork located at F0bes/apple-code-sign-action@demo4
# If we are timing out we should switch to the newest upstream (if I get it upstreamed)
# or use my fork.
# max_wait_seconds: '2000'
staple: true
# Generated using rcodesign
# Despite what the docs say, I found that this file is required and I had 0 luck
# passing the issuer id, key, etc through arguments.
app_store_connect_api_key_json_file: 'key.json'
- name: Zip Build Artifacts
run: |
TAG="$(git tag --points-at HEAD)"
if [ -z "$TAG" ]; then
@@ -150,7 +188,7 @@ jobs:
else
APPNAME="PCSX2-$TAG"
fi
mv build/pcsx2*/PCSX2.app "$APPNAME.app"
mv PCSX2.app "$APPNAME.app"
tar --options xz:compression-level=9 -cvJf "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" "$APPNAME.app"
mkdir ci-artifacts
cp "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" ci-artifacts/macOS.tar.xz

View File

@@ -16,4 +16,5 @@ jobs:
with:
jobName: "MacOS Build"
artifactPrefixName: "PCSX2-macos-Qt"
sign_and_notarize: true # If we find that notarization takes a long time we should disable that on PR builds
secrets: inherit

View File

@@ -40,7 +40,7 @@ jobs:
# Docs - https://github.com/mathieudutour/github-tag-action
- name: Bump Version and Push Tag
id: tag_version
uses: mathieudutour/github-tag-action@v6.2
uses: mathieudutour/github-tag-action@a22cf08638b34d5badda920f9daf6e72c477b07b
with:
github_token: ${{ github.token }}
tag_prefix: v
@@ -68,7 +68,7 @@ jobs:
mv ./release-notes.md ${GITHUB_WORKSPACE}/release-notes.md
- name: Create a GitHub Release (Manual)
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda
if: steps.tag_version.outputs.new_tag && github.event_name == 'workflow_dispatch'
with:
body_path: ./release-notes.md
@@ -77,7 +77,7 @@ jobs:
tag_name: ${{ steps.tag_version.outputs.new_tag }}
- name: Create a GitHub Release (Push)
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda
if: steps.tag_version.outputs.new_tag && github.event_name != 'workflow_dispatch'
with:
body_path: ./release-notes.md
@@ -114,7 +114,6 @@ jobs:
artifactPrefixName: "PCSX2-linux-Qt-x64-flatpak"
compiler: clang
cmakeflags: ""
branch: "stable"
publish: false
fetchTags: true
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
@@ -149,6 +148,7 @@ jobs:
artifactPrefixName: "PCSX2-macos-Qt"
fetchTags: true
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
sign_and_notarize: true
secrets: inherit
# Upload the Artifacts
@@ -205,7 +205,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 16
node-version: 22
- name: Announce Release
env:

View File

@@ -0,0 +1,13 @@
diff --git a/src/core/indicators/ClassicDropIndicatorOverlay.h b/src/core/indicators/ClassicDropIndicatorOverlay.h
index 2dfb9718a..9b01f002e 100644
--- a/src/core/indicators/ClassicDropIndicatorOverlay.h
+++ b/src/core/indicators/ClassicDropIndicatorOverlay.h
@@ -11,7 +11,7 @@
#pragma once
-#include "core/DropIndicatorOverlay.h"
+#include <kddockwidgets/core/DropIndicatorOverlay.h>
namespace KDDockWidgets {

View File

@@ -114,6 +114,15 @@ diff --git a/libshaderc/include/shaderc/shaderc.h b/libshaderc/include/shaderc/s
index 3a3e97d..65d5b77 100644
--- a/libshaderc/include/shaderc/shaderc.h
+++ b/libshaderc/include/shaderc/shaderc.h
@@ -15,6 +15,8 @@
#ifndef SHADERC_SHADERC_H_
#define SHADERC_SHADERC_H_
+#define SHADERC_PCSX2_CUSTOM 1
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -317,7 +317,7 @@ SHADERC_EXPORT void shaderc_compile_options_set_source_language(
// Sets the compiler mode to generate debug information in the output.
@@ -123,69 +132,6 @@ index 3a3e97d..65d5b77 100644
// Sets the compiler optimization level to the given level. Only the last one
// takes effect if multiple calls of this function exist.
@@ -506,6 +506,10 @@ SHADERC_EXPORT void shaderc_compile_options_set_invert_y(
SHADERC_EXPORT void shaderc_compile_options_set_nan_clamp(
shaderc_compile_options_t options, bool enable);
+// Returns a string representation of the specified compilation status.
+SHADERC_EXPORT const char* shaderc_compilation_status_to_string(
+ shaderc_compilation_status status);
+
// An opaque handle to the results of a call to any shaderc_compile_into_*()
// function.
typedef struct shaderc_compilation_result* shaderc_compilation_result_t;
@@ -529,28 +533,31 @@ typedef struct shaderc_compilation_result* shaderc_compilation_result_t;
// present. May be safely called from multiple threads without explicit
// synchronization. If there was failure in allocating the compiler object,
// null will be returned.
-SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_spv(
+SHADERC_EXPORT shaderc_compilation_status shaderc_compile_into_spv(
const shaderc_compiler_t compiler, const char* source_text,
size_t source_text_size, shaderc_shader_kind shader_kind,
const char* input_file_name, const char* entry_point_name,
- const shaderc_compile_options_t additional_options);
+ const shaderc_compile_options_t additional_options,
+ shaderc_compilation_result_t* result);
// Like shaderc_compile_into_spv, but the result contains SPIR-V assembly text
// instead of a SPIR-V binary module. The SPIR-V assembly syntax is as defined
// by the SPIRV-Tools open source project.
-SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_spv_assembly(
+SHADERC_EXPORT shaderc_compilation_status shaderc_compile_into_spv_assembly(
const shaderc_compiler_t compiler, const char* source_text,
size_t source_text_size, shaderc_shader_kind shader_kind,
const char* input_file_name, const char* entry_point_name,
- const shaderc_compile_options_t additional_options);
+ const shaderc_compile_options_t additional_options,
+ shaderc_compilation_result_t* result);
// Like shaderc_compile_into_spv, but the result contains preprocessed source
// code instead of a SPIR-V binary module
-SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_preprocessed_text(
+SHADERC_EXPORT shaderc_compilation_status shaderc_compile_into_preprocessed_text(
const shaderc_compiler_t compiler, const char* source_text,
size_t source_text_size, shaderc_shader_kind shader_kind,
const char* input_file_name, const char* entry_point_name,
- const shaderc_compile_options_t additional_options);
+ const shaderc_compile_options_t additional_options,
+ shaderc_compilation_result_t* result);
// Takes an assembly string of the format defined in the SPIRV-Tools project
// (https://github.com/KhronosGroup/SPIRV-Tools/blob/master/syntax.md),
@@ -561,10 +568,11 @@ SHADERC_EXPORT shaderc_compilation_result_t shaderc_compile_into_preprocessed_te
// May be safely called from multiple threads without explicit synchronization.
// If there was failure in allocating the compiler object, null will be
// returned.
-SHADERC_EXPORT shaderc_compilation_result_t shaderc_assemble_into_spv(
+SHADERC_EXPORT shaderc_compilation_status shaderc_assemble_into_spv(
const shaderc_compiler_t compiler, const char* source_assembly,
size_t source_assembly_size,
- const shaderc_compile_options_t additional_options);
+ const shaderc_compile_options_t additional_options,
+ shaderc_compilation_result_t* result);
// The following functions, operating on shaderc_compilation_result_t objects,
// offer only the basic thread-safety guarantee.
diff --git a/libshaderc/include/shaderc/shaderc.hpp b/libshaderc/include/shaderc/shaderc.hpp
index 3817af8..5592b49 100644
--- a/libshaderc/include/shaderc/shaderc.hpp
@@ -202,119 +148,6 @@ index 3817af8..5592b49 100644
}
// Sets the compiler optimization level to the given level. Only the last one
@@ -425,9 +426,10 @@ class Compiler {
const char* input_file_name,
const char* entry_point_name,
const CompileOptions& options) const {
- shaderc_compilation_result_t compilation_result = shaderc_compile_into_spv(
+ shaderc_compilation_result_t compilation_result = nullptr;
+ shaderc_compile_into_spv(
compiler_, source_text, source_text_size, shader_kind, input_file_name,
- entry_point_name, options.options_);
+ entry_point_name, options.options_, &compilation_result);
return SpvCompilationResult(compilation_result);
}
@@ -451,9 +453,10 @@ class Compiler {
size_t source_text_size,
shaderc_shader_kind shader_kind,
const char* input_file_name) const {
- shaderc_compilation_result_t compilation_result =
- shaderc_compile_into_spv(compiler_, source_text, source_text_size,
- shader_kind, input_file_name, "main", nullptr);
+ shaderc_compilation_result_t compilation_result = nullptr;
+ shaderc_compile_into_spv(compiler_, source_text, source_text_size,
+ shader_kind, input_file_name, "main", nullptr,
+ &compilation_result);
return SpvCompilationResult(compilation_result);
}
@@ -504,8 +507,11 @@ class Compiler {
SpvCompilationResult AssembleToSpv(const char* source_assembly,
size_t source_assembly_size,
const CompileOptions& options) const {
- return SpvCompilationResult(shaderc_assemble_into_spv(
- compiler_, source_assembly, source_assembly_size, options.options_));
+ shaderc_compilation_result_t compilation_result = nullptr;
+ shaderc_assemble_into_spv(
+ compiler_, source_assembly, source_assembly_size, options.options_,
+ &compilation_result);
+ return SpvCompilationResult(compilation_result);
}
// Assembles the given SPIR-V assembly and returns a SPIR-V binary module
@@ -513,8 +519,11 @@ class Compiler {
// Like the first AssembleToSpv method but uses the default compiler options.
SpvCompilationResult AssembleToSpv(const char* source_assembly,
size_t source_assembly_size) const {
- return SpvCompilationResult(shaderc_assemble_into_spv(
- compiler_, source_assembly, source_assembly_size, nullptr));
+ shaderc_compilation_result_t compilation_result = nullptr;
+ shaderc_assemble_into_spv(
+ compiler_, source_assembly, source_assembly_size, nullptr,
+ &compilation_result);
+ return SpvCompilationResult(compilation_result);
}
// Assembles the given SPIR-V assembly and returns a SPIR-V binary module
@@ -523,9 +532,11 @@ class Compiler {
// std::string.
SpvCompilationResult AssembleToSpv(const std::string& source_assembly,
const CompileOptions& options) const {
- return SpvCompilationResult(
- shaderc_assemble_into_spv(compiler_, source_assembly.data(),
- source_assembly.size(), options.options_));
+ shaderc_compilation_result_t compilation_result = nullptr;
+ shaderc_assemble_into_spv(
+ compiler_, source_assembly.data(), source_assembly.size(),
+ options.options_, &compilation_result);
+ return SpvCompilationResult(compilation_result);
}
// Assembles the given SPIR-V assembly and returns a SPIR-V binary module
@@ -533,8 +544,10 @@ class Compiler {
// Like the first AssembleToSpv method but the source is provided as a
// std::string and also uses default compiler options.
SpvCompilationResult AssembleToSpv(const std::string& source_assembly) const {
- return SpvCompilationResult(shaderc_assemble_into_spv(
- compiler_, source_assembly.data(), source_assembly.size(), nullptr));
+ shaderc_compilation_result_t compilation_result = nullptr;
+ shaderc_assemble_into_spv(compiler_, source_assembly.data(),
+ source_assembly.size(), nullptr, &compilation_result);
+ return SpvCompilationResult(compilation_result);
}
// Compiles the given source GLSL and returns the SPIR-V assembly text
@@ -544,10 +557,11 @@ class Compiler {
const char* source_text, size_t source_text_size,
shaderc_shader_kind shader_kind, const char* input_file_name,
const char* entry_point_name, const CompileOptions& options) const {
- shaderc_compilation_result_t compilation_result =
- shaderc_compile_into_spv_assembly(
- compiler_, source_text, source_text_size, shader_kind,
- input_file_name, entry_point_name, options.options_);
+ shaderc_compilation_result_t compilation_result = nullptr;
+ shaderc_compile_into_spv_assembly(
+ compiler_, source_text, source_text_size, shader_kind,
+ input_file_name, entry_point_name, options.options_,
+ &compilation_result);
return AssemblyCompilationResult(compilation_result);
}
@@ -592,10 +606,10 @@ class Compiler {
const char* source_text, size_t source_text_size,
shaderc_shader_kind shader_kind, const char* input_file_name,
const CompileOptions& options) const {
- shaderc_compilation_result_t compilation_result =
- shaderc_compile_into_preprocessed_text(
+ shaderc_compilation_result_t compilation_result;
+ shaderc_compile_into_preprocessed_text(
compiler_, source_text, source_text_size, shader_kind,
- input_file_name, "main", options.options_);
+ input_file_name, "main", options.options_, &compilation_result);
return PreprocessedSourceCompilationResult(compilation_result);
}
diff --git a/libshaderc/src/shaderc.cc b/libshaderc/src/shaderc.cc
index 63f1bbc..c1a9b12 100644
--- a/libshaderc/src/shaderc.cc
@@ -334,146 +167,6 @@ index 63f1bbc..c1a9b12 100644
}
void shaderc_compile_options_set_optimization_level(
@@ -591,8 +595,31 @@ void shaderc_compiler_release(shaderc_compiler_t compiler) {
delete compiler;
}
+const char* shaderc_compilation_status_to_string(shaderc_compilation_status status)
+{
+ static constexpr const std::pair<shaderc_compilation_status, const char*> status_names[] = {
+ {shaderc_compilation_status_success, "shaderc_compilation_status_success"},
+ {shaderc_compilation_status_invalid_stage, "shaderc_compilation_status_invalid_stage"},
+ {shaderc_compilation_status_compilation_error, "shaderc_compilation_status_compilation_error"},
+ {shaderc_compilation_status_internal_error, "shaderc_compilation_status_internal_error"},
+ {shaderc_compilation_status_null_result_object, "shaderc_compilation_status_null_result_object"},
+ {shaderc_compilation_status_invalid_assembly, "shaderc_compilation_status_invalid_assembly"},
+ {shaderc_compilation_status_validation_error, "shaderc_compilation_status_validation_error"},
+ {shaderc_compilation_status_transformation_error, "shaderc_compilation_status_transformation_error"},
+ {shaderc_compilation_status_configuration_error, "shaderc_compilation_status_configuration_error"},
+ };
+
+ for (const auto& it : status_names)
+ {
+ if (status == it.first)
+ return it.second;
+ }
+
+ return "shaderc_compilation_status_unknown";
+}
+
namespace {
-shaderc_compilation_result_t CompileToSpecifiedOutputType(
+shaderc_compilation_result_vector* CompileToSpecifiedOutputType(
const shaderc_compiler_t compiler, const char* source_text,
size_t source_text_size, shaderc_shader_kind shader_kind,
const char* input_file_name, const char* entry_point_name,
@@ -669,48 +696,59 @@ shaderc_compilation_result_t CompileToSpecifiedOutputType(
}
} // anonymous namespace
-shaderc_compilation_result_t shaderc_compile_into_spv(
+shaderc_compilation_status shaderc_compile_into_spv(
const shaderc_compiler_t compiler, const char* source_text,
size_t source_text_size, shaderc_shader_kind shader_kind,
const char* input_file_name, const char* entry_point_name,
- const shaderc_compile_options_t additional_options) {
- return CompileToSpecifiedOutputType(
+ const shaderc_compile_options_t additional_options,
+ shaderc_compilation_result_t* result) {
+ shaderc_compilation_result_vector* resultv = CompileToSpecifiedOutputType(
compiler, source_text, source_text_size, shader_kind, input_file_name,
entry_point_name, additional_options,
shaderc_util::Compiler::OutputType::SpirvBinary);
+ *result = resultv;
+ return resultv ? resultv->compilation_status : shaderc_compilation_status_internal_error;
}
-shaderc_compilation_result_t shaderc_compile_into_spv_assembly(
+shaderc_compilation_status shaderc_compile_into_spv_assembly(
const shaderc_compiler_t compiler, const char* source_text,
size_t source_text_size, shaderc_shader_kind shader_kind,
const char* input_file_name, const char* entry_point_name,
- const shaderc_compile_options_t additional_options) {
- return CompileToSpecifiedOutputType(
+ const shaderc_compile_options_t additional_options,
+ shaderc_compilation_result_t* result) {
+ shaderc_compilation_result_vector* resultv = CompileToSpecifiedOutputType(
compiler, source_text, source_text_size, shader_kind, input_file_name,
entry_point_name, additional_options,
shaderc_util::Compiler::OutputType::SpirvAssemblyText);
+ *result = resultv;
+ return resultv ? resultv->compilation_status : shaderc_compilation_status_internal_error;
}
-shaderc_compilation_result_t shaderc_compile_into_preprocessed_text(
+shaderc_compilation_status shaderc_compile_into_preprocessed_text(
const shaderc_compiler_t compiler, const char* source_text,
size_t source_text_size, shaderc_shader_kind shader_kind,
const char* input_file_name, const char* entry_point_name,
- const shaderc_compile_options_t additional_options) {
- return CompileToSpecifiedOutputType(
+ const shaderc_compile_options_t additional_options,
+ shaderc_compilation_result_t* result) {
+ shaderc_compilation_result_vector* resultv = CompileToSpecifiedOutputType(
compiler, source_text, source_text_size, shader_kind, input_file_name,
entry_point_name, additional_options,
shaderc_util::Compiler::OutputType::PreprocessedText);
+ *result = resultv;
+ return resultv ? resultv->compilation_status : shaderc_compilation_status_internal_error;
}
-shaderc_compilation_result_t shaderc_assemble_into_spv(
+shaderc_compilation_status shaderc_assemble_into_spv(
const shaderc_compiler_t compiler, const char* source_assembly,
size_t source_assembly_size,
- const shaderc_compile_options_t additional_options) {
- auto* result = new (std::nothrow) shaderc_compilation_result_spv_binary;
- if (!result) return nullptr;
- result->compilation_status = shaderc_compilation_status_invalid_assembly;
- if (!compiler->initializer) return result;
- if (source_assembly == nullptr) return result;
+ const shaderc_compile_options_t additional_options,
+ shaderc_compilation_result_t* result) {
+ auto* bresult = new (std::nothrow) shaderc_compilation_result_spv_binary;
+ if (!bresult) return shaderc_compilation_status_internal_error;
+ bresult->compilation_status = shaderc_compilation_status_invalid_assembly;
+ *result = bresult;
+ if (!compiler->initializer) return bresult->compilation_status;
+ if (source_assembly == nullptr) return bresult->compilation_status;
TRY_IF_EXCEPTIONS_ENABLED {
spv_binary assembling_output_data = nullptr;
@@ -724,22 +762,22 @@ shaderc_compilation_result_t shaderc_assemble_into_spv(
GetCompilerTargetEnvVersion(target_env_version),
{source_assembly, source_assembly + source_assembly_size},
&assembling_output_data, &errors);
- result->num_errors = !assembling_succeeded;
+ bresult->num_errors = !assembling_succeeded;
if (assembling_succeeded) {
- result->SetOutputData(assembling_output_data);
- result->output_data_size =
+ bresult->SetOutputData(assembling_output_data);
+ bresult->output_data_size =
assembling_output_data->wordCount * sizeof(uint32_t);
- result->compilation_status = shaderc_compilation_status_success;
+ bresult->compilation_status = shaderc_compilation_status_success;
} else {
- result->messages = std::move(errors);
- result->compilation_status = shaderc_compilation_status_invalid_assembly;
+ bresult->messages = std::move(errors);
+ bresult->compilation_status = shaderc_compilation_status_invalid_assembly;
}
}
CATCH_IF_EXCEPTIONS_ENABLED(...) {
- result->compilation_status = shaderc_compilation_status_internal_error;
+ bresult->compilation_status = shaderc_compilation_status_internal_error;
}
- return result;
+ return bresult->compilation_status;
}
size_t shaderc_result_get_length(const shaderc_compilation_result_t result) {
diff --git a/libshaderc_util/include/libshaderc_util/compiler.h b/libshaderc_util/include/libshaderc_util/compiler.h
index d9d02b9..b076ec8 100644
--- a/libshaderc_util/include/libshaderc_util/compiler.h

View File

@@ -6,6 +6,9 @@ set -e
# While we use custom Qt builds for our releases, the Qt6 package will be good enough
# for just updating translations. Saves building it for this action alone.
"$SCRIPTDIR/../../../../tools/retry.sh" sudo apt-get -y install qt6-l10n-tools
"$SCRIPTDIR/../../../../tools/retry.sh" sudo apt-get -y install qt6-l10n-tools python3
"$SCRIPTDIR/../../../../tools/generate_fullscreen_ui_translation_strings.py"
"$SCRIPTDIR/../../../../pcsx2-qt/Translations/update_glyph_ranges.py"
"$SCRIPTDIR/../../../../tools/generate_update_fa_glyph_ranges.py"
PATH=/usr/lib/qt6/bin:$PATH "$SCRIPTDIR/../../../../pcsx2-qt/Translations/update_base_translation.sh"

View File

@@ -63,9 +63,9 @@ declare -a REMOVE_LIBS=(
set -e
LINUXDEPLOY=./linuxdeploy-x86_64
LINUXDEPLOY_PLUGIN_QT=./linuxdeploy-plugin-qt-x86_64
APPIMAGETOOL=./appimagetool-x86_64
LINUXDEPLOY=./linuxdeploy-x86_64.AppImage
LINUXDEPLOY_PLUGIN_QT=./linuxdeploy-plugin-qt-x86_64.AppImage
APPIMAGETOOL=./appimagetool-x86_64.AppImage
PATCHELF=patchelf
if [ ! -f "$LINUXDEPLOY" ]; then
@@ -78,11 +78,8 @@ if [ ! -f "$LINUXDEPLOY_PLUGIN_QT" ]; then
chmod +x "$LINUXDEPLOY_PLUGIN_QT"
fi
# Using go-appimage
# Backported from https://github.com/stenzek/duckstation/pull/3251
if [ ! -f "$APPIMAGETOOL" ]; then
APPIMAGETOOLURL=$(wget -q https://api.github.com/repos/probonopd/go-appimage/releases -O - | sed 's/[()",{} ]/\n/g' | grep -o 'https.*continuous.*tool.*86_64.*mage$' | head -1)
"$PCSX2DIR/tools/retry.sh" wget -O "$APPIMAGETOOL" "$APPIMAGETOOLURL"
"$PCSX2DIR/tools/retry.sh" wget -O "$APPIMAGETOOL" https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
chmod +x "$APPIMAGETOOL"
fi
@@ -190,28 +187,16 @@ echo "Generating AppStream metainfo..."
mkdir -p "$OUTDIR/usr/share/metainfo"
"$SCRIPTDIR/generate-metainfo.sh" "$OUTDIR/usr/share/metainfo/net.pcsx2.PCSX2.appdata.xml"
# Copy in AppRun hooks.
# Unfortunately linuxdeploy is a bit lame and doesn't let us provide our own AppRun hooks, instead
# they have to come from plugins.. and screw writing one of those just to disable Wayland.
echo "Copying AppRun hooks..."
mkdir -p "$OUTDIR/apprun-hooks"
for hookpath in "$SCRIPTDIR/apprun-hooks"/*; do
hookname=$(basename "$hookpath")
cp -v "$hookpath" "$OUTDIR/apprun-hooks/$hookname"
sed -i -e 's/exec /source "$this_dir"\/apprun-hooks\/"'"$hookname"'"\nexec /' "$OUTDIR/AppRun"
done
echo "Generating AppImage..."
GIT_VERSION=$(git tag --points-at HEAD)
if [[ "${GIT_VERSION}" == "" ]]; then
# In the odd event that we run this script before the release gets tagged.
GIT_VERSION=$(git describe --tags)
GIT_VERSION=$(git describe --tags || true)
if [[ "${GIT_VERSION}" == "" ]]; then
GIT_VERSION=$(git rev-parse HEAD)
fi
fi
rm -f "$NAME.AppImage"
ARCH=x86_64 VERSION="${GIT_VERSION}" "$APPIMAGETOOL" -s "$OUTDIR" && mv ./*.AppImage "$NAME.AppImage"
$APPIMAGETOOL -v "$OUTDIR" "$NAME.AppImage"

View File

@@ -1,9 +0,0 @@
if [[ -z "$I_WANT_A_BROKEN_WAYLAND_UI" ]]; then
echo "Forcing X11 instead of Wayland, due to various protocol limitations"
echo "and Qt issues. If you want to use Wayland, launch PCSX2 with"
echo "I_WANT_A_BROKEN_WAYLAND_UI=YES set."
export QT_QPA_PLATFORM=xcb
else
echo "Wayland is not being disabled. Do not complain when things break."
fi

View File

@@ -15,13 +15,14 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then
fi
LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075
LIBJPEG=9f
LIBPNG=1.6.43
LIBWEBP=1.4.0
LIBJPEGTURBO=3.1.0
LIBPNG=1.6.45
LIBWEBP=1.5.0
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
SDL=SDL2-2.30.6
QT=6.7.2
ZSTD=1.5.6
SDL=SDL3-3.2.8
QT=6.8.2
ZSTD=1.5.7
KDDOCKWIDGETS=2.2.1
SHADERC=2024.1
SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
@@ -33,27 +34,28 @@ cd deps-build
cat > SHASUMS <<EOF
fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.zip
04705c110cb2469caa79fb71fba3d7bf834914706e9641a4589485c1f832565b jpegsrc.v$LIBJPEG.tar.gz
6a5ca0652392a2d7c9db2ae5b40210843c0bbc081cbd410825ab00cc59f14a6c libpng-$LIBPNG.tar.xz
61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 libwebp-$LIBWEBP.tar.gz
9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
c6ef64ca18a19d13df6eb22df9aff19fb0db65610a74cc81dae33a82235cacd4 $SDL.tar.gz
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
c5f22a5e10fb162895ded7de0963328e7307611c688487b5d152c9ee64767599 qtbase-everywhere-src-$QT.tar.xz
e1a1d8785fae67d16ad0a443b01d5f32663a6b68d275f1806ebab257485ce5d6 qtimageformats-everywhere-src-$QT.tar.xz
fb0d1286a35be3583fee34aeb5843c94719e07193bdf1d4d8b0dc14009caef01 qtsvg-everywhere-src-$QT.tar.xz
58e855ad1b2533094726c8a425766b63a04a0eede2ed85086860e54593aa4b2a qttools-everywhere-src-$QT.tar.xz
9845780b5dc1b7279d57836db51aeaf2e4a1160c42be09750616f39157582ca9 qttranslations-everywhere-src-$QT.tar.xz
a2a057e1dd644bd44abb9990fecc194b2e25c2e0f39e81aa9fee4c1e5e2a8a5b qtwayland-everywhere-src-$QT.tar.xz
13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03 $SDL.tar.gz
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
012043ce6d411e6e8a91fdc4e05e6bedcfa10fcb1347d3c33908f7fdd10dfe05 qtbase-everywhere-src-$QT.tar.xz
d2a1bbb84707b8a0aec29227b170be00f04383fbf2361943596d09e7e443c8e1 qtimageformats-everywhere-src-$QT.tar.xz
aa2579f21ca66d19cbcf31d87e9067e07932635d36869c8239d4decd0a9dc1fa qtsvg-everywhere-src-$QT.tar.xz
326381b7d43f07913612f291abc298ae79bd95382e2233abce982cff2b53d2c0 qttools-everywhere-src-$QT.tar.xz
d2106e8a580bfd77702c4c1840299288d344902b0e2c758ca813ea04c6d6a3d1 qttranslations-everywhere-src-$QT.tar.xz
5e46157908295f2bf924462d8c0855b0508ba338ced9e810891fefa295dc9647 qtwayland-everywhere-src-$QT.tar.xz
eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADERC.tar.gz
aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz
5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
03ee1a2c06f3b61008478f4abe9423454e53e580b9488b47c8071547c6a9db47 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
8693e06abee0c88517d8480b22647702a51a0708f3c876ed5385d9a4e356e1a5 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
EOF
curl -C - -L \
curl -L \
-O "https://github.com/ianlancetaylor/libbacktrace/archive/$LIBBACKTRACE.zip" \
-O "https://ijg.org/files/jpegsrc.v$LIBJPEG.tar.gz" \
-O "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$LIBJPEGTURBO/libjpeg-turbo-$LIBJPEGTURBO.tar.gz" \
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
-O "https://github.com/lz4/lz4/archive/$LZ4.tar.gz" \
@@ -68,7 +70,8 @@ curl -C - -L \
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz"
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz" \
-o "KDDockWidgets-$KDDOCKWIDGETS.tar.gz" "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS.tar.gz"
shasum -a 256 --check SHASUMS
@@ -90,16 +93,14 @@ cmake --build build --parallel
ninja -C build install
cd ..
echo "Building libjpeg..."
rm -fr "jpeg-$LIBJPEG"
tar xf "jpegsrc.v$LIBJPEG.tar.gz"
cd "jpeg-$LIBJPEG"
mkdir build
cd build
../configure --prefix="$INSTALLDIR" --disable-static --enable-shared
make "-j$NPROCS"
make install
cd ../..
echo "Building libjpegturbo..."
rm -fr "libjpeg-turbo-$LIBJPEGTURBO"
tar xf "libjpeg-turbo-$LIBJPEGTURBO.tar.gz"
cd "libjpeg-turbo-$LIBJPEGTURBO"
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build -G Ninja
cmake --build build --parallel
ninja -C build install
cd ..
echo "Building LZ4..."
rm -fr "lz4-$LZ4"
@@ -150,7 +151,7 @@ tar xf "qtbase-everywhere-src-$QT.tar.xz"
cd "qtbase-everywhere-src-$QT"
mkdir build
cd build
../configure -prefix "$INSTALLDIR" -release -dbus-linked -gui -widgets -fontconfig -qt-doubleconversion -ssl -openssl-runtime -opengl desktop -qpa xcb,wayland -xkbcommon -xcb -gtk -- -DFEATURE_dbus=ON -DFEATURE_icu=OFF -DFEATURE_sql=OFF -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON
../configure -prefix "$INSTALLDIR" -release -dbus-linked -gui -widgets -fontconfig -qt-doubleconversion -ssl -openssl-runtime -opengl desktop -qpa xcb,wayland -xkbcommon -xcb -gtk -- -DFEATURE_dbus=ON -DFEATURE_icu=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON
cmake --build . --parallel
ninja install
cd ../../
@@ -233,6 +234,16 @@ cmake --build . --parallel
ninja install
cd ../../
echo "Building KDDockWidgets..."
rm -fr "KDDockWidgets-$KDDOCKWIDGETS"
tar xf "KDDockWidgets-$KDDOCKWIDGETS.tar.gz"
cd "KDDockWidgets-$KDDOCKWIDGETS"
patch -p1 < "$SCRIPTDIR/../common/kddockwidgets-dodgy-include.patch"
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build -G Ninja
cmake --build build --parallel
ninja -C build install
cd ..
echo "Building shaderc..."
rm -fr "shaderc-$SHADERC"
tar xf "shaderc-$SHADERC.tar.gz"

View File

@@ -8,8 +8,8 @@
{
"type": "git",
"url": "https://github.com/the-tcpdump-group/libpcap.git",
"tag": "libpcap-1.10.4",
"commit": "104271ba4a14de6743e43bcf87536786d8fddea4"
"tag": "libpcap-1.10.5",
"commit": "bbcbc9174df3298a854daee2b3e666a4b6e5383a"
}
],
"cleanup": [

View File

@@ -1,5 +1,5 @@
{
"name": "sdl2",
"name": "sdl3",
"buildsystem": "cmake-ninja",
"builddir": true,
"config-opts": [
@@ -14,8 +14,8 @@
"sources": [
{
"type": "archive",
"url": "https://libsdl.org/release/SDL2-2.30.6.tar.gz",
"sha256": "c6ef64ca18a19d13df6eb22df9aff19fb0db65610a74cc81dae33a82235cacd4"
"url": "https://libsdl.org/release/SDL3-3.2.8.tar.gz",
"sha256": "13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03"
}
],
"cleanup": [

View File

@@ -0,0 +1,32 @@
{
"name": "kddockwidgets",
"buildsystem": "cmake-ninja",
"builddir": true,
"config-opts": [
"-DKDDockWidgets_QT6=true",
"-DKDDockWidgets_EXAMPLES=false",
"-DKDDockWidgets_FRONTENDS=qtwidgets"
],
"build-options": {
"strip": true
},
"sources": [
{
"type": "git",
"url": "https://github.com/KDAB/KDDockWidgets.git",
"tag": "v2.2.1",
"commit": "3aaccddc00a11a643e0959a24677838993de15ac",
"disable-submodules": true
},
{
"type": "patch",
"path": "../../../common/kddockwidgets-dodgy-include.patch"
}
],
"cleanup": [
"/share/doc/KDDockWidgets-qt6",
"/mkspecs/modules/qt_KDDockWidgets.pri",
"/lib/cmake",
"/include"
]
}

View File

@@ -1,15 +1,15 @@
{
"app-id": "net.pcsx2.PCSX2",
"runtime": "org.kde.Platform",
"runtime-version": "6.7",
"runtime-version": "6.8",
"sdk": "org.kde.Sdk",
"sdk-extensions": [
"org.freedesktop.Sdk.Extension.llvm17"
"org.freedesktop.Sdk.Extension.llvm18"
],
"add-extensions": {
"org.freedesktop.Platform.ffmpeg-full": {
"directory": "lib/ffmpeg",
"version": "23.08",
"version": "24.08",
"add-ld-path": ".",
"autodownload": true
}
@@ -19,16 +19,17 @@
"--device=all",
"--share=network",
"--share=ipc",
"--socket=x11",
"--socket=wayland",
"--socket=fallback-x11",
"--socket=pulseaudio",
"--talk-name=org.freedesktop.ScreenSaver",
"--env=QT_QPA_PLATFORM=xcb"
"--talk-name=org.freedesktop.ScreenSaver"
],
"modules": [
"modules/10-libpcap.json",
"modules/20-sdl2.json",
"modules/20-sdl3.json",
"modules/21-libbacktrace.json",
"modules/22-shaderc.json",
"modules/23-kddockwidgets.json",
{
"name": "pcsx2",
"buildsystem": "cmake-ninja",
@@ -44,8 +45,8 @@
"config-opts": [
"-DCMAKE_BUILD_TYPE=Release",
"-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON",
"-DCMAKE_C_COMPILER=/usr/lib/sdk/llvm17/bin/clang",
"-DCMAKE_CXX_COMPILER=/usr/lib/sdk/llvm17/bin/clang++",
"-DCMAKE_C_COMPILER=/usr/lib/sdk/llvm18/bin/clang",
"-DCMAKE_CXX_COMPILER=/usr/lib/sdk/llvm18/bin/clang++",
"-DCMAKE_EXE_LINKER_FLAGS_INIT=-fuse-ld=lld",
"-DCMAKE_MODULE_LINKER_FLAGS_INIT=-fuse-ld=lld",
"-DCMAKE_SHARED_LINKER_FLAGS_INIT=-fuse-ld=lld",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@@ -6,17 +6,21 @@
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0+</project_license>
<name>PCSX2</name>
<developer_name>PCSX2</developer_name>
<summary>PlayStation 2 Emulator</summary>
<developer id="net.pcsx2">
<name>PCSX2 Team</name>
</developer>
<summary>PlayStation 2 emulator</summary>
<description>
<p>PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to emulate the PS2's hardware, using a combination of MIPS CPU Interpreters, Recompilers, and a Virtual Machine which manages hardware states and PS2 system memory. This allows you to play PS2 games on your PC, with many additional features and benefits.</p>
<p>PlayStation 2 and PS2 are registered trademarks of Sony Interactive Entertainment. This application is not affiliated in any way with Sony Interactive Entertainment.</p>
</description>
<url type="homepage">https://pcsx2.net/</url>
<url type="vcs-browser">https://github.com/PCSX2/pcsx2</url>
<url type="bugtracker">https://github.com/PCSX2/pcsx2/issues</url>
<url type="donation">https://github.com/sponsors/PCSX2</url>
<url type="faq">https://pcsx2.net/docs/</url>
<url type="help">https://pcsx2.net/discord</url>
<url type="contribute">https://github.com/PCSX2/pcsx2/blob/master/.github/CONTRIBUTING.md</url>
<url type="translate">https://crowdin.com/project/pcsx2-emulator</url>
<url type="contact">https://mastodon.social/@PCSX2</url>
<screenshots>
@@ -37,6 +41,26 @@
</caption>
</screenshot>
</screenshots>
<categories>
<category>Game</category>
<category>Emulator</category>
</categories>
<branding>
<color type="primary" scheme_preference="light">#3584e4</color>
<color type="primary" scheme_preference="dark">#241f31</color>
</branding>
<supports>
<control>keyboard</control>
<control>pointing</control>
<internet>offline-only</internet>
</supports>
<recommends>
<control>gamepad</control>
<memory>8192</memory>
</recommends>
<requires>
<display_length compare="ge">768</display_length>
</requires>
<content_rating type="oars-1.1"/>
<update_contact>pcsx2_AT_pcsx2.net</update_contact>
<releases>

View File

@@ -38,17 +38,18 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then
INSTALLDIR="$PWD/$INSTALLDIR"
fi
FREETYPE=2.13.2
HARFBUZZ=8.3.1
SDL=SDL2-2.30.3
ZSTD=1.5.5
FREETYPE=2.13.3
HARFBUZZ=10.0.1
SDL=SDL3-3.2.8
ZSTD=1.5.7
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
LIBPNG=1.6.43
LIBJPEG=9f
LIBWEBP=1.3.2
LIBPNG=1.6.45
LIBJPEGTURBO=3.1.0
LIBWEBP=1.5.0
FFMPEG=6.0
MOLTENVK=1.2.8
QT=6.7.1
MOLTENVK=1.2.9
QT=6.7.3
KDDOCKWIDGETS=2.2.1
SHADERC=2024.1
SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
@@ -74,25 +75,26 @@ CMAKE_ARCH_ARM64=-DCMAKE_OSX_ARCHITECTURES="arm64"
CMAKE_ARCH_UNIVERSAL=-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
cat > SHASUMS <<EOF
12991c4e55c506dd7f9b765933e62fd2be2e06d421505d7950a132e4f1bb484d freetype-$FREETYPE.tar.xz
19a54fe9596f7a47c502549fce8e8a10978c697203774008cc173f8360b19a9a harfbuzz-$HARFBUZZ.tar.gz
820440072f8f5b50188c1dae104f2ad25984de268785be40c41a099a510f0aec $SDL.tar.gz
9c4396cc829cfae319a6e2615202e82aad41372073482fce286fac78646d3ee4 zstd-$ZSTD.tar.gz
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03 $SDL.tar.gz
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
6a5ca0652392a2d7c9db2ae5b40210843c0bbc081cbd410825ab00cc59f14a6c libpng-$LIBPNG.tar.xz
2a499607df669e40258e53d0ade8035ba4ec0175244869d1025d460562aa09b4 libwebp-$LIBWEBP.tar.gz
04705c110cb2469caa79fb71fba3d7bf834914706e9641a4589485c1f832565b jpegsrc.v$LIBJPEG.tar.gz
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082 ffmpeg-$FFMPEG.tar.xz
85beaf8abfcc54d9da0ff0257ae311abd9e7aa96e53da37e1c37d6bc04ac83cd v$MOLTENVK.tar.gz
b7338da1bdccb4d861e714efffaa83f174dfe37e194916bfd7ec82279a6ace19 qtbase-everywhere-src-$QT.tar.xz
a733b98f771064d000476b8861f822143982749448ba8abf9f1813edb8dfe79f qtimageformats-everywhere-src-$QT.tar.xz
3ed5b80f7228c41dd463b7a57284ed273d224d1c323c0dd78c5209635807cbce qtsvg-everywhere-src-$QT.tar.xz
0953cddf6248f3959279a10904892e8a98eb3e463d729a174b6fc47febd99824 qttools-everywhere-src-$QT.tar.xz
03d71565872b0e0e7303349071df031ab0f922f6dbdd3a5ec1ade9e188e4fbf4 qttranslations-everywhere-src-$QT.tar.xz
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz
8ccbb9ab055205ac76632c9eeddd1ed6fc66936fc56afc2ed0fd5d9e23da3097 qtbase-everywhere-src-$QT.tar.xz
9fd58144081654c3373768dd96ead294023830927b14fe3d3c1ef641fb324753 qtimageformats-everywhere-src-$QT.tar.xz
40142cb71fb1e07ad612bc361b67f5d54cd9367f9979ae6b86124a064deda06b qtsvg-everywhere-src-$QT.tar.xz
f03bb7df619cd9ac9dba110e30b7bcab5dd88eb8bdc9cc752563b4367233203f qttools-everywhere-src-$QT.tar.xz
dcc762acac043b9bb5e4d369b6d6f53e0ecfcf76a408fe0db5f7ef071c9d6dc8 qttranslations-everywhere-src-$QT.tar.xz
eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADERC.tar.gz
aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz
5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
03ee1a2c06f3b61008478f4abe9423454e53e580b9488b47c8071547c6a9db47 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
8693e06abee0c88517d8480b22647702a51a0708f3c876ed5385d9a4e356e1a5 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
EOF
curl -C - -L \
@@ -102,7 +104,7 @@ curl -C - -L \
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
-O "https://github.com/lz4/lz4/archive/$LZ4.tar.gz" \
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
-O "https://ijg.org/files/jpegsrc.v$LIBJPEG.tar.gz" \
-O "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$LIBJPEGTURBO/libjpeg-turbo-$LIBJPEGTURBO.tar.gz" \
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
-O "https://github.com/KhronosGroup/MoltenVK/archive/refs/tags/v$MOLTENVK.tar.gz" \
@@ -114,7 +116,8 @@ curl -C - -L \
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz"
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz" \
-o "KDDockWidgets-$KDDOCKWIDGETS.tar.gz" "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS.tar.gz"
shasum -a 256 --check SHASUMS
@@ -200,21 +203,12 @@ merge_binaries $(realpath build) $(realpath build-arm64)
make -C build install
cd ..
echo "Installing libjpeg..."
rm -fr "jpeg-$LIBJPEG"
tar xf "jpegsrc.v$LIBJPEG.tar.gz"
cd "jpeg-$LIBJPEG"
mkdir build
cd build
../configure --prefix="$INSTALLDIR" --disable-static --enable-shared --host="x86_64-apple-darwin" CFLAGS="-arch x86_64"
make "-j$NPROCS"
cd ..
mkdir build-arm64
cd build-arm64
../configure --prefix="$INSTALLDIR" --disable-static --enable-shared --host="aarch64-apple-darwin" CFLAGS="-arch arm64"
make "-j$NPROCS"
cd ..
merge_binaries $(realpath build) $(realpath build-arm64)
echo "Installing libjpegturbo..."
rm -fr "libjpeg-turbo-$LIBJPEGTURBO"
tar xf "libjpeg-turbo-$LIBJPEGTURBO.tar.gz"
cd "libjpeg-turbo-$LIBJPEGTURBO"
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_ARM64" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build-arm64
make -C build "-j$NPROCS"
make -C build install
cd ..
@@ -330,20 +324,6 @@ echo "Installing Qt Tools..."
rm -fr "qttools-everywhere-src-$QT"
tar xf "qttools-everywhere-src-$QT.tar.xz"
cd "qttools-everywhere-src-$QT"
# Linguist relies on a library in the Designer target, which takes 5-7 minutes to build on the CI
# Avoid it by not building Linguist, since we only need the tools that come with it
patch -u src/linguist/CMakeLists.txt <<EOF
--- src/linguist/CMakeLists.txt
+++ src/linguist/CMakeLists.txt
@@ -14,7 +14,7 @@
add_subdirectory(lrelease-pro)
add_subdirectory(lupdate)
add_subdirectory(lupdate-pro)
-if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton AND TARGET Qt::Widgets AND NOT no-png)
+if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton AND TARGET Qt::Widgets AND TARGET Qt::PrintSupport AND NOT no-png)
add_subdirectory(linguist)
endif()
EOF
mkdir build
cd build
"$INSTALLDIR/bin/qt-configure-module" .. -- "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
@@ -380,6 +360,16 @@ make "-j$NPROCS"
make install
cd ../..
echo "Building KDDockWidgets..."
rm -fr "KDDockWidgets-$KDDOCKWIDGETS"
tar xf "KDDockWidgets-$KDDOCKWIDGETS.tar.gz"
cd "KDDockWidgets-$KDDOCKWIDGETS"
patch -p1 < "$SCRIPTDIR/../common/kddockwidgets-dodgy-include.patch"
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_UNIVERSAL" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build
cmake --build build --parallel
cmake --install build
cd ..
echo "Cleaning up..."
cd ..
rm -rf deps-build

View File

@@ -20,17 +20,18 @@ if [ "${INSTALLDIR:0:1}" != "/" ]; then
INSTALLDIR="$PWD/$INSTALLDIR"
fi
FREETYPE=2.13.2
HARFBUZZ=8.3.1
SDL=SDL2-2.30.6
ZSTD=1.5.6
FREETYPE=2.13.3
HARFBUZZ=10.0.1
SDL=SDL3-3.2.8
ZSTD=1.5.7
LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
LIBPNG=1.6.43
LIBJPEG=9f
LIBWEBP=1.4.0
LIBPNG=1.6.45
LIBJPEGTURBO=3.1.0
LIBWEBP=1.5.0
FFMPEG=6.0
MOLTENVK=1.2.9
QT=6.7.2
QT=6.7.3
KDDOCKWIDGETS=2.2.1
SHADERC=2024.1
SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
@@ -54,25 +55,26 @@ CMAKE_COMMON=(
)
cat > SHASUMS <<EOF
12991c4e55c506dd7f9b765933e62fd2be2e06d421505d7950a132e4f1bb484d freetype-$FREETYPE.tar.xz
19a54fe9596f7a47c502549fce8e8a10978c697203774008cc173f8360b19a9a harfbuzz-$HARFBUZZ.tar.gz
c6ef64ca18a19d13df6eb22df9aff19fb0db65610a74cc81dae33a82235cacd4 $SDL.tar.gz
8c29e06cf42aacc1eafc4077ae2ec6c6fcb96a626157e0593d5e82a34fd403c1 zstd-$ZSTD.tar.gz
0550350666d427c74daeb85d5ac7bb353acba5f76956395995311a9c6f063289 freetype-$FREETYPE.tar.xz
e7358ea86fe10fb9261931af6f010d4358dac64f7074420ca9bc94aae2bdd542 harfbuzz-$HARFBUZZ.tar.gz
13388fabb361de768ecdf2b65e52bb27d1054cae6ccb6942ba926e378e00db03 $SDL.tar.gz
eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 zstd-$ZSTD.tar.gz
0728800155f3ed0a0c87e03addbd30ecbe374f7b080678bbca1506051d50dec3 $LZ4.tar.gz
6a5ca0652392a2d7c9db2ae5b40210843c0bbc081cbd410825ab00cc59f14a6c libpng-$LIBPNG.tar.xz
61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 libwebp-$LIBWEBP.tar.gz
04705c110cb2469caa79fb71fba3d7bf834914706e9641a4589485c1f832565b jpegsrc.v$LIBJPEG.tar.gz
926485350139ffb51ef69760db35f78846c805fef3d59bfdcb2fba704663f370 libpng-$LIBPNG.tar.xz
7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c libwebp-$LIBWEBP.tar.gz
9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 libjpeg-turbo-$LIBJPEGTURBO.tar.gz
57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082 ffmpeg-$FFMPEG.tar.xz
f415a09385030c6510a936155ce211f617c31506db5fbc563e804345f1ecf56e v$MOLTENVK.tar.gz
c5f22a5e10fb162895ded7de0963328e7307611c688487b5d152c9ee64767599 qtbase-everywhere-src-$QT.tar.xz
e1a1d8785fae67d16ad0a443b01d5f32663a6b68d275f1806ebab257485ce5d6 qtimageformats-everywhere-src-$QT.tar.xz
fb0d1286a35be3583fee34aeb5843c94719e07193bdf1d4d8b0dc14009caef01 qtsvg-everywhere-src-$QT.tar.xz
58e855ad1b2533094726c8a425766b63a04a0eede2ed85086860e54593aa4b2a qttools-everywhere-src-$QT.tar.xz
9845780b5dc1b7279d57836db51aeaf2e4a1160c42be09750616f39157582ca9 qttranslations-everywhere-src-$QT.tar.xz
8ccbb9ab055205ac76632c9eeddd1ed6fc66936fc56afc2ed0fd5d9e23da3097 qtbase-everywhere-src-$QT.tar.xz
9fd58144081654c3373768dd96ead294023830927b14fe3d3c1ef641fb324753 qtimageformats-everywhere-src-$QT.tar.xz
40142cb71fb1e07ad612bc361b67f5d54cd9367f9979ae6b86124a064deda06b qtsvg-everywhere-src-$QT.tar.xz
f03bb7df619cd9ac9dba110e30b7bcab5dd88eb8bdc9cc752563b4367233203f qttools-everywhere-src-$QT.tar.xz
dcc762acac043b9bb5e4d369b6d6f53e0ecfcf76a408fe0db5f7ef071c9d6dc8 qttranslations-everywhere-src-$QT.tar.xz
eb3b5f0c16313d34f208d90c2fa1e588a23283eed63b101edd5422be6165d528 shaderc-$SHADERC.tar.gz
aa27e4454ce631c5a17924ce0624eac736da19fc6f5a2ab15a6c58da7b36950f shaderc-glslang-$SHADERC_GLSLANG.tar.gz
5d866ce34a4b6908e262e5ebfffc0a5e11dd411640b5f24c85a80ad44c0d4697 shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz
03ee1a2c06f3b61008478f4abe9423454e53e580b9488b47c8071547c6a9db47 shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz
8693e06abee0c88517d8480b22647702a51a0708f3c876ed5385d9a4e356e1a5 KDDockWidgets-$KDDOCKWIDGETS.tar.gz
EOF
curl -L \
@@ -82,7 +84,7 @@ curl -L \
-O "https://github.com/facebook/zstd/releases/download/v$ZSTD/zstd-$ZSTD.tar.gz" \
-O "https://github.com/lz4/lz4/archive/$LZ4.tar.gz" \
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$LIBPNG/libpng-$LIBPNG.tar.xz" \
-O "https://ijg.org/files/jpegsrc.v$LIBJPEG.tar.gz" \
-O "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/$LIBJPEGTURBO/libjpeg-turbo-$LIBJPEGTURBO.tar.gz" \
-O "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-$LIBWEBP.tar.gz" \
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
-O "https://github.com/KhronosGroup/MoltenVK/archive/refs/tags/v$MOLTENVK.tar.gz" \
@@ -94,7 +96,8 @@ curl -L \
-o "shaderc-$SHADERC.tar.gz" "https://github.com/google/shaderc/archive/refs/tags/v$SHADERC.tar.gz" \
-o "shaderc-glslang-$SHADERC_GLSLANG.tar.gz" "https://github.com/KhronosGroup/glslang/archive/$SHADERC_GLSLANG.tar.gz" \
-o "shaderc-spirv-headers-$SHADERC_SPIRVHEADERS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Headers/archive/$SHADERC_SPIRVHEADERS.tar.gz" \
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz"
-o "shaderc-spirv-tools-$SHADERC_SPIRVTOOLS.tar.gz" "https://github.com/KhronosGroup/SPIRV-Tools/archive/$SHADERC_SPIRVTOOLS.tar.gz" \
-o "KDDockWidgets-$KDDOCKWIDGETS.tar.gz" "https://github.com/KDAB/KDDockWidgets/archive/v$KDDOCKWIDGETS.tar.gz"
shasum -a 256 --check SHASUMS
@@ -153,16 +156,14 @@ make -C build "-j$NPROCS"
make -C build install
cd ..
echo "Installing libjpeg..."
rm -fr "jpeg-$LIBJPEG"
tar xf "jpegsrc.v$LIBJPEG.tar.gz"
cd "jpeg-$LIBJPEG"
mkdir build
cd build
../configure --prefix="$INSTALLDIR" --disable-static --enable-shared --host="x86_64-apple-darwin" CFLAGS="-arch x86_64"
make "-j$NPROCS"
make install
cd ../..
echo "Installing libjpegturbo..."
rm -fr "libjpeg-turbo-$LIBJPEGTURBO"
tar xf "libjpeg-turbo-$LIBJPEGTURBO.tar.gz"
cd "libjpeg-turbo-$LIBJPEGTURBO"
cmake "${CMAKE_COMMON[@]}" "$CMAKE_ARCH_X64" -DENABLE_STATIC=OFF -DENABLE_SHARED=ON -B build
make -C build "-j$NPROCS"
make -C build install
cd ..
echo "Installing WebP..."
rm -fr "libwebp-$LIBWEBP"
@@ -180,8 +181,8 @@ rm -fr "freetype-$FREETYPE"
tar xf "freetype-$FREETYPE.tar.xz"
cd "freetype-$FREETYPE"
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -DFT_REQUIRE_ZLIB=ON -DFT_REQUIRE_PNG=ON -DFT_DISABLE_BZIP2=TRUE -DFT_DISABLE_BROTLI=TRUE -DFT_DISABLE_HARFBUZZ=TRUE -B build
cmake --build build --parallel
cmake --install build
make -C build "-j$NPROCS"
make -C build install
cd ..
echo "Building HarfBuzz..."
@@ -189,8 +190,8 @@ rm -fr "harfbuzz-$HARFBUZZ"
tar xf "harfbuzz-$HARFBUZZ.tar.gz"
cd "harfbuzz-$HARFBUZZ"
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -DHB_BUILD_UTILS=OFF -B build
cmake --build build --parallel
cmake --install build
make -C build "-j$NPROCS"
make -C build install
cd ..
echo "Building FreeType with HarfBuzz..."
@@ -198,8 +199,8 @@ rm -fr "freetype-$FREETYPE"
tar xf "freetype-$FREETYPE.tar.xz"
cd "freetype-$FREETYPE"
cmake "${CMAKE_COMMON[@]}" -DBUILD_SHARED_LIBS=ON -DFT_REQUIRE_ZLIB=ON -DFT_REQUIRE_PNG=ON -DFT_DISABLE_BZIP2=TRUE -DFT_DISABLE_BROTLI=TRUE -DFT_REQUIRE_HARFBUZZ=TRUE -B build
cmake --build build --parallel
cmake --install build
make -C build "-j$NPROCS"
make -C build install
cd ..
# MoltenVK already builds universal binaries, nothing special to do here.
@@ -324,6 +325,16 @@ make "-j$NPROCS"
make install
cd ../..
echo "Building KDDockWidgets..."
rm -fr "KDDockWidgets-$KDDOCKWIDGETS"
tar xf "KDDockWidgets-$KDDOCKWIDGETS.tar.gz"
cd "KDDockWidgets-$KDDOCKWIDGETS"
patch -p1 < "$SCRIPTDIR/../common/kddockwidgets-dodgy-include.patch"
cmake "${CMAKE_COMMON[@]}" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build
make -C build "-j$NPROCS"
make -C build install
cd ..
echo "Cleaning up..."
cd ..
rm -rf deps-build

View File

@@ -10,8 +10,8 @@
"license": "ISC",
"dependencies": {
"@octokit/plugin-retry": "^3.0.9",
"@octokit/plugin-throttling": "^3.5.2",
"@octokit/rest": "^18.12.0",
"@octokit/plugin-throttling": "^9.4.0",
"@octokit/rest": "^21.1.1",
"discord.js": "^13.2.0"
}
},
@@ -61,45 +61,102 @@
}
},
"node_modules/@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"dependencies": {
"@octokit/types": "^6.0.3"
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz",
"integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==",
"license": "MIT",
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/core": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz",
"integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==",
"license": "MIT",
"dependencies": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.0",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
"@octokit/auth-token": "^5.0.0",
"@octokit/graphql": "^8.1.2",
"@octokit/request": "^9.2.1",
"@octokit/request-error": "^6.1.7",
"@octokit/types": "^13.6.2",
"before-after-hook": "^3.0.2",
"universal-user-agent": "^7.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/core/node_modules/@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
"license": "MIT"
},
"node_modules/@octokit/core/node_modules/@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^23.0.1"
}
},
"node_modules/@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"version": "10.1.3",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz",
"integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
"@octokit/types": "^13.6.2",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/endpoint/node_modules/@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
"license": "MIT"
},
"node_modules/@octokit/endpoint/node_modules/@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^23.0.1"
}
},
"node_modules/@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz",
"integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==",
"license": "MIT",
"dependencies": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
"@octokit/request": "^9.2.2",
"@octokit/types": "^13.8.0",
"universal-user-agent": "^7.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/graphql/node_modules/@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
"license": "MIT"
},
"node_modules/@octokit/graphql/node_modules/@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^23.0.1"
}
},
"node_modules/@octokit/openapi-types": {
@@ -108,28 +165,75 @@
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "2.16.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
"version": "11.4.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.2.tgz",
"integrity": "sha512-BXJ7XPCTDXFF+wxcg/zscfgw2O/iDPtNSkwwR1W1W5c4Mb3zav/M2XvxQ23nVmKj7jpweB4g8viMeCQdm7LMVA==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^6.33.0"
"@octokit/types": "^13.7.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": ">=6"
}
},
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
"license": "MIT"
},
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^23.0.1"
}
},
"node_modules/@octokit/plugin-request-log": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-5.3.1.tgz",
"integrity": "sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==",
"license": "MIT",
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": ">=3"
"@octokit/core": ">=6"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "5.12.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
"version": "13.3.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.1.tgz",
"integrity": "sha512-o8uOBdsyR+WR8MK9Cco8dCgvG13H1RlM1nWnK/W7TEACQBFux/vPREgKucxUfuDQ5yi1T3hGf4C5ZmZXAERgwQ==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^6.33.0",
"deprecation": "^2.3.1"
"@octokit/types": "^13.8.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": ">=6"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
"license": "MIT"
},
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^23.0.1"
}
},
"node_modules/@octokit/plugin-retry": {
@@ -142,49 +246,107 @@
}
},
"node_modules/@octokit/plugin-throttling": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.7.0.tgz",
"integrity": "sha512-qrKT1Yl/KuwGSC6/oHpLBot3ooC9rq0/ryDYBCpkRtoj+R8T47xTMDT6Tk2CxWopFota/8Pi/2SqArqwC0JPow==",
"version": "9.4.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.4.0.tgz",
"integrity": "sha512-IOlXxXhZA4Z3m0EEYtrrACkuHiArHLZ3CvqWwOez/pURNqRuwfoFlTPbN5Muf28pzFuztxPyiUiNwz8KctdZaQ==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^6.0.1",
"@octokit/types": "^13.7.0",
"bottleneck": "^2.15.3"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": "^3.5.0"
"@octokit/core": "^6.1.3"
}
},
"node_modules/@octokit/plugin-throttling/node_modules/@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
"license": "MIT"
},
"node_modules/@octokit/plugin-throttling/node_modules/@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^23.0.1"
}
},
"node_modules/@octokit/request": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
"integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
"license": "MIT",
"dependencies": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.1",
"universal-user-agent": "^6.0.0"
"@octokit/endpoint": "^10.1.3",
"@octokit/request-error": "^6.1.7",
"@octokit/types": "^13.6.2",
"fast-content-type-parse": "^2.0.0",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"version": "6.1.7",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
"integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
"@octokit/types": "^13.6.2"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/request-error/node_modules/@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
"license": "MIT"
},
"node_modules/@octokit/request-error/node_modules/@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^23.0.1"
}
},
"node_modules/@octokit/request/node_modules/@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
"license": "MIT"
},
"node_modules/@octokit/request/node_modules/@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^23.0.1"
}
},
"node_modules/@octokit/rest": {
"version": "18.12.0",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
"version": "21.1.1",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
"license": "MIT",
"dependencies": {
"@octokit/core": "^3.5.1",
"@octokit/plugin-paginate-rest": "^2.16.8",
"@octokit/plugin-request-log": "^1.0.4",
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
"@octokit/core": "^6.1.4",
"@octokit/plugin-paginate-rest": "^11.4.2",
"@octokit/plugin-request-log": "^5.3.1",
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/types": {
@@ -234,9 +396,10 @@
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"node_modules/before-after-hook": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==",
"license": "Apache-2.0"
},
"node_modules/bottleneck": {
"version": "2.19.5",
@@ -270,11 +433,6 @@
"node": ">=0.4.0"
}
},
"node_modules/deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"node_modules/discord-api-types": {
"version": "0.23.1",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz",
@@ -316,6 +474,22 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/fast-content-type-parse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
"integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "MIT"
},
"node_modules/is-obj": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
@@ -324,14 +498,6 @@
"node": ">=8"
}
},
"node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
@@ -375,14 +541,6 @@
}
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/ow": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz",
@@ -429,9 +587,10 @@
}
},
"node_modules/universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==",
"license": "ISC"
},
"node_modules/vali-date": {
"version": "1.0.0",
@@ -455,11 +614,6 @@
"webidl-conversions": "^3.0.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
@@ -517,45 +671,86 @@
}
},
"@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"requires": {
"@octokit/types": "^6.0.3"
}
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz",
"integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw=="
},
"@octokit/core": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz",
"integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==",
"requires": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.0",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
"@octokit/auth-token": "^5.0.0",
"@octokit/graphql": "^8.1.2",
"@octokit/request": "^9.2.1",
"@octokit/request-error": "^6.1.7",
"@octokit/types": "^13.6.2",
"before-after-hook": "^3.0.2",
"universal-user-agent": "^7.0.0"
},
"dependencies": {
"@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
},
"@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"requires": {
"@octokit/openapi-types": "^23.0.1"
}
}
}
},
"@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"version": "10.1.3",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz",
"integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==",
"requires": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
"@octokit/types": "^13.6.2",
"universal-user-agent": "^7.0.2"
},
"dependencies": {
"@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
},
"@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"requires": {
"@octokit/openapi-types": "^23.0.1"
}
}
}
},
"@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz",
"integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==",
"requires": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
"@octokit/request": "^9.2.2",
"@octokit/types": "^13.8.0",
"universal-user-agent": "^7.0.0"
},
"dependencies": {
"@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
},
"@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"requires": {
"@octokit/openapi-types": "^23.0.1"
}
}
}
},
"@octokit/openapi-types": {
@@ -564,26 +759,55 @@
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
},
"@octokit/plugin-paginate-rest": {
"version": "2.16.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
"version": "11.4.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.2.tgz",
"integrity": "sha512-BXJ7XPCTDXFF+wxcg/zscfgw2O/iDPtNSkwwR1W1W5c4Mb3zav/M2XvxQ23nVmKj7jpweB4g8viMeCQdm7LMVA==",
"requires": {
"@octokit/types": "^6.33.0"
"@octokit/types": "^13.7.0"
},
"dependencies": {
"@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
},
"@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"requires": {
"@octokit/openapi-types": "^23.0.1"
}
}
}
},
"@octokit/plugin-request-log": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-5.3.1.tgz",
"integrity": "sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==",
"requires": {}
},
"@octokit/plugin-rest-endpoint-methods": {
"version": "5.12.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
"version": "13.3.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.1.tgz",
"integrity": "sha512-o8uOBdsyR+WR8MK9Cco8dCgvG13H1RlM1nWnK/W7TEACQBFux/vPREgKucxUfuDQ5yi1T3hGf4C5ZmZXAERgwQ==",
"requires": {
"@octokit/types": "^6.33.0",
"deprecation": "^2.3.1"
"@octokit/types": "^13.8.0"
},
"dependencies": {
"@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
},
"@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"requires": {
"@octokit/openapi-types": "^23.0.1"
}
}
}
},
"@octokit/plugin-retry": {
@@ -596,46 +820,88 @@
}
},
"@octokit/plugin-throttling": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.7.0.tgz",
"integrity": "sha512-qrKT1Yl/KuwGSC6/oHpLBot3ooC9rq0/ryDYBCpkRtoj+R8T47xTMDT6Tk2CxWopFota/8Pi/2SqArqwC0JPow==",
"version": "9.4.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-9.4.0.tgz",
"integrity": "sha512-IOlXxXhZA4Z3m0EEYtrrACkuHiArHLZ3CvqWwOez/pURNqRuwfoFlTPbN5Muf28pzFuztxPyiUiNwz8KctdZaQ==",
"requires": {
"@octokit/types": "^6.0.1",
"@octokit/types": "^13.7.0",
"bottleneck": "^2.15.3"
},
"dependencies": {
"@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
},
"@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"requires": {
"@octokit/openapi-types": "^23.0.1"
}
}
}
},
"@octokit/request": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
"integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
"requires": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.1",
"universal-user-agent": "^6.0.0"
"@octokit/endpoint": "^10.1.3",
"@octokit/request-error": "^6.1.7",
"@octokit/types": "^13.6.2",
"fast-content-type-parse": "^2.0.0",
"universal-user-agent": "^7.0.2"
},
"dependencies": {
"@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
},
"@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"requires": {
"@octokit/openapi-types": "^23.0.1"
}
}
}
},
"@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"version": "6.1.7",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
"integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
"requires": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
"@octokit/types": "^13.6.2"
},
"dependencies": {
"@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g=="
},
"@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"requires": {
"@octokit/openapi-types": "^23.0.1"
}
}
}
},
"@octokit/rest": {
"version": "18.12.0",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
"version": "21.1.1",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
"requires": {
"@octokit/core": "^3.5.1",
"@octokit/plugin-paginate-rest": "^2.16.8",
"@octokit/plugin-request-log": "^1.0.4",
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
"@octokit/core": "^6.1.4",
"@octokit/plugin-paginate-rest": "^11.4.2",
"@octokit/plugin-request-log": "^5.3.1",
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
}
},
"@octokit/types": {
@@ -675,9 +941,9 @@
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"before-after-hook": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="
},
"bottleneck": {
"version": "2.19.5",
@@ -702,11 +968,6 @@
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"discord-api-types": {
"version": "0.23.1",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz",
@@ -735,16 +996,16 @@
"is-obj": "^2.0.0"
}
},
"fast-content-type-parse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
"integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q=="
},
"is-obj": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="
},
"is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
},
"lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
@@ -771,14 +1032,6 @@
"whatwg-url": "^5.0.0"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"ow": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz",
@@ -813,9 +1066,9 @@
"integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="
},
"universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="
},
"vali-date": {
"version": "1.0.0",
@@ -836,11 +1089,6 @@
"webidl-conversions": "^3.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",

View File

@@ -11,8 +11,8 @@
"license": "ISC",
"dependencies": {
"@octokit/plugin-retry": "^3.0.9",
"@octokit/plugin-throttling": "^3.5.2",
"@octokit/rest": "^18.12.0",
"@octokit/plugin-throttling": "^9.4.0",
"@octokit/rest": "^21.1.1",
"discord.js": "^13.2.0"
}
}

View File

@@ -1,22 +1,33 @@
{
"name": "generate-release-notes",
"version": "1.0.0",
"lockfileVersion": 1,
"lockfileVersion": 3,
"requires": true,
"dependencies": {
"@octokit/auth-token": {
"packages": {
"": {
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@octokit/plugin-retry": "^3.0.9",
"@octokit/plugin-throttling": "^3.5.2",
"@octokit/rest": "^21.1.1"
}
},
"node_modules/@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"requires": {
"peer": true,
"dependencies": {
"@octokit/types": "^6.0.3"
}
},
"@octokit/core": {
"node_modules/@octokit/core": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
"requires": {
"peer": true,
"dependencies": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.0",
@@ -26,76 +37,60 @@
"universal-user-agent": "^6.0.0"
}
},
"@octokit/endpoint": {
"node_modules/@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"requires": {
"peer": true,
"dependencies": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/graphql": {
"node_modules/@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"requires": {
"peer": true,
"dependencies": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/openapi-types": {
"node_modules/@octokit/openapi-types": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz",
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
},
"@octokit/plugin-paginate-rest": {
"version": "2.16.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
"requires": {
"@octokit/types": "^6.33.0"
}
},
"@octokit/plugin-request-log": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA=="
},
"@octokit/plugin-rest-endpoint-methods": {
"version": "5.12.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
"requires": {
"@octokit/types": "^6.33.0",
"deprecation": "^2.3.1"
}
},
"@octokit/plugin-retry": {
"node_modules/@octokit/plugin-retry": {
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
"requires": {
"dependencies": {
"@octokit/types": "^6.0.3",
"bottleneck": "^2.15.3"
}
},
"@octokit/plugin-throttling": {
"node_modules/@octokit/plugin-throttling": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.5.2.tgz",
"integrity": "sha512-Eu7kfJxU8vmHqWGNszWpg+GVp2tnAfax3XQV5CkYPEE69C+KvInJXW9WajgSeW+cxYe0UVdouzCtcreGNuJo7A==",
"requires": {
"dependencies": {
"@octokit/types": "^6.0.1",
"bottleneck": "^2.15.3"
},
"peerDependencies": {
"@octokit/core": "^3.5.0"
}
},
"@octokit/request": {
"node_modules/@octokit/request": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
"requires": {
"peer": true,
"dependencies": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
@@ -104,99 +99,295 @@
"universal-user-agent": "^6.0.0"
}
},
"@octokit/request-error": {
"node_modules/@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"requires": {
"peer": true,
"dependencies": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"@octokit/rest": {
"version": "18.12.0",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
"requires": {
"@octokit/core": "^3.5.1",
"@octokit/plugin-paginate-rest": "^2.16.8",
"@octokit/plugin-request-log": "^1.0.4",
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
"node_modules/@octokit/rest": {
"version": "21.1.1",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-21.1.1.tgz",
"integrity": "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg==",
"license": "MIT",
"dependencies": {
"@octokit/core": "^6.1.4",
"@octokit/plugin-paginate-rest": "^11.4.2",
"@octokit/plugin-request-log": "^5.3.1",
"@octokit/plugin-rest-endpoint-methods": "^13.3.0"
},
"engines": {
"node": ">= 18"
}
},
"@octokit/types": {
"node_modules/@octokit/rest/node_modules/@octokit/auth-token": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-5.1.2.tgz",
"integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==",
"license": "MIT",
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/core": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-6.1.4.tgz",
"integrity": "sha512-lAS9k7d6I0MPN+gb9bKDt7X8SdxknYqAMh44S5L+lNqIN2NuV8nvv3g8rPp7MuRxcOpxpUIATWprO0C34a8Qmg==",
"license": "MIT",
"dependencies": {
"@octokit/auth-token": "^5.0.0",
"@octokit/graphql": "^8.1.2",
"@octokit/request": "^9.2.1",
"@octokit/request-error": "^6.1.7",
"@octokit/types": "^13.6.2",
"before-after-hook": "^3.0.2",
"universal-user-agent": "^7.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/endpoint": {
"version": "10.1.3",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-10.1.3.tgz",
"integrity": "sha512-nBRBMpKPhQUxCsQQeW+rCJ/OPSMcj3g0nfHn01zGYZXuNDvvXudF/TYY6APj5THlurerpFN4a/dQAIAaM6BYhA==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^13.6.2",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/graphql": {
"version": "8.2.1",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-8.2.1.tgz",
"integrity": "sha512-n57hXtOoHrhwTWdvhVkdJHdhTv0JstjDbDRhJfwIRNfFqmSo1DaK/mD2syoNUoLCyqSjBpGAKOG0BuwF392slw==",
"license": "MIT",
"dependencies": {
"@octokit/request": "^9.2.2",
"@octokit/types": "^13.8.0",
"universal-user-agent": "^7.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/openapi-types": {
"version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
"license": "MIT"
},
"node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest": {
"version": "11.4.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.4.2.tgz",
"integrity": "sha512-BXJ7XPCTDXFF+wxcg/zscfgw2O/iDPtNSkwwR1W1W5c4Mb3zav/M2XvxQ23nVmKj7jpweB4g8viMeCQdm7LMVA==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^13.7.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": ">=6"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-5.3.1.tgz",
"integrity": "sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw==",
"license": "MIT",
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": ">=6"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "13.3.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.3.1.tgz",
"integrity": "sha512-o8uOBdsyR+WR8MK9Cco8dCgvG13H1RlM1nWnK/W7TEACQBFux/vPREgKucxUfuDQ5yi1T3hGf4C5ZmZXAERgwQ==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^13.8.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": ">=6"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/request": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-9.2.2.tgz",
"integrity": "sha512-dZl0ZHx6gOQGcffgm1/Sf6JfEpmh34v3Af2Uci02vzUYz6qEN6zepoRtmybWXIGXFIK8K9ylE3b+duCWqhArtg==",
"license": "MIT",
"dependencies": {
"@octokit/endpoint": "^10.1.3",
"@octokit/request-error": "^6.1.7",
"@octokit/types": "^13.6.2",
"fast-content-type-parse": "^2.0.0",
"universal-user-agent": "^7.0.2"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/request-error": {
"version": "6.1.7",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.7.tgz",
"integrity": "sha512-69NIppAwaauwZv6aOzb+VVLwt+0havz9GT5YplkeJv7fG7a40qpLt/yZKyiDxAhgz0EtgNdNcb96Z0u+Zyuy2g==",
"license": "MIT",
"dependencies": {
"@octokit/types": "^13.6.2"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/types": {
"version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^23.0.1"
}
},
"node_modules/@octokit/rest/node_modules/before-after-hook": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz",
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==",
"license": "Apache-2.0"
},
"node_modules/@octokit/rest/node_modules/universal-user-agent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.2.tgz",
"integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==",
"license": "ISC"
},
"node_modules/@octokit/types": {
"version": "6.33.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz",
"integrity": "sha512-0zffZ048M0UhthyPXQHLz4038Ak46nMWZXkzlXvXB/M/L1jYPBceq4iZj4qjKVrvveaJrrgKdJ9+3yUuITfcCw==",
"requires": {
"dependencies": {
"@octokit/openapi-types": "^11.1.0"
}
},
"before-after-hook": {
"node_modules/before-after-hook": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==",
"peer": true
},
"bottleneck": {
"node_modules/bottleneck": {
"version": "2.19.5",
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
},
"deprecation": {
"node_modules/deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
"peer": true
},
"is-plain-object": {
"node_modules/fast-content-type-parse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-2.0.1.tgz",
"integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "MIT"
},
"node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node-fetch": {
"node_modules/node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"peer": true,
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"once": {
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"peer": true,
"dependencies": {
"wrappy": "1"
}
},
"tr46": {
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
"peer": true
},
"universal-user-agent": {
"node_modules/universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==",
"peer": true
},
"webidl-conversions": {
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
"peer": true
},
"whatwg-url": {
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"requires": {
"peer": true,
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"wrappy": {
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"peer": true
}
}
}

View File

@@ -12,6 +12,6 @@
"dependencies": {
"@octokit/plugin-retry": "^3.0.9",
"@octokit/plugin-throttling": "^3.5.2",
"@octokit/rest": "^18.12.0"
"@octokit/rest": "^21.1.1"
}
}

View File

@@ -42,39 +42,40 @@ echo INSTALLDIR=%INSTALLDIR%
cd "%BUILDDIR%"
set FREETYPE=2.13.2
set HARFBUZZ=8.3.1
set LIBJPEG=9f
set LIBPNG=1643
set FREETYPE=2.13.3
set HARFBUZZ=10.0.1
set LIBJPEGTURBO=3.1.0
set LIBPNG=1645
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
set QT=6.7.2
set QTMINOR=6.7
set SDL=SDL2-2.30.6
set WEBP=1.4.0
set QT=6.8.2
set QTMINOR=6.8
set SDL=SDL3-3.2.8
set WEBP=1.5.0
set ZLIB=1.3.1
set ZLIBSHORT=131
set ZSTD=1.5.6
set ZSTD=1.5.7
set KDDOCKWIDGETS=2.2.1
set SHADERC=2024.1
set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
set SHADERC_SPIRVHEADERS=5e3ad389ee56fca27c9705d093ae5387ce404df4
set SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 1ac27e16c134a7f2ccea177faba19801131116fd682efc1f5737037c5db224b5 || goto error
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip b2bc56184ae37324bc4829fde7d3f9e6916866ad711ee85792e457547c9fd127 || goto error
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1643.zip fc466a1e638e635d6c66363bdf3f38555b81b0141d0b06ba45b49ccca327436d || goto error
call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.zip 6255da8c89e09d694e6800688c76145eb6870a76ac0d36c74fccd61b3940aafa || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 || goto error
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747 || goto error
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 8adf9f5a4b6022aa2744f45c89ce347df46fea8403e99f01d650b11c417d0aa8 || goto error
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1645.zip a66c4b1350b67776e90263e2550933067cd9ccbd318db489f84dcc0d2b033249 || goto error
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 6d4e00fcbee9fd8985cc2869edeb0b1a751912b87506cf2fb6471e73d981e1f4 || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 488119aad60719a085a1e45c31641ac2406ef86fc088a3c99885c18e9d6b4bb9 || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 8e736b02db7dd67dbe834d56503b242344ce85d3532da692f1812b30ccf80997 || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 85a22142270a92be0dd0ab5d27cc53617b2a2f1a45fc0a3890024164032f8475 || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 9e15f1fdbd83e4123e733bff20aff1b45921c09056c3790fa42eb71d0a5cd01f || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" d1f25e0f68a1282feffdd5fe795a027ee5f16ad19e3b1fa2e04a51cea19110ec || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 7f8ff5c8246db4145301bc122601a5f8cef25ee2c326eddb3e88668849c61ddf || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 102539447c1c76d206f24bcca2c911270cf53991548d9c3d7d0d01855f651e3b || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 33ccac9f99a357ffd83cb2d7179a0c0ffcba85a14d23d86619d5dc9721ded42f || goto error
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 3b1c3b46e416d36931efd34663122d7f51b550c87f74de2d38249516fe7d8be5 || goto error
call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https://github.com/facebook/zstd/commit/fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch 675f144b11f8ab2424b64bed8ccdca5d3f35b9326046fa7a883925dd180f0651 || goto error
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v2.2.1.zip" 78b5e242bf47476e150175b7de934ab84069459e151beb2d5ce84fd067138aa5 || goto error
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error
@@ -108,11 +109,10 @@ cmake --build build --parallel || goto error
ninja -C build install || goto error
cd .. || goto error
echo Building libjpeg...
rmdir /S /Q "jpeg-%LIBJPEG%"
%SEVENZIP% x "jpegsr%LIBJPEG%.zip" || goto error
cd "jpeg-%LIBJPEG%" || goto error
%PATCH% -p1 < "%SCRIPTDIR%\libjpeg-cmake.patch" || goto error
echo Building libjpegturbo...
rmdir /S /Q "libjpeg-turbo-%LIBJPEGTURBO%"
tar -xf "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" || goto error
cd "libjpeg-turbo-%LIBJPEGTURBO%" || goto error
cmake %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=OFF -B build -G Ninja || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error
@@ -159,7 +159,6 @@ echo Building Zstandard...
rmdir /S /Q "zstd-%ZSTD%"
%SEVENZIP% x "-x^!zstd-%ZSTD%\tests\cli-tests\bin" "zstd-%ZSTD%.zip" || goto error
cd "zstd-%ZSTD%"
%PATCH% -p1 < "..\zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" || goto error
cmake %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DZSTD_BUILD_SHARED=ON -DZSTD_BUILD_STATIC=OFF -DZSTD_BUILD_PROGRAMS=OFF -B build -G Ninja build/cmake
cmake --build build --parallel || goto error
ninja -C build install || goto error
@@ -181,7 +180,7 @@ cd "%SDL%" || goto error
cmake -B build %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release %FORCEPDB% -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error
copy build\SDL2.pdb "%INSTALLDIR%\bin" || goto error
copy build\SDL3.pdb "%INSTALLDIR%\bin" || goto error
cd .. || goto error
if %DEBUG%==1 (
@@ -243,6 +242,16 @@ cmake --build . --parallel || goto error
ninja install || goto error
cd ..\.. || goto error
echo "Building KDDockWidgets..."
rmdir /S /Q "KDDockWidgets-%KDDOCKWIDGETS%"
%SEVENZIP% x "KDDockWidgets-%KDDOCKWIDGETS%.zip" || goto error
cd "KDDockWidgets-%KDDOCKWIDGETS%" || goto error
%PATCH% -p1 < "%SCRIPTDIR%\..\common\kddockwidgets-dodgy-include.patch" || goto error
cmake %ARM64TOOLCHAIN% -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build -G Ninja || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error
cd .. || goto error
echo Building shaderc...
rmdir /S /Q "shaderc-%SHADERC%"
%SEVENZIP% x "shaderc-%SHADERC%.zip" || goto error

View File

@@ -40,39 +40,40 @@ set "PATH=%PATH%;%INSTALLDIR%\bin"
cd "%BUILDDIR%"
set FREETYPE=2.13.2
set HARFBUZZ=8.3.1
set LIBJPEG=9f
set LIBPNG=1643
set FREETYPE=2.13.3
set HARFBUZZ=10.0.1
set LIBJPEGTURBO=3.1.0
set LIBPNG=1645
set LZ4=b8fd2d15309dd4e605070bd4486e26b6ef814e29
set QT=6.7.2
set QTMINOR=6.7
set SDL=SDL2-2.30.6
set WEBP=1.4.0
set QT=6.8.2
set QTMINOR=6.8
set SDL=SDL3-3.2.8
set WEBP=1.5.0
set ZLIB=1.3.1
set ZLIBSHORT=131
set ZSTD=1.5.6
set ZSTD=1.5.7
set KDDOCKWIDGETS=2.2.1
set SHADERC=2024.1
set SHADERC_GLSLANG=142052fa30f9eca191aa9dcf65359fcaed09eeec
set SHADERC_SPIRVHEADERS=5e3ad389ee56fca27c9705d093ae5387ce404df4
set SHADERC_SPIRVTOOLS=dd4b663e13c07fea4fbb3f70c1c91c86731099f7
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 1ac27e16c134a7f2ccea177faba19801131116fd682efc1f5737037c5db224b5 || goto error
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip b2bc56184ae37324bc4829fde7d3f9e6916866ad711ee85792e457547c9fd127 || goto error
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1643.zip fc466a1e638e635d6c66363bdf3f38555b81b0141d0b06ba45b49ccca327436d || goto error
call :downloadfile "jpegsr%LIBJPEG%.zip" https://ijg.org/files/jpegsr%LIBJPEG%.zip 6255da8c89e09d694e6800688c76145eb6870a76ac0d36c74fccd61b3940aafa || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 61f873ec69e3be1b99535634340d5bde750b2e4447caa1db9f61be3fd49ab1e5 || goto error
call :downloadfile "freetype-%FREETYPE%.tar.gz" https://sourceforge.net/projects/freetype/files/freetype2/%FREETYPE%/freetype-%FREETYPE%.tar.gz/download 5c3a8e78f7b24c20b25b54ee575d6daa40007a5f4eea2845861c3409b3021747 || goto error
call :downloadfile "harfbuzz-%HARFBUZZ%.zip" https://github.com/harfbuzz/harfbuzz/archive/refs/tags/%HARFBUZZ%.zip 8adf9f5a4b6022aa2744f45c89ce347df46fea8403e99f01d650b11c417d0aa8 || goto error
call :downloadfile "lpng%LIBPNG%.zip" https://download.sourceforge.net/libpng/lpng1645.zip a66c4b1350b67776e90263e2550933067cd9ccbd318db489f84dcc0d2b033249 || goto error
call :downloadfile "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%LIBJPEGTURBO%/libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" 9564c72b1dfd1d6fe6274c5f95a8d989b59854575d4bbee44ade7bc17aa9bc93 || goto error
call :downloadfile "libwebp-%WEBP%.tar.gz" "https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-%WEBP%.tar.gz" 7d6fab70cf844bf6769077bd5d7a74893f8ffd4dfb42861745750c63c2a5c92c || goto error
call :downloadfile "lz4-%LZ4%.zip" "https://github.com/lz4/lz4/archive/%LZ4%.zip" 0c33119688d6b180c7e760b0acd70059222389cfd581632623784bee27e51a31 || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 6d4e00fcbee9fd8985cc2869edeb0b1a751912b87506cf2fb6471e73d981e1f4 || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 488119aad60719a085a1e45c31641ac2406ef86fc088a3c99885c18e9d6b4bb9 || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 8e736b02db7dd67dbe834d56503b242344ce85d3532da692f1812b30ccf80997 || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 85a22142270a92be0dd0ab5d27cc53617b2a2f1a45fc0a3890024164032f8475 || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 9e15f1fdbd83e4123e733bff20aff1b45921c09056c3790fa42eb71d0a5cd01f || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" d1f25e0f68a1282feffdd5fe795a027ee5f16ad19e3b1fa2e04a51cea19110ec || goto error
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 7f8ff5c8246db4145301bc122601a5f8cef25ee2c326eddb3e88668849c61ddf || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 44087aec0caa4aa81437e787917d29d97536484a682a5d51ec035878e57c0b5c || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 83c72b5dfad04854acf61d592e3f9cdc2ed894779aab8d0470d966715266caaf || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" 144d55e4d199793a76c53f19872633a79aec0314039f6f99b6a10b5be7a78fbf || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" 102539447c1c76d206f24bcca2c911270cf53991548d9c3d7d0d01855f651e3b || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" 33ccac9f99a357ffd83cb2d7179a0c0ffcba85a14d23d86619d5dc9721ded42f || goto error
call :downloadfile "zlib%ZLIBSHORT%.zip" "https://zlib.net/zlib%ZLIBSHORT%.zip" 72af66d44fcc14c22013b46b814d5d2514673dda3d115e64b690c1ad636e7b17 || goto error
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 3b1c3b46e416d36931efd34663122d7f51b550c87f74de2d38249516fe7d8be5 || goto error
call :downloadfile "zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" https://github.com/facebook/zstd/commit/fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch 675f144b11f8ab2424b64bed8ccdca5d3f35b9326046fa7a883925dd180f0651 || goto error
call :downloadfile "zstd-%ZSTD%.zip" "https://github.com/facebook/zstd/archive/refs/tags/v%ZSTD%.zip" 7897bc5d620580d9b7cd3539c44b59d78f3657d33663fe97a145e07b4ebd69a4 || goto error
call :downloadfile "KDDockWidgets-%KDDOCKWIDGETS%.zip" "https://github.com/KDAB/KDDockWidgets/archive/v2.2.1.zip" 78b5e242bf47476e150175b7de934ab84069459e151beb2d5ce84fd067138aa5 || goto error
call :downloadfile "shaderc-%SHADERC%.zip" "https://github.com/google/shaderc/archive/refs/tags/v%SHADERC%.zip" 6c9f42ed6bf42750f5369b089909abfdcf0101488b4a1f41116d5159d00af8e7 || goto error
call :downloadfile "shaderc-glslang-%SHADERC_GLSLANG%.zip" "https://github.com/KhronosGroup/glslang/archive/%SHADERC_GLSLANG%.zip" 03ad8a6fa987af4653d0cfe6bdaed41bcf617f1366a151fb1574da75950cd3e8 || goto error
@@ -105,11 +106,10 @@ cmake --build build --parallel || goto error
ninja -C build install || goto error
cd .. || goto error
echo Building libjpeg...
rmdir /S /Q "jpeg-%LIBJPEG%"
%SEVENZIP% x "jpegsr%LIBJPEG%.zip" || goto error
cd "jpeg-%LIBJPEG%" || goto error
%PATCH% -p1 < "%SCRIPTDIR%\libjpeg-cmake.patch" || goto error
echo Building libjpegturbo...
rmdir /S /Q "libjpeg-turbo-%LIBJPEGTURBO%"
tar -xf "libjpeg-turbo-%LIBJPEGTURBO%.tar.gz" || goto error
cd "libjpeg-turbo-%LIBJPEGTURBO%" || goto error
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=OFF -B build -G Ninja || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error
@@ -156,7 +156,6 @@ echo Building Zstandard...
rmdir /S /Q "zstd-%ZSTD%"
%SEVENZIP% x "-x^!zstd-%ZSTD%\tests\cli-tests\bin" "zstd-%ZSTD%.zip" || goto error
cd "zstd-%ZSTD%"
%PATCH% -p1 < "..\zstd-fd5f8106a58601a963ee816e6a57aa7c61fafc53.patch" || goto error
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DZSTD_BUILD_SHARED=ON -DZSTD_BUILD_STATIC=OFF -DZSTD_BUILD_PROGRAMS=OFF -B build -G Ninja build/cmake
cmake --build build --parallel || goto error
ninja -C build install || goto error
@@ -178,7 +177,7 @@ cd "%SDL%" || goto error
cmake -B build -DCMAKE_BUILD_TYPE=Release %FORCEPDB% -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error
copy build\SDL2.pdb "%INSTALLDIR%\bin" || goto error
copy build\SDL3.pdb "%INSTALLDIR%\bin" || goto error
cd .. || goto error
if %DEBUG%==1 (
@@ -195,6 +194,9 @@ cd "qtbase-everywhere-src-%QT%" || goto error
rem Disable the PCRE2 JIT, it doesn't properly verify AVX2 support.
%PATCH% -p1 < "%SCRIPTDIR%\qtbase-disable-pcre2-jit.patch" || goto error
rem Hackfix settings icon stretching
%PATCH% -p1 < "%SCRIPTDIR%\qtbase-fix-icon-stretch.patch" || goto error
cmake -B build -DFEATURE_sql=OFF -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" %FORCEPDB% -DINPUT_gui=yes -DINPUT_widgets=yes -DINPUT_ssl=yes -DINPUT_openssl=no -DINPUT_schannel=yes -DFEATURE_system_png=ON -DFEATURE_system_jpeg=ON -DFEATURE_system_zlib=ON -DFEATURE_system_freetype=ON -DFEATURE_system_harfbuzz=ON %QTBUILDSPEC% || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error
@@ -244,6 +246,16 @@ cmake --build . --parallel || goto error
ninja install || goto error
cd ..\.. || goto error
echo "Building KDDockWidgets..."
rmdir /S /Q "KDDockWidgets-%KDDOCKWIDGETS%"
%SEVENZIP% x "KDDockWidgets-%KDDOCKWIDGETS%.zip" || goto error
cd "KDDockWidgets-%KDDOCKWIDGETS%" || goto error
%PATCH% -p1 < "%SCRIPTDIR%\..\common\kddockwidgets-dodgy-include.patch" || goto error
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="%INSTALLDIR%" -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DKDDockWidgets_QT6=true -DKDDockWidgets_EXAMPLES=false -DKDDockWidgets_FRONTENDS=qtwidgets -B build -G Ninja || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error
cd .. || goto error
echo Building shaderc...
rmdir /S /Q "shaderc-%SHADERC%"
%SEVENZIP% x "shaderc-%SHADERC%.zip" || goto error

View File

@@ -1,422 +0,0 @@
diff -ruN jpeg-9f/CMakeLists.txt jpeg-9f-new/CMakeLists.txt
--- jpeg-9f/CMakeLists.txt 1970-01-01 10:00:00.000000000 +1000
+++ jpeg-9f-new/CMakeLists.txt 2024-03-23 21:29:37.969221600 +1000
@@ -0,0 +1,110 @@
+# CMake configuration for IJG libjpeg
+# Modified from https://github.com/csparker247/jpeg-cmake/blob/develop/resources/CMakeLists.txt
+# To install, copy this file and jconfig.h.in into a libjpeg source directory
+# Adapted from LuaDist's CMakeLists
+# https://github.com/LuaDist/libjpeg/blob/master/CMakeLists.txt
+
+cmake_minimum_required(VERSION 3.5)
+
+### Setup the project ###
+file(READ "configure.ac" ac)
+string(REGEX MATCH "AC_INIT\\(\\[libjpeg\\],\ \\[([0-9]*\\.[0-9]*\\.[0-9]*)\\]\\)" _ ${ac})
+set(version ${CMAKE_MATCH_1})
+project(libjpeg VERSION ${version} LANGUAGES C)
+set(C_STANDARD 99)
+
+### Include extra packages ###
+include(CMakeDependentOption)
+include(GNUInstallDirs)
+
+### Options ###
+option(BUILD_SHARED_LIBS "Build shared libraries" ON)
+option(BUILD_STATIC_LIBS "Build static libraries" ON)
+
+# Make sure we build at least one library
+if(NOT(BUILD_SHARED_LIBS OR BUILD_STATIC_LIBS))
+ message(FATAL_ERROR "Both static and shared libraries are disabled. Nothing will be built.")
+endif()
+
+### Configure jconfig.h ###
+include(ConfigureJConfig.cmake)
+
+### Build the object library ###
+set(PUBLIC_HDRS
+ jconfig.h
+ jerror.h
+ jmorecfg.h
+ jpeglib.h
+)
+
+set(SRCS
+ jaricom.c jcapimin.c jcapistd.c jcarith.c jccoefct.c jccolor.c
+ jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c
+ jcparam.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdarith.c
+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c jdinput.c
+ jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdpostct.c jdsample.c jdtrans.c
+ jerror.c jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c
+ jmemmgr.c jmemnobs.c jquant1.c jquant2.c jutils.c
+)
+
+### Create static and shared libs ###
+if(BUILD_SHARED_LIBS)
+ add_library(libjpeg SHARED ${SRCS})
+ target_compile_definitions(libjpeg PRIVATE COMPILING_LIBJPEG)
+ target_include_directories(libjpeg
+ PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+ $<INSTALL_INTERFACE:include>
+ )
+ set_target_properties(libjpeg
+ PROPERTIES
+ VERSION ${PROJECT_VERSION_MAJOR}
+ POSITION_INDEPENDENT_CODE ON
+ CLEAN_DIRECT_OUTPUT ON
+ PUBLIC_HEADER "${PUBLIC_HDRS}"
+ )
+ install(TARGETS libjpeg
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+ )
+endif()
+
+if(BUILD_STATIC_LIBS)
+ add_library(libjpeg_static STATIC $<TARGET_OBJECTS:jpeg_objs>)
+ target_include_directories(libjpeg_static
+ PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+ $<INSTALL_INTERFACE:include>
+ )
+ set_target_properties(libjpeg_static
+ PROPERTIES
+ OUTPUT_NAME jpeg
+ VERSION ${PROJECT_VERSION_MAJOR}
+ POSITION_INDEPENDENT_CODE ON
+ CLEAN_DIRECT_OUTPUT ON
+ PUBLIC_HEADER "${PUBLIC_HDRS}"
+ )
+ install(TARGETS libjpeg_static
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+ )
+endif()
+
+# Configure and install pkg-config and libtool files
+if(BUILD_STATIC_LIBS OR BUILD_SHARED_LIBS)
+ # Compute the la file's weird version number
+ math(EXPR JPEG_CONF_VER_MAJOR "${PROJECT_VERSION_MAJOR} + ${PROJECT_VERSION_MINOR}")
+ set(JPEG_LIB_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
+ set(JPEG_LIB_VERSION_MINOR ${PROJECT_VERSION_MINOR})
+
+ # Configure and install
+ configure_file(libjpeg.pc.cmakein libjpeg.pc @ONLY)
+ install(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/libjpeg.pc
+ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig
+ )
+endif()
+
diff -ruN jpeg-9f/ConfigureJConfig.cmake jpeg-9f-new/ConfigureJConfig.cmake
--- jpeg-9f/ConfigureJConfig.cmake 1970-01-01 10:00:00.000000000 +1000
+++ jpeg-9f-new/ConfigureJConfig.cmake 2024-03-23 21:09:37.223882900 +1000
@@ -0,0 +1,95 @@
+include(CheckIncludeFile)
+include(CheckSymbolExists)
+include(CheckTypeSize)
+
+# Define this if your system has an ANSI-conforming <stddef.h> file.
+check_include_file(stddef.h HAVE_STDDEF_H)
+
+# Define this if your system has an ANSI-conforming <stdlib.h> file.
+check_include_file(stdlib.h HAVE_STDLIB_H)
+
+# Does your compiler support function prototypes?
+# (If not, you also need to use ansi2knr, see install.txt)
+set(HAVE_PROTOTYPES true CACHE BOOL "Does your compiler support function prototypes?")
+
+# Does your compiler support the declaration "unsigned char" ?
+# How about "unsigned short" ?
+check_type_size("unsigned char" UNSIGNED_CHAR LANGUAGE C)
+check_type_size("unsigned short" UNSIGNED_SHORT LANGUAGE C)
+
+# Define "void" as "char" if your compiler doesn't know about type void.
+# NOTE: be sure to define void such that "void *" represents the most general
+# pointer type, e.g., that returned by malloc().
+# NOT IMPLEMENTED: Modify in jconfig.h.in #
+
+# Define "const" as empty if your compiler doesn't know the "const" keyword.
+# NOT IMPLEMENTED: Modify in jconfig.h.in #
+
+# Define this if an ordinary "char" type is unsigned.
+# If you're not sure, leaving it undefined will work at some cost in speed.
+# If you defined HAVE_UNSIGNED_CHAR then the speed difference is minimal.
+set(CHAR_IS_UNSIGNED false CACHE BOOL "char type is unsigned")
+
+# Define this if your system does not have an ANSI/SysV <string.h>,
+# but does have a BSD-style <strings.h>.
+set(NEED_BSD_STRINGS false CACHE BOOL "Use BSD <strings.h>. Use only if system lacks ANSI/SysV <strings.h>")
+
+# Define this if your system does not provide typedef size_t in any of the
+# ANSI-standard places (stddef.h, stdlib.h, or stdio.h), but places it in
+# <sys/types.h> instead.
+set(NEED_SYS_TYPES_H false CACHE BOOL "size_t defined in <sys/types.h>")
+
+# For 80x86 machines, you need to define NEED_FAR_POINTERS,
+# unless you are using a large-data memory model or 80386 flat-memory mode.
+# On less brain-damaged CPUs this symbol must not be defined.
+# (Defining this symbol causes large data structures to be referenced through
+# "far" pointers and to be allocated with a special version of malloc.)
+set(NEED_FAR_POINTERS false CACHE BOOL "Reference large data structures through 'far' pointers allocated with a special version of malloc")
+
+# Define this if your linker needs global names to be unique in less
+# than the first 15 characters.
+set(NEED_SHORT_EXTERNAL_NAMES false CACHE BOOL "Global names must be unique in less than the first 15 characters")
+
+# Although a real ANSI C compiler can deal perfectly well with pointers to
+# unspecified structures (see "incomplete types" in the spec), a few pre-ANSI
+# and pseudo-ANSI compilers get confused. To keep one of these bozos happy,
+# define INCOMPLETE_TYPES_BROKEN. This is not recommended unless you
+# actually get "missing structure definition" warnings or errors while
+# compiling the JPEG code.
+set(INCOMPLETE_TYPES_BROKEN false CACHE BOOL "Disable pointers to unspecified structures")
+
+# Define "boolean" as unsigned char, not enum, on Windows systems.
+# NOT IMPLEMENTED: Modify in jconfig.h.in #
+
+# The following options affect code selection within the JPEG library,
+# but they don't need to be visible to applications using the library.
+# To minimize application namespace pollution, the symbols won't be
+# defined unless JPEG_INTERNALS has been defined.
+#
+
+# Define this if your compiler implements ">>" on signed values as a logical
+# (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift,
+# which is the normal and rational definition.
+set(RIGHT_SHIFT_IS_UNSIGNED false CACHE BOOL "Compiler implements >> on signed values as a logical (unsigned) shift")
+
+# The remaining options do not affect the JPEG library proper,
+# but only the sample applications cjpeg/djpeg (see cjpeg.c, djpeg.c).
+# Other applications can ignore these.
+#
+
+mark_as_advanced(FORCE
+ HAVE_PROTOTYPES
+ HAVE_UNSIGNED_CHAR
+ HAVE_UNSIGNED_SHORT
+ CHAR_IS_UNSIGNED
+ HAVE_STDDEF_H
+ HAVE_STDLIB_H
+ NEED_BSD_STRINGS
+ NEED_SYS_TYPES_H
+ NEED_FAR_POINTERS
+ NEED_SHORT_EXTERNAL_NAMES
+ INCOMPLETE_TYPES_BROKEN
+ RIGHT_SHIFT_IS_UNSIGNED
+)
+
+configure_file(jconfig.h.in ${CMAKE_CURRENT_SOURCE_DIR}/jconfig.h)
diff -ruN jpeg-9f/jconfig.h.in jpeg-9f-new/jconfig.h.in
--- jpeg-9f/jconfig.h.in 1970-01-01 10:00:00.000000000 +1000
+++ jpeg-9f-new/jconfig.h.in 2024-03-23 21:06:05.204994600 +1000
@@ -0,0 +1,173 @@
+/*
+ * jconfig.h.in
+ *
+ * Copyright (C) 1991-1994, Thomas G. Lane.
+ * Modified 2009-2013 by Guido Vollbeding.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file is a modification of jconfig.txt from libjpeg. In addition to
+ * documenting the configuration options that are required to customize the
+ * JPEG software for a particular system, it is used by jpeg-cmake to configure
+ * jconfig.h
+ */
+
+
+/*
+ * These symbols indicate the properties of your machine or compiler.
+ * #define the symbol if yes, #undef it if no.
+ */
+
+/* Does your compiler support function prototypes?
+ * (If not, you also need to use ansi2knr, see install.txt)
+ */
+#cmakedefine HAVE_PROTOTYPES
+
+/* Does your compiler support the declaration "unsigned char" ?
+ * How about "unsigned short" ?
+ */
+#cmakedefine HAVE_UNSIGNED_CHAR
+#cmakedefine HAVE_UNSIGNED_SHORT
+
+/* Define "void" as "char" if your compiler doesn't know about type void.
+ * NOTE: be sure to define void such that "void *" represents the most general
+ * pointer type, e.g., that returned by malloc().
+ */
+/* #define void char */
+
+/* Define "const" as empty if your compiler doesn't know the "const" keyword.
+ */
+/* #define const */
+
+/* Define this if an ordinary "char" type is unsigned.
+ * If you're not sure, leaving it undefined will work at some cost in speed.
+ * If you defined HAVE_UNSIGNED_CHAR then the speed difference is minimal.
+ */
+#cmakedefine CHAR_IS_UNSIGNED
+
+/* Define this if your system has an ANSI-conforming <stddef.h> file.
+ */
+#cmakedefine HAVE_STDDEF_H
+
+/* Define this if your system has an ANSI-conforming <stdlib.h> file.
+ */
+#cmakedefine HAVE_STDLIB_H
+
+/* Define this if your system does not have an ANSI/SysV <string.h>,
+ * but does have a BSD-style <strings.h>.
+ */
+#cmakedefine NEED_BSD_STRINGS
+
+/* Define this if your system does not provide typedef size_t in any of the
+ * ANSI-standard places (stddef.h, stdlib.h, or stdio.h), but places it in
+ * <sys/types.h> instead.
+ */
+#cmakedefine NEED_SYS_TYPES_H
+
+/* For 80x86 machines, you need to define NEED_FAR_POINTERS,
+ * unless you are using a large-data memory model or 80386 flat-memory mode.
+ * On less brain-damaged CPUs this symbol must not be defined.
+ * (Defining this symbol causes large data structures to be referenced through
+ * "far" pointers and to be allocated with a special version of malloc.)
+ */
+#cmakedefine NEED_FAR_POINTERS
+
+/* Define this if your linker needs global names to be unique in less
+ * than the first 15 characters.
+ */
+#cmakedefine NEED_SHORT_EXTERNAL_NAMES
+
+/* Although a real ANSI C compiler can deal perfectly well with pointers to
+ * unspecified structures (see "incomplete types" in the spec), a few pre-ANSI
+ * and pseudo-ANSI compilers get confused. To keep one of these bozos happy,
+ * define INCOMPLETE_TYPES_BROKEN. This is not recommended unless you
+ * actually get "missing structure definition" warnings or errors while
+ * compiling the JPEG code.
+ */
+#cmakedefine INCOMPLETE_TYPES_BROKEN
+
+/* Define "boolean" as unsigned char, not enum, on Windows systems.
+ */
+#ifdef _WIN32
+#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
+typedef unsigned char boolean;
+#endif
+#ifndef FALSE /* in case these macros already exist */
+#define FALSE 0 /* values of boolean */
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
+#endif
+
+
+/*
+ * The following options affect code selection within the JPEG library,
+ * but they don't need to be visible to applications using the library.
+ * To minimize application namespace pollution, the symbols won't be
+ * defined unless JPEG_INTERNALS has been defined.
+ */
+
+#ifdef JPEG_INTERNALS
+
+/* Define this if your compiler implements ">>" on signed values as a logical
+ * (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift,
+ * which is the normal and rational definition.
+ */
+#cmakedefine RIGHT_SHIFT_IS_UNSIGNED
+
+
+#endif /* JPEG_INTERNALS */
+
+
+/*
+ * The remaining options do not affect the JPEG library proper,
+ * but only the sample applications cjpeg/djpeg (see cjpeg.c, djpeg.c).
+ * Other applications can ignore these.
+ */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+/* These defines indicate which image (non-JPEG) file formats are allowed. */
+
+#cmakedefine BMP_SUPPORTED /* BMP image file format */
+#cmakedefine GIF_SUPPORTED /* GIF image file format */
+#cmakedefine PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#cmakedefine RLE_SUPPORTED /* Utah RLE image file format */
+#cmakedefine TARGA_SUPPORTED /* Targa image file format */
+
+/*
+ * This defines the default output format for djpeg. Must be one of the FMT_*
+ * enums found in djpeg.c or djpegalt.c
+ */
+#cmakedefine DEFAULT_FMT @DEFAULT_FMT@
+
+/* Define this if you want to name both input and output files on the command
+ * line, rather than using stdout and optionally stdin. You MUST do this if
+ * your system can't cope with binary I/O to stdin/stdout. See comments at
+ * head of cjpeg.c or djpeg.c.
+ */
+#cmakedefine TWO_FILE_COMMANDLINE
+
+/* Define this if your system needs explicit cleanup of temporary files.
+ * This is crucial under MS-DOS, where the temporary "files" may be areas
+ * of extended memory; on most other systems it's not as important.
+ */
+#cmakedefine NEED_SIGNAL_CATCHER
+
+/* By default, we open image files with fopen(...,"rb") or fopen(...,"wb").
+ * This is necessary on systems that distinguish text files from binary files,
+ * and is harmless on most systems that don't. If you have one of the rare
+ * systems that complains about the "b" spec, define this symbol.
+ */
+#cmakedefine DONT_USE_B_MODE
+
+/* Define this if you want percent-done progress reports from cjpeg/djpeg.
+ */
+#cmakedefine PROGRESS_REPORT
+
+/* Define this if you *don't* want overwrite confirmation */
+#cmakedefine NO_OVERWRITE_CHECK
+
+#endif /* JPEG_CJPEG_DJPEG */
diff -ruN jpeg-9f/jmorecfg.h jpeg-9f-new/jmorecfg.h
--- jpeg-9f/jmorecfg.h 2022-03-31 19:41:26.000000000 +1000
+++ jpeg-9f-new/jmorecfg.h 2024-03-23 21:20:25.514814400 +1000
@@ -244,8 +244,13 @@
#define LOCAL(type) static type
/* a function referenced thru EXTERNs: */
#define GLOBAL(type) type
+
/* a reference to a GLOBAL function: */
-#define EXTERN(type) extern type
+#ifdef COMPILING_LIBJPEG
+#define EXTERN(type) __declspec(dllexport) extern type
+#else
+#define EXTERN(type) __declspec(dllimport) extern type
+#endif
/* This macro is used to declare a "method", that is, a function pointer.
diff -ruN jpeg-9f/libjpeg.pc.cmakein jpeg-9f-new/libjpeg.pc.cmakein
--- jpeg-9f/libjpeg.pc.cmakein 1970-01-01 10:00:00.000000000 +1000
+++ jpeg-9f-new/libjpeg.pc.cmakein 2024-03-23 21:06:13.922695100 +1000
@@ -0,0 +1,10 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
+
+Name: libjpeg
+Description: Reads and writes JPEG files
+Version: @JPEG_LIB_VERSION_MAJOR@.@JPEG_LIB_VERSION_MINOR@.0
+Libs: -L${libdir} -ljpeg
+Cflags: -I${includedir}

View File

@@ -0,0 +1,13 @@
diff --git a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
index 208420d7e8..26ef6f31ef 100644
--- a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
+++ b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
@@ -4232,8 +4232,6 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption
case SE_ItemViewItemDecoration:
rect = QWindowsStyle::subElementRect(element, option, widget);
- if (qstyleoption_cast<const QStyleOptionViewItem *>(option))
- rect.adjust(-2, 0, 2, 0);
break;
case SE_ItemViewItemFocusRect:

View File

@@ -12,7 +12,7 @@ jobs:
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: xTVaser/first-interaction@v1.2.4
- uses: xTVaser/first-interaction@d62d6eb3c1215eae9f9d6dbfabf12d6725834cb3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
debug-mode: false

View File

@@ -13,7 +13,7 @@ jobs:
lint_vs_proj_files:
name: Lint VS Project Files
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
runs-on: windows-2019
runs-on: windows-2025
steps:
- name: Checkout Repository
uses: actions/checkout@v4

View File

@@ -12,7 +12,7 @@ on:
os:
required: false
type: string
default: windows-2022
default: windows-2025
platform:
required: false
type: string
@@ -55,13 +55,31 @@ jobs:
POWERSHELL_TELEMETRY_OPTOUT: 1
steps:
- name: Tempfix Clang
if: inputs.configuration == 'CMake'
run: choco uninstall llvm
- name: Checkout Repository
uses: actions/checkout@v4
- name: Configure MSBuild Clang Version
if: inputs.configuration != 'CMake'
shell: pwsh
run: |
[string[]] $clang_cl = &clang-cl.exe --version
$version = [Regex]::Match($clang_cl[0], "(\d+\.\d+\.\d+)")
$path = $clang_cl[3].TrimStart("InstalledDir: ").TrimEnd("\bin")
$output = @"
<Project>
<PropertyGroup>
<LLVMInstallDir>$path</LLVMInstallDir>
<LLVMToolsVersion>$version</LLVMToolsVersion>
</PropertyGroup>
</Project>
"@
Write-Host $output
$output | Out-File Directory.build.props
# actions/checkout elides tags, fetch them primarily for releases
- name: Fetch Tags
if: ${{ inputs.fetchTags }}
@@ -100,7 +118,7 @@ jobs:
uses: actions/cache@v4
with:
path: deps
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/windows/build-dependencies.bat') }}
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/windows/build-dependencies.bat', '.github/workflows/scripts/common/*.patch') }}
- name: Build Dependencies
if: steps.cache-deps.outputs.cache-hit != 'true'
@@ -149,8 +167,27 @@ jobs:
!./bin/**/*.pdb
!./bin/**/*.lib
- name: Install the Breakpad Symbol Generator
uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3
with:
crate: dump_syms
- name: Generate Breakpad Symbols # Also flatten pdbs to a 'symbols' directory for upload-artifact
shell: pwsh
run: |
mkdir -Force symbols
Get-ChildItem -Path ./bin -Recurse -File | Where-Object {
($_.Extension -eq ".exe" -or $_.Extension -eq ".pdb") -and ($_.Name -notmatch "updater")
} | ForEach-Object {
& dump_syms $_.FullName >> symbols/pcsx2-qt.bpsym
}
Get-ChildItem -Path ./bin -Recurse -Filter "*.pdb" | ForEach-Object {
Copy-Item $_.FullName -Destination symbols/
}
- name: Upload artifact - with symbols
uses: actions/upload-artifact@v4
with:
name: ${{ steps.artifact-metadata.outputs.artifact-name }}-symbols
path: ./bin/**/*.pdb
path: |
./symbols

1
.gitignore vendored
View File

@@ -119,3 +119,4 @@ oprofile_data/
CMakeSettings.json
/ci-artifacts/
/out/
/.cache/

41
3rdparty/ccc/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,41 @@
cmake_minimum_required(VERSION 3.14)
project(ccc)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_library(ccc STATIC
src/ccc/ast.cpp
src/ccc/ast.h
src/ccc/elf.cpp
src/ccc/elf.h
src/ccc/elf_symtab.cpp
src/ccc/elf_symtab.h
src/ccc/importer_flags.cpp
src/ccc/importer_flags.h
src/ccc/mdebug_analysis.cpp
src/ccc/mdebug_analysis.h
src/ccc/mdebug_importer.cpp
src/ccc/mdebug_importer.h
src/ccc/mdebug_section.cpp
src/ccc/mdebug_section.h
src/ccc/mdebug_symbols.cpp
src/ccc/mdebug_symbols.h
src/ccc/sndll.cpp
src/ccc/sndll.h
src/ccc/stabs.cpp
src/ccc/stabs.h
src/ccc/stabs_to_ast.cpp
src/ccc/stabs_to_ast.h
src/ccc/symbol_database.cpp
src/ccc/symbol_database.h
src/ccc/symbol_file.cpp
src/ccc/symbol_file.h
src/ccc/symbol_table.cpp
src/ccc/symbol_table.h
src/ccc/util.cpp
src/ccc/util.h
)
target_include_directories(ccc PUBLIC src)

37
3rdparty/ccc/README.md vendored Normal file
View File

@@ -0,0 +1,37 @@
# Chaos Compiler Collection
This code was originally developed in the following repository and was copied
into PCSX2 by the author:
- [https://github.com/chaoticgd/ccc](https://github.com/chaoticgd/ccc)
It includes additional resources that are not present in the PCSX2 repository.
## Documentation
### DWARF (.debug) Section
- [DWARF Debugging Information Format](https://dwarfstd.org/doc/dwarf_1_1_0.pdf)
### MIPS Debug (.mdebug) Section
- [Third Eye Software and the MIPS symbol table (Peter Rowell)](http://datahedron.com/mips.html)
- [MIPS Mdebug Debugging Information (David Anderson, 1996)](https://www.prevanders.net/Mdebug.ps)
- MIPS Assembly Language Programmer's Guide, Symbol Table Chapter (Silicon Graphics, 1992)
- Tru64 UNIX Object File and Symbol Table Format Specification, Symbol Table Chapter
- `mdebugread.c` from gdb (reading)
- `ecoff.c` from gas (writing)
- `include/coff/sym.h` from binutils (headers)
### MIPS EABI
- [MIPS EABI](https://sourceware.org/legacy-ml/binutils/2003-06/msg00436.html)
### STABS
- [The "stabs" representation of debugging information (Julia Menapace, Jim Kingdon, and David MacKenzie, 1992-???)](https://sourceware.org/gdb/onlinedocs/stabs.html)
- `stabs.c` from binutils (reading)
- `stabsread.c` from gdb (reading)
- `dbxread.c` from gdb (reading)
- `dbxout.c` from gcc (writing)
- `stab.def` from gcc (symbol codes)

75
3rdparty/ccc/ccc.vcxproj vendored Normal file
View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)common\vsprops\BaseProjectConfig.props" />
<Import Project="$(SolutionDir)common\vsprops\WinSDK.props" />
<PropertyGroup Label="Globals">
<ProjectGuid>{2589F8CE-EA77-4B73-911E-64074569795B}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset Condition="!$(Configuration.Contains(Clang))">$(DefaultPlatformToolset)</PlatformToolset>
<PlatformToolset Condition="$(Configuration.Contains(Clang))">ClangCL</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization Condition="$(Configuration.Contains(Release))">true</WholeProgramOptimization>
<UseDebugLibraries Condition="$(Configuration.Contains(Debug))">true</UseDebugLibraries>
<UseDebugLibraries Condition="!$(Configuration.Contains(Debug))">false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Condition="$(Configuration.Contains(Debug))" Project="..\..\common\vsprops\CodeGen_Debug.props" />
<Import Condition="$(Configuration.Contains(Devel))" Project="..\..\common\vsprops\CodeGen_Devel.props" />
<Import Condition="$(Configuration.Contains(Release))" Project="..\..\common\vsprops\CodeGen_Release.props" />
<Import Condition="!$(Configuration.Contains(Release))" Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<ClInclude Include="src\ccc\ast.h" />
<ClInclude Include="src\ccc\elf.h" />
<ClInclude Include="src\ccc\elf_symtab.h" />
<ClInclude Include="src\ccc\importer_flags.h" />
<ClInclude Include="src\ccc\mdebug_analysis.h" />
<ClInclude Include="src\ccc\mdebug_importer.h" />
<ClInclude Include="src\ccc\mdebug_section.h" />
<ClInclude Include="src\ccc\mdebug_symbols.h" />
<ClInclude Include="src\ccc\sndll.h" />
<ClInclude Include="src\ccc\stabs.h" />
<ClInclude Include="src\ccc\stabs_to_ast.h" />
<ClInclude Include="src\ccc\symbol_database.h" />
<ClInclude Include="src\ccc\symbol_file.h" />
<ClInclude Include="src\ccc\symbol_table.h" />
<ClInclude Include="src\ccc\util.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ccc\ast.cpp" />
<ClCompile Include="src\ccc\elf.cpp" />
<ClCompile Include="src\ccc\elf_symtab.cpp" />
<ClCompile Include="src\ccc\importer_flags.cpp" />
<ClCompile Include="src\ccc\mdebug_analysis.cpp" />
<ClCompile Include="src\ccc\mdebug_importer.cpp" />
<ClCompile Include="src\ccc\mdebug_section.cpp" />
<ClCompile Include="src\ccc\mdebug_symbols.cpp" />
<ClCompile Include="src\ccc\sndll.cpp" />
<ClCompile Include="src\ccc\stabs.cpp" />
<ClCompile Include="src\ccc\stabs_to_ast.cpp" />
<ClCompile Include="src\ccc\symbol_database.cpp" />
<ClCompile Include="src\ccc\symbol_file.cpp" />
<ClCompile Include="src\ccc\symbol_table.cpp" />
<ClCompile Include="src\ccc\util.cpp" />
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<AdditionalIncludeDirectories>$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>

111
3rdparty/ccc/ccc.vcxproj.filters vendored Normal file
View File

@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\ccc\ast.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\elf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\elf_symtab.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\importer_flags.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\mdebug_analysis.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\mdebug_importer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\mdebug_section.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\mdebug_symbols.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\sndll.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\stabs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\stabs_to_ast.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\symbol_database.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\symbol_file.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\symbol_table.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ccc\util.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ccc\ast.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\elf.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\elf_symtab.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\importer_flags.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\mdebug_analysis.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\mdebug_importer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\mdebug_section.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\mdebug_symbols.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\sndll.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\stabs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\stabs_to_ast.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\symbol_database.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\symbol_file.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\symbol_table.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ccc\util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

562
3rdparty/ccc/src/ccc/ast.cpp vendored Normal file
View File

@@ -0,0 +1,562 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "ast.h"
#include "importer_flags.h"
#include "symbol_database.h"
namespace ccc::ast {
static bool compare_nodes_and_merge(
CompareResult& dest, const Node& node_lhs, const Node& node_rhs, const SymbolDatabase* database);
static bool try_to_match_wobbly_typedefs(
const Node& node_lhs, const Node& node_rhs, const SymbolDatabase& database);
void Node::set_access_specifier(AccessSpecifier specifier, u32 importer_flags)
{
if((importer_flags & NO_ACCESS_SPECIFIERS) == 0) {
access_specifier = specifier;
}
}
std::pair<Node*, DataType*> Node::physical_type(SymbolDatabase& database, s32 max_depth)
{
Node* type = this;
DataType* symbol = nullptr;
for(s32 i = 0; i < max_depth && type->descriptor == TYPE_NAME; i++) {
DataType* data_type = database.data_types.symbol_from_handle(type->as<TypeName>().data_type_handle);
if (!data_type || !data_type->type()) {
break;
}
type = data_type->type();
symbol = data_type;
}
return std::pair(type, symbol);
}
std::pair<const Node*, const DataType*> Node::physical_type(const SymbolDatabase& database, s32 max_depth) const
{
return const_cast<Node*>(this)->physical_type(const_cast<SymbolDatabase&>(database), max_depth);
}
const char* member_function_modifier_to_string(MemberFunctionModifier modifier)
{
switch(modifier) {
case MemberFunctionModifier::NONE: return "none";
case MemberFunctionModifier::STATIC: return "static";
case MemberFunctionModifier::VIRTUAL: return "virtual";
}
return "";
}
bool StructOrUnion::flatten_fields(
std::vector<FlatField>& output,
const DataType* symbol,
const SymbolDatabase& database,
bool skip_statics,
s32 base_offset,
s32 max_fields,
s32 max_depth) const
{
if(max_depth == 0) {
return false;
}
for(const std::unique_ptr<Node>& type_name : base_classes) {
if(type_name->descriptor != TYPE_NAME) {
continue;
}
s32 new_base_offset = base_offset + type_name->offset_bytes;
DataTypeHandle handle = type_name->as<TypeName>().data_type_handle;
const DataType* base_class_symbol = database.data_types.symbol_from_handle(handle);
if(!base_class_symbol || !base_class_symbol->type() || base_class_symbol->type()->descriptor != STRUCT_OR_UNION) {
continue;
}
const StructOrUnion& base_class = base_class_symbol->type()->as<StructOrUnion>();
if(!base_class.flatten_fields(output, base_class_symbol, database, skip_statics, new_base_offset, max_fields, max_depth - 1)) {
return false;
}
}
for(const std::unique_ptr<Node>& field : fields) {
if(skip_statics && field->storage_class == STORAGE_CLASS_STATIC) {
continue;
}
if((s32) output.size() >= max_fields) {
return false;
}
FlatField& flat = output.emplace_back();
flat.node = field.get();
flat.symbol = symbol;
flat.base_offset = base_offset;
}
return true;
}
const char* type_name_source_to_string(TypeNameSource source)
{
switch(source) {
case TypeNameSource::REFERENCE: return "reference";
case TypeNameSource::CROSS_REFERENCE: return "cross_reference";
case TypeNameSource::UNNAMED_THIS: return "this";
}
return "";
}
const char* forward_declared_type_to_string(ForwardDeclaredType type)
{
switch(type) {
case ForwardDeclaredType::STRUCT: return "struct";
case ForwardDeclaredType::UNION: return "union";
case ForwardDeclaredType::ENUM: return "enum";
}
return "";
}
DataTypeHandle TypeName::data_type_handle_unless_forward_declared() const
{
if(!is_forward_declared) {
return data_type_handle;
} else {
return DataTypeHandle();
}
}
CompareResult compare_nodes(
const Node& node_lhs, const Node& node_rhs, const SymbolDatabase* database, bool check_intrusive_fields)
{
CompareResult result = CompareResultType::MATCHES_NO_SWAP;
if(node_lhs.descriptor != node_rhs.descriptor) {
return CompareFailReason::DESCRIPTOR;
}
if(check_intrusive_fields) {
if(node_lhs.storage_class != node_rhs.storage_class) {
// In some cases we can determine that a type was typedef'd for C
// translation units, but not for C++ translation units, so we need
// to add a special case for that here.
if(node_lhs.storage_class == STORAGE_CLASS_TYPEDEF && node_rhs.storage_class == STORAGE_CLASS_NONE) {
result = CompareResultType::MATCHES_FAVOUR_LHS;
} else if(node_lhs.storage_class == STORAGE_CLASS_NONE && node_rhs.storage_class == STORAGE_CLASS_TYPEDEF) {
result = CompareResultType::MATCHES_FAVOUR_RHS;
} else {
return CompareFailReason::STORAGE_CLASS;
}
}
// Vtable pointers and constructors can sometimes contain type numbers
// that are different between translation units, so we don't want to
// compare them.
bool is_vtable_pointer = node_lhs.is_vtable_pointer && node_rhs.is_vtable_pointer;
bool is_numbered_constructor = node_lhs.name.starts_with("$_") && node_rhs.name.starts_with("$_");
if(node_lhs.name != node_rhs.name && !is_vtable_pointer && !is_numbered_constructor) {
return CompareFailReason::NAME;
}
if(node_lhs.offset_bytes != node_rhs.offset_bytes) {
return CompareFailReason::RELATIVE_OFFSET_BYTES;
}
if(node_lhs.size_bits != node_rhs.size_bits) {
return CompareFailReason::SIZE_BITS;
}
if(node_lhs.is_const != node_rhs.is_const) {
return CompareFailReason::CONSTNESS;
}
}
switch(node_lhs.descriptor) {
case ARRAY: {
const auto [lhs, rhs] = Node::as<Array>(node_lhs, node_rhs);
if(compare_nodes_and_merge(result, *lhs.element_type.get(), *rhs.element_type.get(), database)) {
return result;
}
if(lhs.element_count != rhs.element_count) {
return CompareFailReason::ARRAY_ELEMENT_COUNT;
}
break;
}
case BITFIELD: {
const auto [lhs, rhs] = Node::as<BitField>(node_lhs, node_rhs);
if(lhs.bitfield_offset_bits != rhs.bitfield_offset_bits) {
return CompareFailReason::BITFIELD_OFFSET_BITS;
}
if(compare_nodes_and_merge(result, *lhs.underlying_type.get(), *rhs.underlying_type.get(), database)) {
return result;
}
break;
}
case BUILTIN: {
const auto [lhs, rhs] = Node::as<BuiltIn>(node_lhs, node_rhs);
if(lhs.bclass != rhs.bclass) {
return CompareFailReason::BUILTIN_CLASS;
}
break;
}
case ENUM: {
const auto [lhs, rhs] = Node::as<Enum>(node_lhs, node_rhs);
if(lhs.constants != rhs.constants) {
return CompareFailReason::ENUM_CONSTANTS;
}
break;
}
case ERROR_NODE: {
break;
}
case FUNCTION: {
const auto [lhs, rhs] = Node::as<Function>(node_lhs, node_rhs);
if(lhs.return_type.has_value() != rhs.return_type.has_value()) {
return CompareFailReason::FUNCTION_RETURN_TYPE_HAS_VALUE;
}
if(lhs.return_type.has_value()) {
if(compare_nodes_and_merge(result, *lhs.return_type->get(), *rhs.return_type->get(), database)) {
return result;
}
}
if(lhs.parameters.has_value() && rhs.parameters.has_value()) {
if(lhs.parameters->size() != rhs.parameters->size()) {
return CompareFailReason::FUNCTION_PARAMAETER_COUNT;
}
for(size_t i = 0; i < lhs.parameters->size(); i++) {
if(compare_nodes_and_merge(result, *(*lhs.parameters)[i].get(), *(*rhs.parameters)[i].get(), database)) {
return result;
}
}
} else if(lhs.parameters.has_value() != rhs.parameters.has_value()) {
return CompareFailReason::FUNCTION_PARAMETERS_HAS_VALUE;
}
if(lhs.modifier != rhs.modifier) {
return CompareFailReason::FUNCTION_MODIFIER;
}
break;
}
case POINTER_OR_REFERENCE: {
const auto [lhs, rhs] = Node::as<PointerOrReference>(node_lhs, node_rhs);
if(lhs.is_pointer != rhs.is_pointer) {
return CompareFailReason::DESCRIPTOR;
}
if(compare_nodes_and_merge(result, *lhs.value_type.get(), *rhs.value_type.get(), database)) {
return result;
}
break;
}
case POINTER_TO_DATA_MEMBER: {
const auto [lhs, rhs] = Node::as<PointerToDataMember>(node_lhs, node_rhs);
if(compare_nodes_and_merge(result, *lhs.class_type.get(), *rhs.class_type.get(), database)) {
return result;
}
if(compare_nodes_and_merge(result, *lhs.member_type.get(), *rhs.member_type.get(), database)) {
return result;
}
break;
}
case STRUCT_OR_UNION: {
const auto [lhs, rhs] = Node::as<StructOrUnion>(node_lhs, node_rhs);
if(lhs.is_struct != rhs.is_struct) {
return CompareFailReason::DESCRIPTOR;
}
if(lhs.base_classes.size() != rhs.base_classes.size()) {
return CompareFailReason::BASE_CLASS_COUNT;
}
for(size_t i = 0; i < lhs.base_classes.size(); i++) {
if(compare_nodes_and_merge(result, *lhs.base_classes[i].get(), *rhs.base_classes[i].get(), database)) {
return result;
}
}
if(lhs.fields.size() != rhs.fields.size()) {
return CompareFailReason::FIELDS_SIZE;
}
for(size_t i = 0; i < lhs.fields.size(); i++) {
if(compare_nodes_and_merge(result, *lhs.fields[i].get(), *rhs.fields[i].get(), database)) {
return result;
}
}
if(lhs.member_functions.size() != rhs.member_functions.size()) {
return CompareFailReason::MEMBER_FUNCTION_COUNT;
}
for(size_t i = 0; i < lhs.member_functions.size(); i++) {
if(compare_nodes_and_merge(result, *lhs.member_functions[i].get(), *rhs.member_functions[i].get(), database)) {
return result;
}
}
break;
}
case TYPE_NAME: {
const auto [lhs, rhs] = Node::as<TypeName>(node_lhs, node_rhs);
// Don't check the source so that REFERENCE and CROSS_REFERENCE are
// treated as the same.
if(lhs.data_type_handle != rhs.data_type_handle) {
return CompareFailReason::TYPE_NAME;
}
const TypeName::UnresolvedStabs* lhs_unresolved_stabs = lhs.unresolved_stabs.get();
const TypeName::UnresolvedStabs* rhs_unresolved_stabs = rhs.unresolved_stabs.get();
if(lhs_unresolved_stabs && rhs_unresolved_stabs) {
if(lhs_unresolved_stabs->type_name != rhs_unresolved_stabs->type_name) {
return CompareFailReason::TYPE_NAME;
}
} else if(lhs_unresolved_stabs || rhs_unresolved_stabs) {
return CompareFailReason::TYPE_NAME;
}
break;
}
}
return result;
}
static bool compare_nodes_and_merge(
CompareResult& dest, const Node& node_lhs, const Node& node_rhs, const SymbolDatabase* database)
{
CompareResult result = compare_nodes(node_lhs, node_rhs, database, true);
if(database) {
if(result.type == CompareResultType::DIFFERS && try_to_match_wobbly_typedefs(node_lhs, node_rhs, *database)) {
result.type = CompareResultType::MATCHES_FAVOUR_LHS;
} else if(result.type == CompareResultType::DIFFERS && try_to_match_wobbly_typedefs(node_rhs, node_lhs, *database)) {
result.type = CompareResultType::MATCHES_FAVOUR_RHS;
}
}
if(dest.type != result.type) {
if(dest.type == CompareResultType::DIFFERS || result.type == CompareResultType::DIFFERS) {
// If any of the inner types differ, the outer type does too.
dest.type = CompareResultType::DIFFERS;
} else if(dest.type == CompareResultType::MATCHES_CONFUSED || result.type == CompareResultType::MATCHES_CONFUSED) {
// Propagate confusion.
dest.type = CompareResultType::MATCHES_CONFUSED;
} else if(dest.type == CompareResultType::MATCHES_FAVOUR_LHS && result.type == CompareResultType::MATCHES_FAVOUR_RHS) {
// One of the results favours the LHS node and the other favours the
// RHS node so we are confused.
dest.type = CompareResultType::MATCHES_CONFUSED;
} else if(dest.type == CompareResultType::MATCHES_FAVOUR_RHS && result.type == CompareResultType::MATCHES_FAVOUR_LHS) {
// One of the results favours the LHS node and the other favours the
// RHS node so we are confused.
dest.type = CompareResultType::MATCHES_CONFUSED;
} else if(dest.type == CompareResultType::MATCHES_FAVOUR_LHS || result.type == CompareResultType::MATCHES_FAVOUR_LHS) {
// One of the results favours the LHS node and the other is neutral
// so go with the LHS node.
dest.type = CompareResultType::MATCHES_FAVOUR_LHS;
} else if(dest.type == CompareResultType::MATCHES_FAVOUR_RHS || result.type == CompareResultType::MATCHES_FAVOUR_RHS) {
// One of the results favours the RHS node and the other is neutral
// so go with the RHS node.
dest.type = CompareResultType::MATCHES_FAVOUR_RHS;
}
}
if(dest.fail_reason == CompareFailReason::NONE) {
dest.fail_reason = result.fail_reason;
}
return dest.type == CompareResultType::DIFFERS;
}
static bool try_to_match_wobbly_typedefs(
const Node& type_name_node, const Node& raw_node, const SymbolDatabase& database)
{
// Detect if one side has a typedef when the other just has the plain type.
// This was previously a common reason why type deduplication would fail.
if(type_name_node.descriptor != TYPE_NAME) {
return false;
}
const TypeName& type_name = type_name_node.as<TypeName>();
if(const TypeName::UnresolvedStabs* unresolved_stabs = type_name.unresolved_stabs.get()) {
if(unresolved_stabs->referenced_file_handle == (u32) -1 || !unresolved_stabs->stabs_type_number.valid()) {
return false;
}
const SourceFile* source_file =
database.source_files.symbol_from_handle(unresolved_stabs->referenced_file_handle);
CCC_ASSERT(source_file);
auto handle = source_file->stabs_type_number_to_handle.find(unresolved_stabs->stabs_type_number);
if(handle != source_file->stabs_type_number_to_handle.end()) {
const DataType* referenced_type = database.data_types.symbol_from_handle(handle->second);
CCC_ASSERT(referenced_type && referenced_type->type());
// Don't compare 'intrusive' fields e.g. the offset.
CompareResult new_result = compare_nodes(*referenced_type->type(), raw_node, &database, false);
if(new_result.type != CompareResultType::DIFFERS) {
return true;
}
}
}
return false;
}
const char* compare_fail_reason_to_string(CompareFailReason reason)
{
switch(reason) {
case CompareFailReason::NONE: return "error";
case CompareFailReason::DESCRIPTOR: return "descriptor";
case CompareFailReason::STORAGE_CLASS: return "storage class";
case CompareFailReason::NAME: return "name";
case CompareFailReason::RELATIVE_OFFSET_BYTES: return "relative offset";
case CompareFailReason::ABSOLUTE_OFFSET_BYTES: return "absolute offset";
case CompareFailReason::BITFIELD_OFFSET_BITS: return "bitfield offset";
case CompareFailReason::SIZE_BITS: return "size";
case CompareFailReason::CONSTNESS: return "constness";
case CompareFailReason::ARRAY_ELEMENT_COUNT: return "array element count";
case CompareFailReason::BUILTIN_CLASS: return "builtin class";
case CompareFailReason::FUNCTION_RETURN_TYPE_HAS_VALUE: return "function return type has value";
case CompareFailReason::FUNCTION_PARAMAETER_COUNT: return "function paramaeter count";
case CompareFailReason::FUNCTION_PARAMETERS_HAS_VALUE: return "function parameter";
case CompareFailReason::FUNCTION_MODIFIER: return "function modifier";
case CompareFailReason::ENUM_CONSTANTS: return "enum constant";
case CompareFailReason::BASE_CLASS_COUNT: return "base class count";
case CompareFailReason::FIELDS_SIZE: return "fields size";
case CompareFailReason::MEMBER_FUNCTION_COUNT: return "member function count";
case CompareFailReason::VTABLE_GLOBAL: return "vtable global";
case CompareFailReason::TYPE_NAME: return "type name";
case CompareFailReason::VARIABLE_CLASS: return "variable class";
case CompareFailReason::VARIABLE_TYPE: return "variable type";
case CompareFailReason::VARIABLE_STORAGE: return "variable storage";
case CompareFailReason::VARIABLE_BLOCK: return "variable block";
}
return "";
}
const char* node_type_to_string(const Node& node)
{
switch(node.descriptor) {
case ARRAY: return "array";
case BITFIELD: return "bitfield";
case BUILTIN: return "builtin";
case ENUM: return "enum";
case ERROR_NODE: return "error";
case FUNCTION: return "function";
case POINTER_OR_REFERENCE: {
const PointerOrReference& pointer_or_reference = node.as<PointerOrReference>();
if(pointer_or_reference.is_pointer) {
return "pointer";
} else {
return "reference";
}
}
case POINTER_TO_DATA_MEMBER: return "pointer_to_data_member";
case STRUCT_OR_UNION: {
const StructOrUnion& struct_or_union = node.as<StructOrUnion>();
if(struct_or_union.is_struct) {
return "struct";
} else {
return "union";
}
}
case TYPE_NAME: return "type_name";
}
return "";
}
const char* storage_class_to_string(StorageClass storage_class)
{
switch(storage_class) {
case STORAGE_CLASS_NONE: return "none";
case STORAGE_CLASS_TYPEDEF: return "typedef";
case STORAGE_CLASS_EXTERN: return "extern";
case STORAGE_CLASS_STATIC: return "static";
case STORAGE_CLASS_AUTO: return "auto";
case STORAGE_CLASS_REGISTER: return "register";
}
return "";
}
const char* access_specifier_to_string(AccessSpecifier specifier)
{
switch(specifier) {
case AS_PUBLIC: return "public";
case AS_PROTECTED: return "protected";
case AS_PRIVATE: return "private";
}
return "";
}
const char* builtin_class_to_string(BuiltInClass bclass)
{
switch(bclass) {
case BuiltInClass::VOID_TYPE: return "void";
case BuiltInClass::UNSIGNED_8: return "8-bit unsigned integer";
case BuiltInClass::SIGNED_8: return "8-bit signed integer";
case BuiltInClass::UNQUALIFIED_8: return "8-bit integer";
case BuiltInClass::BOOL_8: return "8-bit boolean";
case BuiltInClass::UNSIGNED_16: return "16-bit unsigned integer";
case BuiltInClass::SIGNED_16: return "16-bit signed integer";
case BuiltInClass::UNSIGNED_32: return "32-bit unsigned integer";
case BuiltInClass::SIGNED_32: return "32-bit signed integer";
case BuiltInClass::FLOAT_32: return "32-bit floating point";
case BuiltInClass::UNSIGNED_64: return "64-bit unsigned integer";
case BuiltInClass::SIGNED_64: return "64-bit signed integer";
case BuiltInClass::FLOAT_64: return "64-bit floating point";
case BuiltInClass::UNSIGNED_128: return "128-bit unsigned integer";
case BuiltInClass::SIGNED_128: return "128-bit signed integer";
case BuiltInClass::UNQUALIFIED_128: return "128-bit integer";
case BuiltInClass::FLOAT_128: return "128-bit floating point";
}
return "";
}
s32 builtin_class_size(BuiltInClass bclass)
{
switch(bclass) {
case BuiltInClass::VOID_TYPE: return 0;
case BuiltInClass::UNSIGNED_8: return 1;
case BuiltInClass::SIGNED_8: return 1;
case BuiltInClass::UNQUALIFIED_8: return 1;
case BuiltInClass::BOOL_8: return 1;
case BuiltInClass::UNSIGNED_16: return 2;
case BuiltInClass::SIGNED_16: return 2;
case BuiltInClass::UNSIGNED_32: return 4;
case BuiltInClass::SIGNED_32: return 4;
case BuiltInClass::FLOAT_32: return 4;
case BuiltInClass::UNSIGNED_64: return 8;
case BuiltInClass::SIGNED_64: return 8;
case BuiltInClass::FLOAT_64: return 8;
case BuiltInClass::UNSIGNED_128: return 16;
case BuiltInClass::SIGNED_128: return 16;
case BuiltInClass::UNQUALIFIED_128: return 16;
case BuiltInClass::FLOAT_128: return 16;
}
return 0;
}
}

377
3rdparty/ccc/src/ccc/ast.h vendored Normal file
View File

@@ -0,0 +1,377 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include "symbol_database.h"
namespace ccc::ast {
enum NodeDescriptor : u8 {
ARRAY,
BITFIELD,
BUILTIN,
ENUM,
ERROR_NODE,
FUNCTION,
POINTER_OR_REFERENCE,
POINTER_TO_DATA_MEMBER,
STRUCT_OR_UNION,
TYPE_NAME
};
enum AccessSpecifier {
AS_PUBLIC = 0,
AS_PROTECTED = 1,
AS_PRIVATE = 2
};
// To add a new type of node:
// 1. Add it to the NodeDescriptor enum.
// 2. Create a struct for it.
// 3. Add support for it in for_each_node.
// 4. Add support for it in compute_size_bytes_recursive.
// 5. Add support for it in compare_nodes.
// 6. Add support for it in node_type_to_string.
// 7. Add support for it in CppPrinter::ast_node.
// 8. Add support for it in write_json.
// 9. Add support for it in refine_node.
struct Node {
const NodeDescriptor descriptor;
u8 is_const : 1 = false;
u8 is_volatile : 1 = false;
u8 is_virtual_base_class : 1 = false;
u8 is_vtable_pointer : 1 = false;
u8 is_constructor_or_destructor : 1 = false;
u8 is_special_member_function : 1 = false;
u8 is_operator_member_function : 1 = false;
u8 cannot_compute_size : 1 = false;
u8 storage_class : 4 = STORAGE_CLASS_NONE;
u8 access_specifier : 2 = AS_PUBLIC;
s32 size_bytes = -1;
// If the name isn't populated for a given node, the name from the last
// ancestor to have one should be used i.e. when processing the tree you
// should pass the name down.
std::string name;
s32 offset_bytes = -1; // Offset relative to start of last inline struct/union.
s32 size_bits = -1; // Size stored in the .mdebug symbol table, may not be set.
Node(NodeDescriptor d) : descriptor(d) {}
Node(const Node& rhs) = default;
virtual ~Node() {}
template <typename SubType>
SubType& as() {
CCC_ASSERT(descriptor == SubType::DESCRIPTOR);
return *static_cast<SubType*>(this);
}
template <typename SubType>
const SubType& as() const {
CCC_ASSERT(descriptor == SubType::DESCRIPTOR);
return *static_cast<const SubType*>(this);
}
template <typename SubType>
static std::pair<const SubType&, const SubType&> as(const Node& lhs, const Node& rhs) {
CCC_ASSERT(lhs.descriptor == SubType::DESCRIPTOR && rhs.descriptor == SubType::DESCRIPTOR);
return std::pair<const SubType&, const SubType&>(static_cast<const SubType&>(lhs), static_cast<const SubType&>(rhs));
}
void set_access_specifier(AccessSpecifier specifier, u32 importer_flags);
// If this node is a type name, repeatedly resolve it to the type it's
// referencing, otherwise return (this, nullptr).
std::pair<Node*, DataType*> physical_type(SymbolDatabase& database, s32 max_depth = 100);
std::pair<const Node*, const DataType*> physical_type(const SymbolDatabase& database, s32 max_depth = 100) const;
};
struct Array : Node {
std::unique_ptr<Node> element_type;
s32 element_count = -1;
Array() : Node(DESCRIPTOR) {}
static const constexpr NodeDescriptor DESCRIPTOR = ARRAY;
};
struct BitField : Node {
s32 bitfield_offset_bits = -1; // Offset relative to the last byte (not the position of the underlying type!).
std::unique_ptr<Node> underlying_type;
BitField() : Node(DESCRIPTOR) {}
static const constexpr NodeDescriptor DESCRIPTOR = BITFIELD;
};
enum class BuiltInClass {
VOID_TYPE,
UNSIGNED_8, SIGNED_8, UNQUALIFIED_8, BOOL_8,
UNSIGNED_16, SIGNED_16,
UNSIGNED_32, SIGNED_32, FLOAT_32,
UNSIGNED_64, SIGNED_64, FLOAT_64,
UNSIGNED_128, SIGNED_128, UNQUALIFIED_128, FLOAT_128
};
struct BuiltIn : Node {
BuiltInClass bclass = BuiltInClass::VOID_TYPE;
BuiltIn() : Node(DESCRIPTOR) {}
static const constexpr NodeDescriptor DESCRIPTOR = BUILTIN;
};
struct Enum : Node {
std::vector<std::pair<s32, std::string>> constants;
Enum() : Node(DESCRIPTOR) {}
static const constexpr NodeDescriptor DESCRIPTOR = ENUM;
};
struct Error : Node {
std::string message;
Error() : Node(ERROR_NODE) {}
static const constexpr NodeDescriptor DESCRIPTOR = ERROR_NODE;
};
enum class MemberFunctionModifier {
NONE,
STATIC,
VIRTUAL
};
const char* member_function_modifier_to_string(MemberFunctionModifier modifier);
struct Function : Node {
std::optional<std::unique_ptr<Node>> return_type;
std::optional<std::vector<std::unique_ptr<Node>>> parameters;
MemberFunctionModifier modifier = MemberFunctionModifier::NONE;
s32 vtable_index = -1;
FunctionHandle definition_handle; // Filled in by fill_in_pointers_to_member_function_definitions.
Function() : Node(DESCRIPTOR) {}
static const constexpr NodeDescriptor DESCRIPTOR = FUNCTION;
};
struct PointerOrReference : Node {
bool is_pointer = true;
std::unique_ptr<Node> value_type;
PointerOrReference() : Node(DESCRIPTOR) {}
static const constexpr NodeDescriptor DESCRIPTOR = POINTER_OR_REFERENCE;
};
struct PointerToDataMember : Node {
std::unique_ptr<Node> class_type;
std::unique_ptr<Node> member_type;
PointerToDataMember() : Node(DESCRIPTOR) {}
static const constexpr NodeDescriptor DESCRIPTOR = POINTER_TO_DATA_MEMBER;
};
struct StructOrUnion : Node {
bool is_struct = true;
std::vector<std::unique_ptr<Node>> base_classes;
std::vector<std::unique_ptr<Node>> fields;
std::vector<std::unique_ptr<Node>> member_functions;
StructOrUnion() : Node(DESCRIPTOR) {}
static const constexpr NodeDescriptor DESCRIPTOR = STRUCT_OR_UNION;
struct FlatField {
// The field itself.
const Node* node;
// The symbol that owns the node.
const DataType* symbol;
// Offset of the innermost enclosing base class in the object.
s32 base_offset = 0;
};
// Generate a flat list of all the fields in this class as well as all the
// base classes recursively, but only until the max_fields or max_depth
// limits are reached. Return true if all the fields were enumerated.
bool flatten_fields(
std::vector<FlatField>& output,
const DataType* symbol,
const SymbolDatabase& database,
bool skip_statics,
s32 base_offset = 0,
s32 max_fields = 100000,
s32 max_depth = 100) const;
};
enum class TypeNameSource : u8 {
REFERENCE, // A STABS type reference.
CROSS_REFERENCE, // A STABS cross reference.
UNNAMED_THIS // A this parameter (or return type) referencing an unnamed type.
};
const char* type_name_source_to_string(TypeNameSource source);
enum class ForwardDeclaredType {
STRUCT,
UNION,
ENUM // Should be illegal but STABS supports cross references to enums so it's here.
};
const char* forward_declared_type_to_string(ForwardDeclaredType type);
struct TypeName : Node {
DataTypeHandle data_type_handle;
TypeNameSource source = TypeNameSource::REFERENCE;
bool is_forward_declared = false;
DataTypeHandle data_type_handle_unless_forward_declared() const;
struct UnresolvedStabs {
std::string type_name;
SourceFileHandle referenced_file_handle;
StabsTypeNumber stabs_type_number;
std::optional<ForwardDeclaredType> type;
};
std::unique_ptr<UnresolvedStabs> unresolved_stabs;
TypeName() : Node(DESCRIPTOR) {}
static const constexpr NodeDescriptor DESCRIPTOR = TYPE_NAME;
};
enum class CompareResultType {
MATCHES_NO_SWAP, // Both lhs and rhs are identical.
MATCHES_CONFUSED, // Both lhs and rhs are almost identical, and we don't which is better.
MATCHES_FAVOUR_LHS, // Both lhs and rhs are almost identical, but lhs is better.
MATCHES_FAVOUR_RHS, // Both lhs and rhs are almost identical, but rhs is better.
DIFFERS, // The two nodes differ substantially.
};
enum class CompareFailReason {
NONE,
DESCRIPTOR,
STORAGE_CLASS,
NAME,
RELATIVE_OFFSET_BYTES,
ABSOLUTE_OFFSET_BYTES,
BITFIELD_OFFSET_BITS,
SIZE_BITS,
CONSTNESS,
ARRAY_ELEMENT_COUNT,
BUILTIN_CLASS,
FUNCTION_RETURN_TYPE_HAS_VALUE,
FUNCTION_PARAMAETER_COUNT,
FUNCTION_PARAMETERS_HAS_VALUE,
FUNCTION_MODIFIER,
ENUM_CONSTANTS,
BASE_CLASS_COUNT,
FIELDS_SIZE,
MEMBER_FUNCTION_COUNT,
VTABLE_GLOBAL,
TYPE_NAME,
VARIABLE_CLASS,
VARIABLE_TYPE,
VARIABLE_STORAGE,
VARIABLE_BLOCK
};
struct CompareResult {
CompareResult(CompareResultType type) : type(type), fail_reason(CompareFailReason::NONE) {}
CompareResult(CompareFailReason reason) : type(CompareResultType::DIFFERS), fail_reason(reason) {}
CompareResultType type;
CompareFailReason fail_reason;
};
// Compare two AST nodes and their children recursively. This will only check
// fields that will be equal for two versions of the same type from different
// translation units.
CompareResult compare_nodes(const Node& lhs, const Node& rhs, const SymbolDatabase* database, bool check_intrusive_fields);
const char* compare_fail_reason_to_string(CompareFailReason reason);
const char* node_type_to_string(const Node& node);
const char* storage_class_to_string(StorageClass storage_class);
const char* access_specifier_to_string(AccessSpecifier specifier);
const char* builtin_class_to_string(BuiltInClass bclass);
s32 builtin_class_size(BuiltInClass bclass);
enum TraversalOrder {
PREORDER_TRAVERSAL,
POSTORDER_TRAVERSAL
};
enum ExplorationMode {
EXPLORE_CHILDREN,
DONT_EXPLORE_CHILDREN
};
template <typename ThisNode, typename Callback>
void for_each_node(ThisNode& node, TraversalOrder order, Callback callback)
{
if(order == PREORDER_TRAVERSAL && callback(node) == DONT_EXPLORE_CHILDREN) {
return;
}
switch(node.descriptor) {
case ARRAY: {
auto& array = node.template as<Array>();
for_each_node(*array.element_type.get(), order, callback);
break;
}
case BITFIELD: {
auto& bitfield = node.template as<BitField>();
for_each_node(*bitfield.underlying_type.get(), order, callback);
break;
}
case BUILTIN: {
break;
}
case ENUM: {
break;
}
case ERROR_NODE: {
break;
}
case FUNCTION: {
auto& func = node.template as<Function>();
if(func.return_type.has_value()) {
for_each_node(*func.return_type->get(), order, callback);
}
if(func.parameters.has_value()) {
for(auto& child : *func.parameters) {
for_each_node(*child.get(), order, callback);
}
}
break;
}
case POINTER_OR_REFERENCE: {
auto& pointer_or_reference = node.template as<PointerOrReference>();
for_each_node(*pointer_or_reference.value_type.get(), order, callback);
break;
}
case POINTER_TO_DATA_MEMBER: {
auto& pointer = node.template as<PointerToDataMember>();
for_each_node(*pointer.class_type.get(), order, callback);
for_each_node(*pointer.member_type.get(), order, callback);
break;
}
case STRUCT_OR_UNION: {
auto& struct_or_union = node.template as<StructOrUnion>();
for(auto& child : struct_or_union.base_classes) {
for_each_node(*child.get(), order, callback);
}
for(auto& child : struct_or_union.fields) {
for_each_node(*child.get(), order, callback);
}
for(auto& child : struct_or_union.member_functions) {
for_each_node(*child.get(), order, callback);
}
break;
}
case TYPE_NAME: {
break;
}
}
if(order == POSTORDER_TRAVERSAL) {
callback(node);
}
}
}

128
3rdparty/ccc/src/ccc/elf.cpp vendored Normal file
View File

@@ -0,0 +1,128 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "elf.h"
namespace ccc {
Result<ElfFile> ElfFile::parse(std::vector<u8> image)
{
ElfFile elf;
elf.image = std::move(image);
const ElfIdentHeader* ident = get_unaligned<ElfIdentHeader>(elf.image, 0);
CCC_CHECK(ident, "ELF ident header out of range.");
CCC_CHECK(ident->magic == CCC_FOURCC("\x7f\x45\x4c\x46"), "Not an ELF file.");
CCC_CHECK(ident->e_class == ElfIdentClass::B32, "Wrong ELF class (not 32 bit).");
const ElfFileHeader* header = get_unaligned<ElfFileHeader>(elf.image, sizeof(ElfIdentHeader));
CCC_CHECK(header, "ELF file header out of range.");
elf.file_header = *header;
const ElfSectionHeader* shstr_section_header =
get_unaligned<ElfSectionHeader>(elf.image, header->shoff + header->shstrndx * sizeof(ElfSectionHeader));
CCC_CHECK(shstr_section_header, "ELF section name header out of range.");
for(u32 i = 0; i < header->shnum; i++) {
u64 header_offset = header->shoff + i * sizeof(ElfSectionHeader);
const ElfSectionHeader* section_header = get_unaligned<ElfSectionHeader>(elf.image, header_offset);
CCC_CHECK(section_header, "ELF section header out of range.");
std::optional<std::string_view> name = get_string(elf.image, shstr_section_header->offset + section_header->name);
CCC_CHECK(name.has_value(), "ELF section name out of range.");
ElfSection& section = elf.sections.emplace_back();
section.name = *name;
section.header = *section_header;
}
for(u32 i = 0; i < header->phnum; i++) {
u64 header_offset = header->phoff + i * sizeof(ElfProgramHeader);
const ElfProgramHeader* program_header = get_unaligned<ElfProgramHeader>(elf.image, header_offset);
CCC_CHECK(program_header, "ELF program header out of range.");
elf.segments.emplace_back(*program_header);
}
return elf;
}
Result<void> ElfFile::create_section_symbols(
SymbolDatabase& database, const SymbolGroup& group) const
{
for(const ElfSection& section : sections) {
Address address = Address::non_zero(section.header.addr);
Result<Section*> symbol = database.sections.create_symbol(
section.name, address, group.source, group.module_symbol);
CCC_RETURN_IF_ERROR(symbol);
(*symbol)->set_size(section.header.size);
}
return Result<void>();
}
const ElfSection* ElfFile::lookup_section(const char* name) const
{
for(const ElfSection& section : sections) {
if(section.name == name) {
return &section;
}
}
return nullptr;
}
std::optional<u32> ElfFile::file_offset_to_virtual_address(u32 file_offset) const
{
for(const ElfProgramHeader& segment : segments) {
if(file_offset >= segment.offset && file_offset < segment.offset + segment.filesz) {
return segment.vaddr + file_offset - segment.offset;
}
}
return std::nullopt;
}
const ElfProgramHeader* ElfFile::entry_point_segment() const
{
const ccc::ElfProgramHeader* entry_segment = nullptr;
for(const ccc::ElfProgramHeader& segment : segments) {
if(file_header.entry >= segment.vaddr && file_header.entry < segment.vaddr + segment.filesz) {
entry_segment = &segment;
}
}
return entry_segment;
}
std::optional<std::span<const u8>> ElfFile::get_virtual(u32 address, u32 size) const
{
u32 end_address = address + size;
if(end_address >= address) {
for(const ElfProgramHeader& segment : segments) {
if(address >= segment.vaddr && end_address <= segment.vaddr + segment.filesz) {
size_t begin_offset = segment.offset + (address - segment.vaddr);
size_t end_offset = begin_offset + size;
if(begin_offset <= image.size() && end_offset <= image.size()) {
return std::span<const u8>(image.data() + begin_offset, image.data() + end_offset);
}
}
}
}
return std::nullopt;
}
bool ElfFile::copy_virtual(u8* dest, u32 address, u32 size) const
{
std::optional<std::span<const u8>> block = get_virtual(address, size);
if(!block.has_value()) {
return false;
}
memcpy(dest, block->data(), size);
return true;
}
}

160
3rdparty/ccc/src/ccc/elf.h vendored Normal file
View File

@@ -0,0 +1,160 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include "symbol_database.h"
namespace ccc {
enum class ElfIdentClass : u8 {
B32 = 0x1,
B64 = 0x2
};
CCC_PACKED_STRUCT(ElfIdentHeader,
/* 0x0 */ u32 magic; // 7f 45 4c 46
/* 0x4 */ ElfIdentClass e_class;
/* 0x5 */ u8 endianess;
/* 0x6 */ u8 version;
/* 0x7 */ u8 os_abi;
/* 0x8 */ u8 abi_version;
/* 0x9 */ u8 pad[7];
)
enum class ElfFileType : u16 {
NONE = 0x00,
REL = 0x01,
EXEC = 0x02,
DYN = 0x03,
CORE = 0x04,
LOOS = 0xfe00,
HIOS = 0xfeff,
LOPROC = 0xff00,
HIPROC = 0xffff
};
enum class ElfMachine : u16 {
MIPS = 0x08
};
CCC_PACKED_STRUCT(ElfFileHeader,
/* 0x10 */ ElfFileType type;
/* 0x12 */ ElfMachine machine;
/* 0x14 */ u32 version;
/* 0x18 */ u32 entry;
/* 0x1c */ u32 phoff;
/* 0x20 */ u32 shoff;
/* 0x24 */ u32 flags;
/* 0x28 */ u16 ehsize;
/* 0x2a */ u16 phentsize;
/* 0x2c */ u16 phnum;
/* 0x2e */ u16 shentsize;
/* 0x30 */ u16 shnum;
/* 0x32 */ u16 shstrndx;
)
enum class ElfSectionType : u32 {
NULL_SECTION = 0x0,
PROGBITS = 0x1,
SYMTAB = 0x2,
STRTAB = 0x3,
RELA = 0x4,
HASH = 0x5,
DYNAMIC = 0x6,
NOTE = 0x7,
NOBITS = 0x8,
REL = 0x9,
SHLIB = 0xa,
DYNSYM = 0xb,
INIT_ARRAY = 0xe,
FINI_ARRAY = 0xf,
PREINIT_ARRAY = 0x10,
GROUP = 0x11,
SYMTAB_SHNDX = 0x12,
NUM = 0x13,
LOOS = 0x60000000,
MIPS_DEBUG = 0x70000005
};
CCC_PACKED_STRUCT(ElfSectionHeader,
/* 0x00 */ u32 name;
/* 0x04 */ ElfSectionType type;
/* 0x08 */ u32 flags;
/* 0x0c */ u32 addr;
/* 0x10 */ u32 offset;
/* 0x14 */ u32 size;
/* 0x18 */ u32 link;
/* 0x1c */ u32 info;
/* 0x20 */ u32 addralign;
/* 0x24 */ u32 entsize;
)
struct ElfSection {
std::string name;
ElfSectionHeader header;
};
CCC_PACKED_STRUCT(ElfProgramHeader,
/* 0x00 */ u32 type;
/* 0x04 */ u32 offset;
/* 0x08 */ u32 vaddr;
/* 0x0c */ u32 paddr;
/* 0x10 */ u32 filesz;
/* 0x14 */ u32 memsz;
/* 0x18 */ u32 flags;
/* 0x1c */ u32 align;
)
struct ElfFile {
ElfFileHeader file_header;
std::vector<u8> image;
std::vector<ElfSection> sections;
std::vector<ElfProgramHeader> segments;
// Parse the ELF file header, section headers and program headers.
static Result<ElfFile> parse(std::vector<u8> image);
// Create a section object for each section header in the ELF file.
Result<void> create_section_symbols(SymbolDatabase& database, const SymbolGroup& group) const;
const ElfSection* lookup_section(const char* name) const;
std::optional<u32> file_offset_to_virtual_address(u32 file_offset) const;
// Find the program header for the segment that contains the entry point.
const ElfProgramHeader* entry_point_segment() const;
// Retrieve a block of data in an ELF file given its address and size.
std::optional<std::span<const u8>> get_virtual(u32 address, u32 size) const;
// Copy a block of data in an ELF file to the destination buffer given its
// address and size.
bool copy_virtual(u8* dest, u32 address, u32 size) const;
// Retrieve an object of type T from an ELF file given its address.
template <typename T>
std::optional<T> get_object_virtual(u32 address) const
{
std::optional<std::span<const u8>> result = get_virtual(address, sizeof(T));
if(!result.has_value()) {
return std::nullopt;
}
return *(T*) result->data();
}
// Retrieve an array of objects of type T from an ELF file given its
// address and element count.
template <typename T>
std::optional<std::span<const T>> get_array_virtual(u32 address, u32 element_count) const
{
std::optional<std::span<const u8>> result = get_virtual(address, element_count * sizeof(T));
if(!result.has_value()) {
return std::nullopt;
}
return std::span<const T>((T*) result->data(), (T*) (result->data() + result->size()));
}
};
}

214
3rdparty/ccc/src/ccc/elf_symtab.cpp vendored Normal file
View File

@@ -0,0 +1,214 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "elf_symtab.h"
#include "importer_flags.h"
namespace ccc::elf {
enum class SymbolBind : u8 {
LOCAL = 0,
GLOBAL = 1,
WEAK = 2,
NUM = 3,
GNU_UNIQUE = 10
};
enum class SymbolType : u8 {
NOTYPE = 0,
OBJECT = 1,
FUNC = 2,
SECTION = 3,
FILE = 4,
COMMON = 5,
TLS = 6,
NUM = 7,
GNU_IFUNC = 10
};
enum class SymbolVisibility {
DEFAULT = 0,
INTERNAL = 1,
HIDDEN = 2,
PROTECTED = 3
};
CCC_PACKED_STRUCT(Symbol,
/* 0x0 */ u32 name;
/* 0x4 */ u32 value;
/* 0x8 */ u32 size;
/* 0xc */ u8 info;
/* 0xd */ u8 other;
/* 0xe */ u16 shndx;
SymbolType type() const { return (SymbolType) (info & 0xf); }
SymbolBind bind() const { return (SymbolBind) (info >> 4); }
SymbolVisibility visibility() const { return (SymbolVisibility) (other & 0x3); }
)
static const char* symbol_bind_to_string(SymbolBind bind);
static const char* symbol_type_to_string(SymbolType type);
static const char* symbol_visibility_to_string(SymbolVisibility visibility);
Result<void> import_symbols(
SymbolDatabase& database,
const SymbolGroup& group,
std::span<const u8> symtab,
std::span<const u8> strtab,
u32 importer_flags,
DemanglerFunctions demangler)
{
for(u32 i = 0; i < symtab.size() / sizeof(Symbol); i++) {
const Symbol* symbol = get_unaligned<Symbol>(symtab, i * sizeof(Symbol));
CCC_ASSERT(symbol);
Address address;
if(symbol->value != 0) {
address = symbol->value;
}
if(!address.valid() || symbol->visibility() != SymbolVisibility::DEFAULT) {
continue;
}
if(!(importer_flags & DONT_DEDUPLICATE_SYMBOLS)) {
if(database.functions.first_handle_from_starting_address(address).valid()) {
continue;
}
if(database.global_variables.first_handle_from_starting_address(address).valid()) {
continue;
}
if(database.local_variables.first_handle_from_starting_address(address).valid()) {
continue;
}
}
std::optional<std::string_view> string_view = get_string(strtab, symbol->name);
CCC_CHECK(string_view.has_value(), "Symbol string out of range.");
std::string string(*string_view);
switch(symbol->type()) {
case SymbolType::NOTYPE: {
Result<Label*> label = database.labels.create_symbol(
std::move(string), group.source, group.module_symbol, address, importer_flags, demangler);
CCC_RETURN_IF_ERROR(label);
// These symbols get emitted at the same addresses as functions
// and aren't extremely useful, so we want to mark them to
// prevent them from possibly being used as function names.
(*label)->is_junk =
(*label)->name() == "__gnu_compiled_c" ||
(*label)->name() == "__gnu_compiled_cplusplus" ||
(*label)->name() == "gcc2_compiled.";
break;
}
case SymbolType::OBJECT: {
if(symbol->size != 0) {
Result<GlobalVariable*> global_variable = database.global_variables.create_symbol(
std::move(string), group.source, group.module_symbol, address, importer_flags, demangler);
CCC_RETURN_IF_ERROR(global_variable);
if(*global_variable) {
(*global_variable)->set_size(symbol->size);
}
} else {
Result<Label*> label = database.labels.create_symbol(
std::move(string), group.source, group.module_symbol, address, importer_flags, demangler);
CCC_RETURN_IF_ERROR(label);
}
break;
}
case SymbolType::FUNC: {
Result<Function*> function = database.functions.create_symbol(
std::move(string), group.source, group.module_symbol, address, importer_flags, demangler);
CCC_RETURN_IF_ERROR(function);
if(*function) {
(*function)->set_size(symbol->size);
}
break;
}
case SymbolType::FILE: {
Result<SourceFile*> source_file = database.source_files.create_symbol(
std::move(string), group.source, group.module_symbol);
CCC_RETURN_IF_ERROR(source_file);
break;
}
default: {}
}
}
return Result<void>();
}
Result<void> print_symbol_table(FILE* out, std::span<const u8> symtab, std::span<const u8> strtab)
{
fprintf(out, "ELF SYMBOLS:\n");
fprintf(out, " Num: Value Size Type Bind Vis Ndx Name\n");
for(u32 i = 0; i < symtab.size() / sizeof(Symbol); i++) {
const Symbol* symbol = get_unaligned<Symbol>(symtab, i * sizeof(Symbol));
CCC_ASSERT(symbol);
const char* type = symbol_type_to_string(symbol->type());
const char* bind = symbol_bind_to_string(symbol->bind());
const char* visibility = symbol_visibility_to_string(symbol->visibility());
std::optional<std::string_view> string = get_string(strtab, symbol->name);
CCC_CHECK(string.has_value(), "Symbol string out of range.");
fprintf(out, "%6u: %08x %5u %-7s %-7s %-7s %3u %s\n",
i, symbol->value, symbol->size, type, bind, visibility, symbol->shndx, string->data());
}
return Result<void>();
}
static const char* symbol_bind_to_string(SymbolBind bind)
{
switch(bind) {
case SymbolBind::LOCAL: return "LOCAL";
case SymbolBind::GLOBAL: return "GLOBAL";
case SymbolBind::WEAK: return "WEAK";
case SymbolBind::NUM: return "NUM";
case SymbolBind::GNU_UNIQUE: return "GNU_UNIQUE";
}
return "ERROR";
}
static const char* symbol_type_to_string(SymbolType type)
{
switch(type) {
case SymbolType::NOTYPE: return "NOTYPE";
case SymbolType::OBJECT: return "OBJECT";
case SymbolType::FUNC: return "FUNC";
case SymbolType::SECTION: return "SECTION";
case SymbolType::FILE: return "FILE";
case SymbolType::COMMON: return "COMMON";
case SymbolType::TLS: return "TLS";
case SymbolType::NUM: return "NUM";
case SymbolType::GNU_IFUNC: return "GNU_IFUNC";
}
return "ERROR";
}
static const char* symbol_visibility_to_string(SymbolVisibility visibility)
{
switch(visibility) {
case SymbolVisibility::DEFAULT: return "DEFAULT";
case SymbolVisibility::INTERNAL: return "INTERNAL";
case SymbolVisibility::HIDDEN: return "HIDDEN";
case SymbolVisibility::PROTECTED: return "PROTECTED";
}
return "ERROR";
}
}

20
3rdparty/ccc/src/ccc/elf_symtab.h vendored Normal file
View File

@@ -0,0 +1,20 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include "symbol_database.h"
namespace ccc::elf {
Result<void> import_symbols(
SymbolDatabase& database,
const SymbolGroup& group,
std::span<const u8> symtab,
std::span<const u8> strtab,
u32 importer_flags,
DemanglerFunctions demangler);
Result<void> print_symbol_table(FILE* out, std::span<const u8> symtab, std::span<const u8> strtab);
}

95
3rdparty/ccc/src/ccc/importer_flags.cpp vendored Normal file
View File

@@ -0,0 +1,95 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "importer_flags.h"
namespace ccc {
const std::vector<ImporterFlagInfo> IMPORTER_FLAGS = {
{DEMANGLE_PARAMETERS, "--demangle-parameters", {
"Include parameters in demangled function names."
}},
{DEMANGLE_RETURN_TYPE, "--demangle-return-type", {
"Include return types at the end of demangled",
"function names if they're available."
}},
{DONT_DEDUPLICATE_SYMBOLS, "--dont-deduplicate-symbols", {
"Do not deduplicate matching symbols from",
"different symbol tables. This options has no",
"effect on data types."
}},
{DONT_DEDUPLICATE_TYPES, "--dont-deduplicate-types", {
"Do not deduplicate data types from different",
"translation units."
}},
{DONT_DEMANGLE_NAMES, "--dont-demangle-names", {
"Do not demangle function names, global variable",
"names, or overloaded operator names."
}},
{INCLUDE_GENERATED_MEMBER_FUNCTIONS, "--include-generated-functions", {
"Output member functions that were likely",
"automatically generated by the compiler."
}},
{NO_ACCESS_SPECIFIERS, "--no-access-specifiers", {
"Do not print access specifiers."
}},
{NO_MEMBER_FUNCTIONS, "--no-member-functions", {
"Do not print member functions."
}},
{NO_OPTIMIZED_OUT_FUNCTIONS, "--no-optimized-out-functions", {
"Discard functions that were optimized out."
}},
{STRICT_PARSING, "--strict", {
"Make more types of errors fatal."
}},
{TYPEDEF_ALL_ENUMS, "--typedef-all-enums", {
"Force all emitted C++ enums to be defined using",
"a typedef. With STABS, it is not always possible",
"to determine if an enum was like this in the",
"original source code, so this option should be",
"useful for reverse engineering C projects."
}},
{TYPEDEF_ALL_STRUCTS, "--typedef-all-structs", {
"Force all emitted C++ structure types to be",
"defined using a typedef."
}},
{TYPEDEF_ALL_UNIONS, "--typedef-all-unions", {
"Force all emitted C++ union types to be defined",
"using a typedef."
}},
{UNIQUE_FUNCTIONS, "--unique-functions", {
" If multiple identical .mdebug function symbols",
"are present, find the one that seems to have",
"actually been included in the linked binary, and",
"remove the addresses from all the rest. Using",
"this importer flag in combination with",
"--no-optimized-out-functions will remove these",
"duplicate function symbols entirely."
}}
};
u32 parse_importer_flag(const char* argument)
{
for(const ImporterFlagInfo& flag : IMPORTER_FLAGS) {
if(strcmp(flag.argument, argument) == 0) {
return flag.flag;
}
}
return NO_IMPORTER_FLAGS;
}
void print_importer_flags_help(FILE* out)
{
for(const ImporterFlagInfo& flag : IMPORTER_FLAGS) {
fprintf(out, "\n");
fprintf(out, " %-29s ", flag.argument);
for(size_t i = 0; i < flag.help_text.size(); i++) {
if(i > 0) {
fprintf(out, " ");
}
fprintf(out, "%s\n", flag.help_text[i]);
}
}
}
}

39
3rdparty/ccc/src/ccc/importer_flags.h vendored Normal file
View File

@@ -0,0 +1,39 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include "util.h"
namespace ccc {
enum ImporterFlags {
NO_IMPORTER_FLAGS = 0,
DEMANGLE_PARAMETERS = (1 << 0),
DEMANGLE_RETURN_TYPE = (1 << 1),
DONT_DEDUPLICATE_SYMBOLS = (1 << 2),
DONT_DEDUPLICATE_TYPES = (1 << 3),
DONT_DEMANGLE_NAMES = (1 << 4),
INCLUDE_GENERATED_MEMBER_FUNCTIONS = (1 << 5),
NO_ACCESS_SPECIFIERS = (1 << 6),
NO_MEMBER_FUNCTIONS = (1 << 7),
NO_OPTIMIZED_OUT_FUNCTIONS = (1 << 8),
STRICT_PARSING = (1 << 9),
TYPEDEF_ALL_ENUMS = (1 << 10),
TYPEDEF_ALL_STRUCTS = (1 << 11),
TYPEDEF_ALL_UNIONS = (1 << 12),
UNIQUE_FUNCTIONS = (1 << 13)
};
struct ImporterFlagInfo {
ImporterFlags flag;
const char* argument;
std::vector<const char*> help_text;
};
extern const std::vector<ImporterFlagInfo> IMPORTER_FLAGS;
u32 parse_importer_flag(const char* argument);
void print_importer_flags_help(FILE* out);
}

349
3rdparty/ccc/src/ccc/mdebug_analysis.cpp vendored Normal file
View File

@@ -0,0 +1,349 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "mdebug_analysis.h"
#include "stabs_to_ast.h"
namespace ccc::mdebug {
Result<void> LocalSymbolTableAnalyser::stab_magic(const char* magic)
{
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::source_file(const char* path, Address text_address)
{
if(m_next_relative_path.empty()) {
m_next_relative_path = m_source_file.command_line_path;
}
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::data_type(const ParsedSymbol& symbol)
{
Result<std::unique_ptr<ast::Node>> node = stabs_type_to_ast(
*symbol.name_colon_type.type.get(), nullptr, m_stabs_to_ast_state, 0, false, false);
CCC_RETURN_IF_ERROR(node);
if(symbol.is_typedef && (*node)->descriptor == ast::STRUCT_OR_UNION) {
ast::StructOrUnion& struct_or_union = (*node)->as<ast::StructOrUnion>();
const std::string& name = symbol.name_colon_type.name;
StabsTypeNumber type_number = symbol.name_colon_type.type->type_number;
fix_recursively_emitted_structures(struct_or_union, name, type_number, m_stabs_to_ast_state.file_handle);
}
bool is_struct = (*node)->descriptor == ast::STRUCT_OR_UNION && (*node)->as<ast::StructOrUnion>().is_struct;
bool force_typedef =
((m_context.importer_flags & TYPEDEF_ALL_ENUMS) && (*node)->descriptor == ast::ENUM) ||
((m_context.importer_flags & TYPEDEF_ALL_STRUCTS) && (*node)->descriptor == ast::STRUCT_OR_UNION && is_struct) ||
((m_context.importer_flags & TYPEDEF_ALL_UNIONS) && (*node)->descriptor == ast::STRUCT_OR_UNION && !is_struct);
(*node)->name = (symbol.name_colon_type.name == " ") ? "" : symbol.name_colon_type.name;
if(symbol.is_typedef || force_typedef) {
(*node)->storage_class = STORAGE_CLASS_TYPEDEF;
}
const char* name = (*node)->name.c_str();
StabsTypeNumber number = symbol.name_colon_type.type->type_number;
if(m_context.importer_flags & DONT_DEDUPLICATE_TYPES) {
Result<DataType*> data_type = m_database.data_types.create_symbol(
name, m_context.group.source, m_context.group.module_symbol);
CCC_RETURN_IF_ERROR(data_type);
m_source_file.stabs_type_number_to_handle[number] = (*data_type)->handle();
(*data_type)->set_type(std::move(*node));
(*data_type)->files = {m_source_file.handle()};
} else {
Result<ccc::DataType*> type = m_database.create_data_type_if_unique(
std::move(*node), number, name, m_source_file, m_context.group);
CCC_RETURN_IF_ERROR(type);
}
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::global_variable(
const char* mangled_name, Address address, const StabsType& type, bool is_static, GlobalStorageLocation location)
{
Result<GlobalVariable*> global = m_database.global_variables.create_symbol(
mangled_name, m_context.group.source, m_context.group.module_symbol, address, m_context.importer_flags, m_context.demangler);
CCC_RETURN_IF_ERROR(global);
CCC_ASSERT(*global);
m_global_variables.emplace_back((*global)->handle());
Result<std::unique_ptr<ast::Node>> node = stabs_type_to_ast(type, nullptr, m_stabs_to_ast_state, 0, true, false);
CCC_RETURN_IF_ERROR(node);
if(is_static) {
(*global)->storage_class = STORAGE_CLASS_STATIC;
}
(*global)->set_type(std::move(*node));
(*global)->storage.location = location;
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::sub_source_file(const char* path, Address text_address)
{
if(m_current_function && m_state == IN_FUNCTION_BEGINNING) {
Function::SubSourceFile& sub = m_current_function->sub_source_files.emplace_back();
sub.address = text_address;
sub.relative_path = path;
} else {
m_next_relative_path = path;
}
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::procedure(
const char* mangled_name, Address address, const ProcedureDescriptor* procedure_descriptor, bool is_static)
{
if(!m_current_function || strcmp(mangled_name, m_current_function->mangled_name().c_str()) != 0) {
Result<void> result = create_function(mangled_name, address);
CCC_RETURN_IF_ERROR(result);
}
if(is_static) {
m_current_function->storage_class = STORAGE_CLASS_STATIC;
}
if(procedure_descriptor) {
m_current_function->stack_frame_size = procedure_descriptor->frame_size;
}
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::label(const char* label, Address address, s32 line_number)
{
if(address.valid() && m_current_function && label[0] == '$') {
Function::LineNumberPair& pair = m_current_function->line_numbers.emplace_back();
pair.address = address;
pair.line_number = line_number;
}
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::text_end(const char* name, s32 function_size)
{
if(m_state == IN_FUNCTION_BEGINNING) {
CCC_CHECK(m_current_function, "END TEXT symbol outside of function.");
m_current_function->set_size(function_size);
m_state = IN_FUNCTION_END;
}
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::function(const char* mangled_name, const StabsType& return_type, Address address)
{
if(!m_current_function || strcmp(mangled_name, m_current_function->mangled_name().c_str()) != 0) {
Result<void> result = create_function(mangled_name, address);
CCC_RETURN_IF_ERROR(result);
} else {
// For MTV Music Maker 2, the addresses for static functions stored in
// the PROC symbols are relative to the translation unit, while the
// addresses stored in the FUN symbol are absolute. This is the only
// game I've found that seems to have this problem, but since in all
// other cases it seems all these addresses are all absolute, I may as
// well add in a hack here to deal with it.
bool no_module_base_address = m_context.group.module_symbol && m_context.group.module_symbol->address().get_or_zero() == 0;
bool new_address_greater = address.valid() && address > m_current_function->address();
if(no_module_base_address && new_address_greater) {
m_database.functions.move_symbol(m_current_function->handle(), address);
}
}
Result<std::unique_ptr<ast::Node>> node = stabs_type_to_ast(return_type, nullptr, m_stabs_to_ast_state, 0, true, true);
CCC_RETURN_IF_ERROR(node);
m_current_function->set_type(std::move(*node));
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::function_end()
{
if(m_current_function) {
m_current_function->set_parameter_variables(std::move(m_current_parameter_variables), m_database);
m_current_function->set_local_variables(std::move(m_current_local_variables), m_database);
}
m_current_function = nullptr;
m_current_parameter_variables = std::vector<ParameterVariableHandle>();
m_current_local_variables = std::vector<LocalVariableHandle>();
m_blocks.clear();
m_pending_local_variables.clear();
m_state = NOT_IN_FUNCTION;
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::parameter(
const char* name, const StabsType& type, bool is_stack, s32 value, bool is_by_reference)
{
CCC_CHECK(m_current_function, "Parameter symbol before first func/proc symbol.");
Result<ParameterVariable*> parameter_variable = m_database.parameter_variables.create_symbol(
name, m_context.group.source, m_context.group.module_symbol);
CCC_RETURN_IF_ERROR(parameter_variable);
m_current_parameter_variables.emplace_back((*parameter_variable)->handle());
Result<std::unique_ptr<ast::Node>> node = stabs_type_to_ast(type, nullptr, m_stabs_to_ast_state, 0, true, true);
CCC_RETURN_IF_ERROR(node);
(*parameter_variable)->set_type(std::move(*node));
if(is_stack) {
StackStorage& stack_storage = (*parameter_variable)->storage.emplace<StackStorage>();
stack_storage.stack_pointer_offset = value;
} else {
RegisterStorage& register_storage = (*parameter_variable)->storage.emplace<RegisterStorage>();
register_storage.dbx_register_number = value;
register_storage.is_by_reference = is_by_reference;
}
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::local_variable(
const char* name, const StabsType& type, u32 value, StabsSymbolDescriptor desc, SymbolClass sclass)
{
if(!m_current_function) {
return Result<void>();
}
Address address = (desc == StabsSymbolDescriptor::STATIC_LOCAL_VARIABLE) ? value : Address();
Result<LocalVariable*> local_variable = m_database.local_variables.create_symbol(
name, address, m_context.group.source, m_context.group.module_symbol);
CCC_RETURN_IF_ERROR(local_variable);
m_current_local_variables.emplace_back((*local_variable)->handle());
m_pending_local_variables.emplace_back((*local_variable)->handle());
Result<std::unique_ptr<ast::Node>> node = stabs_type_to_ast(type, nullptr, m_stabs_to_ast_state, 0, true, false);
CCC_RETURN_IF_ERROR(node);
if(desc == StabsSymbolDescriptor::STATIC_LOCAL_VARIABLE) {
GlobalStorage& global_storage = (*local_variable)->storage.emplace<GlobalStorage>();
std::optional<GlobalStorageLocation> location_opt =
symbol_class_to_global_variable_location(sclass);
CCC_CHECK(location_opt.has_value(),
"Invalid static local variable location %s.",
symbol_class(sclass));
global_storage.location = *location_opt;
(*node)->storage_class = STORAGE_CLASS_STATIC;
} else if(desc == StabsSymbolDescriptor::REGISTER_VARIABLE) {
RegisterStorage& register_storage = (*local_variable)->storage.emplace<RegisterStorage>();
register_storage.dbx_register_number = (s32) value;
} else if(desc == StabsSymbolDescriptor::LOCAL_VARIABLE) {
StackStorage& stack_storage = (*local_variable)->storage.emplace<StackStorage>();
stack_storage.stack_pointer_offset = (s32) value;
} else {
return CCC_FAILURE("LocalSymbolTableAnalyser::local_variable() called with bad symbol descriptor.");
}
(*local_variable)->set_type(std::move(*node));
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::lbrac(s32 begin_offset)
{
for(LocalVariableHandle local_variable_handle : m_pending_local_variables) {
if(LocalVariable* local_variable = m_database.local_variables.symbol_from_handle(local_variable_handle)) {
local_variable->live_range.low = m_source_file.address().value + begin_offset;
}
}
m_blocks.emplace_back(std::move(m_pending_local_variables));
m_pending_local_variables = {};
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::rbrac(s32 end_offset)
{
CCC_CHECK(!m_blocks.empty(), "RBRAC symbol without a matching LBRAC symbol.");
std::vector<LocalVariableHandle>& variables = m_blocks.back();
for(LocalVariableHandle local_variable_handle : variables) {
if(LocalVariable* local_variable = m_database.local_variables.symbol_from_handle(local_variable_handle)) {
local_variable->live_range.high = m_source_file.address().value + end_offset;
}
}
m_blocks.pop_back();
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::finish()
{
CCC_CHECK(m_state != IN_FUNCTION_BEGINNING,
"Unexpected end of symbol table for '%s'.", m_source_file.name().c_str());
if(m_current_function) {
Result<void> result = function_end();
CCC_RETURN_IF_ERROR(result);
}
m_source_file.set_functions(std::move(m_functions), m_database);
m_source_file.set_global_variables(std::move(m_global_variables), m_database);
return Result<void>();
}
Result<void> LocalSymbolTableAnalyser::create_function(const char* mangled_name, Address address)
{
if(m_current_function) {
Result<void> result = function_end();
CCC_RETURN_IF_ERROR(result);
}
Result<Function*> function = m_database.functions.create_symbol(
mangled_name, m_context.group.source, m_context.group.module_symbol, address, m_context.importer_flags, m_context.demangler);
CCC_RETURN_IF_ERROR(function);
CCC_ASSERT(*function);
m_current_function = *function;
m_functions.emplace_back(m_current_function->handle());
m_state = IN_FUNCTION_BEGINNING;
if(!m_next_relative_path.empty() && m_current_function->relative_path != m_source_file.command_line_path) {
m_current_function->relative_path = m_next_relative_path;
}
return Result<void>();
}
std::optional<GlobalStorageLocation> symbol_class_to_global_variable_location(SymbolClass symbol_class)
{
std::optional<GlobalStorageLocation> location;
switch(symbol_class) {
case SymbolClass::NIL: location = GlobalStorageLocation::NIL; break;
case SymbolClass::DATA: location = GlobalStorageLocation::DATA; break;
case SymbolClass::BSS: location = GlobalStorageLocation::BSS; break;
case SymbolClass::ABS: location = GlobalStorageLocation::ABS; break;
case SymbolClass::SDATA: location = GlobalStorageLocation::SDATA; break;
case SymbolClass::SBSS: location = GlobalStorageLocation::SBSS; break;
case SymbolClass::RDATA: location = GlobalStorageLocation::RDATA; break;
case SymbolClass::COMMON: location = GlobalStorageLocation::COMMON; break;
case SymbolClass::SCOMMON: location = GlobalStorageLocation::SCOMMON; break;
case SymbolClass::SUNDEFINED: location = GlobalStorageLocation::SUNDEFINED; break;
default: {}
}
return location;
}
}

99
3rdparty/ccc/src/ccc/mdebug_analysis.h vendored Normal file
View File

@@ -0,0 +1,99 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include "importer_flags.h"
#include "mdebug_section.h"
#include "mdebug_symbols.h"
#include "stabs.h"
#include "stabs_to_ast.h"
#include "symbol_database.h"
namespace ccc::mdebug {
struct AnalysisContext {
const mdebug::SymbolTableReader* reader = nullptr;
const std::map<u32, const mdebug::Symbol*>* external_functions = nullptr;
const std::map<std::string, const mdebug::Symbol*>* external_globals = nullptr;
SymbolGroup group;
u32 importer_flags = NO_IMPORTER_FLAGS;
DemanglerFunctions demangler;
};
class LocalSymbolTableAnalyser {
public:
LocalSymbolTableAnalyser(SymbolDatabase& database, const StabsToAstState& stabs_to_ast_state, const AnalysisContext& context, SourceFile& source_file)
: m_database(database)
, m_context(context)
, m_stabs_to_ast_state(stabs_to_ast_state)
, m_source_file(source_file) {}
// Functions for processing individual symbols.
//
// In most cases these symbols will appear in the following order:
// PROC TEXT
// ... line numbers ... ($LM<N>)
// END TEXT
// LABEL TEXT FUN
// ... parameters ...
// ... blocks ... (... local variables ... LBRAC ... subblocks ... RBRAC)
// NIL NIL FUN
//
// For some compiler versions the symbols can appear in this order:
// LABEL TEXT FUN
// ... parameters ...
// first line number ($LM1)
// PROC TEXT
// ... line numbers ... ($LM<N>)
// END TEXT
// ... blocks ... (... local variables ... LBRAC ... subblocks ... RBRAC)
Result<void> stab_magic(const char* magic);
Result<void> source_file(const char* path, Address text_address);
Result<void> data_type(const ParsedSymbol& symbol);
Result<void> global_variable(
const char* mangled_name, Address address, const StabsType& type, bool is_static, GlobalStorageLocation location);
Result<void> sub_source_file(const char* name, Address text_address);
Result<void> procedure(
const char* mangled_name, Address address, const ProcedureDescriptor* procedure_descriptor, bool is_static);
Result<void> label(const char* label, Address address, s32 line_number);
Result<void> text_end(const char* name, s32 function_size);
Result<void> function(const char* mangled_name, const StabsType& return_type, Address address);
Result<void> function_end();
Result<void> parameter(
const char* name, const StabsType& type, bool is_stack, s32 value, bool is_by_reference);
Result<void> local_variable(
const char* name, const StabsType& type, u32 value, StabsSymbolDescriptor desc, SymbolClass sclass);
Result<void> lbrac(s32 begin_offset);
Result<void> rbrac(s32 end_offset);
Result<void> finish();
Result<void> create_function(const char* mangled_name, Address address);
protected:
enum AnalysisState {
NOT_IN_FUNCTION,
IN_FUNCTION_BEGINNING,
IN_FUNCTION_END
};
SymbolDatabase& m_database;
const AnalysisContext& m_context;
const StabsToAstState& m_stabs_to_ast_state;
AnalysisState m_state = NOT_IN_FUNCTION;
SourceFile& m_source_file;
std::vector<FunctionHandle> m_functions;
std::vector<GlobalVariableHandle> m_global_variables;
Function* m_current_function = nullptr;
std::vector<ParameterVariableHandle> m_current_parameter_variables;
std::vector<LocalVariableHandle> m_current_local_variables;
std::vector<std::vector<LocalVariableHandle>> m_blocks;
std::vector<LocalVariableHandle> m_pending_local_variables;
std::string m_next_relative_path;
};
std::optional<GlobalStorageLocation> symbol_class_to_global_variable_location(SymbolClass symbol_class);
};

668
3rdparty/ccc/src/ccc/mdebug_importer.cpp vendored Normal file
View File

@@ -0,0 +1,668 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "mdebug_importer.h"
namespace ccc::mdebug {
static Result<void> resolve_type_names(
SymbolDatabase& database, const SymbolGroup& group, u32 importer_flags);
static Result<void> resolve_type_name(
ast::TypeName& type_name,
SymbolDatabase& database,
const SymbolGroup& group,
u32 importer_flags);
static void compute_size_bytes(ast::Node& node, SymbolDatabase& database);
static void detect_duplicate_functions(SymbolDatabase& database, const SymbolGroup& group);
static void detect_fake_functions(SymbolDatabase& database, const std::map<u32, const mdebug::Symbol*>& external_functions, const SymbolGroup& group);
static void destroy_optimized_out_functions(
SymbolDatabase& database, const SymbolGroup& group);
Result<void> import_symbol_table(
SymbolDatabase& database,
std::span<const u8> elf,
s32 section_offset,
const SymbolGroup& group,
u32 importer_flags,
const DemanglerFunctions& demangler,
const std::atomic_bool* interrupt)
{
SymbolTableReader reader;
Result<void> reader_result = reader.init(elf, section_offset);
CCC_RETURN_IF_ERROR(reader_result);
Result<std::vector<mdebug::Symbol>> external_symbols = reader.parse_external_symbols();
CCC_RETURN_IF_ERROR(external_symbols);
// The addresses of the global variables aren't present in the local symbol
// table, so here we extract them from the external table. In addition, for
// some games we need to cross reference the function symbols in the local
// symbol table with the entries in the external symbol table.
std::map<u32, const mdebug::Symbol*> external_functions;
std::map<std::string, const mdebug::Symbol*> external_globals;
for(const mdebug::Symbol& external : *external_symbols) {
if(external.symbol_type == mdebug::SymbolType::PROC) {
external_functions[external.value] = &external;
}
if(external.symbol_type == mdebug::SymbolType::GLOBAL
&& (external.symbol_class != mdebug::SymbolClass::UNDEFINED)) {
external_globals[external.string] = &external;
}
}
// Bundle together some unchanging state to pass to import_files.
AnalysisContext context;
context.reader = &reader;
context.external_functions = &external_functions;
context.external_globals = &external_globals;
context.group = group;
context.importer_flags = importer_flags;
context.demangler = demangler;
Result<void> result = import_files(database, context, interrupt);
CCC_RETURN_IF_ERROR(result);
return Result<void>();
}
Result<void> import_files(SymbolDatabase& database, const AnalysisContext& context, const std::atomic_bool* interrupt)
{
Result<s32> file_count = context.reader->file_count();
CCC_RETURN_IF_ERROR(file_count);
for(s32 i = 0; i < *file_count; i++) {
if(interrupt && *interrupt) {
return CCC_FAILURE("Operation interrupted by user.");
}
Result<mdebug::File> file = context.reader->parse_file(i);
CCC_RETURN_IF_ERROR(file);
Result<void> result = import_file(database, *file, context);
CCC_RETURN_IF_ERROR(result);
}
// The files field may be modified by further analysis passes, so we
// need to save this information here.
for(DataType& data_type : database.data_types) {
if(context.group.is_in_group(data_type) && data_type.files.size() == 1) {
data_type.only_defined_in_single_translation_unit = true;
}
}
// Lookup data types and store data type handles in type names.
Result<void> type_name_result = resolve_type_names(database, context.group, context.importer_flags);
CCC_RETURN_IF_ERROR(type_name_result);
// Compute the size in bytes of all the AST nodes.
database.for_each_symbol([&](ccc::Symbol& symbol) {
if(context.group.is_in_group(symbol) && symbol.type()) {
compute_size_bytes(*symbol.type(), database);
}
});
// Propagate the size information to the global variable symbols.
for(GlobalVariable& global_variable : database.global_variables) {
if(global_variable.type() && global_variable.type()->size_bytes > -1) {
global_variable.set_size((u32) global_variable.type()->size_bytes);
}
}
// Propagate the size information to the static local variable symbols.
for(LocalVariable& local_variable : database.local_variables) {
bool is_static_local = std::holds_alternative<GlobalStorage>(local_variable.storage);
if(is_static_local && local_variable.type() && local_variable.type()->size_bytes > -1) {
local_variable.set_size((u32) local_variable.type()->size_bytes);
}
}
// Some games (e.g. Jet X2O) have multiple function symbols across different
// translation units with the same name and address.
if(context.importer_flags & UNIQUE_FUNCTIONS) {
detect_duplicate_functions(database, context.group);
}
// If multiple functions appear at the same address, discard the addresses
// of all of them except the real one.
if(context.external_functions) {
detect_fake_functions(database, *context.external_functions, context.group);
}
// Remove functions with no address. If there are any such functions, this
// will invalidate all pointers to symbols.
if(context.importer_flags & NO_OPTIMIZED_OUT_FUNCTIONS) {
destroy_optimized_out_functions(database, context.group);
}
return Result<void>();
}
Result<void> import_file(SymbolDatabase& database, const mdebug::File& input, const AnalysisContext& context)
{
// Parse the stab strings into a data structure that's vaguely
// one-to-one with the text-based representation.
u32 importer_flags_for_this_file = context.importer_flags;
Result<std::vector<ParsedSymbol>> symbols = parse_symbols(input.symbols, importer_flags_for_this_file);
CCC_RETURN_IF_ERROR(symbols);
// In stabs, types can be referenced by their number from other stabs,
// so here we build a map of type numbers to the parsed types.
std::map<StabsTypeNumber, const StabsType*> stabs_types;
for(const ParsedSymbol& symbol : *symbols) {
if(symbol.type == ParsedSymbolType::NAME_COLON_TYPE) {
symbol.name_colon_type.type->enumerate_numbered_types(stabs_types);
}
}
Result<SourceFile*> source_file = database.source_files.create_symbol(
input.full_path, input.address, context.group.source, context.group.module_symbol);
CCC_RETURN_IF_ERROR(source_file);
(*source_file)->working_dir = input.working_dir;
(*source_file)->command_line_path = input.command_line_path;
// Sometimes the INFO symbols contain information about what toolchain
// version was used for building the executable.
for(const mdebug::Symbol& symbol : input.symbols) {
if(symbol.symbol_class == mdebug::SymbolClass::INFO && strcmp(symbol.string, "@stabs") != 0) {
(*source_file)->toolchain_version_info.emplace(symbol.string);
}
}
StabsToAstState stabs_to_ast_state;
stabs_to_ast_state.file_handle = (*source_file)->handle().value;
stabs_to_ast_state.stabs_types = &stabs_types;
stabs_to_ast_state.importer_flags = importer_flags_for_this_file;
stabs_to_ast_state.demangler = context.demangler;
// Convert the parsed stabs symbols to a more standard C AST.
LocalSymbolTableAnalyser analyser(database, stabs_to_ast_state, context, **source_file);
for(const ParsedSymbol& symbol : *symbols) {
if(symbol.duplicate) {
continue;
}
switch(symbol.type) {
case ParsedSymbolType::NAME_COLON_TYPE: {
switch(symbol.name_colon_type.descriptor) {
case StabsSymbolDescriptor::LOCAL_FUNCTION:
case StabsSymbolDescriptor::GLOBAL_FUNCTION: {
const char* name = symbol.name_colon_type.name.c_str();
const StabsType& type = *symbol.name_colon_type.type.get();
Result<void> result = analyser.function(name, type, symbol.raw->value);
CCC_RETURN_IF_ERROR(result);
break;
}
case StabsSymbolDescriptor::REFERENCE_PARAMETER_A:
case StabsSymbolDescriptor::REGISTER_PARAMETER:
case StabsSymbolDescriptor::VALUE_PARAMETER:
case StabsSymbolDescriptor::REFERENCE_PARAMETER_V: {
const char* name = symbol.name_colon_type.name.c_str();
const StabsType& type = *symbol.name_colon_type.type.get();
bool is_stack_variable = symbol.name_colon_type.descriptor == StabsSymbolDescriptor::VALUE_PARAMETER;
bool is_by_reference = symbol.name_colon_type.descriptor == StabsSymbolDescriptor::REFERENCE_PARAMETER_A
|| symbol.name_colon_type.descriptor == StabsSymbolDescriptor::REFERENCE_PARAMETER_V;
Result<void> result = analyser.parameter(name, type, is_stack_variable, symbol.raw->value, is_by_reference);
CCC_RETURN_IF_ERROR(result);
break;
}
case StabsSymbolDescriptor::REGISTER_VARIABLE:
case StabsSymbolDescriptor::LOCAL_VARIABLE:
case StabsSymbolDescriptor::STATIC_LOCAL_VARIABLE: {
const char* name = symbol.name_colon_type.name.c_str();
const StabsType& type = *symbol.name_colon_type.type.get();
Result<void> result = analyser.local_variable(
name, type, symbol.raw->value, symbol.name_colon_type.descriptor, symbol.raw->symbol_class);
CCC_RETURN_IF_ERROR(result);
break;
}
case StabsSymbolDescriptor::GLOBAL_VARIABLE:
case StabsSymbolDescriptor::STATIC_GLOBAL_VARIABLE: {
const char* name = symbol.name_colon_type.name.c_str();
u32 address = -1;
std::optional<GlobalStorageLocation> location =
symbol_class_to_global_variable_location(symbol.raw->symbol_class);
if(symbol.name_colon_type.descriptor == StabsSymbolDescriptor::GLOBAL_VARIABLE) {
// The address for non-static global variables is
// only stored in the external symbol table (and
// the ELF symbol table), so we pull that
// information in here.
if(context.external_globals) {
auto global_symbol = context.external_globals->find(symbol.name_colon_type.name);
if(global_symbol != context.external_globals->end()) {
address = (u32) global_symbol->second->value;
location = symbol_class_to_global_variable_location(global_symbol->second->symbol_class);
}
}
} else {
// And for static global variables it's just stored
// in the local symbol table.
address = (u32) symbol.raw->value;
}
CCC_CHECK(location.has_value(), "Invalid global variable location.")
const StabsType& type = *symbol.name_colon_type.type.get();
bool is_static = symbol.name_colon_type.descriptor == StabsSymbolDescriptor::STATIC_GLOBAL_VARIABLE;
Result<void> result = analyser.global_variable(name, address, type, is_static, *location);
CCC_RETURN_IF_ERROR(result);
break;
}
case StabsSymbolDescriptor::TYPE_NAME:
case StabsSymbolDescriptor::ENUM_STRUCT_OR_TYPE_TAG: {
Result<void> result = analyser.data_type(symbol);
CCC_RETURN_IF_ERROR(result);
break;
}
}
break;
}
case ParsedSymbolType::SOURCE_FILE: {
Result<void> result = analyser.source_file(symbol.raw->string, symbol.raw->value);
CCC_RETURN_IF_ERROR(result);
break;
}
case ParsedSymbolType::SUB_SOURCE_FILE: {
Result<void> result = analyser.sub_source_file(symbol.raw->string, symbol.raw->value);
CCC_RETURN_IF_ERROR(result);
break;
}
case ParsedSymbolType::LBRAC: {
Result<void> result = analyser.lbrac(symbol.raw->value);
CCC_RETURN_IF_ERROR(result);
break;
}
case ParsedSymbolType::RBRAC: {
Result<void> result = analyser.rbrac(symbol.raw->value);
CCC_RETURN_IF_ERROR(result);
break;
}
case ParsedSymbolType::FUNCTION_END: {
Result<void> result = analyser.function_end();
CCC_RETURN_IF_ERROR(result);
break;
}
case ParsedSymbolType::NON_STABS: {
if(symbol.raw->symbol_class == mdebug::SymbolClass::TEXT) {
if(symbol.raw->symbol_type == mdebug::SymbolType::PROC) {
Result<void> result = analyser.procedure(symbol.raw->string, symbol.raw->value, symbol.raw->procedure_descriptor, false);
CCC_RETURN_IF_ERROR(result);
} else if(symbol.raw->symbol_type == mdebug::SymbolType::STATICPROC) {
Result<void> result = analyser.procedure(symbol.raw->string, symbol.raw->value, symbol.raw->procedure_descriptor, true);
CCC_RETURN_IF_ERROR(result);
} else if(symbol.raw->symbol_type == mdebug::SymbolType::LABEL) {
Result<void> result = analyser.label(symbol.raw->string, symbol.raw->value, symbol.raw->index);
CCC_RETURN_IF_ERROR(result);
} else if(symbol.raw->symbol_type == mdebug::SymbolType::END) {
Result<void> result = analyser.text_end(symbol.raw->string, symbol.raw->value);
CCC_RETURN_IF_ERROR(result);
}
}
break;
}
}
}
Result<void> result = analyser.finish();
CCC_RETURN_IF_ERROR(result);
return Result<void>();
}
static Result<void> resolve_type_names(
SymbolDatabase& database, const SymbolGroup& group, u32 importer_flags)
{
Result<void> result;
database.for_each_symbol([&](ccc::Symbol& symbol) {
if(group.is_in_group(symbol) && symbol.type()) {
ast::for_each_node(*symbol.type(), ast::PREORDER_TRAVERSAL, [&](ast::Node& node) {
if(node.descriptor == ast::TYPE_NAME) {
Result<void> type_name_result = resolve_type_name(node.as<ast::TypeName>(), database, group, importer_flags);
if(!type_name_result.success()) {
result = std::move(type_name_result);
}
}
return ast::EXPLORE_CHILDREN;
});
}
});
return result;
}
static Result<void> resolve_type_name(
ast::TypeName& type_name,
SymbolDatabase& database,
const SymbolGroup& group,
u32 importer_flags)
{
ast::TypeName::UnresolvedStabs* unresolved_stabs = type_name.unresolved_stabs.get();
if(!unresolved_stabs) {
return Result<void>();
}
// Lookup the type by its STABS type number. This path ensures that the
// correct type is found even if multiple types have the same name.
if(unresolved_stabs->referenced_file_handle != (u32) -1 && unresolved_stabs->stabs_type_number.valid()) {
const SourceFile* source_file = database.source_files.symbol_from_handle(unresolved_stabs->referenced_file_handle);
CCC_ASSERT(source_file);
auto handle = source_file->stabs_type_number_to_handle.find(unresolved_stabs->stabs_type_number);
if(handle != source_file->stabs_type_number_to_handle.end()) {
type_name.data_type_handle = handle->second.value;
type_name.is_forward_declared = false;
type_name.unresolved_stabs.reset();
return Result<void>();
}
}
// Looking up the type by its STABS type number failed, so look for it by
// its name instead. This happens when a type is forward declared but not
// defined in a given translation unit.
if(!unresolved_stabs->type_name.empty()) {
for(auto& name_handle : database.data_types.handles_from_name(unresolved_stabs->type_name)) {
DataType* data_type = database.data_types.symbol_from_handle(name_handle.second);
if(data_type && group.is_in_group(*data_type)) {
type_name.data_type_handle = name_handle.second.value;
type_name.is_forward_declared = true;
type_name.unresolved_stabs.reset();
return Result<void>();
}
}
}
// If this branch is taken it means the type name was probably from an
// automatically generated member function of a nested struct trying to
// reference the struct (for the this parameter). We shouldn't create a
// forward declared type in this case.
if(type_name.source == ast::TypeNameSource::UNNAMED_THIS) {
return Result<void>();
}
// Type lookup failed. This happens when a type is forward declared in a
// translation unit with symbols but is not defined in one. We haven't
// already created a forward declared type, so we create one now.
std::unique_ptr<ast::Node> forward_declared_node;
if(unresolved_stabs->type.has_value()) {
switch(*unresolved_stabs->type) {
case ast::ForwardDeclaredType::STRUCT: {
std::unique_ptr<ast::StructOrUnion> node = std::make_unique<ast::StructOrUnion>();
node->is_struct = true;
forward_declared_node = std::move(node);
break;
}
case ast::ForwardDeclaredType::UNION: {
std::unique_ptr<ast::StructOrUnion> node = std::make_unique<ast::StructOrUnion>();
node->is_struct = false;
forward_declared_node = std::move(node);
break;
}
case ast::ForwardDeclaredType::ENUM: {
std::unique_ptr<ast::Enum> node = std::make_unique<ast::Enum>();
forward_declared_node = std::move(node);
break;
}
}
}
if(forward_declared_node) {
Result<DataType*> forward_declared_type = database.data_types.create_symbol(
unresolved_stabs->type_name, group.source, group.module_symbol);
CCC_RETURN_IF_ERROR(forward_declared_type);
(*forward_declared_type)->set_type(std::move(forward_declared_node));
(*forward_declared_type)->not_defined_in_any_translation_unit = true;
type_name.data_type_handle = (*forward_declared_type)->handle().value;
type_name.is_forward_declared = true;
type_name.unresolved_stabs.reset();
return Result<void>();
}
const char* error_message = "Unresolved %s type name '%s' with STABS type number (%d,%d).";
if(importer_flags & STRICT_PARSING) {
return CCC_FAILURE(error_message,
ast::type_name_source_to_string(type_name.source),
type_name.unresolved_stabs->type_name.c_str(),
type_name.unresolved_stabs->stabs_type_number.file,
type_name.unresolved_stabs->stabs_type_number.type);
} else {
CCC_WARN(error_message,
ast::type_name_source_to_string(type_name.source),
type_name.unresolved_stabs->type_name.c_str(),
type_name.unresolved_stabs->stabs_type_number.file,
type_name.unresolved_stabs->stabs_type_number.type);
}
return Result<void>();
}
static void compute_size_bytes(ast::Node& node, SymbolDatabase& database)
{
for_each_node(node, ast::POSTORDER_TRAVERSAL, [&](ast::Node& node) {
// Skip nodes that have already been processed.
if(node.size_bytes > -1 || node.cannot_compute_size) {
return ast::EXPLORE_CHILDREN;
}
// Can't compute size recursively.
node.cannot_compute_size = true;
switch(node.descriptor) {
case ast::ARRAY: {
ast::Array& array = node.as<ast::Array>();
if(array.element_type->size_bytes > -1) {
array.size_bytes = array.element_type->size_bytes * array.element_count;
}
break;
}
case ast::BITFIELD: {
break;
}
case ast::BUILTIN: {
ast::BuiltIn& built_in = node.as<ast::BuiltIn>();
built_in.size_bytes = builtin_class_size(built_in.bclass);
break;
}
case ast::FUNCTION: {
break;
}
case ast::ENUM: {
node.size_bytes = 4;
break;
}
case ast::ERROR_NODE: {
break;
}
case ast::STRUCT_OR_UNION: {
node.size_bytes = node.size_bits / 8;
break;
}
case ast::POINTER_OR_REFERENCE: {
node.size_bytes = 4;
break;
}
case ast::POINTER_TO_DATA_MEMBER: {
break;
}
case ast::TYPE_NAME: {
ast::TypeName& type_name = node.as<ast::TypeName>();
DataType* resolved_type = database.data_types.symbol_from_handle(type_name.data_type_handle_unless_forward_declared());
if(resolved_type) {
ast::Node* resolved_node = resolved_type->type();
CCC_ASSERT(resolved_node);
if(resolved_node->size_bytes < 0 && !resolved_node->cannot_compute_size) {
compute_size_bytes(*resolved_node, database);
}
type_name.size_bytes = resolved_node->size_bytes;
}
break;
}
}
if(node.size_bytes > -1) {
node.cannot_compute_size = false;
}
return ast::EXPLORE_CHILDREN;
});
}
static void detect_duplicate_functions(SymbolDatabase& database, const SymbolGroup& group)
{
std::vector<FunctionHandle> duplicate_functions;
for(Function& test_function : database.functions) {
if(!test_function.address().valid() && !group.is_in_group(test_function)) {
continue;
}
// Find cases where there are two or more functions at the same address.
auto functions_with_same_address = database.functions.handles_from_starting_address(test_function.address());
if(functions_with_same_address.begin() == functions_with_same_address.end()) {
continue;
}
if(++functions_with_same_address.begin() == functions_with_same_address.end()) {
continue;
}
// Try to figure out the address of the translation unit which the
// version of the function that actually ended up in the linked binary
// comes from. We can't just check which source file the symbol comes
// from because it may be present in multiple.
u32 source_file_address = UINT32_MAX;
for(SourceFile& source_file : database.source_files) {
if(source_file.address() < test_function.address()) {
source_file_address = std::min(source_file.address().value, source_file_address);
}
}
if(source_file_address == UINT32_MAX) {
continue;
}
// Remove the addresses from all the matching symbols from other
// translation units.
FunctionHandle best_handle;
u32 best_offset = UINT32_MAX;
for(const auto& [address, handle] : functions_with_same_address) {
ccc::Function* function = database.functions.symbol_from_handle(handle);
if(!function || !group.is_in_group(*function) || function->mangled_name() != test_function.mangled_name()) {
continue;
}
if(address - source_file_address < best_offset) {
if(best_handle.valid()) {
duplicate_functions.emplace_back(best_handle);
}
best_handle = function->handle();
best_offset = address - source_file_address;
} else {
duplicate_functions.emplace_back(function->handle());
}
}
for(FunctionHandle duplicate_function : duplicate_functions) {
database.functions.move_symbol(duplicate_function, Address());
}
duplicate_functions.clear();
}
}
static void detect_fake_functions(SymbolDatabase& database, const std::map<u32, const mdebug::Symbol*>& external_functions, const SymbolGroup& group)
{
// Find cases where multiple fake function symbols were emitted for a given
// address and cross-reference with the external symbol table to try and
// find which one is the real one.
s32 fake_function_count = 0;
for(Function& function : database.functions) {
if(!function.address().valid() || !group.is_in_group(function)) {
continue;
}
// Find cases where there are two or more functions at the same address.
auto functions_with_same_address = database.functions.handles_from_starting_address(function.address());
if(functions_with_same_address.begin() == functions_with_same_address.end()) {
continue;
}
if(++functions_with_same_address.begin() == functions_with_same_address.end()) {
continue;
}
auto external_function = external_functions.find(function.address().value);
if(external_function == external_functions.end() || strcmp(function.mangled_name().c_str(), external_function->second->string) != 0) {
database.functions.move_symbol(function.handle(), Address());
if(fake_function_count < 10) {
CCC_WARN("Discarding address of function symbol '%s' as it is probably incorrect.", function.mangled_name().c_str());
} else if(fake_function_count == 10) {
CCC_WARN("Discarding more addresses of function symbols.");
}
fake_function_count++;
}
}
}
static void destroy_optimized_out_functions(
SymbolDatabase& database, const SymbolGroup& group)
{
bool marked = false;
for(Function& function : database.functions) {
if(group.is_in_group(function) && !function.address().valid()) {
function.mark_for_destruction();
marked = true;
}
}
if(marked) {
// This will invalidate all pointers to symbols in the database.
database.destroy_marked_symbols();
}
}
void fill_in_pointers_to_member_function_definitions(SymbolDatabase& database)
{
// Fill in pointers from member function declaration to corresponding definitions.
for(Function& function : database.functions) {
const std::string& qualified_name = function.name();
std::string::size_type name_separator_pos = qualified_name.find_last_of("::");
if(name_separator_pos == std::string::npos || name_separator_pos < 2) {
continue;
}
std::string function_name = qualified_name.substr(name_separator_pos + 1);
// This won't work for some template types.
std::string::size_type type_separator_pos = qualified_name.find_last_of("::", name_separator_pos - 2);
std::string type_name;
if(type_separator_pos != std::string::npos) {
type_name = qualified_name.substr(type_separator_pos + 1, name_separator_pos - type_separator_pos - 2);
} else {
type_name = qualified_name.substr(0, name_separator_pos - 1);
}
for(const auto& name_handle : database.data_types.handles_from_name(type_name)) {
DataType* data_type = database.data_types.symbol_from_handle(name_handle.second);
if(!data_type || !data_type->type() || data_type->type()->descriptor != ast::STRUCT_OR_UNION) {
continue;
}
ast::StructOrUnion& struct_or_union = data_type->type()->as<ast::StructOrUnion>();
for(std::unique_ptr<ast::Node>& declaration : struct_or_union.member_functions) {
if(declaration->name == function_name) {
declaration->as<ast::Function>().definition_handle = function.handle().value;
function.is_member_function_ish = true;
break;
}
}
if(function.is_member_function_ish) {
break;
}
}
}
}
}

31
3rdparty/ccc/src/ccc/mdebug_importer.h vendored Normal file
View File

@@ -0,0 +1,31 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include <atomic>
#include "mdebug_analysis.h"
#include "mdebug_section.h"
#include "symbol_database.h"
namespace ccc::mdebug {
// Perform all the main analysis passes on the mdebug symbol table and convert
// it to a set of C++ ASTs.
Result<void> import_symbol_table(
SymbolDatabase& database,
std::span<const u8> elf,
s32 section_offset,
const SymbolGroup& group,
u32 importer_flags,
const DemanglerFunctions& demangler,
const std::atomic_bool* interrupt);
Result<void> import_files(SymbolDatabase& database, const AnalysisContext& context, const std::atomic_bool* interrupt);
Result<void> import_file(SymbolDatabase& database, const mdebug::File& input, const AnalysisContext& context);
// Try to add pointers from member function declarations to their definitions
// using a heuristic.
void fill_in_pointers_to_member_function_definitions(SymbolDatabase& database);
}

474
3rdparty/ccc/src/ccc/mdebug_section.cpp vendored Normal file
View File

@@ -0,0 +1,474 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "mdebug_section.h"
namespace ccc::mdebug {
// MIPS debug symbol table headers.
// See include/coff/sym.h from GNU binutils for more information.
CCC_PACKED_STRUCT(SymbolicHeader,
/* 0x00 */ s16 magic;
/* 0x02 */ s16 version_stamp;
/* 0x04 */ s32 line_number_count;
/* 0x08 */ s32 line_numbers_size_bytes;
/* 0x0c */ s32 line_numbers_offset;
/* 0x10 */ s32 dense_numbers_count;
/* 0x14 */ s32 dense_numbers_offset;
/* 0x18 */ s32 procedure_descriptor_count;
/* 0x1c */ s32 procedure_descriptors_offset;
/* 0x20 */ s32 local_symbol_count;
/* 0x24 */ s32 local_symbols_offset;
/* 0x28 */ s32 optimization_symbols_count;
/* 0x2c */ s32 optimization_symbols_offset;
/* 0x30 */ s32 auxiliary_symbol_count;
/* 0x34 */ s32 auxiliary_symbols_offset;
/* 0x38 */ s32 local_strings_size_bytes;
/* 0x3c */ s32 local_strings_offset;
/* 0x40 */ s32 external_strings_size_bytes;
/* 0x44 */ s32 external_strings_offset;
/* 0x48 */ s32 file_descriptor_count;
/* 0x4c */ s32 file_descriptors_offset;
/* 0x50 */ s32 relative_file_descriptor_count;
/* 0x54 */ s32 relative_file_descriptors_offset;
/* 0x58 */ s32 external_symbols_count;
/* 0x5c */ s32 external_symbols_offset;
)
CCC_PACKED_STRUCT(FileDescriptor,
/* 0x00 */ u32 address;
/* 0x04 */ s32 file_path_string_offset;
/* 0x08 */ s32 strings_offset;
/* 0x0c */ s32 cb_ss;
/* 0x10 */ s32 isym_base;
/* 0x14 */ s32 symbol_count;
/* 0x18 */ s32 line_number_entry_index_base;
/* 0x1c */ s32 cline;
/* 0x20 */ s32 optimization_entry_index_base;
/* 0x24 */ s32 copt;
/* 0x28 */ u16 ipd_first;
/* 0x2a */ u16 procedure_descriptor_count;
/* 0x2c */ s32 iaux_base;
/* 0x30 */ s32 caux;
/* 0x34 */ s32 rfd_base;
/* 0x38 */ s32 crfd;
/* 0x3c */ u32 lang : 5;
/* 0x3c */ u32 f_merge : 1;
/* 0x3c */ u32 f_readin : 1;
/* 0x3c */ u32 f_big_endian : 1;
/* 0x3c */ u32 reserved_1 : 22;
/* 0x40 */ s32 line_number_offset;
/* 0x44 */ s32 cb_line;
)
static_assert(sizeof(FileDescriptor) == 0x48);
CCC_PACKED_STRUCT(SymbolHeader,
/* 0x0 */ u32 iss;
/* 0x4 */ u32 value;
/* 0x8 */ u32 st : 6;
/* 0x8 */ u32 sc : 5;
/* 0x8 */ u32 reserved : 1;
/* 0x8 */ u32 index : 20;
)
static_assert(sizeof(SymbolHeader) == 0xc);
CCC_PACKED_STRUCT(ExternalSymbolHeader,
/* 0x0 */ u16 flags;
/* 0x2 */ s16 ifd;
/* 0x4 */ SymbolHeader symbol;
)
static_assert(sizeof(ExternalSymbolHeader) == 0x10);
static void print_symbol(FILE* out, const Symbol& symbol);
static void print_procedure_descriptor(FILE* out, const ProcedureDescriptor& procedure_descriptor);
static Result<s32> get_corruption_fixing_fudge_offset(s32 section_offset, const SymbolicHeader& hdrr);
static Result<Symbol> get_symbol(const SymbolHeader& header, std::span<const u8> elf, s32 strings_offset);
Result<void> SymbolTableReader::init(std::span<const u8> elf, s32 section_offset)
{
m_elf = elf;
m_section_offset = section_offset;
m_hdrr = get_unaligned<SymbolicHeader>(m_elf, m_section_offset);
CCC_CHECK(m_hdrr != nullptr, "MIPS debug section header out of bounds.");
CCC_CHECK(m_hdrr->magic == 0x7009, "Invalid symbolic header.");
Result<s32> fudge_offset = get_corruption_fixing_fudge_offset(m_section_offset, *m_hdrr);
CCC_RETURN_IF_ERROR(fudge_offset);
m_fudge_offset = *fudge_offset;
m_ready = true;
return Result<void>();
}
s32 SymbolTableReader::file_count() const
{
CCC_ASSERT(m_ready);
return m_hdrr->file_descriptor_count;
}
Result<File> SymbolTableReader::parse_file(s32 index) const
{
CCC_ASSERT(m_ready);
File file;
u64 fd_offset = m_hdrr->file_descriptors_offset + index * sizeof(FileDescriptor);
const FileDescriptor* fd_header = get_unaligned<FileDescriptor>(m_elf, fd_offset + m_fudge_offset);
CCC_CHECK(fd_header != nullptr, "MIPS debug file descriptor out of bounds.");
CCC_CHECK(fd_header->f_big_endian == 0, "Not little endian or bad file descriptor table.");
file.address = fd_header->address;
s32 rel_raw_path_offset = fd_header->strings_offset + fd_header->file_path_string_offset;
s32 raw_path_offset = m_hdrr->local_strings_offset + rel_raw_path_offset + m_fudge_offset;
std::optional<std::string_view> command_line_path = get_string(m_elf, raw_path_offset);
if(command_line_path.has_value()) {
file.command_line_path = *command_line_path;
}
// Parse local symbols.
for(s64 j = 0; j < fd_header->symbol_count; j++) {
u64 rel_symbol_offset = (fd_header->isym_base + j) * sizeof(SymbolHeader);
u64 symbol_offset = m_hdrr->local_symbols_offset + rel_symbol_offset + m_fudge_offset;
const SymbolHeader* symbol_header = get_unaligned<SymbolHeader>(m_elf, symbol_offset);
CCC_CHECK(symbol_header != nullptr, "Symbol header out of bounds.");
s32 strings_offset = m_hdrr->local_strings_offset + fd_header->strings_offset + m_fudge_offset;
Result<Symbol> sym = get_symbol(*symbol_header, m_elf, strings_offset);
CCC_RETURN_IF_ERROR(sym);
bool string_offset_equal = (s32) symbol_header->iss == fd_header->file_path_string_offset;
if(file.working_dir.empty() && string_offset_equal && sym->is_stabs() && sym->code() == N_SO && file.symbols.size() > 2) {
const Symbol& working_dir = file.symbols.back();
if(working_dir.is_stabs() && working_dir.code() == N_SO) {
file.working_dir = working_dir.string;
}
}
file.symbols.emplace_back(std::move(*sym));
}
// Parse procedure descriptors.
for(s64 i = 0; i < fd_header->procedure_descriptor_count; i++) {
u64 rel_procedure_offset = (fd_header->ipd_first + i) * sizeof(ProcedureDescriptor);
u64 procedure_offset = m_hdrr->procedure_descriptors_offset + rel_procedure_offset + m_fudge_offset;
const ProcedureDescriptor* procedure_descriptor = get_unaligned<ProcedureDescriptor>(m_elf, procedure_offset);
CCC_CHECK(procedure_descriptor != nullptr, "Procedure descriptor out of bounds.");
CCC_CHECK(procedure_descriptor->symbol_index < file.symbols.size(), "Symbol index out of bounds.");
file.symbols[procedure_descriptor->symbol_index].procedure_descriptor = procedure_descriptor;
}
file.full_path = merge_paths(file.working_dir, file.command_line_path);
return file;
}
Result<std::vector<Symbol>> SymbolTableReader::parse_external_symbols() const
{
CCC_ASSERT(m_ready);
std::vector<Symbol> external_symbols;
for(s64 i = 0; i < m_hdrr->external_symbols_count; i++) {
u64 sym_offset = m_hdrr->external_symbols_offset + i * sizeof(ExternalSymbolHeader);
const ExternalSymbolHeader* external_header = get_unaligned<ExternalSymbolHeader>(m_elf, sym_offset + m_fudge_offset);
CCC_CHECK(external_header != nullptr, "External header out of bounds.");
Result<Symbol> sym = get_symbol(external_header->symbol, m_elf, m_hdrr->external_strings_offset + m_fudge_offset);
CCC_RETURN_IF_ERROR(sym);
external_symbols.emplace_back(std::move(*sym));
}
return external_symbols;
}
void SymbolTableReader::print_header(FILE* dest) const
{
CCC_ASSERT(m_ready);
fprintf(dest, "Symbolic Header, magic = %hx, vstamp = %hx:\n",
(u16) m_hdrr->magic,
(u16) m_hdrr->version_stamp);
fprintf(dest, "\n");
fprintf(dest, " Offset Size (Bytes) Count\n");
fprintf(dest, " ------ ------------ -----\n");
fprintf(dest, " Line Numbers 0x%-8x " "0x%-8x " "%-8d\n",
(u32) m_hdrr->line_numbers_offset,
(u32) m_hdrr->line_numbers_size_bytes,
m_hdrr->line_number_count);
fprintf(dest, " Dense Numbers 0x%-8x " "0x%-8x " "%-8d\n",
(u32) m_hdrr->dense_numbers_offset,
(u32) m_hdrr->dense_numbers_count * 8,
m_hdrr->dense_numbers_count);
fprintf(dest, " Procedure Descriptors 0x%-8x " "0x%-8x " "%-8d\n",
(u32) m_hdrr->procedure_descriptors_offset,
(u32) m_hdrr->procedure_descriptor_count * (u32) sizeof(ProcedureDescriptor),
m_hdrr->procedure_descriptor_count);
fprintf(dest, " Local Symbols 0x%-8x " "0x%-8x " "%-8d\n",
(u32) m_hdrr->local_symbols_offset,
(u32) m_hdrr->local_symbol_count * (u32) sizeof(SymbolHeader),
m_hdrr->local_symbol_count);
fprintf(dest, " Optimization Symbols 0x%-8x " "- " "%-8d\n",
(u32) m_hdrr->optimization_symbols_offset,
m_hdrr->optimization_symbols_count);
fprintf(dest, " Auxiliary Symbols 0x%-8x " "0x%-8x " "%-8d\n",
(u32) m_hdrr->auxiliary_symbols_offset,
(u32) m_hdrr->auxiliary_symbol_count * 4,
m_hdrr->auxiliary_symbol_count);
fprintf(dest, " Local Strings 0x%-8x " "0x%-8x " "-\n",
(u32) m_hdrr->local_strings_offset,
(u32) m_hdrr->local_strings_size_bytes);
fprintf(dest, " External Strings 0x%-8x " "0x%-8x " "-\n",
(u32) m_hdrr->external_strings_offset,
(u32) m_hdrr->external_strings_size_bytes);
fprintf(dest, " File Descriptors 0x%-8x " "0x%-8x " "%-8d\n",
(u32) m_hdrr->file_descriptors_offset,
(u32) m_hdrr->file_descriptor_count * (u32) sizeof(FileDescriptor),
m_hdrr->file_descriptor_count);
fprintf(dest, " Relative File Descriptors 0x%-8x " "0x%-8x " "%-8d\n",
(u32) m_hdrr->relative_file_descriptors_offset,
(u32) m_hdrr->relative_file_descriptor_count * 4,
m_hdrr->relative_file_descriptor_count);
fprintf(dest, " External Symbols 0x%-8x " "0x%-8x " "%-8d\n",
(u32) m_hdrr->external_symbols_offset,
(u32) m_hdrr->external_symbols_count * 16,
m_hdrr->external_symbols_count);
}
Result<void> SymbolTableReader::print_symbols(FILE* out, bool print_locals, bool print_procedure_descriptors, bool print_externals) const
{
if(print_locals || print_procedure_descriptors) {
s32 count = file_count();
for(s32 i = 0; i < count; i++) {
Result<File> file = parse_file(i);
CCC_RETURN_IF_ERROR(file);
fprintf(out, "FILE %s:\n", file->command_line_path.c_str());
for(const Symbol& symbol : file->symbols) {
if(print_locals || symbol.procedure_descriptor) {
print_symbol(out, symbol);
}
if(print_procedure_descriptors && symbol.procedure_descriptor) {
print_procedure_descriptor(out, *symbol.procedure_descriptor);
}
}
}
}
if(print_externals) {
fprintf(out, "EXTERNAL SYMBOLS:\n");
Result<std::vector<Symbol>> external_symbols = parse_external_symbols();
CCC_RETURN_IF_ERROR(external_symbols);
for(const Symbol& symbol : *external_symbols) {
print_symbol(out, symbol);
}
}
return Result<void>();
}
static void print_symbol(FILE* out, const Symbol& symbol)
{
fprintf(out, " %8x ", symbol.value);
const char* symbol_type_str = symbol_type(symbol.symbol_type);
if(symbol_type_str) {
fprintf(out, "%-11s ", symbol_type_str);
} else {
fprintf(out, "ST(%7u) ", (u32) symbol.symbol_type);
}
const char* symbol_class_str = symbol_class(symbol.symbol_class);
if(symbol_class_str) {
fprintf(out, "%-4s ", symbol_class_str);
} else if ((u32) symbol.symbol_class == 0) {
fprintf(out, " ");
} else {
fprintf(out, "SC(%4u) ", (u32) symbol.symbol_class);
}
if(symbol.is_stabs()) {
fprintf(out, "%-8s ", stabs_code_to_string(symbol.code()));
} else {
fprintf(out, "SI(%4u) ", symbol.index);
}
fprintf(out, "%s\n", symbol.string);
}
static void print_procedure_descriptor(FILE* out, const ProcedureDescriptor& procedure_descriptor)
{
fprintf(out, " Address 0x%08x\n", procedure_descriptor.address);
fprintf(out, " Symbol Index %d\n", procedure_descriptor.symbol_index);
fprintf(out, " Line Number Entry Index %d\n", procedure_descriptor.line_number_entry_index);
fprintf(out, " Saved Register Mask 0x%08x\n", procedure_descriptor.saved_register_mask);
fprintf(out, " Saved Register Offset %d\n", procedure_descriptor.saved_register_offset);
fprintf(out, " Optimization Entry Index %d\n", procedure_descriptor.optimization_entry_index);
fprintf(out, " Saved Float Register Mask 0x%08x\n", procedure_descriptor.saved_float_register_mask);
fprintf(out, " Saved Float Register Offset %d\n", procedure_descriptor.saved_float_register_offset);
fprintf(out, " Frame Size %d\n", procedure_descriptor.frame_size);
fprintf(out, " Frame Pointer Register %hd\n", procedure_descriptor.frame_pointer_register);
fprintf(out, " Return PC Register %hd\n", procedure_descriptor.return_pc_register);
fprintf(out, " Line Number Low %d\n", procedure_descriptor.line_number_low);
fprintf(out, " Line Number High %d\n", procedure_descriptor.line_number_high);
fprintf(out, " Line Number Offset %d\n", procedure_descriptor.line_number_offset);
}
static Result<s32> get_corruption_fixing_fudge_offset(s32 section_offset, const SymbolicHeader& hdrr)
{
// GCC will always put the first part of the symbol table right after the
// header, so if the header says it's somewhere else we know the section has
// probably been moved without updating its contents.
s32 right_after_header = INT32_MAX;
if(hdrr.line_numbers_offset > 0) right_after_header = std::min(hdrr.line_numbers_offset, right_after_header);
if(hdrr.dense_numbers_offset > 0) right_after_header = std::min(hdrr.dense_numbers_offset, right_after_header);
if(hdrr.procedure_descriptors_offset > 0) right_after_header = std::min(hdrr.procedure_descriptors_offset, right_after_header);
if(hdrr.local_symbols_offset > 0) right_after_header = std::min(hdrr.local_symbols_offset, right_after_header);
if(hdrr.optimization_symbols_offset > 0) right_after_header = std::min(hdrr.optimization_symbols_offset, right_after_header);
if(hdrr.auxiliary_symbols_offset > 0) right_after_header = std::min(hdrr.auxiliary_symbols_offset, right_after_header);
if(hdrr.local_strings_offset > 0) right_after_header = std::min(hdrr.local_strings_offset, right_after_header);
if(hdrr.external_strings_offset > 0) right_after_header = std::min(hdrr.external_strings_offset, right_after_header);
if(hdrr.file_descriptors_offset > 0) right_after_header = std::min(hdrr.file_descriptors_offset, right_after_header);
if(hdrr.relative_file_descriptors_offset > 0) right_after_header = std::min(hdrr.relative_file_descriptors_offset, right_after_header);
if(hdrr.external_symbols_offset > 0) right_after_header = std::min(hdrr.external_symbols_offset, right_after_header);
CCC_CHECK(right_after_header >= 0 && right_after_header < INT32_MAX, "Invalid symbolic header.");
// Figure out how much we need to adjust all the file offsets by.
s32 fudge_offset = section_offset - (right_after_header - sizeof(SymbolicHeader));
if(fudge_offset != 0) {
CCC_WARN("The .mdebug section was moved without updating its contents. Adjusting file offsets by %d bytes.", fudge_offset);
}
return fudge_offset;
}
static Result<Symbol> get_symbol(const SymbolHeader& header, std::span<const u8> elf, s32 strings_offset)
{
Symbol symbol;
std::optional<std::string_view> string = get_string(elf, strings_offset + header.iss);
CCC_CHECK(string.has_value(), "Symbol has invalid string.");
symbol.string = string->data();
symbol.value = header.value;
symbol.symbol_type = (SymbolType) header.st;
symbol.symbol_class = (SymbolClass) header.sc;
symbol.index = header.index;
if(symbol.is_stabs()) {
CCC_CHECK(stabs_code_to_string(symbol.code()) != nullptr, "Bad stabs symbol code '%x'.", symbol.code());
}
return symbol;
}
const char* symbol_type(SymbolType type)
{
switch(type) {
case SymbolType::NIL: return "NIL";
case SymbolType::GLOBAL: return "GLOBAL";
case SymbolType::STATIC: return "STATIC";
case SymbolType::PARAM: return "PARAM";
case SymbolType::LOCAL: return "LOCAL";
case SymbolType::LABEL: return "LABEL";
case SymbolType::PROC: return "PROC";
case SymbolType::BLOCK: return "BLOCK";
case SymbolType::END: return "END";
case SymbolType::MEMBER: return "MEMBER";
case SymbolType::TYPEDEF: return "TYPEDEF";
case SymbolType::FILE_SYMBOL: return "FILE";
case SymbolType::STATICPROC: return "STATICPROC";
case SymbolType::CONSTANT: return "CONSTANT";
}
return nullptr;
}
const char* symbol_class(SymbolClass symbol_class)
{
switch(symbol_class) {
case SymbolClass::NIL: return "NIL";
case SymbolClass::TEXT: return "TEXT";
case SymbolClass::DATA: return "DATA";
case SymbolClass::BSS: return "BSS";
case SymbolClass::REGISTER: return "REGISTER";
case SymbolClass::ABS: return "ABS";
case SymbolClass::UNDEFINED: return "UNDEFINED";
case SymbolClass::LOCAL: return "LOCAL";
case SymbolClass::BITS: return "BITS";
case SymbolClass::DBX: return "DBX";
case SymbolClass::REG_IMAGE: return "REG_IMAGE";
case SymbolClass::INFO: return "INFO";
case SymbolClass::USER_STRUCT: return "USER_STRUCT";
case SymbolClass::SDATA: return "SDATA";
case SymbolClass::SBSS: return "SBSS";
case SymbolClass::RDATA: return "RDATA";
case SymbolClass::VAR: return "VAR";
case SymbolClass::COMMON: return "COMMON";
case SymbolClass::SCOMMON: return "SCOMMON";
case SymbolClass::VAR_REGISTER: return "VAR_REGISTER";
case SymbolClass::VARIANT: return "VARIANT";
case SymbolClass::SUNDEFINED: return "SUNDEFINED";
case SymbolClass::INIT: return "INIT";
case SymbolClass::BASED_VAR: return "BASED_VAR";
case SymbolClass::XDATA: return "XDATA";
case SymbolClass::PDATA: return "PDATA";
case SymbolClass::FINI: return "FINI";
case SymbolClass::NONGP: return "NONGP";
}
return nullptr;
}
const char* stabs_code_to_string(StabsCode code)
{
switch(code) {
case STAB: return "STAB";
case N_GSYM: return "GSYM";
case N_FNAME: return "FNAME";
case N_FUN: return "FUN";
case N_STSYM: return "STSYM";
case N_LCSYM: return "LCSYM";
case N_MAIN: return "MAIN";
case N_PC: return "PC";
case N_NSYMS: return "NSYMS";
case N_NOMAP: return "NOMAP";
case N_OBJ: return "OBJ";
case N_OPT: return "OPT";
case N_RSYM: return "RSYM";
case N_M2C: return "M2C";
case N_SLINE: return "SLINE";
case N_DSLINE: return "DSLINE";
case N_BSLINE: return "BSLINE";
case N_EFD: return "EFD";
case N_EHDECL: return "EHDECL";
case N_CATCH: return "CATCH";
case N_SSYM: return "SSYM";
case N_SO: return "SO";
case N_LSYM: return "LSYM";
case N_BINCL: return "BINCL";
case N_SOL: return "SOL";
case N_PSYM: return "PSYM";
case N_EINCL: return "EINCL";
case N_ENTRY: return "ENTRY";
case N_LBRAC: return "LBRAC";
case N_EXCL: return "EXCL";
case N_SCOPE: return "SCOPE";
case N_RBRAC: return "RBRAC";
case N_BCOMM: return "BCOMM";
case N_ECOMM: return "ECOMM";
case N_ECOML: return "ECOML";
case N_NBTEXT: return "NBTEXT";
case N_NBDATA: return "NBDATA";
case N_NBBSS: return "NBBSS";
case N_NBSTS: return "NBSTS";
case N_NBLCS: return "NBLCS";
case N_LENG: return "LENG";
}
return nullptr;
}
}

176
3rdparty/ccc/src/ccc/mdebug_section.h vendored Normal file
View File

@@ -0,0 +1,176 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include "util.h"
namespace ccc::mdebug {
struct SymbolicHeader;
enum class SymbolType : u32 {
NIL = 0,
GLOBAL = 1,
STATIC = 2,
PARAM = 3,
LOCAL = 4,
LABEL = 5,
PROC = 6,
BLOCK = 7,
END = 8,
MEMBER = 9,
TYPEDEF = 10,
FILE_SYMBOL = 11,
STATICPROC = 14,
CONSTANT = 15
};
enum class SymbolClass : u32 {
NIL = 0,
TEXT = 1,
DATA = 2,
BSS = 3,
REGISTER = 4,
ABS = 5,
UNDEFINED = 6,
LOCAL = 7,
BITS = 8,
DBX = 9,
REG_IMAGE = 10,
INFO = 11,
USER_STRUCT = 12,
SDATA = 13,
SBSS = 14,
RDATA = 15,
VAR = 16,
COMMON = 17,
SCOMMON = 18,
VAR_REGISTER = 19,
VARIANT = 20,
SUNDEFINED = 21,
INIT = 22,
BASED_VAR = 23,
XDATA = 24,
PDATA = 25,
FINI = 26,
NONGP = 27
};
// See stab.def from gcc for documentation on what all these are.
enum StabsCode {
STAB = 0x00,
N_GSYM = 0x20,
N_FNAME = 0x22,
N_FUN = 0x24,
N_STSYM = 0x26,
N_LCSYM = 0x28,
N_MAIN = 0x2a,
N_PC = 0x30,
N_NSYMS = 0x32,
N_NOMAP = 0x34,
N_OBJ = 0x38,
N_OPT = 0x3c,
N_RSYM = 0x40,
N_M2C = 0x42,
N_SLINE = 0x44,
N_DSLINE = 0x46,
N_BSLINE = 0x48,
N_EFD = 0x4a,
N_EHDECL = 0x50,
N_CATCH = 0x54,
N_SSYM = 0x60,
N_SO = 0x64,
N_LSYM = 0x80,
N_BINCL = 0x82,
N_SOL = 0x84,
N_PSYM = 0xa0,
N_EINCL = 0xa2,
N_ENTRY = 0xa4,
N_LBRAC = 0xc0,
N_EXCL = 0xc2,
N_SCOPE = 0xc4,
N_RBRAC = 0xe0,
N_BCOMM = 0xe2,
N_ECOMM = 0xe4,
N_ECOML = 0xe8,
N_NBTEXT = 0xf0,
N_NBDATA = 0xf2,
N_NBBSS = 0xf4,
N_NBSTS = 0xf6,
N_NBLCS = 0xf8,
N_LENG = 0xfe
};
CCC_PACKED_STRUCT(ProcedureDescriptor,
/* 0x00 */ u32 address;
/* 0x04 */ u32 symbol_index;
/* 0x08 */ s32 line_number_entry_index;
/* 0x0c */ s32 saved_register_mask;
/* 0x10 */ s32 saved_register_offset;
/* 0x14 */ s32 optimization_entry_index;
/* 0x18 */ s32 saved_float_register_mask;
/* 0x1c */ s32 saved_float_register_offset;
/* 0x20 */ s32 frame_size;
/* 0x24 */ s16 frame_pointer_register;
/* 0x26 */ s16 return_pc_register;
/* 0x28 */ s32 line_number_low;
/* 0x2c */ s32 line_number_high;
/* 0x30 */ u32 line_number_offset;
)
static_assert(sizeof(ProcedureDescriptor) == 0x34);
struct Symbol {
u32 value;
SymbolType symbol_type;
SymbolClass symbol_class;
u32 index;
const char* string;
const ProcedureDescriptor* procedure_descriptor = nullptr;
bool is_stabs() const {
return (index & 0xfff00) == 0x8f300;
}
StabsCode code() const {
return (StabsCode) (index - 0x8f300);
}
};
struct File {
std::vector<Symbol> symbols;
u32 address = 0;
std::string working_dir; // The working directory of gcc.
std::string command_line_path; // The source file path passed on the command line to gcc.
std::string full_path; // The full combined path.
};
class SymbolTableReader {
public:
Result<void> init(std::span<const u8> elf, s32 section_offset);
s32 file_count() const;
Result<File> parse_file(s32 index) const;
Result<std::vector<Symbol>> parse_external_symbols() const;
void print_header(FILE* out) const;
Result<void> print_symbols(FILE* out, bool print_locals, bool print_procedure_descriptors, bool print_externals) const;
protected:
bool m_ready = false;
std::span<const u8> m_elf;
s32 m_section_offset;
// If the .mdebug section was moved without updating its contents all the
// absolute file offsets stored within will be incorrect by a fixed amount.
s32 m_fudge_offset;
const SymbolicHeader* m_hdrr;
};
const char* symbol_type(SymbolType type);
const char* symbol_class(SymbolClass symbol_class);
const char* stabs_code_to_string(StabsCode code);
}

220
3rdparty/ccc/src/ccc/mdebug_symbols.cpp vendored Normal file
View File

@@ -0,0 +1,220 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "mdebug_symbols.h"
#include "importer_flags.h"
namespace ccc::mdebug {
static void mark_duplicate_symbols(std::vector<ParsedSymbol>& symbols);
Result<std::vector<ParsedSymbol>> parse_symbols(const std::vector<mdebug::Symbol>& input, u32& importer_flags)
{
std::vector<ParsedSymbol> output;
std::string prefix;
for(const mdebug::Symbol& symbol : input) {
if(symbol.is_stabs()) {
switch(symbol.code()) {
case mdebug::N_GSYM: // Global variable
case mdebug::N_FUN: // Function
case mdebug::N_STSYM: // Data section static global variable
case mdebug::N_LCSYM: // BSS section static global variable
case mdebug::N_RSYM: // Register variable
case mdebug::N_LSYM: // Automatic variable or type definition
case mdebug::N_PSYM: { // Parameter variable
// Some STABS symbols are split between multiple strings.
if(symbol.string[0] != '\0') {
if(symbol.string[strlen(symbol.string) - 1] == '\\') {
prefix += std::string(symbol.string, symbol.string + strlen(symbol.string) - 1);
} else {
std::string merged_string;
const char* string;
if(!prefix.empty()) {
merged_string = prefix + symbol.string;
string = merged_string.c_str();
prefix.clear();
} else {
string = symbol.string;
}
const char* input = string;
Result<StabsSymbol> parse_result = parse_stabs_symbol(input);
if(parse_result.success()) {
if(*input != '\0') {
if(importer_flags & STRICT_PARSING) {
return CCC_FAILURE("Unknown data '%s' at the end of the '%s' stab.", input, parse_result->name.c_str());
} else {
CCC_WARN("Unknown data '%s' at the end of the '%s' stab.", input, parse_result->name.c_str());
}
}
ParsedSymbol& parsed = output.emplace_back();
parsed.type = ParsedSymbolType::NAME_COLON_TYPE;
parsed.raw = &symbol;
parsed.name_colon_type = std::move(*parse_result);
} else if(parse_result.error().message == STAB_TRUNCATED_ERROR_MESSAGE) {
// Symbol truncated due to a GCC bug. Report a
// warning and try to tolerate further faults
// caused as a result of this.
CCC_WARN("%s Symbol string: %s", STAB_TRUNCATED_ERROR_MESSAGE, string);
importer_flags &= ~STRICT_PARSING;
} else {
return CCC_FAILURE("%s Symbol string: %s",
parse_result.error().message.c_str(), string);
}
}
} else {
CCC_CHECK(prefix.empty(), "Invalid STABS continuation.");
if(symbol.code() == mdebug::N_FUN) {
ParsedSymbol& func_end = output.emplace_back();
func_end.type = ParsedSymbolType::FUNCTION_END;
func_end.raw = &symbol;
}
}
break;
}
case mdebug::N_SOL: { // Sub-source file
ParsedSymbol& sub = output.emplace_back();
sub.type = ParsedSymbolType::SUB_SOURCE_FILE;
sub.raw = &symbol;
break;
}
case mdebug::N_LBRAC: { // Begin block
ParsedSymbol& begin_block = output.emplace_back();
begin_block.type = ParsedSymbolType::LBRAC;
begin_block.raw = &symbol;
break;
}
case mdebug::N_RBRAC: { // End block
ParsedSymbol& end_block = output.emplace_back();
end_block.type = ParsedSymbolType::RBRAC;
end_block.raw = &symbol;
break;
}
case mdebug::N_SO: { // Source filename
ParsedSymbol& so_symbol = output.emplace_back();
so_symbol.type = ParsedSymbolType::SOURCE_FILE;
so_symbol.raw = &symbol;
break;
}
case mdebug::STAB:
case mdebug::N_OPT:
case mdebug::N_BINCL:
case mdebug::N_EINCL: {
break;
}
case mdebug::N_FNAME:
case mdebug::N_MAIN:
case mdebug::N_PC:
case mdebug::N_NSYMS:
case mdebug::N_NOMAP:
case mdebug::N_OBJ:
case mdebug::N_M2C:
case mdebug::N_SLINE:
case mdebug::N_DSLINE:
case mdebug::N_BSLINE:
case mdebug::N_EFD:
case mdebug::N_EHDECL:
case mdebug::N_CATCH:
case mdebug::N_SSYM:
case mdebug::N_ENTRY:
case mdebug::N_EXCL:
case mdebug::N_SCOPE:
case mdebug::N_BCOMM:
case mdebug::N_ECOMM:
case mdebug::N_ECOML:
case mdebug::N_NBTEXT:
case mdebug::N_NBDATA:
case mdebug::N_NBBSS:
case mdebug::N_NBSTS:
case mdebug::N_NBLCS:
case mdebug::N_LENG: {
CCC_WARN("Unhandled N_%s symbol: %s", mdebug::stabs_code_to_string(symbol.code()), symbol.string);
break;
}
}
} else {
ParsedSymbol& non_stabs_symbol = output.emplace_back();
non_stabs_symbol.type = ParsedSymbolType::NON_STABS;
non_stabs_symbol.raw = &symbol;
}
}
mark_duplicate_symbols(output);
return output;
}
static void mark_duplicate_symbols(std::vector<ParsedSymbol>& symbols)
{
std::map<StabsTypeNumber, size_t> stabs_type_number_to_symbol;
for(size_t i = 0; i < symbols.size(); i++) {
ParsedSymbol& symbol = symbols[i];
if(symbol.type == ParsedSymbolType::NAME_COLON_TYPE) {
StabsType& type = *symbol.name_colon_type.type;
if(type.type_number.valid() && type.descriptor.has_value()) {
stabs_type_number_to_symbol.emplace(type.type_number, i);
}
}
}
for(ParsedSymbol& symbol : symbols) {
symbol.is_typedef =
symbol.type == ParsedSymbolType::NAME_COLON_TYPE &&
symbol.name_colon_type.descriptor == StabsSymbolDescriptor::TYPE_NAME &&
symbol.name_colon_type.type->descriptor != StabsTypeDescriptor::ENUM;
}
for(size_t i = 0; i < symbols.size(); i++) {
ParsedSymbol& symbol = symbols[i];
if(symbol.type != ParsedSymbolType::NAME_COLON_TYPE) {
continue;
}
bool is_type =
symbol.name_colon_type.descriptor == StabsSymbolDescriptor::TYPE_NAME ||
symbol.name_colon_type.descriptor == StabsSymbolDescriptor::ENUM_STRUCT_OR_TYPE_TAG;
if(!is_type) {
continue;
}
StabsType& type = *symbol.name_colon_type.type;
if(!type.descriptor.has_value()) {
auto referenced_index = stabs_type_number_to_symbol.find(type.type_number);
if(referenced_index != stabs_type_number_to_symbol.end()) {
ParsedSymbol& referenced = symbols[referenced_index->second];
if(referenced.name_colon_type.name == symbol.name_colon_type.name) {
// symbol: "Struct:T(1,1)=s1;"
// referenced: "Struct:t(1,1)"
symbol.duplicate = true;
}
}
}
if(type.descriptor.has_value() && type.descriptor == StabsTypeDescriptor::TYPE_REFERENCE) {
auto referenced_index = stabs_type_number_to_symbol.find(type.as<StabsTypeReferenceType>().type->type_number);
if(referenced_index != stabs_type_number_to_symbol.end() && referenced_index->second != i) {
ParsedSymbol& referenced = symbols[referenced_index->second];
if(referenced.name_colon_type.name == " ") {
// referenced: " :T(1,1)=e;"
// symbol: "ErraticEnum:t(1,2)=(1,1)"
referenced.name_colon_type.name = symbol.name_colon_type.name;
referenced.is_typedef = true;
symbol.duplicate = true;
}
if(referenced.name_colon_type.name == symbol.name_colon_type.name) {
// referenced: "NamedTypedefedStruct:T(1,1)=s1;"
// symbol: "NamedTypedefedStruct:t(1,2)=(1,1)"
referenced.is_typedef = true;
symbol.duplicate = true;
}
}
}
}
}
}

32
3rdparty/ccc/src/ccc/mdebug_symbols.h vendored Normal file
View File

@@ -0,0 +1,32 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include "util.h"
#include "stabs.h"
#include "mdebug_section.h"
namespace ccc::mdebug {
enum class ParsedSymbolType {
NAME_COLON_TYPE,
SOURCE_FILE,
SUB_SOURCE_FILE,
LBRAC,
RBRAC,
FUNCTION_END,
NON_STABS
};
struct ParsedSymbol {
ParsedSymbolType type;
const mdebug::Symbol* raw;
StabsSymbol name_colon_type;
bool duplicate = false;
bool is_typedef = false;
};
Result<std::vector<ParsedSymbol>> parse_symbols(const std::vector<mdebug::Symbol>& input, u32& importer_flags);
}

193
3rdparty/ccc/src/ccc/sndll.cpp vendored Normal file
View File

@@ -0,0 +1,193 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "sndll.h"
#include "importer_flags.h"
namespace ccc {
CCC_PACKED_STRUCT(SNDLLHeaderCommon,
/* 0x00 */ u32 magic;
/* 0x04 */ u32 relocations;
/* 0x08 */ u32 relocation_count;
/* 0x0c */ u32 symbols;
/* 0x10 */ u32 symbol_count;
/* 0x14 */ u32 elf_path;
/* 0x18 */ u32 load_func;
/* 0x1c */ u32 unload_func;
/* 0x20 */ u32 unknown_20;
/* 0x24 */ u32 unknown_24;
/* 0x28 */ u32 unknown_28;
/* 0x2c */ u32 file_size;
/* 0x30 */ u32 unknown_30;
)
CCC_PACKED_STRUCT(SNDLLHeaderV1,
/* 0x00 */ SNDLLHeaderCommon common;
)
CCC_PACKED_STRUCT(SNDLLHeaderV2,
/* 0x00 */ SNDLLHeaderCommon common;
/* 0x34 */ u32 unknown_34;
/* 0x38 */ u32 unknown_38;
)
CCC_PACKED_STRUCT(SNDLLRelocation,
/* 0x0 */ u32 unknown_0;
/* 0x4 */ u32 unknown_4;
/* 0x8 */ u32 unknown_8;
)
CCC_PACKED_STRUCT(SNDLLSymbolHeader,
/* 0x0 */ u32 string;
/* 0x4 */ u32 value;
/* 0x8 */ u8 unknown_8;
/* 0x9 */ u8 unknown_9;
/* 0xa */ SNDLLSymbolType type;
/* 0xb */ u8 processed;
)
static Result<SNDLLFile> parse_sndll_common(
std::span<const u8> image, Address address, SNDLLType type, const SNDLLHeaderCommon& common, SNDLLVersion version);
static const char* sndll_symbol_type_to_string(SNDLLSymbolType type);
Result<SNDLLFile> parse_sndll_file(std::span<const u8> image, Address address, SNDLLType type)
{
std::optional<u32> magic = copy_unaligned<u32>(image, 0);
CCC_CHECK(magic.has_value(), "Failed to read SNDLL header.");
CCC_CHECK((*magic & 0xffffff) == CCC_FOURCC("SNR\00"), "Not a SNDLL %s.", address.valid() ? "section" : "file");
char version = *magic >> 24;
switch(version) {
case '1': {
const SNDLLHeaderV1* header = get_unaligned<SNDLLHeaderV1>(image, 0);
CCC_CHECK(header, "File too small to contain SNDLL V1 header.");
return parse_sndll_common(image, address, type, header->common, SNDLL_V1);
}
case '2': {
const SNDLLHeaderV2* header = get_unaligned<SNDLLHeaderV2>(image, 0);
CCC_CHECK(header, "File too small to contain SNDLL V2 header.");
return parse_sndll_common(image, address, type, header->common, SNDLL_V2);
}
}
return CCC_FAILURE("Unknown SNDLL version '%c'.", version);
}
static Result<SNDLLFile> parse_sndll_common(
std::span<const u8> image, Address address, SNDLLType type, const SNDLLHeaderCommon& common, SNDLLVersion version)
{
SNDLLFile sndll;
sndll.address = address;
sndll.type = type;
sndll.version = version;
if(common.elf_path) {
std::optional<std::string_view> elf_path = get_string(image, common.elf_path);
CCC_CHECK(elf_path.has_value(), "SNDLL header has invalid ELF path field.");
sndll.elf_path = *elf_path;
}
CCC_CHECK(common.symbol_count < (32 * 1024 * 1024) / sizeof(SNDLLSymbol), "SNDLL symbol count is too high.");
sndll.symbols.reserve(common.symbol_count);
for(u32 i = 0; i < common.symbol_count; i++) {
u32 symbol_offset = common.symbols - address.get_or_zero() + i * sizeof(SNDLLSymbolHeader);
const SNDLLSymbolHeader* symbol_header = get_unaligned<SNDLLSymbolHeader>(image, symbol_offset);
CCC_CHECK(symbol_header, "SNDLL symbol out of range.");
std::optional<std::string_view> string;
if(symbol_header->string) {
string = get_string(image, symbol_header->string - address.get_or_zero());
}
SNDLLSymbol& symbol = sndll.symbols.emplace_back();
symbol.type = symbol_header->type;
symbol.value = symbol_header->value;
if(string.has_value()) {
symbol.string = *string;
}
}
return sndll;
}
Result<void> import_sndll_symbols(
SymbolDatabase& database,
const SNDLLFile& sndll,
const SymbolGroup& group,
u32 importer_flags,
DemanglerFunctions demangler)
{
for(const SNDLLSymbol& symbol : sndll.symbols) {
if(symbol.value == 0 || symbol.string.empty()) {
continue;
}
u32 address = symbol.value;
if(symbol.type != SNDLL_ABSOLUTE && sndll.type == SNDLLType::DYNAMIC_LIBRARY) {
address += sndll.address.get_or_zero();
}
if(!(importer_flags & DONT_DEDUPLICATE_SYMBOLS)) {
if(database.functions.first_handle_from_starting_address(address).valid()) {
continue;
}
if(database.global_variables.first_handle_from_starting_address(address).valid()) {
continue;
}
if(database.local_variables.first_handle_from_starting_address(address).valid()) {
continue;
}
}
const Section* section = database.sections.symbol_overlapping_address(address);
if(section) {
if(section->contains_code()) {
Result<Function*> function = database.functions.create_symbol(
symbol.string, group.source, group.module_symbol, address, importer_flags, demangler);
CCC_RETURN_IF_ERROR(function);
continue;
} else if(section->contains_data()) {
Result<GlobalVariable*> global_variable = database.global_variables.create_symbol(
symbol.string, group.source, group.module_symbol, address, importer_flags, demangler);
CCC_RETURN_IF_ERROR(global_variable);
continue;
}
}
Result<Label*> label = database.labels.create_symbol(
symbol.string, group.source, group.module_symbol, address, importer_flags, demangler);
CCC_RETURN_IF_ERROR(label);
}
return Result<void>();
}
void print_sndll_symbols(FILE* out, const SNDLLFile& sndll)
{
fprintf(out, "SNDLL SYMBOLS:\n");
for(const SNDLLSymbol& symbol : sndll.symbols) {
const char* type = sndll_symbol_type_to_string(symbol.type);
const char* string = !symbol.string.empty() ? symbol.string.c_str() : "(no string)";
fprintf(out, "%8s %08x %s\n", type, symbol.value, string);
}
}
static const char* sndll_symbol_type_to_string(SNDLLSymbolType type)
{
switch(type) {
case SNDLL_NIL: return "NIL";
case SNDLL_EXTERNAL: return "EXTERNAL";
case SNDLL_RELATIVE: return "RELATIVE";
case SNDLL_WEAK: return "WEAK";
case SNDLL_ABSOLUTE: return "ABSOLUTE";
}
return "invalid";
}
}

55
3rdparty/ccc/src/ccc/sndll.h vendored Normal file
View File

@@ -0,0 +1,55 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include "symbol_database.h"
namespace ccc {
enum class SNDLLType {
SNDATA_SECTION,
DYNAMIC_LIBRARY
};
enum SNDLLVersion {
SNDLL_V1,
SNDLL_V2
};
enum SNDLLSymbolType : u8 {
SNDLL_NIL = 0, // I think this is just so that the first real symbol has an index of 1.
SNDLL_EXTERNAL = 1, // Symbol with an empty value, to be filled in from another module.
SNDLL_RELATIVE = 2, // Global symbol, value is relative to the start of the SNDLL file.
SNDLL_WEAK = 3, // Weak symbol, value is relative to the start of the SNDLL file.
SNDLL_ABSOLUTE = 4 // Global symbol, value is an absolute address.
};
struct SNDLLSymbol {
SNDLLSymbolType type = SNDLL_NIL;
u32 value = 0;
std::string string;
};
struct SNDLLFile {
Address address;
SNDLLType type;
SNDLLVersion version;
std::string elf_path;
std::vector<SNDLLSymbol> symbols;
};
// If a valid address is passed, the pointers in the header will be treated as
// addresses, otherwise they will be treated as file offsets.
Result<SNDLLFile> parse_sndll_file(std::span<const u8> image, Address address, SNDLLType type);
Result<void> import_sndll_symbols(
SymbolDatabase& database,
const SNDLLFile& sndll,
const SymbolGroup& group,
u32 importer_flags,
DemanglerFunctions demangler);
void print_sndll_symbols(FILE* out, const SNDLLFile& sndll);
}

835
3rdparty/ccc/src/ccc/stabs.cpp vendored Normal file
View File

@@ -0,0 +1,835 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "stabs.h"
namespace ccc {
#define STABS_DEBUG(...) //__VA_ARGS__
#define STABS_DEBUG_PRINTF(...) STABS_DEBUG(printf(__VA_ARGS__);)
static bool validate_symbol_descriptor(StabsSymbolDescriptor descriptor);
static Result<std::unique_ptr<StabsType>> parse_stabs_type(const char*& input);
static Result<std::vector<StabsStructOrUnionType::Field>> parse_field_list(const char*& input);
static Result<std::vector<StabsStructOrUnionType::MemberFunctionSet>> parse_member_functions(const char*& input);
static Result<StabsStructOrUnionType::Visibility> parse_visibility_character(const char*& input);
STABS_DEBUG(static void print_field(const StabsStructOrUnionType::Field& field);)
const char* STAB_TRUNCATED_ERROR_MESSAGE =
"STABS symbol truncated. This was probably caused by a GCC bug. "
"Other symbols from the same translation unit may also be invalid.";
Result<StabsSymbol> parse_stabs_symbol(const char*& input)
{
STABS_DEBUG_PRINTF("PARSING %s\n", input);
StabsSymbol symbol;
Result<std::string> name = parse_dodgy_stabs_identifier(input, ':');
CCC_RETURN_IF_ERROR(name);
symbol.name = *name;
CCC_EXPECT_CHAR(input, ':', "identifier");
CCC_CHECK(*input != '\0', "Unexpected end of input.");
if((*input >= '0' && *input <= '9') || *input == '(') {
symbol.descriptor = StabsSymbolDescriptor::LOCAL_VARIABLE;
} else {
char symbol_descriptor = *(input++);
CCC_CHECK(symbol_descriptor != '\0', "Failed to parse symbol descriptor.");
symbol.descriptor = (StabsSymbolDescriptor) symbol_descriptor;
}
CCC_CHECK(validate_symbol_descriptor(symbol.descriptor),
"Invalid symbol descriptor '%c'.",
(char) symbol.descriptor);
CCC_CHECK(*input != '\0', "Unexpected end of input.");
if(*input == 't') {
input++;
}
auto type = parse_top_level_stabs_type(input);
CCC_RETURN_IF_ERROR(type);
// Handle nested functions.
bool is_function =
symbol.descriptor == StabsSymbolDescriptor::LOCAL_FUNCTION ||
symbol.descriptor == StabsSymbolDescriptor::GLOBAL_FUNCTION;
if(is_function && input[0] == ',') {
input++;
while(*input != ',' && *input != '\0') input++; // enclosing function
CCC_EXPECT_CHAR(input, ',', "nested function suffix");
while(*input != ',' && *input != '\0') input++; // function
}
symbol.type = std::move(*type);
// Make sure that variable names aren't used as type names e.g. the STABS
// symbol "somevar:P123=*456" may be referenced by the type number 123, but
// the type name is not "somevar".
bool is_type = symbol.descriptor == StabsSymbolDescriptor::TYPE_NAME
|| symbol.descriptor == StabsSymbolDescriptor::ENUM_STRUCT_OR_TYPE_TAG;
if(is_type) {
symbol.type->name = symbol.name;
}
symbol.type->is_typedef = symbol.descriptor == StabsSymbolDescriptor::TYPE_NAME;
symbol.type->is_root = true;
return symbol;
}
static bool validate_symbol_descriptor(StabsSymbolDescriptor descriptor)
{
bool valid;
switch(descriptor) {
case StabsSymbolDescriptor::LOCAL_VARIABLE:
case StabsSymbolDescriptor::REFERENCE_PARAMETER_A:
case StabsSymbolDescriptor::LOCAL_FUNCTION:
case StabsSymbolDescriptor::GLOBAL_FUNCTION:
case StabsSymbolDescriptor::GLOBAL_VARIABLE:
case StabsSymbolDescriptor::REGISTER_PARAMETER:
case StabsSymbolDescriptor::VALUE_PARAMETER:
case StabsSymbolDescriptor::REGISTER_VARIABLE:
case StabsSymbolDescriptor::STATIC_GLOBAL_VARIABLE:
case StabsSymbolDescriptor::TYPE_NAME:
case StabsSymbolDescriptor::ENUM_STRUCT_OR_TYPE_TAG:
case StabsSymbolDescriptor::STATIC_LOCAL_VARIABLE:
case StabsSymbolDescriptor::REFERENCE_PARAMETER_V:
valid = true;
break;
default:
valid = false;
break;
}
return valid;
}
Result<std::unique_ptr<StabsType>> parse_top_level_stabs_type(const char*& input)
{
Result<std::unique_ptr<StabsType>> type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(type);
// Handle first base class suffixes.
if((*type)->descriptor == StabsTypeDescriptor::STRUCT && input[0] == '~' && input[1] == '%') {
input += 2;
Result<std::unique_ptr<StabsType>> first_base_class = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(first_base_class);
(*type)->as<StabsStructType>().first_base_class = std::move(*first_base_class);
CCC_EXPECT_CHAR(input, ';', "first base class suffix");
}
// Handle extra live range information.
if(input[0] == ';' && input[1] == 'l') {
input += 2;
CCC_EXPECT_CHAR(input, '(', "live range suffix");
CCC_EXPECT_CHAR(input, '#', "live range suffix");
std::optional<s32> start = parse_number_s32(input);
CCC_CHECK(start.has_value(), "Failed to parse live range suffix.");
CCC_EXPECT_CHAR(input, ',', "live range suffix");
CCC_EXPECT_CHAR(input, '#', "live range suffix");
std::optional<s32> end = parse_number_s32(input);
CCC_CHECK(end.has_value(), "Failed to parse live range suffix.");
CCC_EXPECT_CHAR(input, ')', "live range suffix");
}
return type;
}
static Result<std::unique_ptr<StabsType>> parse_stabs_type(const char*& input)
{
StabsTypeNumber type_number;
CCC_CHECK(*input != '\0', "Unexpected end of input.");
if(*input == '(') {
// This file has type numbers made up of two pieces: an include file
// index and a type number.
input++;
std::optional<s32> file_index = parse_number_s32(input);
CCC_CHECK(file_index.has_value(), "Failed to parse type number (file index).");
CCC_EXPECT_CHAR(input, ',', "type number");
std::optional<s32> type_index = parse_number_s32(input);
CCC_CHECK(type_index.has_value(), "Failed to parse type number (type index).");
CCC_EXPECT_CHAR(input, ')', "type number");
type_number.file = *file_index;
type_number.type = *type_index;
if(*input != '=') {
return std::make_unique<StabsType>(type_number);
}
input++;
} else if(*input >= '0' && *input <= '9') {
// This file has type numbers which are just a single number. This is
// the more common case for games.
std::optional<s32> type_index = parse_number_s32(input);
CCC_CHECK(type_index.has_value(), "Failed to parse type number.");
type_number.type = *type_index;
if(*input != '=') {
return std::make_unique<StabsType>(type_number);
}
input++;
}
CCC_CHECK(*input != '\0', "Unexpected end of input.");
StabsTypeDescriptor descriptor;
if((*input >= '0' && *input <= '9') || *input == '(') {
descriptor = StabsTypeDescriptor::TYPE_REFERENCE;
} else {
char descriptor_char = *(input++);
CCC_CHECK(descriptor_char != '\0', "Failed to parse type descriptor.");
descriptor = (StabsTypeDescriptor) descriptor_char;
}
std::unique_ptr<StabsType> out_type;
switch(descriptor) {
case StabsTypeDescriptor::TYPE_REFERENCE: { // 0..9
auto type_reference = std::make_unique<StabsTypeReferenceType>(type_number);
auto type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(type);
type_reference->type = std::move(*type);
out_type = std::move(type_reference);
break;
}
case StabsTypeDescriptor::ARRAY: { // a
auto array = std::make_unique<StabsArrayType>(type_number);
auto index_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(index_type);
array->index_type = std::move(*index_type);
auto element_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(element_type);
array->element_type = std::move(*element_type);
out_type = std::move(array);
break;
}
case StabsTypeDescriptor::ENUM: { // e
auto enum_type = std::make_unique<StabsEnumType>(type_number);
STABS_DEBUG_PRINTF("enum {\n");
while(*input != ';') {
std::optional<std::string> name = parse_stabs_identifier(input, ':');
CCC_CHECK(name.has_value(), "Failed to parse enum field name.");
CCC_EXPECT_CHAR(input, ':', "enum");
std::optional<s32> value = parse_number_s32(input);
CCC_CHECK(value.has_value(), "Failed to parse enum value.");
enum_type->fields.emplace_back(*value, std::move(*name));
CCC_EXPECT_CHAR(input, ',', "enum");
}
input++;
STABS_DEBUG_PRINTF("}\n");
out_type = std::move(enum_type);
break;
}
case StabsTypeDescriptor::FUNCTION: { // f
auto function = std::make_unique<StabsFunctionType>(type_number);
auto return_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(return_type);
function->return_type = std::move(*return_type);
out_type = std::move(function);
break;
}
case StabsTypeDescriptor::VOLATILE_QUALIFIER: { // B
auto volatile_qualifier = std::make_unique<StabsVolatileQualifierType>(type_number);
auto type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(type);
volatile_qualifier->type = std::move(*type);
out_type = std::move(volatile_qualifier);
break;
}
case StabsTypeDescriptor::CONST_QUALIFIER: { // k
auto const_qualifier = std::make_unique<StabsConstQualifierType>(type_number);
auto type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(type);
const_qualifier->type = std::move(*type);
out_type = std::move(const_qualifier);
break;
}
case StabsTypeDescriptor::RANGE: { // r
auto range = std::make_unique<StabsRangeType>(type_number);
auto type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(type);
range->type = std::move(*type);
CCC_EXPECT_CHAR(input, ';', "range type descriptor");
std::optional<std::string> low = parse_stabs_identifier(input, ';');
CCC_CHECK(low.has_value(), "Failed to parse low part of range.");
CCC_EXPECT_CHAR(input, ';', "low range value");
std::optional<std::string> high = parse_stabs_identifier(input, ';');
CCC_CHECK(high.has_value(), "Failed to parse high part of range.");
CCC_EXPECT_CHAR(input, ';', "high range value");
range->low = std::move(*low);
range->high = std::move(*high);
out_type = std::move(range);
break;
}
case StabsTypeDescriptor::STRUCT: { // s
auto struct_type = std::make_unique<StabsStructType>(type_number);
STABS_DEBUG_PRINTF("struct {\n");
std::optional<s64> struct_size = parse_number_s64(input);
CCC_CHECK(struct_size.has_value(), "Failed to parse struct size.");
struct_type->size = *struct_size;
if(*input == '!') {
input++;
std::optional<s32> base_class_count = parse_number_s32(input);
CCC_CHECK(base_class_count.has_value(), "Failed to parse base class count.");
CCC_EXPECT_CHAR(input, ',', "base class section");
for(s64 i = 0; i < *base_class_count; i++) {
StabsStructOrUnionType::BaseClass base_class;
char is_virtual = *(input++);
switch(is_virtual) {
case '0': base_class.is_virtual = false; break;
case '1': base_class.is_virtual = true; break;
default: return CCC_FAILURE("Failed to parse base class (virtual character).");
}
Result<StabsStructOrUnionType::Visibility> visibility = parse_visibility_character(input);
CCC_RETURN_IF_ERROR(visibility);
base_class.visibility = *visibility;
std::optional<s32> offset = parse_number_s32(input);
CCC_CHECK(offset.has_value(), "Failed to parse base class offset.");
base_class.offset = (s32) *offset;
CCC_EXPECT_CHAR(input, ',', "base class section");
auto base_class_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(base_class_type);
base_class.type = std::move(*base_class_type);
CCC_EXPECT_CHAR(input, ';', "base class section");
struct_type->base_classes.emplace_back(std::move(base_class));
}
}
auto fields = parse_field_list(input);
CCC_RETURN_IF_ERROR(fields);
struct_type->fields = std::move(*fields);
auto member_functions = parse_member_functions(input);
CCC_RETURN_IF_ERROR(member_functions);
struct_type->member_functions = std::move(*member_functions);
STABS_DEBUG_PRINTF("}\n");
out_type = std::move(struct_type);
break;
}
case StabsTypeDescriptor::UNION: { // u
auto union_type = std::make_unique<StabsUnionType>(type_number);
STABS_DEBUG_PRINTF("union {\n");
std::optional<s64> union_size = parse_number_s64(input);
CCC_CHECK(union_size.has_value(), "Failed to parse struct size.");
union_type->size = *union_size;
auto fields = parse_field_list(input);
CCC_RETURN_IF_ERROR(fields);
union_type->fields = std::move(*fields);
auto member_functions = parse_member_functions(input);
CCC_RETURN_IF_ERROR(member_functions);
union_type->member_functions = std::move(*member_functions);
STABS_DEBUG_PRINTF("}\n");
out_type = std::move(union_type);
break;
}
case StabsTypeDescriptor::CROSS_REFERENCE: { // x
auto cross_reference = std::make_unique<StabsCrossReferenceType>(type_number);
char cross_reference_type = *(input++);
CCC_CHECK(cross_reference_type != '\0', "Failed to parse cross reference type.");
switch(cross_reference_type) {
case 'e': cross_reference->type = ast::ForwardDeclaredType::ENUM; break;
case 's': cross_reference->type = ast::ForwardDeclaredType::STRUCT; break;
case 'u': cross_reference->type = ast::ForwardDeclaredType::UNION; break;
default:
return CCC_FAILURE("Invalid cross reference type '%c'.", cross_reference->type);
}
Result<std::string> identifier = parse_dodgy_stabs_identifier(input, ':');
CCC_RETURN_IF_ERROR(identifier);
cross_reference->identifier = std::move(*identifier);
cross_reference->name = cross_reference->identifier;
CCC_EXPECT_CHAR(input, ':', "cross reference");
out_type = std::move(cross_reference);
break;
}
case StabsTypeDescriptor::FLOATING_POINT_BUILTIN: { // R
auto fp_builtin = std::make_unique<StabsFloatingPointBuiltInType>(type_number);
std::optional<s32> fpclass = parse_number_s32(input);
CCC_CHECK(fpclass.has_value(), "Failed to parse floating point built-in class.");
fp_builtin->fpclass = *fpclass;
CCC_EXPECT_CHAR(input, ';', "floating point builtin");
std::optional<s32> bytes = parse_number_s32(input);
CCC_CHECK(bytes.has_value(), "Failed to parse floating point built-in.");
fp_builtin->bytes = *bytes;
CCC_EXPECT_CHAR(input, ';', "floating point builtin");
std::optional<s32> value = parse_number_s32(input);
CCC_CHECK(value.has_value(), "Failed to parse floating point built-in.");
CCC_EXPECT_CHAR(input, ';', "floating point builtin");
out_type = std::move(fp_builtin);
break;
}
case StabsTypeDescriptor::METHOD: { // #
auto method = std::make_unique<StabsMethodType>(type_number);
if(*input == '#') {
input++;
auto return_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(return_type);
method->return_type = std::move(*return_type);
if(*input == ';') {
input++;
}
} else {
auto class_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(class_type);
method->class_type = std::move(*class_type);
CCC_EXPECT_CHAR(input, ',', "method");
auto return_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(return_type);
method->return_type = std::move(*return_type);
while(*input != '\0') {
if(*input == ';') {
input++;
break;
}
CCC_EXPECT_CHAR(input, ',', "method");
auto parameter_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(parameter_type);
method->parameter_types.emplace_back(std::move(*parameter_type));
}
}
out_type = std::move(method);
break;
}
case StabsTypeDescriptor::REFERENCE: { // &
auto reference = std::make_unique<StabsReferenceType>(type_number);
auto value_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(value_type);
reference->value_type = std::move(*value_type);
out_type = std::move(reference);
break;
}
case StabsTypeDescriptor::POINTER: { // *
auto pointer = std::make_unique<StabsPointerType>(type_number);
auto value_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(value_type);
pointer->value_type = std::move(*value_type);
out_type = std::move(pointer);
break;
}
case StabsTypeDescriptor::TYPE_ATTRIBUTE: { // @
if((*input >= '0' && *input <= '9') || *input == '(') {
auto member_pointer = std::make_unique<StabsPointerToDataMemberType>(type_number);
auto class_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(class_type);
member_pointer->class_type = std::move(*class_type);
CCC_EXPECT_CHAR(input, ',', "pointer to non-static data member");
auto member_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(member_type);
member_pointer->member_type = std::move(*member_type);
out_type = std::move(member_pointer);
} else {
auto type_attribute = std::make_unique<StabsSizeTypeAttributeType>(type_number);
CCC_CHECK(*input == 's', "Weird value following '@' type descriptor.");
input++;
std::optional<s64> size_bits = parse_number_s64(input);
CCC_CHECK(size_bits.has_value(), "Failed to parse type attribute.")
type_attribute->size_bits = *size_bits;
CCC_EXPECT_CHAR(input, ';', "type attribute");
auto type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(type);
type_attribute->type = std::move(*type);
out_type = std::move(type_attribute);
}
break;
}
case StabsTypeDescriptor::BUILTIN: { // -
auto built_in = std::make_unique<StabsBuiltInType>(type_number);
std::optional<s64> type_id = parse_number_s64(input);
CCC_CHECK(type_id.has_value(), "Failed to parse built-in.");
built_in->type_id = *type_id;
CCC_EXPECT_CHAR(input, ';', "builtin");
out_type = std::move(built_in);
break;
}
default: {
return CCC_FAILURE(
"Invalid type descriptor '%c' (%02x).",
(u32) descriptor, (u32) descriptor);
}
}
return out_type;
}
static Result<std::vector<StabsStructOrUnionType::Field>> parse_field_list(const char*& input)
{
std::vector<StabsStructOrUnionType::Field> fields;
while(*input != '\0') {
if(*input == ';') {
input++;
break;
}
const char* before_field = input;
StabsStructOrUnionType::Field field;
Result<std::string> name = parse_dodgy_stabs_identifier(input, ':');
CCC_RETURN_IF_ERROR(name);
field.name = std::move(*name);
CCC_EXPECT_CHAR(input, ':', "identifier");
if(*input == '/') {
input++;
Result<StabsStructOrUnionType::Visibility> visibility = parse_visibility_character(input);
CCC_RETURN_IF_ERROR(visibility);
field.visibility = *visibility;
}
if(*input == ':') {
input = before_field;
break;
}
auto type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(type);
field.type = std::move(*type);
if(field.name.size() >= 1 && field.name[0] == '$') {
// Virtual function table pointers and virtual base class pointers.
CCC_EXPECT_CHAR(input, ',', "field type");
std::optional<s32> offset_bits = parse_number_s32(input);
CCC_CHECK(offset_bits.has_value(), "Failed to parse field offset.");
field.offset_bits = *offset_bits;
CCC_EXPECT_CHAR(input, ';', "field offset");
} else if(*input == ':') {
// Static fields.
input++;
field.is_static = true;
std::optional<std::string> type_name = parse_stabs_identifier(input, ';');
CCC_CHECK(type_name.has_value(), "Failed to parse static field type name.");
field.type_name = std::move(*type_name);
CCC_EXPECT_CHAR(input, ';', "identifier");
} else if(*input == ',') {
// Normal fields.
input++;
std::optional<s32> offset_bits = parse_number_s32(input);
CCC_CHECK(offset_bits.has_value(), "Failed to parse field offset.");
field.offset_bits = *offset_bits;
CCC_EXPECT_CHAR(input, ',', "field offset");
std::optional<s32> size_bits = parse_number_s32(input);
CCC_CHECK(size_bits.has_value(), "Failed to parse field size.");
field.size_bits = *size_bits;
CCC_EXPECT_CHAR(input, ';', "field size");
} else {
return CCC_FAILURE("Expected ':' or ',', got '%c' (%hhx).", *input, *input);
}
STABS_DEBUG(print_field(field);)
fields.emplace_back(std::move(field));
}
return fields;
}
static Result<std::vector<StabsStructOrUnionType::MemberFunctionSet>> parse_member_functions(const char*& input)
{
// Check for if the next character is from an enclosing field list. If this
// is the case, the next character will be ',' for normal fields and ':' for
// static fields (see above).
if(*input == ',' || *input == ':') {
return std::vector<StabsStructOrUnionType::MemberFunctionSet>();
}
std::vector<StabsStructOrUnionType::MemberFunctionSet> member_functions;
while(*input != '\0') {
if(*input == ';') {
input++;
break;
}
StabsStructOrUnionType::MemberFunctionSet member_function_set;
std::optional<std::string> name = parse_stabs_identifier(input, ':');
CCC_CHECK(name.has_value(), "Failed to parse member function name.");
member_function_set.name = std::move(*name);
CCC_EXPECT_CHAR(input, ':', "member function");
CCC_EXPECT_CHAR(input, ':', "member function");
while(*input != '\0') {
if(*input == ';') {
input++;
break;
}
StabsStructOrUnionType::MemberFunction function;
auto type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(type);
function.type = std::move(*type);
CCC_EXPECT_CHAR(input, ':', "member function");
std::optional<std::string> identifier = parse_stabs_identifier(input, ';');
CCC_CHECK(identifier.has_value(), "Invalid member function identifier.");
CCC_EXPECT_CHAR(input, ';', "member function");
Result<StabsStructOrUnionType::Visibility> visibility = parse_visibility_character(input);
CCC_RETURN_IF_ERROR(visibility);
function.visibility = *visibility;
char modifiers = *(input++);
CCC_CHECK(modifiers != '\0', "Failed to parse member function modifiers.");
switch(modifiers) {
case 'A':
function.is_const = false;
function.is_volatile = false;
break;
case 'B':
function.is_const = true;
function.is_volatile = false;
break;
case 'C':
function.is_const = false;
function.is_volatile = true;
break;
case 'D':
function.is_const = true;
function.is_volatile = true;
break;
case '?':
case '.':
break;
default:
return CCC_FAILURE("Invalid member function modifiers.");
}
char flag = *(input++);
CCC_CHECK(flag != '\0', "Failed to parse member function type.");
switch(flag) {
case '.': { // normal member function
function.modifier = ast::MemberFunctionModifier::NONE;
break;
}
case '?': { // static member function
function.modifier = ast::MemberFunctionModifier::STATIC;
break;
}
case '*': { // virtual member function
std::optional<s32> vtable_index = parse_number_s32(input);
CCC_CHECK(vtable_index.has_value(), "Failed to parse vtable index.");
function.vtable_index = *vtable_index;
CCC_EXPECT_CHAR(input, ';', "virtual member function");
auto virtual_type = parse_stabs_type(input);
CCC_RETURN_IF_ERROR(virtual_type);
function.virtual_type = std::move(*virtual_type);
CCC_EXPECT_CHAR(input, ';', "virtual member function");
function.modifier = ast::MemberFunctionModifier::VIRTUAL;
break;
}
default:
return CCC_FAILURE("Invalid member function type.");
}
member_function_set.overloads.emplace_back(std::move(function));
}
STABS_DEBUG_PRINTF("member func: %s\n", member_function_set.name.c_str());
member_functions.emplace_back(std::move(member_function_set));
}
return member_functions;
}
static Result<StabsStructOrUnionType::Visibility> parse_visibility_character(const char*& input)
{
char visibility = *(input++);
switch(visibility) {
case '0': return StabsStructOrUnionType::Visibility::PRIVATE;
case '1': return StabsStructOrUnionType::Visibility::PROTECTED;
case '2': return StabsStructOrUnionType::Visibility::PUBLIC;
case '9': return StabsStructOrUnionType::Visibility::PUBLIC_OPTIMIZED_OUT;
default: break;
}
return CCC_FAILURE("Failed to parse visibility character.");
}
std::optional<s32> parse_number_s32(const char*& input)
{
char* end;
s64 value = strtoll(input, &end, 10);
if(end == input) {
return std::nullopt;
}
input = end;
return (s32) value;
}
std::optional<s64> parse_number_s64(const char*& input)
{
char* end;
s64 value = strtoll(input, &end, 10);
if(end == input) {
return std::nullopt;
}
input = end;
return value;
}
std::optional<std::string> parse_stabs_identifier(const char*& input, char terminator)
{
const char* begin = input;
for(; *input != '\0'; input++) {
if(*input == terminator) {
return std::string(begin, input);
}
}
return std::nullopt;
}
// The complexity here is because the input may contain an unescaped namespace
// separator '::' even if the field terminator is supposed to be a colon, as
// well as the raw contents of character literals. See test/ccc/stabs_tests.cpp
// for some examples.
Result<std::string> parse_dodgy_stabs_identifier(const char*& input, char terminator)
{
const char* begin = input;
s32 template_depth = 0;
for(; *input != '\0'; input++) {
// Skip past character literals.
if(*input == '\'') {
input++;
if(*input == '\'') {
input++; // Handle character literals containing a single quote.
}
while(*input != '\'' && *input != '\0') {
input++;
}
if(*input == '\0') {
break;
}
input++;
}
// Keep track of the template depth so we know when to expect the
// terminator character.
if(*input == '<') {
template_depth++;
}
if(*input == '>') {
template_depth--;
}
if(*input == terminator && template_depth == 0) {
return std::string(begin, input);
}
}
return CCC_FAILURE(STAB_TRUNCATED_ERROR_MESSAGE);
}
STABS_DEBUG(
static void print_field(const StabsStructOrUnionType::Field& field)
{
printf("\t%04x %04x %04x %04x %s\n", field.offset_bits / 8, field.size_bits / 8, field.offset_bits, field.size_bits, field.name.c_str());
}
)
const char* stabs_field_visibility_to_string(StabsStructOrUnionType::Visibility visibility)
{
switch(visibility) {
case StabsStructOrUnionType::Visibility::PRIVATE: return "private";
case StabsStructOrUnionType::Visibility::PROTECTED: return "protected";
case StabsStructOrUnionType::Visibility::PUBLIC: return "public";
case StabsStructOrUnionType::Visibility::PUBLIC_OPTIMIZED_OUT: return "public_optimizedout";
default: return "none";
}
return "";
}
}

379
3rdparty/ccc/src/ccc/stabs.h vendored Normal file
View File

@@ -0,0 +1,379 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include "ast.h"
#include "util.h"
namespace ccc {
enum class StabsSymbolDescriptor : u8 {
LOCAL_VARIABLE = '_',
REFERENCE_PARAMETER_A = 'a',
LOCAL_FUNCTION = 'f',
GLOBAL_FUNCTION = 'F',
GLOBAL_VARIABLE = 'G',
REGISTER_PARAMETER = 'P',
VALUE_PARAMETER = 'p',
REGISTER_VARIABLE = 'r',
STATIC_GLOBAL_VARIABLE = 'S',
TYPE_NAME = 't',
ENUM_STRUCT_OR_TYPE_TAG = 'T',
STATIC_LOCAL_VARIABLE = 'V',
REFERENCE_PARAMETER_V = 'v'
};
struct StabsType;
struct StabsSymbol {
StabsSymbolDescriptor descriptor;
std::string name;
std::unique_ptr<StabsType> type;
};
Result<StabsSymbol> parse_stabs_symbol(const char*& input);
enum class StabsTypeDescriptor : u8 {
TYPE_REFERENCE = 0xef, // '0'..'9','('
ARRAY = 'a',
ENUM = 'e',
FUNCTION = 'f',
CONST_QUALIFIER = 'k',
RANGE = 'r',
STRUCT = 's',
UNION = 'u',
CROSS_REFERENCE = 'x',
VOLATILE_QUALIFIER = 'B',
FLOATING_POINT_BUILTIN = 'R',
METHOD = '#',
REFERENCE = '&',
POINTER = '*',
TYPE_ATTRIBUTE = '@',
POINTER_TO_DATA_MEMBER = 0xee, // also '@'
BUILTIN = '-'
};
struct StabsBaseClass;
struct StabsField;
struct StabsMemberFunctionSet;
// e.g. for "123=*456" 123 would be the type_number, the type descriptor would
// be of type POINTER and StabsPointerType::value_type would point to a type
// with type_number = 456.
struct StabsType {
StabsTypeNumber type_number;
// The name field is only populated for root types and cross references.
std::optional<std::string> name;
bool is_typedef = false;
bool is_root = false;
std::optional<StabsTypeDescriptor> descriptor;
StabsType(StabsTypeNumber n) : type_number(n) {}
StabsType(StabsTypeDescriptor d) : descriptor(d) {}
StabsType(StabsTypeNumber n, StabsTypeDescriptor d) : type_number(n), descriptor(d) {}
virtual ~StabsType() {}
template <typename SubType>
SubType& as()
{
CCC_ASSERT(descriptor == SubType::DESCRIPTOR);
return *static_cast<SubType*>(this);
}
template <typename SubType>
const SubType& as() const
{
CCC_ASSERT(descriptor == SubType::DESCRIPTOR);
return *static_cast<const SubType*>(this);
}
virtual void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const
{
if(type_number.valid() && descriptor.has_value()) {
output.emplace(type_number, this);
}
}
};
struct StabsTypeReferenceType : StabsType {
std::unique_ptr<StabsType> type;
StabsTypeReferenceType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::TYPE_REFERENCE;
void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const override
{
StabsType::enumerate_numbered_types(output);
type->enumerate_numbered_types(output);
}
};
struct StabsArrayType : StabsType {
std::unique_ptr<StabsType> index_type;
std::unique_ptr<StabsType> element_type;
StabsArrayType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::ARRAY;
void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const override
{
StabsType::enumerate_numbered_types(output);
index_type->enumerate_numbered_types(output);
element_type->enumerate_numbered_types(output);
}
};
struct StabsEnumType : StabsType {
std::vector<std::pair<s32, std::string>> fields;
StabsEnumType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::ENUM;
};
struct StabsFunctionType : StabsType {
std::unique_ptr<StabsType> return_type;
StabsFunctionType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::FUNCTION;
void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const override
{
StabsType::enumerate_numbered_types(output);
return_type->enumerate_numbered_types(output);
}
};
struct StabsVolatileQualifierType : StabsType {
std::unique_ptr<StabsType> type;
StabsVolatileQualifierType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::VOLATILE_QUALIFIER;
void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const override
{
StabsType::enumerate_numbered_types(output);
type->enumerate_numbered_types(output);
}
};
struct StabsConstQualifierType : StabsType {
std::unique_ptr<StabsType> type;
StabsConstQualifierType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::CONST_QUALIFIER;
void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const override
{
StabsType::enumerate_numbered_types(output);
type->enumerate_numbered_types(output);
}
};
struct StabsRangeType : StabsType {
std::unique_ptr<StabsType> type;
std::string low;
std::string high; // Some compilers wrote out a wrapped around value here for zero (or variable?) length arrays.
StabsRangeType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::RANGE;
void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const override
{
StabsType::enumerate_numbered_types(output);
type->enumerate_numbered_types(output);
}
};
struct StabsStructOrUnionType : StabsType {
enum class Visibility : u8 {
NONE,
PRIVATE,
PROTECTED,
PUBLIC,
PUBLIC_OPTIMIZED_OUT
};
struct BaseClass {
bool is_virtual;
Visibility visibility;
s32 offset = -1;
std::unique_ptr<StabsType> type;
};
struct Field {
std::string name;
Visibility visibility = Visibility::NONE;
std::unique_ptr<StabsType> type;
bool is_static = false;
s32 offset_bits = 0;
s32 size_bits = 0;
std::string type_name;
};
struct MemberFunction {
std::unique_ptr<StabsType> type;
std::unique_ptr<StabsType> virtual_type;
Visibility visibility;
bool is_const = false;
bool is_volatile = false;
ast::MemberFunctionModifier modifier = ast::MemberFunctionModifier::NONE;
s32 vtable_index = -1;
};
struct MemberFunctionSet {
std::string name;
std::vector<MemberFunction> overloads;
};
s64 size = -1;
std::vector<BaseClass> base_classes;
std::vector<Field> fields;
std::vector<MemberFunctionSet> member_functions;
std::unique_ptr<StabsType> first_base_class;
StabsStructOrUnionType(StabsTypeNumber n, StabsTypeDescriptor d) : StabsType(n, d) {}
void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const override
{
StabsType::enumerate_numbered_types(output);
for(const BaseClass& base_class : base_classes) {
base_class.type->enumerate_numbered_types(output);
}
for(const Field& field : fields) {
field.type->enumerate_numbered_types(output);
}
for(const MemberFunctionSet& member_function_set : member_functions) {
for(const MemberFunction& member_function : member_function_set.overloads) {
member_function.type->enumerate_numbered_types(output);
if(member_function.virtual_type.get()) {
member_function.virtual_type->enumerate_numbered_types(output);
}
}
}
if(first_base_class.get()) {
first_base_class->enumerate_numbered_types(output);
}
}
};
struct StabsStructType : StabsStructOrUnionType {
StabsStructType(StabsTypeNumber n) : StabsStructOrUnionType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::STRUCT;
};
struct StabsUnionType : StabsStructOrUnionType {
StabsUnionType(StabsTypeNumber n) : StabsStructOrUnionType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::UNION;
};
struct StabsCrossReferenceType : StabsType {
ast::ForwardDeclaredType type;
std::string identifier;
StabsCrossReferenceType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::CROSS_REFERENCE;
};
struct StabsFloatingPointBuiltInType : StabsType {
s32 fpclass = -1;
s32 bytes = -1;
StabsFloatingPointBuiltInType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::FLOATING_POINT_BUILTIN;
};
struct StabsMethodType : StabsType {
std::unique_ptr<StabsType> return_type;
std::optional<std::unique_ptr<StabsType>> class_type;
std::vector<std::unique_ptr<StabsType>> parameter_types;
StabsMethodType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::METHOD;
void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const override
{
StabsType::enumerate_numbered_types(output);
return_type->enumerate_numbered_types(output);
if(class_type.has_value()) {
(*class_type)->enumerate_numbered_types(output);
}
for(const std::unique_ptr<StabsType>& parameter_type : parameter_types) {
parameter_type->enumerate_numbered_types(output);
}
}
};
struct StabsReferenceType : StabsType {
std::unique_ptr<StabsType> value_type;
StabsReferenceType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::REFERENCE;
void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const override
{
StabsType::enumerate_numbered_types(output);
value_type->enumerate_numbered_types(output);
}
};
struct StabsPointerType : StabsType {
std::unique_ptr<StabsType> value_type;
StabsPointerType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::POINTER;
void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const override
{
StabsType::enumerate_numbered_types(output);
value_type->enumerate_numbered_types(output);
}
};
struct StabsSizeTypeAttributeType : StabsType {
s64 size_bits = -1;
std::unique_ptr<StabsType> type;
StabsSizeTypeAttributeType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::TYPE_ATTRIBUTE;
void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const override
{
StabsType::enumerate_numbered_types(output);
type->enumerate_numbered_types(output);
}
};
struct StabsPointerToDataMemberType : StabsType {
std::unique_ptr<StabsType> class_type;
std::unique_ptr<StabsType> member_type;
StabsPointerToDataMemberType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::POINTER_TO_DATA_MEMBER;
void enumerate_numbered_types(std::map<StabsTypeNumber, const StabsType*>& output) const override
{
StabsType::enumerate_numbered_types(output);
class_type->enumerate_numbered_types(output);
member_type->enumerate_numbered_types(output);
}
};
struct StabsBuiltInType : StabsType {
s64 type_id = -1;
StabsBuiltInType(StabsTypeNumber n) : StabsType(n, DESCRIPTOR) {}
static const constexpr StabsTypeDescriptor DESCRIPTOR = StabsTypeDescriptor::BUILTIN;
};
extern const char* STAB_TRUNCATED_ERROR_MESSAGE;
Result<std::unique_ptr<StabsType>> parse_top_level_stabs_type(const char*& input);
std::optional<s32> parse_number_s32(const char*& input);
std::optional<s64> parse_number_s64(const char*& input);
std::optional<std::string> parse_stabs_identifier(const char*& input, char terminator);
Result<std::string> parse_dodgy_stabs_identifier(const char*& input, char terminator);
const char* stabs_field_visibility_to_string(StabsStructOrUnionType::Visibility visibility);
}

834
3rdparty/ccc/src/ccc/stabs_to_ast.cpp vendored Normal file
View File

@@ -0,0 +1,834 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "stabs_to_ast.h"
#include "importer_flags.h"
#define AST_DEBUG(...) //__VA_ARGS__
#define AST_DEBUG_PRINTF(...) AST_DEBUG(printf(__VA_ARGS__);)
namespace ccc {
struct MemberFunctionInfo {
std::string name;
bool is_constructor_or_destructor = false;
bool is_special_member_function = false;
bool is_operator_member_function = false;
};
static bool is_void_like(const StabsType& type);
static Result<ast::BuiltInClass> classify_range(const StabsRangeType& type);
static Result<std::unique_ptr<ast::Node>> field_to_ast(
const StabsStructOrUnionType::Field& field,
const StabsType& enclosing_struct,
const StabsToAstState& state,
s32 depth);
static Result<bool> detect_bitfield(const StabsStructOrUnionType::Field& field, const StabsToAstState& state);
static Result<std::vector<std::unique_ptr<ast::Node>>> member_functions_to_ast(
const StabsStructOrUnionType& type, const StabsToAstState& state, s32 depth);
static MemberFunctionInfo check_member_function(
const std::string& mangled_name,
std::string_view type_name_no_template_args,
const DemanglerFunctions& demangler,
u32 importer_flags);
Result<std::unique_ptr<ast::Node>> stabs_type_to_ast(
const StabsType& type,
const StabsType* enclosing_struct,
const StabsToAstState& state,
s32 depth,
bool substitute_type_name,
bool force_substitute)
{
AST_DEBUG_PRINTF("%-*stype desc=%hhx '%c' num=(%d,%d) name=%s\n",
depth * 4, "",
type.descriptor.has_value() ? (u8) *type.descriptor : 'X',
(type.descriptor.has_value() && isprint((u8) *type.descriptor)) ? (u8) *type.descriptor : '!',
type.type_number.file, type.type_number.type,
type.name.has_value() ? type.name->c_str() : "");
if(depth > 200) {
const char* error_message = "Call depth greater than 200 in stabs_type_to_ast, probably infinite recursion.";
if(state.importer_flags & STRICT_PARSING) {
return CCC_FAILURE(error_message);
} else {
CCC_WARN(error_message);
auto error = std::make_unique<ast::Error>();
error->message = error_message;
return std::unique_ptr<ast::Node>(std::move(error));
}
}
// This makes sure that types are replaced with their type name in cases
// where that would be more appropriate.
if(type.name.has_value()) {
bool try_substitute = depth > 0 && (type.is_root
|| type.descriptor == StabsTypeDescriptor::RANGE
|| type.descriptor == StabsTypeDescriptor::BUILTIN);
// GCC emits anonymous enums with a name of " " since apparently some
// debuggers can't handle zero-length names.
bool is_name_empty = type.name == "" || type.name == " ";
// Cross references will be handled below.
bool is_cross_reference = type.descriptor == StabsTypeDescriptor::CROSS_REFERENCE;
bool is_void = is_void_like(type);
if((substitute_type_name || try_substitute) && !is_name_empty && !is_cross_reference && !is_void) {
auto type_name = std::make_unique<ast::TypeName>();
type_name->source = ast::TypeNameSource::REFERENCE;
type_name->unresolved_stabs = std::make_unique<ast::TypeName::UnresolvedStabs>();
type_name->unresolved_stabs->type_name = *type.name;
type_name->unresolved_stabs->referenced_file_handle = state.file_handle;
type_name->unresolved_stabs->stabs_type_number = type.type_number;
return std::unique_ptr<ast::Node>(std::move(type_name));
}
}
// This prevents infinite recursion when an automatically generated member
// function references an unnamed type.
bool can_compare_type_numbers = type.type_number.valid() && enclosing_struct && enclosing_struct->type_number.valid();
if(force_substitute && can_compare_type_numbers && type.type_number == enclosing_struct->type_number) {
// It's probably a this parameter (or return type) for an unnamed type.
auto type_name = std::make_unique<ast::TypeName>();
type_name->source = ast::TypeNameSource::UNNAMED_THIS;
type_name->unresolved_stabs = std::make_unique<ast::TypeName::UnresolvedStabs>();
type_name->unresolved_stabs->type_name = enclosing_struct->name.has_value() ? *enclosing_struct->name : "";
type_name->unresolved_stabs->referenced_file_handle = state.file_handle;
type_name->unresolved_stabs->stabs_type_number = type.type_number;
return std::unique_ptr<ast::Node>(std::move(type_name));
}
if(!type.descriptor.has_value()) {
// The definition of the type has been defined previously, so we have to
// look it up by its type number.
CCC_CHECK(type.type_number.valid(), "Cannot lookup type (type is anonymous).");
auto stabs_type = state.stabs_types->find(type.type_number);
if(stabs_type == state.stabs_types->end()) {
std::string error_message = "Failed to lookup STABS type by its type number ("
+ std::to_string(type.type_number.file) + "," + std::to_string(type.type_number.type) + ").";
if(state.importer_flags & STRICT_PARSING) {
return CCC_FAILURE("%s", error_message.c_str());
} else {
CCC_WARN("%s", error_message.c_str());
std::unique_ptr<ast::Error> error = std::make_unique<ast::Error>();
error->message = std::move(error_message);
return std::unique_ptr<ast::Node>(std::move(error));
}
}
return stabs_type_to_ast(
*stabs_type->second,
enclosing_struct,
state,
depth + 1,
substitute_type_name,
force_substitute);
}
std::unique_ptr<ast::Node> result;
switch(*type.descriptor) {
case StabsTypeDescriptor::TYPE_REFERENCE: {
const auto& stabs_type_ref = type.as<StabsTypeReferenceType>();
if(!type.type_number.valid() || !stabs_type_ref.type->type_number.valid() || stabs_type_ref.type->type_number != type.type_number) {
auto node = stabs_type_to_ast(
*stabs_type_ref.type,
enclosing_struct,
state,
depth + 1,
substitute_type_name,
force_substitute);
CCC_RETURN_IF_ERROR(node);
result = std::move(*node);
} else {
// I still don't know why in STABS void is a reference to
// itself, maybe because I'm not a philosopher.
auto builtin = std::make_unique<ast::BuiltIn>();
builtin->bclass = ast::BuiltInClass::VOID_TYPE;
result = std::move(builtin);
}
break;
}
case StabsTypeDescriptor::ARRAY: {
auto array = std::make_unique<ast::Array>();
const auto& stabs_array = type.as<StabsArrayType>();
auto element_node = stabs_type_to_ast(
*stabs_array.element_type,
enclosing_struct,
state,
depth + 1,
true,
force_substitute);
CCC_RETURN_IF_ERROR(element_node);
array->element_type = std::move(*element_node);
const StabsRangeType& index = stabs_array.index_type->as<StabsRangeType>();
char* end = nullptr;
const char* low = index.low.c_str();
s64 low_value = strtoll(low, &end, 10);
CCC_CHECK(end != low, "Failed to parse low part of range as integer.");
CCC_CHECK(low_value == 0, "Invalid index type for array.");
const char* high = index.high.c_str();
s64 high_value = strtoll(high, &end, 10);
CCC_CHECK(end != high, "Failed to parse low part of range as integer.");
if(high_value == 4294967295) {
// Some compilers wrote out a wrapped around value here.
array->element_count = 0;
} else {
array->element_count = (s32) high_value + 1;
}
result = std::move(array);
break;
}
case StabsTypeDescriptor::ENUM: {
auto inline_enum = std::make_unique<ast::Enum>();
const auto& stabs_enum = type.as<StabsEnumType>();
inline_enum->constants = stabs_enum.fields;
result = std::move(inline_enum);
break;
}
case StabsTypeDescriptor::FUNCTION: {
auto function = std::make_unique<ast::Function>();
auto node = stabs_type_to_ast(
*type.as<StabsFunctionType>().return_type,
enclosing_struct,
state,
depth + 1,
true,
force_substitute);
CCC_RETURN_IF_ERROR(node);
function->return_type = std::move(*node);
result = std::move(function);
break;
}
case StabsTypeDescriptor::VOLATILE_QUALIFIER: {
const auto& volatile_qualifier = type.as<StabsVolatileQualifierType>();
auto node = stabs_type_to_ast(
*volatile_qualifier.type.get(),
enclosing_struct,
state,
depth + 1,
substitute_type_name,
force_substitute);
CCC_RETURN_IF_ERROR(node);
result = std::move(*node);
result->is_volatile = true;
break;
}
case StabsTypeDescriptor::CONST_QUALIFIER: {
const auto& const_qualifier = type.as<StabsConstQualifierType>();
auto node = stabs_type_to_ast(
*const_qualifier.type.get(),
enclosing_struct,
state,
depth + 1,
substitute_type_name,
force_substitute);
result = std::move(*node);
result->is_const = true;
break;
}
case StabsTypeDescriptor::RANGE: {
auto builtin = std::make_unique<ast::BuiltIn>();
Result<ast::BuiltInClass> bclass = classify_range(type.as<StabsRangeType>());
CCC_RETURN_IF_ERROR(bclass);
builtin->bclass = *bclass;
result = std::move(builtin);
break;
}
case StabsTypeDescriptor::STRUCT:
case StabsTypeDescriptor::UNION: {
const StabsStructOrUnionType* stabs_struct_or_union;
if(type.descriptor == StabsTypeDescriptor::STRUCT) {
stabs_struct_or_union = &type.as<StabsStructType>();
} else {
stabs_struct_or_union = &type.as<StabsUnionType>();
}
auto struct_or_union = std::make_unique<ast::StructOrUnion>();
struct_or_union->is_struct = type.descriptor == StabsTypeDescriptor::STRUCT;
struct_or_union->size_bits = (s32) stabs_struct_or_union->size * 8;
for(const StabsStructOrUnionType::BaseClass& stabs_base_class : stabs_struct_or_union->base_classes) {
auto base_class = stabs_type_to_ast(
*stabs_base_class.type,
&type,
state,
depth + 1,
true,
force_substitute);
CCC_RETURN_IF_ERROR(base_class);
(*base_class)->offset_bytes = stabs_base_class.offset;
(*base_class)->set_access_specifier(stabs_field_visibility_to_access_specifier(stabs_base_class.visibility), state.importer_flags);
if(stabs_base_class.is_virtual) {
(*base_class)->is_virtual_base_class = true;
}
struct_or_union->base_classes.emplace_back(std::move(*base_class));
}
AST_DEBUG_PRINTF("%-*s beginfields\n", depth * 4, "");
for(const StabsStructOrUnionType::Field& field : stabs_struct_or_union->fields) {
auto node = field_to_ast(field, type, state, depth);
CCC_RETURN_IF_ERROR(node);
struct_or_union->fields.emplace_back(std::move(*node));
}
AST_DEBUG_PRINTF("%-*s endfields\n", depth * 4, "");
AST_DEBUG_PRINTF("%-*s beginmemberfuncs\n", depth * 4, "");
Result<std::vector<std::unique_ptr<ast::Node>>> member_functions =
member_functions_to_ast(*stabs_struct_or_union, state, depth);
CCC_RETURN_IF_ERROR(member_functions);
struct_or_union->member_functions = std::move(*member_functions);
AST_DEBUG_PRINTF("%-*s endmemberfuncs\n", depth * 4, "");
result = std::move(struct_or_union);
break;
}
case StabsTypeDescriptor::CROSS_REFERENCE: {
const auto& cross_reference = type.as<StabsCrossReferenceType>();
auto type_name = std::make_unique<ast::TypeName>();
type_name->source = ast::TypeNameSource::CROSS_REFERENCE;
type_name->unresolved_stabs = std::make_unique<ast::TypeName::UnresolvedStabs>();
type_name->unresolved_stabs->type_name = cross_reference.identifier;
type_name->unresolved_stabs->type = cross_reference.type;
result = std::move(type_name);
break;
}
case ccc::StabsTypeDescriptor::FLOATING_POINT_BUILTIN: {
const auto& fp_builtin = type.as<StabsFloatingPointBuiltInType>();
auto builtin = std::make_unique<ast::BuiltIn>();
switch(fp_builtin.bytes) {
case 1: builtin->bclass = ast::BuiltInClass::UNSIGNED_8; break;
case 2: builtin->bclass = ast::BuiltInClass::UNSIGNED_16; break;
case 4: builtin->bclass = ast::BuiltInClass::UNSIGNED_32; break;
case 8: builtin->bclass = ast::BuiltInClass::UNSIGNED_64; break;
case 16: builtin->bclass = ast::BuiltInClass::UNSIGNED_128; break;
default: builtin->bclass = ast::BuiltInClass::UNSIGNED_8; break;
}
result = std::move(builtin);
break;
}
case StabsTypeDescriptor::METHOD: {
const auto& stabs_method = type.as<StabsMethodType>();
auto function = std::make_unique<ast::Function>();
auto return_node = stabs_type_to_ast(
*stabs_method.return_type.get(),
enclosing_struct,
state,
depth + 1,
true,
true);
CCC_RETURN_IF_ERROR(return_node);
function->return_type = std::move(*return_node);
function->parameters.emplace();
for(const std::unique_ptr<StabsType>& parameter_type : stabs_method.parameter_types) {
auto parameter_node = stabs_type_to_ast(
*parameter_type,
enclosing_struct,
state,
depth + 1,
true,
true);
CCC_RETURN_IF_ERROR(parameter_node);
function->parameters->emplace_back(std::move(*parameter_node));
}
result = std::move(function);
break;
}
case StabsTypeDescriptor::POINTER: {
auto pointer = std::make_unique<ast::PointerOrReference>();
pointer->is_pointer = true;
auto value_node = stabs_type_to_ast(
*type.as<StabsPointerType>().value_type,
enclosing_struct,
state,
depth + 1,
true,
force_substitute);
CCC_RETURN_IF_ERROR(value_node);
pointer->value_type = std::move(*value_node);
result = std::move(pointer);
break;
}
case StabsTypeDescriptor::REFERENCE: {
auto reference = std::make_unique<ast::PointerOrReference>();
reference->is_pointer = false;
auto value_node = stabs_type_to_ast(
*type.as<StabsReferenceType>().value_type,
enclosing_struct,
state,
depth + 1,
true,
force_substitute);
CCC_RETURN_IF_ERROR(value_node);
reference->value_type = std::move(*value_node);
result = std::move(reference);
break;
}
case StabsTypeDescriptor::TYPE_ATTRIBUTE: {
const auto& stabs_type_attribute = type.as<StabsSizeTypeAttributeType>();
auto node = stabs_type_to_ast(
*stabs_type_attribute.type,
enclosing_struct,
state,
depth + 1,
substitute_type_name,
force_substitute);
CCC_RETURN_IF_ERROR(node);
result = std::move(*node);
result->size_bits = (s32) stabs_type_attribute.size_bits;
break;
}
case StabsTypeDescriptor::POINTER_TO_DATA_MEMBER: {
const auto& stabs_member_pointer = type.as<StabsPointerToDataMemberType>();
auto member_pointer = std::make_unique<ast::PointerToDataMember>();
auto class_node = stabs_type_to_ast(
*stabs_member_pointer.class_type.get(),
enclosing_struct,
state,
depth + 1,
true,
true);
CCC_RETURN_IF_ERROR(class_node);
member_pointer->class_type = std::move(*class_node);
auto member_node = stabs_type_to_ast(
*stabs_member_pointer.member_type.get(),
enclosing_struct,
state,
depth + 1,
true,
true);
CCC_RETURN_IF_ERROR(member_node);
member_pointer->member_type = std::move(*member_node);
result = std::move(member_pointer);
break;
}
case StabsTypeDescriptor::BUILTIN: {
CCC_CHECK(type.as<StabsBuiltInType>().type_id == 16,
"Unknown built-in type!");
auto builtin = std::make_unique<ast::BuiltIn>();
builtin->bclass = ast::BuiltInClass::BOOL_8;
result = std::move(builtin);
break;
}
}
CCC_CHECK(result, "Result of stabs_type_to_ast call is nullptr.");
return result;
}
static bool is_void_like(const StabsType& type)
{
// Unfortunately, a common case seems to be that various types (most
// commonly __builtin_va_list) are indistinguishable from void or void*, so
// we have to output them as a void built-in.
if(type.descriptor.has_value()) {
switch(*type.descriptor) {
case StabsTypeDescriptor::POINTER: {
return is_void_like(*type.as<StabsPointerType>().value_type.get());
}
case StabsTypeDescriptor::TYPE_REFERENCE: {
return type.as<StabsTypeReferenceType>().type->type_number == type.type_number;
}
default: {
break;
}
}
}
return false;
}
static Result<ast::BuiltInClass> classify_range(const StabsRangeType& type)
{
const char* low = type.low.c_str();
const char* high = type.high.c_str();
// Handle some special cases and values that are too large to easily store
// in a 64-bit integer.
static const struct { const char* low; const char* high; ast::BuiltInClass classification; } strings[] = {
{"4", "0", ast::BuiltInClass::FLOAT_32},
{"000000000000000000000000", "001777777777777777777777", ast::BuiltInClass::UNSIGNED_64},
{"00000000000000000000000000000000000000000000", "00000000000000000000001777777777777777777777", ast::BuiltInClass::UNSIGNED_64},
{"0000000000000", "01777777777777777777777", ast::BuiltInClass::UNSIGNED_64}, // IOP
{"0", "18446744073709551615", ast::BuiltInClass::UNSIGNED_64},
{"001000000000000000000000", "000777777777777777777777", ast::BuiltInClass::SIGNED_64},
{"00000000000000000000001000000000000000000000", "00000000000000000000000777777777777777777777", ast::BuiltInClass::SIGNED_64},
{"01000000000000000000000", "0777777777777777777777", ast::BuiltInClass::SIGNED_64}, // IOP
{"-9223372036854775808", "9223372036854775807", ast::BuiltInClass::SIGNED_64},
{"8", "0", ast::BuiltInClass::FLOAT_64},
{"00000000000000000000000000000000000000000000", "03777777777777777777777777777777777777777777", ast::BuiltInClass::UNSIGNED_128},
{"02000000000000000000000000000000000000000000", "01777777777777777777777777777777777777777777", ast::BuiltInClass::SIGNED_128},
{"000000000000000000000000", "0377777777777777777777777777777777", ast::BuiltInClass::UNQUALIFIED_128},
{"16", "0", ast::BuiltInClass::FLOAT_128},
{"0", "-1", ast::BuiltInClass::UNQUALIFIED_128} // Old homebrew toolchain
};
for(const auto& range : strings) {
if(strcmp(range.low, low) == 0 && strcmp(range.high, high) == 0) {
return range.classification;
}
}
// For smaller values we actually parse the bounds as integers.
char* end = nullptr;
s64 low_value = strtoll(type.low.c_str(), &end, low[0] == '0' ? 8 : 10);
CCC_CHECK(end != low, "Failed to parse low part of range as integer.");
s64 high_value = strtoll(type.high.c_str(), &end, high[0] == '0' ? 8 : 10);
CCC_CHECK(end != high, "Failed to parse high part of range as integer.");
static const struct { s64 low; s64 high; ast::BuiltInClass classification; } integers[] = {
{0, 255, ast::BuiltInClass::UNSIGNED_8},
{-128, 127, ast::BuiltInClass::SIGNED_8},
{0, 127, ast::BuiltInClass::UNQUALIFIED_8},
{0, 65535, ast::BuiltInClass::UNSIGNED_16},
{-32768, 32767, ast::BuiltInClass::SIGNED_16},
{0, 4294967295, ast::BuiltInClass::UNSIGNED_32},
{-2147483648, 2147483647, ast::BuiltInClass::SIGNED_32},
};
for(const auto& range : integers) {
if((range.low == low_value || range.low == -low_value) && range.high == high_value) {
return range.classification;
}
}
return CCC_FAILURE("Failed to classify range.");
}
static Result<std::unique_ptr<ast::Node>> field_to_ast(
const StabsStructOrUnionType::Field& field,
const StabsType& enclosing_struct,
const StabsToAstState& state,
s32 depth)
{
AST_DEBUG_PRINTF("%-*s field %s\n", depth * 4, "", field.name.c_str());
Result<bool> is_bitfield = detect_bitfield(field, state);
CCC_RETURN_IF_ERROR(is_bitfield);
if(*is_bitfield) {
// Process bitfields.
auto bitfield_node = stabs_type_to_ast(
*field.type,
&enclosing_struct,
state,
depth + 1,
true,
false);
CCC_RETURN_IF_ERROR(bitfield_node);
std::unique_ptr<ast::BitField> bitfield = std::make_unique<ast::BitField>();
bitfield->name = (field.name == " ") ? "" : field.name;
bitfield->offset_bytes = field.offset_bits / 8;
bitfield->size_bits = field.size_bits;
bitfield->underlying_type = std::move(*bitfield_node);
bitfield->bitfield_offset_bits = field.offset_bits % 8;
bitfield->set_access_specifier(stabs_field_visibility_to_access_specifier(field.visibility), state.importer_flags);
return std::unique_ptr<ast::Node>(std::move(bitfield));
} else {
// Process a normal field.
Result<std::unique_ptr<ast::Node>> node = stabs_type_to_ast(
*field.type,
&enclosing_struct,
state,
depth + 1,
true,
false);
CCC_RETURN_IF_ERROR(node);
(*node)->name = field.name;
(*node)->offset_bytes = field.offset_bits / 8;
(*node)->size_bits = field.size_bits;
(*node)->set_access_specifier(stabs_field_visibility_to_access_specifier(field.visibility), state.importer_flags);
if(field.name.starts_with("$vf") || field.name.starts_with("_vptr$") || field.name.starts_with("_vptr.")) {
(*node)->is_vtable_pointer = true;
}
if(field.is_static) {
(*node)->storage_class = STORAGE_CLASS_STATIC;
}
return node;
}
}
static Result<bool> detect_bitfield(const StabsStructOrUnionType::Field& field, const StabsToAstState& state)
{
// Static fields can't be bitfields.
if(field.is_static) {
return false;
}
// Resolve type references.
const StabsType* type = field.type.get();
for(s32 i = 0; i < 50; i++) {
if(!type->descriptor.has_value()) {
if(!type->type_number.valid()) {
return false;
}
auto next_type = state.stabs_types->find(type->type_number);
if(next_type == state.stabs_types->end() || next_type->second == type) {
return false;
}
type = next_type->second;
} else if(type->descriptor == StabsTypeDescriptor::TYPE_REFERENCE) {
type = type->as<StabsTypeReferenceType>().type.get();
} else if(type->descriptor == StabsTypeDescriptor::CONST_QUALIFIER) {
type = type->as<StabsConstQualifierType>().type.get();
} else if(type->descriptor == StabsTypeDescriptor::VOLATILE_QUALIFIER) {
type = type->as<StabsVolatileQualifierType>().type.get();
} else {
break;
}
// Prevent an infinite loop if there's a cycle (fatal frame).
if(i == 49) {
return false;
}
}
// Determine the size of the underlying type.
s32 underlying_type_size_bits = 0;
switch(*type->descriptor) {
case ccc::StabsTypeDescriptor::RANGE: {
Result<ast::BuiltInClass> bclass = classify_range(type->as<StabsRangeType>());
CCC_RETURN_IF_ERROR(bclass);
underlying_type_size_bits = builtin_class_size(*bclass) * 8;
break;
}
case ccc::StabsTypeDescriptor::CROSS_REFERENCE: {
if(type->as<StabsCrossReferenceType>().type == ast::ForwardDeclaredType::ENUM) {
underlying_type_size_bits = 32;
} else {
return false;
}
break;
}
case ccc::StabsTypeDescriptor::TYPE_ATTRIBUTE: {
underlying_type_size_bits = (s32) type->as<StabsSizeTypeAttributeType>().size_bits;
break;
}
case ccc::StabsTypeDescriptor::BUILTIN: {
underlying_type_size_bits = 8; // bool
break;
}
default: {
return false;
}
}
if(underlying_type_size_bits == 0) {
return false;
}
return field.size_bits != underlying_type_size_bits;
}
static Result<std::vector<std::unique_ptr<ast::Node>>> member_functions_to_ast(
const StabsStructOrUnionType& type, const StabsToAstState& state, s32 depth)
{
if(state.importer_flags & NO_MEMBER_FUNCTIONS) {
return std::vector<std::unique_ptr<ast::Node>>();
}
std::string_view type_name_no_template_args;
if(type.name.has_value()) {
type_name_no_template_args =
std::string_view(*type.name).substr(0, type.name->find("<"));
}
std::vector<std::unique_ptr<ast::Node>> member_functions;
bool only_special_functions = true;
for(const StabsStructOrUnionType::MemberFunctionSet& function_set : type.member_functions) {
MemberFunctionInfo info = check_member_function(
function_set.name, type_name_no_template_args, state.demangler, state.importer_flags);
if(!info.is_special_member_function) {
only_special_functions = false;
}
for(const StabsStructOrUnionType::MemberFunction& stabs_func : function_set.overloads) {
auto node = stabs_type_to_ast(
*stabs_func.type,
&type,
state,
depth + 1,
true,
true);
CCC_RETURN_IF_ERROR(node);
(*node)->is_constructor_or_destructor = info.is_constructor_or_destructor;
(*node)->is_special_member_function = info.is_special_member_function;
(*node)->is_operator_member_function = info.is_operator_member_function;
(*node)->name = info.name;
(*node)->set_access_specifier(stabs_field_visibility_to_access_specifier(stabs_func.visibility), state.importer_flags);
if((*node)->descriptor == ast::FUNCTION) {
ast::Function& function = (*node)->as<ast::Function>();
function.modifier = stabs_func.modifier;
function.vtable_index = stabs_func.vtable_index;
}
member_functions.emplace_back(std::move(*node));
}
}
if(only_special_functions && (state.importer_flags & INCLUDE_GENERATED_MEMBER_FUNCTIONS) == 0) {
return std::vector<std::unique_ptr<ast::Node>>();
}
return member_functions;
}
static MemberFunctionInfo check_member_function(
const std::string& mangled_name,
std::string_view type_name_no_template_args,
const DemanglerFunctions& demangler,
u32 importer_flags)
{
MemberFunctionInfo info;
// Some compiler versions output gcc opnames for overloaded operators
// instead of their proper names.
if((importer_flags & DONT_DEMANGLE_NAMES) == 0 && demangler.cplus_demangle_opname) {
char* demangled_name = demangler.cplus_demangle_opname(mangled_name.c_str(), 0);
if(demangled_name) {
info.name = demangled_name;
free(reinterpret_cast<void*>(demangled_name));
}
}
if(info.name.empty()) {
info.name = mangled_name;
}
bool is_constructor =
info.name == "__ct" || // Takes a parameter to decide whether or not to construct virtual base classes.
info.name == "__comp_ctor" || // Constructs virtual base classes.
info.name == "__base_ctor"; // Does not construct virtual base classes.
if(!is_constructor && !type_name_no_template_args.empty()) {
is_constructor |= info.name == type_name_no_template_args; // Named constructor.
}
bool is_destructor =
info.name == "__dt" || // Takes parameters to decide whether or not to construct virtual base classes and/or delete the object.
info.name == "__comp_dtor" || // Destructs virtual base classes.
info.name == "__base_dtor" || // Does not construct virtual base classes.
info.name == "__deleting_dtor"; // Destructs virtual base clases then deletes the entire object.
if(!is_destructor && !info.name.empty()) {
is_destructor |= info.name[0] == '~' && std::string_view(info.name).substr(1) == type_name_no_template_args; // Named destructor.
}
info.is_constructor_or_destructor = is_constructor || is_destructor || info.name.starts_with("$_");
info.is_special_member_function = info.is_constructor_or_destructor || info.name == "operator=";
return info;
}
void fix_recursively_emitted_structures(
ast::StructOrUnion& outer_struct, const std::string& name, StabsTypeNumber type_number, SourceFileHandle file_handle)
{
// This is a rather peculiar case. For some compiler versions, when a struct
// or a union defined using a typedef is being emitted and it needs to
// reference itself from a member function parameter, it will emit its
// entire definition again in the middle of the first definition, although
// thankfully it won't recurse more than once.
//
// The game Sega Soccer Slam is affected by this. See the PeculiarParameter
// test case in mdebug_importer_tests.cpp for a bare bones example.
for(std::unique_ptr<ast::Node>& node : outer_struct.member_functions) {
if(node->descriptor != ast::FUNCTION) {
continue;
}
ast::Function& function = node->as<ast::Function>();
if(!function.parameters.has_value()) {
continue;
}
for(std::unique_ptr<ast::Node>& parameter : *function.parameters) {
if(parameter->descriptor != ast::POINTER_OR_REFERENCE) {
continue;
}
ast::PointerOrReference& pointer_or_reference = parameter->as<ast::PointerOrReference>();
if(pointer_or_reference.value_type->descriptor != ast::STRUCT_OR_UNION) {
continue;
}
ast::StructOrUnion& inner_struct = pointer_or_reference.value_type->as<ast::StructOrUnion>();
// Since C++ doesn't allow struct definitions in function parameter
// lists normally, and most of the time the member function
// parameters aren't even filled in by GCC, this is a really rare
// case, so here we only bother to do some very basic checks to
// verify that the inner struct is similar to the outer struct.
if(inner_struct.base_classes.size() != outer_struct.base_classes.size()) {
continue;
}
if(inner_struct.fields.size() != outer_struct.fields.size()) {
continue;
}
if(inner_struct.member_functions.size() != outer_struct.member_functions.size()) {
continue;
}
auto type_name = std::make_unique<ast::TypeName>();
type_name->source = ast::TypeNameSource::REFERENCE;
type_name->unresolved_stabs = std::make_unique<ast::TypeName::UnresolvedStabs>();
type_name->unresolved_stabs->type_name = name;
type_name->unresolved_stabs->referenced_file_handle = file_handle;
type_name->unresolved_stabs->stabs_type_number = type_number;
pointer_or_reference.value_type = std::move(type_name);
}
}
}
ast::AccessSpecifier stabs_field_visibility_to_access_specifier(StabsStructOrUnionType::Visibility visibility)
{
ast::AccessSpecifier access_specifier = ast::AS_PUBLIC;
switch(visibility) {
case StabsStructOrUnionType::Visibility::NONE: access_specifier = ast::AS_PUBLIC; break;
case StabsStructOrUnionType::Visibility::PUBLIC: access_specifier = ast::AS_PUBLIC; break;
case StabsStructOrUnionType::Visibility::PROTECTED: access_specifier = ast::AS_PROTECTED; break;
case StabsStructOrUnionType::Visibility::PRIVATE: access_specifier = ast::AS_PRIVATE; break;
case StabsStructOrUnionType::Visibility::PUBLIC_OPTIMIZED_OUT: access_specifier = ast::AS_PUBLIC; break;
}
return access_specifier;
}
}

29
3rdparty/ccc/src/ccc/stabs_to_ast.h vendored Normal file
View File

@@ -0,0 +1,29 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include "ast.h"
#include "stabs.h"
namespace ccc {
struct StabsToAstState {
u32 file_handle;
std::map<StabsTypeNumber, const StabsType*>* stabs_types;
u32 importer_flags;
DemanglerFunctions demangler;
};
Result<std::unique_ptr<ast::Node>> stabs_type_to_ast(
const StabsType& type,
const StabsType* enclosing_struct,
const StabsToAstState& state,
s32 depth,
bool substitute_type_name,
bool force_substitute);
void fix_recursively_emitted_structures(
ast::StructOrUnion& outer_struct, const std::string& name, StabsTypeNumber type_number, SourceFileHandle file_handle);
ast::AccessSpecifier stabs_field_visibility_to_access_specifier(StabsStructOrUnionType::Visibility visibility);
}

1204
3rdparty/ccc/src/ccc/symbol_database.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

721
3rdparty/ccc/src/ccc/symbol_database.h vendored Normal file
View File

@@ -0,0 +1,721 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include <map>
#include <atomic>
#include <variant>
#include "util.h"
namespace ccc {
// An X macro for all the symbol types.
#define CCC_FOR_EACH_SYMBOL_TYPE_DO_X \
CCC_X(DataType, data_types) \
CCC_X(Function, functions) \
CCC_X(GlobalVariable, global_variables) \
CCC_X(Label, labels) \
CCC_X(LocalVariable, local_variables) \
CCC_X(Module, modules) \
CCC_X(ParameterVariable, parameter_variables) \
CCC_X(Section, sections) \
CCC_X(SourceFile, source_files) \
CCC_X(SymbolSource, symbol_sources)
// An enum for all the symbol types.
enum SymbolDescriptor {
DATA_TYPE = 1 << 0,
FUNCTION = 1 << 1,
GLOBAL_VARIABLE = 1 << 2,
LABEL = 1 << 3,
LOCAL_VARIABLE = 1 << 4,
MODULE = 1 << 5,
PARAMETER_VARIABLE = 1 << 6,
SECTION = 1 << 7,
SOURCE_FILE = 1 << 8,
SYMBOL_SOURCE = 1 << 9
};
enum {
ALL_SYMBOL_TYPES = 0xffff
};
// Forward declare all the different types of symbol objects.
#define CCC_X(SymbolType, symbol_list) class SymbolType;
CCC_FOR_EACH_SYMBOL_TYPE_DO_X
#undef CCC_X
class SymbolDatabase;
// Strongly typed handles for all of the symbol objects. These are here to solve
// the problem of dangling references to symbols.
template <typename SymbolType>
struct SymbolHandle {
u32 value = (u32) -1;
SymbolHandle() {}
SymbolHandle(u32 v) : value(v) {}
SymbolHandle(const SymbolType* symbol)
: value(symbol ? symbol->handle().value : (u32) -1) {}
// Check if this symbol handle has been initialised. Note that this doesn't
// determine whether or not the symbol it points to has been deleted!
bool valid() const { return value != (u32) -1; }
friend auto operator<=>(const SymbolHandle& lhs, const SymbolHandle& rhs) = default;
};
#define CCC_X(SymbolType, symbol_list) using SymbolType##Handle = SymbolHandle<SymbolType>;
CCC_FOR_EACH_SYMBOL_TYPE_DO_X
#undef CCC_X
enum SymbolFlag {
NO_SYMBOL_FLAGS = 0,
WITH_ADDRESS_MAP = 1 << 0,
WITH_NAME_MAP = 1 << 1,
NAME_NEEDS_DEMANGLING = 1 << 2
};
// A container class for symbols of a given type that maintains maps of their
// names and addresses depending on the value of SymbolType::FLAGS.
template <typename SymbolType>
class SymbolList {
public:
// Lookup symbols from their handles using binary search.
SymbolType* symbol_from_handle(SymbolHandle<SymbolType> handle);
const SymbolType* symbol_from_handle(SymbolHandle<SymbolType> handle) const;
// Lookup multiple symbols from their handles using binary search.
std::vector<SymbolType*> symbols_from_handles(const std::vector<SymbolHandle<SymbolType>>& handles);
std::vector<const SymbolType*> symbols_from_handles(const std::vector<SymbolHandle<SymbolType>>& handles) const;
std::vector<SymbolType*> optional_symbols_from_handles(const std::optional<std::vector<SymbolHandle<SymbolType>>>& handles);
std::vector<const SymbolType*> optional_symbols_from_handles(const std::optional<std::vector<SymbolHandle<SymbolType>>>& handles) const;
using Iterator = typename std::vector<SymbolType>::iterator;
using ConstIterator = typename std::vector<SymbolType>::const_iterator;
// For iterating over all the symbols.
Iterator begin();
ConstIterator begin() const;
Iterator end();
ConstIterator end() const;
using AddressToHandleMap = std::multimap<u32, SymbolHandle<SymbolType>>;
using NameToHandleMap = std::multimap<std::string, SymbolHandle<SymbolType>>;
template <typename Iterator>
class Iterators {
public:
Iterators(Iterator b, Iterator e)
: m_begin(b), m_end(e) {}
Iterator begin() const { return m_begin; }
Iterator end() const { return m_end; }
protected:
Iterator m_begin;
Iterator m_end;
};
using AddressToHandleMapIterators = Iterators<typename AddressToHandleMap::const_iterator>;
using NameToHandleMapIterators = Iterators<typename NameToHandleMap::const_iterator>;
// Lookup symbols by their address.
AddressToHandleMapIterators handles_from_starting_address(Address address) const;
AddressToHandleMapIterators handles_from_address_range(AddressRange range) const;
SymbolHandle<SymbolType> first_handle_from_starting_address(Address address) const;
SymbolHandle<SymbolType> first_handle_after_address(Address address) const;
// Lookup symbols by their name.
NameToHandleMapIterators handles_from_name(const std::string& name) const;
SymbolHandle<SymbolType> first_handle_from_name(const std::string& name) const;
// Find a symbol with an address range that contains the provided address.
// For example, to find which function an instruction belongs to.
SymbolType* symbol_overlapping_address(Address address);
const SymbolType* symbol_overlapping_address(Address address) const;
// Convert handles to underlying array indices.
s32 index_from_handle(SymbolHandle<SymbolType> handle) const;
// Index into the underlying array.
SymbolType& symbol_from_index(s32 index);
const SymbolType& symbol_from_index(s32 index) const;
// Determine if any symbols are being stored.
bool empty() const;
// Retrieve the number of symbols stored.
s32 size() const;
// Create a new symbol. If it's a SymbolSource symbol, source can be left
// empty, otherwise it has to be valid.
Result<SymbolType*> create_symbol(
std::string name, Address address, SymbolSourceHandle source, const Module* module_symbol = nullptr);
// Create a new symbol. Similar to above, but for symbols without addresses.
Result<SymbolType*> create_symbol(
std::string name, SymbolSourceHandle source, const Module* module_symbol = nullptr);
// Create a new symbol. Similar to above, but unless DONT_DEMANGLE_NAMES is
// set, the name of the symbol will be demangled.
Result<SymbolType*> create_symbol(
std::string name,
SymbolSourceHandle source,
const Module* module_symbol,
Address address,
u32 importer_flags,
DemanglerFunctions demangler);
// Update the address of a symbol without changing its handle.
bool move_symbol(SymbolHandle<SymbolType> handle, Address new_address);
// Update the name of a symbol without changing its handle.
bool rename_symbol(SymbolHandle<SymbolType> handle, std::string new_name);
// Move all the symbols from the passed list into this list.
void merge_from(SymbolList<SymbolType>& list);
// Mark a symbol for destruction. If the correct symbol database pointer is
// passed, all descendants will also be marked. For example, marking a
// function will also mark its parameters and local variables.
bool mark_symbol_for_destruction(SymbolHandle<SymbolType> handle, SymbolDatabase* database);
// Mark all the symbols from a given symbol source for destruction. For
// example you can use this to free a symbol table without destroying
// user-defined symbols. The behaviour for marking descendants is the same
// as destroy_symbol.
void mark_symbols_from_source_for_destruction(SymbolSourceHandle source, SymbolDatabase* database);
// Mark all the symbols from a given module for destruction. The behaviour
// for marking descendants is the same as destroy_symbol.
void mark_symbols_from_module_for_destruction(ModuleHandle module_handle, SymbolDatabase* database);
// Destroy all symbols that have previously been marked for destruction.
// This invalidates all pointers to symbols in this list.
void destroy_marked_symbols();
// Destroy all symbols, but don't reset m_next_handle so we don't have to
// worry about dangling handles.
void clear();
protected:
// Do a binary search for a handle, and return either its index, or the
// index where it could be inserted.
size_t binary_search(SymbolHandle<SymbolType> handle) const;
// Keep the address map in sync with the symbol list.
void link_address_map(SymbolType& symbol);
void unlink_address_map(SymbolType& symbol);
// Keep the name map in sync with the symbol list.
void link_name_map(SymbolType& symbol);
void unlink_name_map(SymbolType& symbol);
std::vector<SymbolType> m_symbols;
AddressToHandleMap m_address_to_handle;
NameToHandleMap m_name_to_handle;
// We share this between symbol lists of the same type so that we can merge
// them without having to rewrite all the handles.
static std::atomic<u32> m_next_handle;
};
// Base class for all the symbols.
class Symbol {
template <typename SymbolType>
friend class SymbolList;
public:
const std::string& name() const { return m_name; }
u32 raw_handle() const { return m_handle; }
SymbolSourceHandle source() const { return m_source; }
ModuleHandle module_handle() const { return m_module; }
Address address() const { return m_address; }
u32 size() const { return m_size; }
void set_size(u32 size) { m_size = size; }
AddressRange address_range() const { return AddressRange(m_address, m_address.get_or_zero() + m_size); }
ast::Node* type() { return m_type.get(); }
const ast::Node* type() const { return m_type.get(); }
void set_type(std::unique_ptr<ast::Node> type);
u32 generation() const { return m_generation; }
// This MUST be called after any AST nodes have been created/deleted/moved.
// For the set_type function this is done for you.
void invalidate_node_handles() { m_generation++; }
// Mark a single symbol for destruction, not including its descendants.
void mark_for_destruction() { m_marked_for_destruction = true; }
bool is_marked_for_destruction() { return m_marked_for_destruction; }
protected:
void on_create() {}
void on_destroy(SymbolDatabase* database) {}
u32 m_handle = (u32) -1;
SymbolSourceHandle m_source;
Address m_address;
u32 m_size = 0;
std::string m_name;
std::unique_ptr<ast::Node> m_type;
u32 m_generation : 31 = 0;
u32 m_marked_for_destruction : 1 = false;
ModuleHandle m_module;
};
// Variable storage types. This is different to whether the variable is a
// global, local or parameter. For example local variables can have global
// storage (static locals).
enum GlobalStorageLocation {
NIL,
DATA,
BSS,
ABS,
SDATA,
SBSS,
RDATA,
COMMON,
SCOMMON,
SUNDEFINED
};
const char* global_storage_location_to_string(GlobalStorageLocation location);
struct GlobalStorage {
GlobalStorageLocation location = GlobalStorageLocation::NIL;
GlobalStorage() {}
friend auto operator<=>(const GlobalStorage& lhs, const GlobalStorage& rhs) = default;
};
struct RegisterStorage {
s32 dbx_register_number = -1;
bool is_by_reference;
RegisterStorage() {}
friend auto operator<=>(const RegisterStorage& lhs, const RegisterStorage& rhs) = default;
};
struct StackStorage {
s32 stack_pointer_offset = -1;
StackStorage() {}
friend auto operator<=>(const StackStorage& lhs, const StackStorage& rhs) = default;
};
// The hashing algorithm for functions. If you change this algorithm make sure
// to bump the version number for the JSON format so we can know if a hash was
// generated using the new algorithm or not.
class FunctionHash {
public:
void update(u32 instruction)
{
// Separate out the opcode so that the hash remains the same regardless
// of if relocations are applied or not.
u32 opcode = instruction >> 26;
m_hash = m_hash * 31 + opcode;
}
u32 get() const
{
return m_hash;
}
protected:
u32 m_hash = 0;
};
// All the different types of symbol objects.
// A C/C++ data type.
class DataType : public Symbol {
friend SourceFile;
public:
static constexpr const SymbolDescriptor DESCRIPTOR = DATA_TYPE;
static constexpr const char* NAME = "Data Type";
static constexpr const u32 FLAGS = WITH_NAME_MAP;
DataTypeHandle handle() const { return m_handle; }
std::vector<SourceFileHandle> files; // List of files for which a given top-level type is present.
const char* compare_fail_reason = nullptr;
bool not_defined_in_any_translation_unit : 1 = false;
bool only_defined_in_single_translation_unit : 1 = false;
};
// A function. The type stored is the return type.
class Function : public Symbol {
friend SourceFile;
friend SymbolList<Function>;
public:
static constexpr const SymbolDescriptor DESCRIPTOR = FUNCTION;
static constexpr const char* NAME = "Function";
static constexpr const u32 FLAGS = WITH_ADDRESS_MAP | WITH_NAME_MAP | NAME_NEEDS_DEMANGLING;
FunctionHandle handle() const { return m_handle; }
SourceFileHandle source_file() const { return m_source_file; }
const std::optional<std::vector<ParameterVariableHandle>>& parameter_variables() const;
void set_parameter_variables(std::optional<std::vector<ParameterVariableHandle>> parameter_variables, SymbolDatabase& database);
const std::optional<std::vector<LocalVariableHandle>>& local_variables() const;
void set_local_variables(std::optional<std::vector<LocalVariableHandle>> local_variables, SymbolDatabase& database);
const std::string& mangled_name() const;
void set_mangled_name(std::string mangled);
// A hash of all the opcodes in the function, read from file.
u32 original_hash() const;
void set_original_hash(u32 hash);
// A hash of all the opcodes in the function, read from memory.
u32 current_hash() const;
void set_current_hash(FunctionHash hash);
struct LineNumberPair {
Address address;
s32 line_number;
};
struct SubSourceFile {
Address address;
std::string relative_path;
};
std::string relative_path;
StorageClass storage_class;
s32 stack_frame_size = -1;
std::vector<LineNumberPair> line_numbers;
std::vector<SubSourceFile> sub_source_files;
bool is_member_function_ish = false; // Filled in by fill_in_pointers_to_member_function_definitions.
bool is_no_return = false;
protected:
void on_destroy(SymbolDatabase* database);
SourceFileHandle m_source_file;
std::optional<std::vector<ParameterVariableHandle>> m_parameter_variables;
std::optional<std::vector<LocalVariableHandle>> m_local_variables;
std::string m_mangled_name;
u32 m_original_hash = 0;
u32 m_current_hash = 0;
};
// A global variable.
class GlobalVariable : public Symbol {
friend SourceFile;
public:
static constexpr const SymbolDescriptor DESCRIPTOR = GLOBAL_VARIABLE;
static constexpr const char* NAME = "Global Variable";
static constexpr u32 FLAGS = WITH_ADDRESS_MAP | WITH_NAME_MAP | NAME_NEEDS_DEMANGLING;
GlobalVariableHandle handle() const { return m_handle; }
SourceFileHandle source_file() const { return m_source_file; };
const std::string& mangled_name() const;
void set_mangled_name(std::string mangled);
GlobalStorage storage;
StorageClass storage_class;
protected:
SourceFileHandle m_source_file;
std::string m_mangled_name;
};
// A label. This could be a label defined in assembly, C/C++, or just a symbol
// that we can't automatically determine the type of (e.g. SNDLL symbols).
class Label : public Symbol {
public:
static constexpr const SymbolDescriptor DESCRIPTOR = LABEL;
static constexpr const char* NAME = "Label";
static constexpr u32 FLAGS = WITH_ADDRESS_MAP | WITH_NAME_MAP;
LabelHandle handle() const { return m_handle; }
// Indicates that this label should not be used as a function name.
bool is_junk = false;
};
// A local variable. This includes static local variables which have global
// storage.
class LocalVariable : public Symbol {
friend Function;
public:
static constexpr const SymbolDescriptor DESCRIPTOR = LOCAL_VARIABLE;
static constexpr const char* NAME = "Local Variable";
static constexpr u32 FLAGS = WITH_ADDRESS_MAP;
LocalVariableHandle handle() const { return m_handle; }
FunctionHandle function() const { return m_function; };
std::variant<GlobalStorage, RegisterStorage, StackStorage> storage;
AddressRange live_range;
protected:
FunctionHandle m_function;
};
// A program module e.g. an ELF file or an SNDLL file. Every symbol has a module
// field indicating what module the symbol belongs to. This can be used to
// delete all the symbols associated with a given module. Additionally, when a
// valid module pointer is passed to SymbolList<>::create_symbol, the address of
// the symbol will be added to the address of the new symbol.
class Module : public Symbol {
friend SymbolList<Module>;
public:
static constexpr const SymbolDescriptor DESCRIPTOR = MODULE;
static constexpr const char* NAME = "Module";
static constexpr u32 FLAGS = WITH_NAME_MAP;
ModuleHandle handle() const { return m_handle; }
// These are used for IRX modules.
bool is_irx = false;
s32 version_major = -1;
s32 version_minor = -1;
protected:
void on_create();
};
// A parameter variable.
class ParameterVariable : public Symbol {
friend Function;
public:
static constexpr const SymbolDescriptor DESCRIPTOR = PARAMETER_VARIABLE;
static constexpr const char* NAME = "Parameter Variable";
static constexpr u32 FLAGS = NO_SYMBOL_FLAGS;
ParameterVariableHandle handle() const { return m_handle; }
FunctionHandle function() const { return m_function; };
std::variant<RegisterStorage, StackStorage> storage;
protected:
FunctionHandle m_function;
};
// An ELF section. These are created from the ELF section headers.
class Section : public Symbol {
public:
static constexpr const SymbolDescriptor DESCRIPTOR = SECTION;
static constexpr const char* NAME = "Section";
static constexpr u32 FLAGS = WITH_ADDRESS_MAP | WITH_NAME_MAP;
SectionHandle handle() const { return m_handle; }
// Check if the section name is ".text".
bool contains_code() const;
// Check for known data section names.
bool contains_data() const;
};
// A source file (.c or .cpp file). One of these will be created for every
// translation unit in the program (but only if debugging symbols are present).
class SourceFile : public Symbol {
friend SymbolList<SourceFile>;
public:
static constexpr const SymbolDescriptor DESCRIPTOR = SOURCE_FILE;
static constexpr const char* NAME = "Source File";
static constexpr u32 FLAGS = WITH_ADDRESS_MAP | WITH_NAME_MAP;
SourceFileHandle handle() const { return m_handle; }
const std::string& full_path() const { return name(); }
const std::vector<FunctionHandle>& functions() const;
void set_functions(std::vector<FunctionHandle> functions, SymbolDatabase& database);
const std::vector<GlobalVariableHandle>& global_variables() const;
void set_global_variables(std::vector<GlobalVariableHandle> global_variables, SymbolDatabase& database);
// Check whether at least half of the functions associated with the source
// file match their original hash (meaning they haven't been overwritten).
bool functions_match() const;
void check_functions_match(const SymbolDatabase& database);
std::string working_dir;
std::string command_line_path;
std::map<StabsTypeNumber, DataTypeHandle> stabs_type_number_to_handle;
std::set<std::string> toolchain_version_info;
protected:
void on_destroy(SymbolDatabase* database);
std::vector<FunctionHandle> m_functions;
std::vector<GlobalVariableHandle> m_global_variables;
bool m_functions_match = true;
};
// A symbol source. Every symbol has a symbol source field indicating how the
// symbol was created. For example, the symbol table importers will each create
// one of these (if it doesn't already exist).
class SymbolSource : public Symbol {
friend SymbolList<SymbolSource>;
public:
static constexpr const SymbolDescriptor DESCRIPTOR = SYMBOL_SOURCE;
static constexpr const char* NAME = "Symbol Source";
static constexpr u32 FLAGS = WITH_NAME_MAP;
SymbolSourceHandle handle() const { return m_handle; }
protected:
void on_create();
};
// Bundles together all the information needed to identify if a symbol came from
// a specific symbol table import operation. For example, this is used to make
// sure that we don't reference symbols from another symbol table during the
// import process.
struct SymbolGroup {
SymbolSourceHandle source;
Module* module_symbol = nullptr;
bool is_in_group(const Symbol& symbol) const;
};
// The symbol database itself. This owns all the symbols.
class SymbolDatabase {
public:
SymbolList<DataType> data_types;
SymbolList<Function> functions;
SymbolList<GlobalVariable> global_variables;
SymbolList<Label> labels;
SymbolList<LocalVariable> local_variables;
SymbolList<Module> modules;
SymbolList<ParameterVariable> parameter_variables;
SymbolList<Section> sections;
SymbolList<SourceFile> source_files;
SymbolList<SymbolSource> symbol_sources;
// Sum up the symbol counts for each symbol list.
s32 symbol_count() const;
// Find a symbol of any of the specified types given an address. Symbols of
// the types specified higher up in the CCC_FOR_EACH_SYMBOL_TYPE_DO_X macro
// are checked for first.
const Symbol* symbol_starting_at_address(
Address address, u32 descriptors = ALL_SYMBOL_TYPES, SymbolDescriptor* descriptor_out = nullptr) const;
const Symbol* symbol_after_address(
Address address, u32 descriptors = ALL_SYMBOL_TYPES, SymbolDescriptor* descriptor_out = nullptr) const;
const Symbol* symbol_overlapping_address(
Address address, u32 descriptors = ALL_SYMBOL_TYPES, SymbolDescriptor* descriptor_out = nullptr) const;
// Find a symbol of any of the specified types given its name. Symbols of
// the types specified higher up in the CCC_FOR_EACH_SYMBOL_TYPE_DO_X macro
// are checked for first.
const Symbol* symbol_with_name(
const std::string& name, u32 descriptors = ALL_SYMBOL_TYPES, SymbolDescriptor* descriptor_out = nullptr) const;
// Finds a symbol source object with the given name or creates one if it
// doesn't already exist.
Result<SymbolSourceHandle> get_symbol_source(const std::string& name);
// Deduplicate matching data types with the same name. May replace the
// existing data type with the new one if the new one is better.
Result<DataType*> create_data_type_if_unique(
std::unique_ptr<ast::Node> node,
StabsTypeNumber number,
const char* name,
SourceFile& source_file,
const SymbolGroup& group);
// Move all the symbols in the passed database into this database.
void merge_from(SymbolDatabase& database);
// Destroy all the symbols from a given symbol source. For example you can
// use this to free a symbol table without destroying user-defined symbols.
void destroy_symbols_from_source(SymbolSourceHandle source, bool destroy_descendants);
// Destroy all the symbols from a given module.
void destroy_symbols_from_module(ModuleHandle module_handle, bool destroy_descendants);
// Destroy all the symbols that have previously been marked for destruction.
// This invalidates all pointers to symbols in this database.
void destroy_marked_symbols();
// Destroy all the symbols in the symbol database.
void clear();
template <typename Callback>
void for_each_symbol(Callback callback) {
// Use indices here to avoid iterator invalidation.
#define CCC_X(SymbolType, symbol_list) \
for(s32 i = 0; i < symbol_list.size(); i++) { \
callback(symbol_list.symbol_from_index(i)); \
}
CCC_FOR_EACH_SYMBOL_TYPE_DO_X
#undef CCC_X
}
};
// A handle to a symbol of any type.
class MultiSymbolHandle {
public:
// Create an empty multi symbol handle.
MultiSymbolHandle();
// Create a multi symbol handle of the specified type.
template <typename SymbolType>
MultiSymbolHandle(const SymbolType& symbol);
MultiSymbolHandle(SymbolDescriptor descriptor, u32 handle);
bool valid() const;
SymbolDescriptor descriptor() const;
u32 handle() const;
Symbol* lookup_symbol(SymbolDatabase& database);
const Symbol* lookup_symbol(const SymbolDatabase& database) const;
bool is_flag_set(SymbolFlag flag) const;
bool move_symbol(Address new_address, SymbolDatabase& database) const;
bool rename_symbol(std::string new_name, SymbolDatabase& database) const;
bool destroy_symbol(SymbolDatabase& database, bool destroy_descendants) const;
friend auto operator<=>(const MultiSymbolHandle& lhs, const MultiSymbolHandle& rhs) = default;
protected:
SymbolDescriptor m_descriptor = DATA_TYPE;
u32 m_handle = (u32) -1;
};
// A handle to an AST node.
class NodeHandle {
friend SymbolDatabase;
public:
// Create an empty node handle.
NodeHandle();
// Create a node handle that will always allow accesses to its node. You
// should only use this if you know the lifetime of the handle is a subset
// of the lifetime of the node.
NodeHandle(const ast::Node* node);
// Create a node handle pointing to an AST node from a given symbol that
// will prevent accesses to the node if the symbol is deleted.
template <typename SymbolType>
NodeHandle(const SymbolType& symbol, const ast::Node* node);
NodeHandle(SymbolDescriptor descriptor, const Symbol& symbol, const ast::Node* node);
bool valid() const;
const MultiSymbolHandle& symbol() const;
const ast::Node* lookup_node(const SymbolDatabase& database) const;
NodeHandle handle_for_child(const ast::Node* child_node) const;
friend auto operator<=>(const NodeHandle& lhs, const NodeHandle& rhs) = default;
protected:
MultiSymbolHandle m_symbol;
const ast::Node* m_node = nullptr;
u32 m_generation = 0;
};
}

114
3rdparty/ccc/src/ccc/symbol_file.cpp vendored Normal file
View File

@@ -0,0 +1,114 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "symbol_file.h"
namespace ccc {
Result<std::unique_ptr<SymbolFile>> parse_symbol_file(std::vector<u8> image, std::string file_name)
{
const std::optional<u32> magic = copy_unaligned<u32>(image, 0);
CCC_CHECK(magic.has_value(), "File too small.");
std::unique_ptr<SymbolFile> symbol_file;
switch(*magic) {
case CCC_FOURCC("\x7f""ELF"): {
Result<ElfFile> elf = ElfFile::parse(std::move(image));
CCC_RETURN_IF_ERROR(elf);
symbol_file = std::make_unique<ElfSymbolFile>(std::move(*elf), std::move(file_name));
break;
}
case CCC_FOURCC("SNR1"):
case CCC_FOURCC("SNR2"): {
Result<SNDLLFile> sndll = parse_sndll_file(image, Address(), SNDLLType::DYNAMIC_LIBRARY);
CCC_RETURN_IF_ERROR(sndll);
symbol_file = std::make_unique<SNDLLSymbolFile>(std::make_shared<SNDLLFile>(std::move(*sndll)));
break;
}
default: {
return CCC_FAILURE("Unknown file type.");
}
}
return symbol_file;
}
ElfSymbolFile::ElfSymbolFile(ElfFile elf, std::string elf_name)
: m_elf(std::move(elf)), m_name(std::move(elf_name)) {}
std::string ElfSymbolFile::name() const
{
return m_name;
}
Result<std::vector<std::unique_ptr<SymbolTable>>> ElfSymbolFile::get_all_symbol_tables() const
{
std::vector<std::unique_ptr<SymbolTable>> symbol_tables;
symbol_tables.emplace_back(std::make_unique<ElfSectionHeadersSymbolTable>(m_elf));
for(size_t i = 0; i < SYMBOL_TABLE_FORMATS.size(); i++) {
const SymbolTableFormatInfo& info = SYMBOL_TABLE_FORMATS[i];
const ElfSection* section = m_elf.lookup_section(info.section_name);
if(section) {
Result<std::unique_ptr<SymbolTable>> symbol_table = create_elf_symbol_table(*section, m_elf, info.format);
CCC_RETURN_IF_ERROR(symbol_table);
if(*symbol_table) {
symbol_tables.emplace_back(std::move(*symbol_table));
}
}
}
return symbol_tables;
}
Result<std::vector<std::unique_ptr<SymbolTable>>> ElfSymbolFile::get_symbol_tables_from_sections(
const std::vector<SymbolTableLocation>& sections) const
{
std::vector<std::unique_ptr<SymbolTable>> symbol_tables;
for(const SymbolTableLocation& location : sections) {
const ElfSection* section = m_elf.lookup_section(location.section_name.c_str());
CCC_CHECK(section, "No '%s' section.", location.section_name.c_str());
Result<std::unique_ptr<SymbolTable>> symbol_table = create_elf_symbol_table(*section, m_elf, location.format);
CCC_RETURN_IF_ERROR(symbol_table);
if(*symbol_table) {
symbol_tables.emplace_back(std::move(*symbol_table));
}
}
return symbol_tables;
}
const ElfFile& ElfSymbolFile::elf() const
{
return m_elf;
}
SNDLLSymbolFile::SNDLLSymbolFile(std::shared_ptr<SNDLLFile> sndll)
: m_sndll(std::move(sndll)) {}
std::string SNDLLSymbolFile::name() const
{
return m_sndll->elf_path;
}
Result<std::vector<std::unique_ptr<SymbolTable>>> SNDLLSymbolFile::get_all_symbol_tables() const
{
std::vector<std::unique_ptr<SymbolTable>> symbol_tables;
symbol_tables.emplace_back(std::make_unique<SNDLLSymbolTable>(m_sndll));
return symbol_tables;
}
Result<std::vector<std::unique_ptr<SymbolTable>>> SNDLLSymbolFile::get_symbol_tables_from_sections(
const std::vector<SymbolTableLocation>& sections) const
{
return CCC_FAILURE("An SNDLL file is not composed of sections.");
}
}

62
3rdparty/ccc/src/ccc/symbol_file.h vendored Normal file
View File

@@ -0,0 +1,62 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include "elf.h"
#include "sndll.h"
#include "symbol_table.h"
namespace ccc {
struct SymbolTableLocation {
std::string section_name;
SymbolTableFormat format;
};
class SymbolFile {
public:
virtual ~SymbolFile() {}
virtual std::string name() const = 0;
virtual Result<std::vector<std::unique_ptr<SymbolTable>>> get_all_symbol_tables() const = 0;
virtual Result<std::vector<std::unique_ptr<SymbolTable>>> get_symbol_tables_from_sections(
const std::vector<SymbolTableLocation>& sections) const = 0;
};
// Determine the type of the input file and parse it.
Result<std::unique_ptr<SymbolFile>> parse_symbol_file(std::vector<u8> image, std::string file_name);
class ElfSymbolFile : public SymbolFile {
public:
ElfSymbolFile(ElfFile elf, std::string elf_name);
std::string name() const override;
Result<std::vector<std::unique_ptr<SymbolTable>>> get_all_symbol_tables() const override;
Result<std::vector<std::unique_ptr<SymbolTable>>> get_symbol_tables_from_sections(
const std::vector<SymbolTableLocation>& sections) const override;
const ElfFile& elf() const;
protected:
ElfFile m_elf;
std::string m_name;
};
class SNDLLSymbolFile : public SymbolFile {
public:
SNDLLSymbolFile(std::shared_ptr<SNDLLFile> sndll);
std::string name() const override;
Result<std::vector<std::unique_ptr<SymbolTable>>> get_all_symbol_tables() const override;
Result<std::vector<std::unique_ptr<SymbolTable>>> get_symbol_tables_from_sections(
const std::vector<SymbolTableLocation>& sections) const override;
protected:
std::shared_ptr<SNDLLFile> m_sndll;
};
}

285
3rdparty/ccc/src/ccc/symbol_table.cpp vendored Normal file
View File

@@ -0,0 +1,285 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "symbol_table.h"
#include "elf.h"
#include "elf_symtab.h"
#include "mdebug_importer.h"
#include "mdebug_section.h"
#include "sndll.h"
namespace ccc {
const std::vector<SymbolTableFormatInfo> SYMBOL_TABLE_FORMATS = {
{MDEBUG, "mdebug", ".mdebug"}, // The infamous Third Eye symbol table.
{SYMTAB, "symtab", ".symtab"}, // The standard ELF symbol table.
{SNDLL, "sndll", ".sndata"} // The SNDLL symbol table.
};
const SymbolTableFormatInfo* symbol_table_format_from_enum(SymbolTableFormat format)
{
for(size_t i = 0; i < SYMBOL_TABLE_FORMATS.size(); i++) {
if(SYMBOL_TABLE_FORMATS[i].format == format) {
return &SYMBOL_TABLE_FORMATS[i];
}
}
return nullptr;
}
const SymbolTableFormatInfo* symbol_table_format_from_name(const char* format_name)
{
for(size_t i = 0; i < SYMBOL_TABLE_FORMATS.size(); i++) {
if(strcmp(SYMBOL_TABLE_FORMATS[i].format_name, format_name) == 0) {
return &SYMBOL_TABLE_FORMATS[i];
}
}
return nullptr;
}
const SymbolTableFormatInfo* symbol_table_format_from_section(const char* section_name)
{
for(size_t i = 0; i < SYMBOL_TABLE_FORMATS.size(); i++) {
if(strcmp(SYMBOL_TABLE_FORMATS[i].section_name, section_name) == 0) {
return &SYMBOL_TABLE_FORMATS[i];
}
}
return nullptr;
}
// *****************************************************************************
Result<std::unique_ptr<SymbolTable>> create_elf_symbol_table(
const ElfSection& section, const ElfFile& elf, SymbolTableFormat format)
{
std::unique_ptr<SymbolTable> symbol_table;
switch(format) {
case MDEBUG: {
symbol_table = std::make_unique<MdebugSymbolTable>(elf.image, (s32) section.header.offset);
break;
}
case SYMTAB: {
CCC_CHECK(section.header.offset + section.header.size <= elf.image.size(),
"Section '%s' out of range.", section.name.c_str());
std::span<const u8> data = std::span(elf.image).subspan(section.header.offset, section.header.size);
CCC_CHECK(section.header.link != 0, "Section '%s' has no linked string table.", section.name.c_str());
CCC_CHECK(section.header.link < elf.sections.size(),
"Section '%s' has out of range link field.", section.name.c_str());
const ElfSection& linked_section = elf.sections[section.header.link];
CCC_CHECK(linked_section.header.offset + linked_section.header.size <= elf.image.size(),
"Linked section '%s' out of range.", linked_section.name.c_str());
std::span<const u8> linked_data = std::span(elf.image).subspan(
linked_section.header.offset, linked_section.header.size);
symbol_table = std::make_unique<SymtabSymbolTable>(data, linked_data);
break;
}
case SNDLL: {
CCC_CHECK(section.header.offset + section.header.size <= elf.image.size(),
"Section '%s' out of range.", section.name.c_str());
std::span<const u8> data = std::span(elf.image).subspan(section.header.offset, section.header.size);
if(data.size() >= 4 && data[0] != '\0') {
Result<SNDLLFile> file = parse_sndll_file(data, Address::non_zero(section.header.addr), SNDLLType::SNDATA_SECTION);
CCC_RETURN_IF_ERROR(file);
symbol_table = std::make_unique<SNDLLSymbolTable>(std::make_shared<SNDLLFile>(std::move(*file)));
} else {
CCC_WARN("Invalid SNDLL section.");
}
break;
}
}
return symbol_table;
}
Result<ModuleHandle> import_symbol_tables(
SymbolDatabase& database,
const std::vector<std::unique_ptr<SymbolTable>>& symbol_tables,
std::string module_name,
Address base_address,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt)
{
Result<SymbolSourceHandle> module_source = database.get_symbol_source("Symbol Table Importer");
CCC_RETURN_IF_ERROR(module_source);
Result<Module*> module_symbol = database.modules.create_symbol(
std::move(module_name), base_address, *module_source, nullptr);
CCC_RETURN_IF_ERROR(module_symbol);
ModuleHandle module_handle = (*module_symbol)->handle();
for(const std::unique_ptr<SymbolTable>& symbol_table : symbol_tables) {
// Find a symbol source object with the right name, or create one if one
// doesn't already exist.
Result<SymbolSourceHandle> source = database.get_symbol_source(symbol_table->name());
if(!source.success()) {
database.destroy_symbols_from_module(module_handle, false);
return source;
}
// Import the symbol table.
SymbolGroup group;
group.source = *source;
group.module_symbol = database.modules.symbol_from_handle(module_handle);
Result<void> result = symbol_table->import(
database, group, importer_flags, demangler, interrupt);
if(!result.success()) {
database.destroy_symbols_from_module(module_handle, false);
return result;
}
}
return module_handle;
}
// *****************************************************************************
MdebugSymbolTable::MdebugSymbolTable(std::span<const u8> image, s32 section_offset)
: m_image(image), m_section_offset(section_offset) {}
const char* MdebugSymbolTable::name() const
{
return "MIPS Debug Symbol Table";
}
Result<void> MdebugSymbolTable::import(
SymbolDatabase& database,
const SymbolGroup& group,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt) const
{
return mdebug::import_symbol_table(
database, m_image, m_section_offset, group, importer_flags, demangler, interrupt);
}
Result<void> MdebugSymbolTable::print_headers(FILE* out) const
{
mdebug::SymbolTableReader reader;
Result<void> reader_result = reader.init(m_image, m_section_offset);
CCC_RETURN_IF_ERROR(reader_result);
reader.print_header(out);
return Result<void>();
}
Result<void> MdebugSymbolTable::print_symbols(FILE* out, u32 flags) const
{
mdebug::SymbolTableReader reader;
Result<void> reader_result = reader.init(m_image, m_section_offset);
CCC_RETURN_IF_ERROR(reader_result);
Result<void> print_result = reader.print_symbols(
out, flags & PRINT_LOCALS, flags & PRINT_PROCEDURE_DESCRIPTORS, flags & PRINT_EXTERNALS);
CCC_RETURN_IF_ERROR(print_result);
return Result<void>();
}
// *****************************************************************************
SymtabSymbolTable::SymtabSymbolTable(std::span<const u8> symtab, std::span<const u8> strtab)
: m_symtab(symtab), m_strtab(strtab) {}
const char* SymtabSymbolTable::name() const
{
return "ELF Symbol Table";
}
Result<void> SymtabSymbolTable::import(
SymbolDatabase& database,
const SymbolGroup& group,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt) const
{
return elf::import_symbols(database, group, m_symtab, m_strtab, importer_flags, demangler);
}
Result<void> SymtabSymbolTable::print_headers(FILE* out) const
{
return Result<void>();
}
Result<void> SymtabSymbolTable::print_symbols(FILE* out, u32 flags) const
{
Result<void> symbtab_result = elf::print_symbol_table(out, m_symtab, m_strtab);
CCC_RETURN_IF_ERROR(symbtab_result);
return Result<void>();
}
// *****************************************************************************
SNDLLSymbolTable::SNDLLSymbolTable(std::shared_ptr<SNDLLFile> sndll)
: m_sndll(std::move(sndll)) {}
const char* SNDLLSymbolTable::name() const
{
return "SNDLL Symbol Table";
}
Result<void> SNDLLSymbolTable::import(
SymbolDatabase& database,
const SymbolGroup& group,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt) const
{
return import_sndll_symbols(database, *m_sndll, group, importer_flags, demangler);
}
Result<void> SNDLLSymbolTable::print_headers(FILE* out) const
{
return Result<void>();
}
Result<void> SNDLLSymbolTable::print_symbols(FILE* out, u32 flags) const
{
print_sndll_symbols(out, *m_sndll);
return Result<void>();
}
// *****************************************************************************
ElfSectionHeadersSymbolTable::ElfSectionHeadersSymbolTable(const ElfFile& elf)
: m_elf(elf) {}
const char* ElfSectionHeadersSymbolTable::name() const
{
return "ELF Section Headers";
}
Result<void> ElfSectionHeadersSymbolTable::import(
SymbolDatabase& database,
const SymbolGroup& group,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt) const
{
return m_elf.create_section_symbols(database, group);
}
Result<void> ElfSectionHeadersSymbolTable::print_headers(FILE* out) const
{
return Result<void>();
}
Result<void> ElfSectionHeadersSymbolTable::print_symbols(FILE* out, u32 flags) const
{
return Result<void>();
}
}

164
3rdparty/ccc/src/ccc/symbol_table.h vendored Normal file
View File

@@ -0,0 +1,164 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include <atomic>
#include "symbol_database.h"
namespace ccc {
// Determine which symbol tables are present in a given file.
enum SymbolTableFormat {
MDEBUG = 0, // The infamous Third Eye symbol table
SYMTAB = 1, // Standard ELF symbol table
SNDLL = 2 // SNDLL section
};
struct SymbolTableFormatInfo {
SymbolTableFormat format;
const char* format_name;
const char* section_name;
};
// All the supported symbol table formats, sorted from best to worst.
extern const std::vector<SymbolTableFormatInfo> SYMBOL_TABLE_FORMATS;
const SymbolTableFormatInfo* symbol_table_format_from_enum(SymbolTableFormat format);
const SymbolTableFormatInfo* symbol_table_format_from_name(const char* format_name);
const SymbolTableFormatInfo* symbol_table_format_from_section(const char* section_name);
enum SymbolPrintFlags {
PRINT_LOCALS = 1 << 0,
PRINT_PROCEDURE_DESCRIPTORS = 1 << 1,
PRINT_EXTERNALS = 1 << 2
};
class SymbolTable {
public:
virtual ~SymbolTable() {}
virtual const char* name() const = 0;
// Imports this symbol table into the passed database.
virtual Result<void> import(
SymbolDatabase& database,
const SymbolGroup& group,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt) const = 0;
// Print out all the field in the header structure if one exists.
virtual Result<void> print_headers(FILE* out) const = 0;
// Print out all the symbols in the symbol table. For .mdebug symbol tables
// the symbols are split between those that are local to a specific
// translation unit and those that are external, which is what the
// print_locals and print_externals parameters control.
virtual Result<void> print_symbols(FILE* out, u32 flags) const = 0;
};
struct ElfSection;
struct ElfFile;
// Create a symbol table from an ELF section. The return value may be null.
Result<std::unique_ptr<SymbolTable>> create_elf_symbol_table(
const ElfSection& section, const ElfFile& elf, SymbolTableFormat format);
// Utility function to call import_symbol_table on all the passed symbol tables
// and to generate a module handle.
Result<ModuleHandle> import_symbol_tables(
SymbolDatabase& database,
const std::vector<std::unique_ptr<SymbolTable>>& symbol_tables,
std::string module_name,
Address base_address,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt);
class MdebugSymbolTable : public SymbolTable {
public:
MdebugSymbolTable(std::span<const u8> image, s32 section_offset);
const char* name() const override;
Result<void> import(
SymbolDatabase& database,
const SymbolGroup& group,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt) const override;
Result<void> print_headers(FILE* out) const override;
Result<void> print_symbols(FILE* out, u32 flags) const override;
protected:
std::span<const u8> m_image;
s32 m_section_offset;
};
class SymtabSymbolTable : public SymbolTable {
public:
SymtabSymbolTable(std::span<const u8> symtab, std::span<const u8> strtab);
const char* name() const override;
Result<void> import(
SymbolDatabase& database,
const SymbolGroup& group,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt) const override;
Result<void> print_headers(FILE* out) const override;
Result<void> print_symbols(FILE* out, u32 flags) const override;
protected:
std::span<const u8> m_symtab;
std::span<const u8> m_strtab;
};
struct SNDLLFile;
class SNDLLSymbolTable : public SymbolTable {
public:
SNDLLSymbolTable(std::shared_ptr<SNDLLFile> sndll);
const char* name() const override;
Result<void> import(
SymbolDatabase& database,
const SymbolGroup& group,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt) const override;
Result<void> print_headers(FILE* out) const override;
Result<void> print_symbols(FILE* out, u32 flags) const override;
protected:
std::shared_ptr<SNDLLFile> m_sndll;
};
class ElfSectionHeadersSymbolTable : public SymbolTable {
public:
ElfSectionHeadersSymbolTable(const ElfFile& elf);
const char* name() const override;
Result<void> import(
SymbolDatabase& database,
const SymbolGroup& group,
u32 importer_flags,
DemanglerFunctions demangler,
const std::atomic_bool* interrupt) const override;
Result<void> print_headers(FILE* out) const override;
Result<void> print_symbols(FILE* out, u32 flags) const override;
protected:
const ElfFile& m_elf;
};
}

176
3rdparty/ccc/src/ccc/util.cpp vendored Normal file
View File

@@ -0,0 +1,176 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#include "util.h"
namespace ccc {
static CustomErrorCallback custom_error_callback = nullptr;
Error format_error(const char* source_file, int source_line, const char* format, ...)
{
va_list args;
va_start(args, format);
char message[4096];
if(vsnprintf(message, sizeof(message), format, args) < 0) {
strncpy(message, "Failed to generate error message.", sizeof(message));
}
Error error;
error.message = message;
error.source_file = source_file;
error.source_line = source_line;
va_end(args);
return error;
}
void report_error(const Error& error)
{
if(custom_error_callback) {
custom_error_callback(error, ERROR_LEVEL_ERROR);
} else {
fprintf(stderr, "[%s:%d] " CCC_ANSI_COLOUR_RED "error:" CCC_ANSI_COLOUR_OFF " %s\n",
error.source_file, error.source_line, error.message.c_str());
}
}
void report_warning(const Error& warning)
{
if(custom_error_callback) {
custom_error_callback(warning, ERROR_LEVEL_WARNING);
} else {
fprintf(stderr, "[%s:%d] " CCC_ANSI_COLOUR_MAGENTA "warning:" CCC_ANSI_COLOUR_OFF " %s\n",
warning.source_file, warning.source_line, warning.message.c_str());
}
}
void set_custom_error_callback(CustomErrorCallback callback)
{
custom_error_callback = callback;
}
std::optional<std::string_view> get_string(std::span<const u8> bytes, u64 offset)
{
for(u64 i = offset; i < bytes.size(); i++) {
if(bytes[i] == '\0') {
return std::string_view(
reinterpret_cast<const char*>(&bytes[offset]),
reinterpret_cast<const char*>(&bytes[i]));
}
}
return std::nullopt;
}
std::string merge_paths(const std::string& base, const std::string& path)
{
// Try to figure out if we're dealing with a Windows path of a UNIX path.
bool is_windows_path = false;
if(base.empty()) {
is_windows_path = guess_is_windows_path(path.c_str());
} else {
is_windows_path = guess_is_windows_path(base.c_str());
}
// Actually merge the paths. If path is the entire path, we don't need to
// append base onto the front, so check for that now.
bool is_absolute_unix = (path.size() >= 1) && (path[0] == '/' || path[0] == '\\');
bool is_absolute_windows = (path.size() >= 3) && path[1] == ':' && (path[2] == '/' || path[2] == '\\');
if(base.empty() || is_absolute_unix || is_absolute_windows) {
return normalise_path(path.c_str(), is_windows_path);
}
return normalise_path((base + "/" + path).c_str(), is_windows_path);
}
std::string normalise_path(const char* input, bool use_backslashes_as_path_separators)
{
bool is_absolute = false;
std::optional<char> drive_letter;
std::vector<std::string> parts;
// Parse the beginning of the path.
if(*input == '/' || *input == '\\') { // UNIX path, drive relative Windows path or UNC Windows path.
is_absolute = true;
} else if(isalpha(*input) && input[1] == ':' && (input[2] == '/' || input[2] == '\\')) { // Absolute Windows path.
is_absolute = true;
drive_letter = toupper(*input);
input += 2;
} else {
parts.emplace_back();
}
// Parse the rest of the path.
while(*input != 0) {
if(*input == '/' || *input == '\\') {
while(*input == '/' || *input == '\\') input++;
parts.emplace_back();
} else {
parts.back() += *(input++);
}
}
// Remove "." and ".." parts.
for(s32 i = 0; i < (s32) parts.size(); i++) {
if(parts[i] == ".") {
parts.erase(parts.begin() + i);
i--;
} else if(parts[i] == ".." && i > 0 && parts[i - 1] != "..") {
parts.erase(parts.begin() + i);
parts.erase(parts.begin() + i - 1);
i -= 2;
}
}
// Output the path in a normal form.
std::string output;
if(is_absolute) {
if(drive_letter.has_value()) {
output += *drive_letter;
output += ":";
}
output += use_backslashes_as_path_separators ? '\\' : '/';
}
for(size_t i = 0; i < parts.size(); i++) {
output += parts[i];
if(i != parts.size() - 1) {
output += use_backslashes_as_path_separators ? '\\' : '/';
}
}
return output;
}
bool guess_is_windows_path(const char* path)
{
for(const char* ptr = path; *ptr != 0; ptr++) {
if(*ptr == '\\') {
return true;
} else if(*ptr == '/') {
return false;
}
}
return false;
}
std::string extract_file_name(const std::string& path)
{
std::string::size_type forward_pos = path.find_last_of('/');
std::string::size_type backward_pos = path.find_last_of('\\');
std::string::size_type pos;
if(forward_pos == std::string::npos) {
pos = backward_pos;
} else if(backward_pos == std::string::npos) {
pos = forward_pos;
} else {
pos = std::max(forward_pos, backward_pos);
}
if(pos + 1 != path.size() && pos != std::string::npos) {
return path.substr(pos + 1);
} else {
return path;
}
}
}

341
3rdparty/ccc/src/ccc/util.h vendored Normal file
View File

@@ -0,0 +1,341 @@
// This file is part of the Chaos Compiler Collection.
// SPDX-License-Identifier: MIT
#pragma once
#include <set>
#include <span>
#include <cstdio>
#include <vector>
#include <memory>
#include <string>
#include <cstdint>
#include <cstdarg>
#include <cstdlib>
#include <cstring>
#include <optional>
namespace ccc {
using u8 = unsigned char;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using s8 = signed char;
using s16 = int16_t;
using s32 = int32_t;
using s64 = int64_t;
#ifdef _WIN32
#define CCC_ANSI_COLOUR_OFF ""
#define CCC_ANSI_COLOUR_RED ""
#define CCC_ANSI_COLOUR_MAGENTA ""
#define CCC_ANSI_COLOUR_GRAY ""
#else
#define CCC_ANSI_COLOUR_OFF "\033[0m"
#define CCC_ANSI_COLOUR_RED "\033[31m"
#define CCC_ANSI_COLOUR_MAGENTA "\033[35m"
#define CCC_ANSI_COLOUR_GRAY "\033[90m"
#endif
struct Error {
std::string message;
const char* source_file;
s32 source_line;
};
enum ErrorLevel {
ERROR_LEVEL_ERROR,
ERROR_LEVEL_WARNING
};
typedef void (*CustomErrorCallback)(const Error& error, ErrorLevel level);
Error format_error(const char* source_file, int source_line, const char* format, ...);
void report_error(const Error& error);
void report_warning(const Error& warning);
void set_custom_error_callback(CustomErrorCallback callback);
#define CCC_FATAL(...) \
{ \
ccc::Error error = ccc::format_error(__FILE__, __LINE__, __VA_ARGS__); \
ccc::report_error(error); \
exit(1); \
}
#define CCC_CHECK_FATAL(condition, ...) \
if(!(condition)) { \
ccc::Error error = ccc::format_error(__FILE__, __LINE__, __VA_ARGS__); \
ccc::report_error(error); \
exit(1); \
}
#define CCC_ABORT_IF_FALSE(condition, ...) \
if(!(condition)) { \
ccc::Error error = ccc::format_error(__FILE__, __LINE__, __VA_ARGS__); \
ccc::report_error(error); \
abort(); \
}
#define CCC_ASSERT(condition) \
CCC_ABORT_IF_FALSE(condition, #condition)
// The main error handling construct in CCC. This class is used to bundle
// together a return value and a pointer to error information, so that errors
// can be propagated up the stack.
template <typename Value>
class [[nodiscard]] Result {
template <typename OtherValue>
friend class Result;
protected:
Value m_value;
std::unique_ptr<Error> m_error;
Result() {}
public:
Result(Value value) : m_value(std::move(value)), m_error(nullptr) {}
// Used to propagate errors up the call stack.
template <typename OtherValue>
Result(Result<OtherValue>&& rhs)
{
CCC_ASSERT(rhs.m_error != nullptr);
m_error = std::move(rhs.m_error);
}
static Result<Value> failure(Error error)
{
Result<Value> result;
result.m_error = std::make_unique<Error>(std::move(error));
return result;
}
bool success() const
{
return m_error == nullptr;
}
const Error& error() const
{
CCC_ASSERT(m_error != nullptr);
return *m_error;
}
Value& operator*()
{
CCC_ASSERT(m_error == nullptr);
return m_value;
}
const Value& operator*() const
{
CCC_ASSERT(m_error == nullptr);
return m_value;
}
Value* operator->()
{
CCC_ASSERT(m_error == nullptr);
return &m_value;
}
const Value* operator->() const
{
CCC_ASSERT(m_error == nullptr);
return &m_value;
}
};
template <>
class [[nodiscard]] Result<void> : public Result<int> {
public:
Result() : Result<int>(0) {}
// Used to propagate errors up the call stack.
template <typename OtherValue>
Result(Result<OtherValue>&& rhs)
{
CCC_ASSERT(rhs.m_error != nullptr);
m_error = std::move(rhs.m_error);
}
};
#define CCC_FAILURE(...) ccc::Result<int>::failure(ccc::format_error(__FILE__, __LINE__, __VA_ARGS__))
#define CCC_CHECK(condition, ...) \
if(!(condition)) { \
return CCC_FAILURE(__VA_ARGS__); \
}
#define CCC_EXPECT_CHAR(input, c, context) \
CCC_CHECK(*(input++) == c, \
"Expected '%c' in %s, got '%c' (%02hhx)", \
c, context, *(input - 1), *(input - 1))
#define CCC_RETURN_IF_ERROR(result) \
if(!(result).success()) { \
return (result); \
}
#define CCC_EXIT_IF_ERROR(result) \
if(!(result).success()) { \
ccc::report_error((result).error()); \
exit(1); \
}
#define CCC_GTEST_FAIL_IF_ERROR(result) \
if(!(result).success()) { \
FAIL() << (result).error().message; \
}
template <typename... Args>
void warn_impl(const char* source_file, int source_line, const char* format, Args... args)
{
Error warning = format_error(source_file, source_line, format, args...);
report_warning(warning);
}
#define CCC_WARN(...) \
ccc::warn_impl(__FILE__, __LINE__, __VA_ARGS__)
#ifdef _MSC_VER
#define CCC_PACKED_STRUCT(name, ...) \
__pragma(pack(push, 1)) struct name { __VA_ARGS__ } __pragma(pack(pop));
#else
#define CCC_PACKED_STRUCT(name, ...) \
struct __attribute__((__packed__)) name { __VA_ARGS__ };
#endif
template <typename T>
const T* get_aligned(std::span<const u8> bytes, u64 offset)
{
if(offset > bytes.size() || bytes.size() - offset < sizeof(T) || offset % alignof(T) != 0) {
return nullptr;
}
return reinterpret_cast<const T*>(&bytes[offset]);
}
template <typename T>
const T* get_unaligned(std::span<const u8> bytes, u64 offset)
{
if(offset > bytes.size() || bytes.size() - offset < sizeof(T)) {
return nullptr;
}
return reinterpret_cast<const T*>(&bytes[offset]);
}
template <typename T>
std::optional<T> copy_unaligned(std::span<const u8> bytes, u64 offset)
{
if(offset > bytes.size() || bytes.size() - offset < sizeof(T)) {
return std::nullopt;
}
T value;
memcpy(&value, &bytes[offset], sizeof(T));
return value;
}
std::optional<std::string_view> get_string(std::span<const u8> bytes, u64 offset);
#define CCC_BEGIN_END(x) (x).begin(), (x).end()
#define CCC_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define CCC_FOURCC(string) ((string)[0] | (string)[1] << 8 | (string)[2] << 16 | (string)[3] << 24)
struct Address {
u32 value = (u32) -1;
Address() {}
Address(u32 v) : value(v) {}
bool valid() const
{
return value != (u32) -1;
}
u32 get_or_zero() const
{
if(valid()) {
return value;
} else {
return 0;
}
}
Address add_base_address(Address base_address) const
{
if(valid()) {
return base_address.get_or_zero() + value;
} else {
return Address();
}
}
static Address non_zero(u32 address)
{
Address result;
if(address != 0) {
result = address;
}
return result;
}
friend auto operator<=>(const Address& lhs, const Address& rhs) = default;
};
struct AddressRange {
Address low;
Address high;
AddressRange() {}
AddressRange(Address address) : low(address), high(address) {}
AddressRange(Address l, Address h) : low(l), high(h) {}
friend auto operator<=>(const AddressRange& lhs, const AddressRange& rhs) = default;
};
// These functions are to be used only for source file paths present in the
// symbol table, since we want them to be handled consistently across different
// platforms, which with std::filesystem::path doesn't seem to be possible.
std::string merge_paths(const std::string& base, const std::string& path);
std::string normalise_path(const char* input, bool use_backslashes_as_path_separators);
bool guess_is_windows_path(const char* path);
std::string extract_file_name(const std::string& path);
namespace ast { struct Node; }
// These are used to reference STABS types from other types within a single
// translation unit. For most games these will just be a single number, the type
// number. In some cases, for example with the homebrew SDK, type numbers are a
// pair of two numbers surrounded by round brackets e.g. (1,23) where the first
// number is the index of the include file to use (includes are listed for each
// translation unit separately), and the second number is the type number.
struct StabsTypeNumber {
s32 file = -1;
s32 type = -1;
friend auto operator<=>(const StabsTypeNumber& lhs, const StabsTypeNumber& rhs) = default;
bool valid() const { return type > -1; }
};
enum StorageClass {
STORAGE_CLASS_NONE = 0,
STORAGE_CLASS_TYPEDEF = 1,
STORAGE_CLASS_EXTERN = 2,
STORAGE_CLASS_STATIC = 3,
STORAGE_CLASS_AUTO = 4,
STORAGE_CLASS_REGISTER = 5
};
// Function pointers for the GNU demangler functions, so we can build CCC as a
// library without linking against the demangler.
struct DemanglerFunctions {
char* (*cplus_demangle)(const char *mangled, int options) = nullptr;
char* (*cplus_demangle_opname)(const char *opname, int options) = nullptr;
};
}

View File

@@ -60,7 +60,7 @@ ssize_t CPUINFO_ABI cpuinfo_mock_read(int fd, void* buffer, size_t capacity);
void CPUINFO_ABI cpuinfo_set_hwcap(uint32_t hwcap);
#endif
#if CPUINFO_ARCH_ARM
void CPUINFO_ABI cpuinfo_set_hwcap2(uint32_t hwcap2);
void CPUINFO_ABI cpuinfo_set_hwcap2(uint64_t hwcap2);
#endif
#endif

View File

@@ -419,6 +419,8 @@ enum cpuinfo_uarch {
cpuinfo_uarch_zen3 = 0x0020010B,
/** AMD Zen 4 microarchitecture. */
cpuinfo_uarch_zen4 = 0x0020010C,
/** AMD Zen 5 microarchitecture. */
cpuinfo_uarch_zen5 = 0x0020010D,
/** NSC Geode and AMD Geode GX and LX. */
cpuinfo_uarch_geode = 0x00200200,
@@ -496,13 +498,19 @@ enum cpuinfo_uarch {
cpuinfo_uarch_cortex_x2 = 0x00300502,
/** ARM Cortex-X3. */
cpuinfo_uarch_cortex_x3 = 0x00300503,
/** ARM Cortex-X4. */
cpuinfo_uarch_cortex_x4 = 0x00300504,
/** ARM Cortex-A510. */
cpuinfo_uarch_cortex_a510 = 0x00300551,
/** ARM Cortex-A520. */
cpuinfo_uarch_cortex_a520 = 0x00300552,
/** ARM Cortex-A710. */
cpuinfo_uarch_cortex_a710 = 0x00300571,
/** ARM Cortex-A715. */
cpuinfo_uarch_cortex_a715 = 0x00300572,
/** ARM Cortex-A720. */
cpuinfo_uarch_cortex_a720 = 0x00300573,
/** Qualcomm Scorpion. */
cpuinfo_uarch_scorpion = 0x00400100,
@@ -812,6 +820,7 @@ struct cpuinfo_x86_isa {
bool avx512vp2intersect;
bool avx512_4vnniw;
bool avx512_4fmaps;
bool avx10_1;
bool amx_bf16;
bool amx_tile;
bool amx_int8;
@@ -1427,6 +1436,14 @@ static inline bool cpuinfo_has_x86_avx_ne_convert(void) {
#endif
}
static inline bool cpuinfo_has_x86_avx10_1(void) {
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
return cpuinfo_isa.avx10_1;
#else
return false;
#endif
}
static inline bool cpuinfo_has_x86_hle(void) {
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
return cpuinfo_isa.hle;
@@ -1664,6 +1681,14 @@ struct cpuinfo_arm_isa {
bool sve;
bool sve2;
bool i8mm;
bool sme;
bool sme2;
bool sme2p1;
bool sme_i16i32;
bool sme_bi32i32;
bool sme_b16b16;
bool sme_f16f16;
uint32_t svelen;
#endif
bool rdm;
bool fp16arith;
@@ -2036,6 +2061,71 @@ static inline bool cpuinfo_has_arm_sve2(void) {
#endif
}
// Function to get the max SVE vector length on ARM CPU's which support SVE.
static inline uint32_t cpuinfo_get_max_arm_sve_length(void) {
#if CPUINFO_ARCH_ARM64
return cpuinfo_isa.svelen * 8; // bytes * 8 = bit length(vector length)
#else
return 0;
#endif
}
static inline bool cpuinfo_has_arm_sme(void) {
#if CPUINFO_ARCH_ARM64
return cpuinfo_isa.sme;
#else
return false;
#endif
}
static inline bool cpuinfo_has_arm_sme2(void) {
#if CPUINFO_ARCH_ARM64
return cpuinfo_isa.sme2;
#else
return false;
#endif
}
static inline bool cpuinfo_has_arm_sme2p1(void) {
#if CPUINFO_ARCH_ARM64
return cpuinfo_isa.sme2p1;
#else
return false;
#endif
}
static inline bool cpuinfo_has_arm_sme_i16i32(void) {
#if CPUINFO_ARCH_ARM64
return cpuinfo_isa.sme_i16i32;
#else
return false;
#endif
}
static inline bool cpuinfo_has_arm_sme_bi32i32(void) {
#if CPUINFO_ARCH_ARM64
return cpuinfo_isa.sme_bi32i32;
#else
return false;
#endif
}
static inline bool cpuinfo_has_arm_sme_b16b16(void) {
#if CPUINFO_ARCH_ARM64
return cpuinfo_isa.sme_b16b16;
#else
return false;
#endif
}
static inline bool cpuinfo_has_arm_sme_f16f16(void) {
#if CPUINFO_ARCH_ARM64
return cpuinfo_isa.sme_f16f16;
#else
return false;
#endif
}
#if CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
/* This structure is not a part of stable API. Use cpuinfo_has_riscv_* functions
* instead. */

View File

@@ -64,6 +64,7 @@ enum cpuinfo_arm_chipset_series {
cpuinfo_arm_chipset_series_telechips_tcc,
cpuinfo_arm_chipset_series_texas_instruments_omap,
cpuinfo_arm_chipset_series_unisoc_t,
cpuinfo_arm_chipset_series_unisoc_ums,
cpuinfo_arm_chipset_series_wondermedia_wm,
cpuinfo_arm_chipset_series_max,
};

View File

@@ -1341,7 +1341,8 @@ void cpuinfo_arm_decode_cache(
* information, please refer to the technical manuals
* linked above
*/
const uint32_t min_l2_size_KB = uarch == cpuinfo_uarch_neoverse_v2 ? 1024 : 256;
const uint32_t min_l2_size_KB =
(uarch == cpuinfo_uarch_neoverse_v2 || midr_is_ampere_altra(midr)) ? 1024 : 256;
const uint32_t min_l3_size_KB = 0;
*l1i = (struct cpuinfo_cache){

View File

@@ -24,7 +24,7 @@ void cpuinfo_set_wcid(uint32_t wcid) {
void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
uint32_t features,
uint32_t features2,
uint64_t features2,
uint32_t midr,
uint32_t architecture_version,
uint32_t architecture_flags,
@@ -147,6 +147,8 @@ void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
"VDOT instructions disabled: cause occasional SIGILL on Spreadtrum SC9863A");
} else if (chipset->series == cpuinfo_arm_chipset_series_unisoc_t && chipset->model == 310) {
cpuinfo_log_warning("VDOT instructions disabled: cause occasional SIGILL on Unisoc T310");
} else if (chipset->series == cpuinfo_arm_chipset_series_unisoc_ums && chipset->model == 312) {
cpuinfo_log_warning("VDOT instructions disabled: cause occasional SIGILL on Unisoc UMS312");
} else {
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
case UINT32_C(0x4100D0B0): /* Cortex-A76 */

View File

@@ -3,9 +3,11 @@
#include <arm/linux/api.h>
#include <cpuinfo/log.h>
#include <sys/prctl.h>
void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
uint32_t features,
uint32_t features2,
uint64_t features2,
uint32_t midr,
const struct cpuinfo_arm_chipset chipset[restrict static 1],
struct cpuinfo_arm_isa isa[restrict static 1]) {
@@ -142,6 +144,27 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SVE2) {
isa->sve2 = true;
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME) {
isa->sme = true;
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME2) {
isa->sme2 = true;
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME2P1) {
isa->sme2p1 = true;
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME_I16I32) {
isa->sme_i16i32 = true;
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME_BI32I32) {
isa->sme_bi32i32 = true;
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME_B16B16) {
isa->sme_b16b16 = true;
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SME_F16F16) {
isa->sme_f16f16 = true;
}
// SVEBF16 is set iff SVE and BF16 are both supported, but the SVEBF16
// feature flag was added in Linux kernel before the BF16 feature flag,
// so we check for either.
@@ -151,4 +174,21 @@ void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDFHM) {
isa->fhm = true;
}
#ifndef PR_SVE_GET_VL
#define PR_SVE_GET_VL 51
#endif
#ifndef PR_SVE_VL_LEN_MASK
#define PR_SVE_VL_LEN_MASK 0xffff
#endif
int ret = prctl(PR_SVE_GET_VL);
if (ret < 0) {
cpuinfo_log_warning("No SVE support on this machine");
isa->svelen = 0; // Assume no SVE support if the call fails
} else {
// Mask out the SVE vector length bits
isa->svelen = ret & PR_SVE_VL_LEN_MASK;
}
}

View File

@@ -137,6 +137,13 @@ struct cpuinfo_arm_linux_proc_cpuinfo_cache {
#define CPUINFO_ARM_LINUX_FEATURE2_DGH UINT32_C(0x00008000)
#define CPUINFO_ARM_LINUX_FEATURE2_RNG UINT32_C(0x00010000)
#define CPUINFO_ARM_LINUX_FEATURE2_BTI UINT32_C(0x00020000)
#define CPUINFO_ARM_LINUX_FEATURE2_SME UINT32_C(0x00800000)
#define CPUINFO_ARM_LINUX_FEATURE2_SME2 UINT64_C(0x0000002000000000)
#define CPUINFO_ARM_LINUX_FEATURE2_SME2P1 UINT64_C(0x0000004000000000)
#define CPUINFO_ARM_LINUX_FEATURE2_SME_I16I32 UINT64_C(0x0000008000000000)
#define CPUINFO_ARM_LINUX_FEATURE2_SME_BI32I32 UINT64_C(0x0000010000000000)
#define CPUINFO_ARM_LINUX_FEATURE2_SME_B16B16 UINT64_C(0x0000020000000000)
#define CPUINFO_ARM_LINUX_FEATURE2_SME_F16F16 UINT64_C(0x0000040000000000)
#endif
#define CPUINFO_ARM_LINUX_VALID_ARCHITECTURE UINT32_C(0x00010000)
@@ -172,7 +179,7 @@ struct cpuinfo_arm_linux_processor {
struct cpuinfo_arm_linux_proc_cpuinfo_cache proc_cpuinfo_cache;
#endif
uint32_t features;
uint32_t features2;
uint64_t features2;
/**
* Main ID Register value.
*/
@@ -295,14 +302,14 @@ CPUINFO_INTERNAL bool cpuinfo_arm_linux_parse_proc_cpuinfo(
#if CPUINFO_ARCH_ARM
CPUINFO_INTERNAL bool cpuinfo_arm_linux_hwcap_from_getauxval(
uint32_t hwcap[restrict static 1],
uint32_t hwcap2[restrict static 1]);
uint64_t hwcap2[restrict static 1]);
CPUINFO_INTERNAL bool cpuinfo_arm_linux_hwcap_from_procfs(
uint32_t hwcap[restrict static 1],
uint32_t hwcap2[restrict static 1]);
uint64_t hwcap2[restrict static 1]);
CPUINFO_INTERNAL void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
uint32_t features,
uint32_t features2,
uint64_t features2,
uint32_t midr,
uint32_t architecture_version,
uint32_t architecture_flags,
@@ -311,11 +318,11 @@ CPUINFO_INTERNAL void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
#elif CPUINFO_ARCH_ARM64
CPUINFO_INTERNAL void cpuinfo_arm_linux_hwcap_from_getauxval(
uint32_t hwcap[restrict static 1],
uint32_t hwcap2[restrict static 1]);
uint64_t hwcap2[restrict static 1]);
CPUINFO_INTERNAL void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
uint32_t features,
uint32_t features2,
uint64_t features2,
uint32_t midr,
const struct cpuinfo_arm_chipset chipset[restrict static 1],
struct cpuinfo_arm_isa isa[restrict static 1]);

View File

@@ -85,6 +85,7 @@ static enum cpuinfo_arm_chipset_vendor chipset_series_vendor[cpuinfo_arm_chipset
[cpuinfo_arm_chipset_series_telechips_tcc] = cpuinfo_arm_chipset_vendor_telechips,
[cpuinfo_arm_chipset_series_texas_instruments_omap] = cpuinfo_arm_chipset_vendor_texas_instruments,
[cpuinfo_arm_chipset_series_unisoc_t] = cpuinfo_arm_chipset_vendor_unisoc,
[cpuinfo_arm_chipset_series_unisoc_ums] = cpuinfo_arm_chipset_vendor_unisoc,
[cpuinfo_arm_chipset_series_wondermedia_wm] = cpuinfo_arm_chipset_vendor_wondermedia,
};
@@ -959,6 +960,70 @@ static bool match_t(const char* start, const char* end, struct cpuinfo_arm_chips
return true;
}
/**
* Tries to match, case-sentitively, /Unisoc UMS\d{3,4}/ signature for Unisoc UMS
* chipset. If match successful, extracts model information into \p chipset
* argument.
*
* @param start - start of the platform identifier (/proc/cpuinfo Hardware
* string, ro.product.board, ro.board.platform, or ro.chipname) to match.
* @param end - end of the platform identifier (/proc/cpuinfo Hardware string,
* ro.product.board, ro.board.platform, or ro.chipname) to match.
* @param[out] chipset - location where chipset information will be stored upon
* a successful match.
*
* @returns true if signature matched, false otherwise.
*/
static bool match_ums(const char* start, const char* end, struct cpuinfo_arm_chipset chipset[restrict static 1]) {
/* Expect 13-14 symbols: "Unisoc UMS" (10 symbols) + 3-4-digit model number
*/
const size_t length = end - start;
switch (length) {
case 13:
case 14:
break;
default:
return false;
}
/* Check that string starts with "Unisoc UMS". The first four characters
* are loaded as 32-bit little endian word */
const uint32_t expected_unis = load_u32le(start);
if (expected_unis != UINT32_C(0x73696E55) /* "sinU" = reverse("Unis") */) {
return false;
}
/* The next four characters are loaded as 32-bit little endian word */
const uint32_t expected_oc_u = load_u32le(start + 4);
if (expected_oc_u != UINT32_C(0x5520636F) /* "U co" = reverse("oc U") */) {
return false;
}
/* The next four characters are loaded as 16-bit little endian word */
const uint16_t expected_ms = load_u16le(start + 8);
if (expected_ms != UINT16_C(0x534D) /* "SM" = reverse("MS") */) {
return false;
}
/* Validate and parse 3-4 digit model number */
uint32_t model = 0;
for (uint32_t i = 10; i < length; i++) {
const uint32_t digit = (uint32_t)(uint8_t)start[i] - '0';
if (digit >= 10) {
/* Not really a digit */
return false;
}
model = model * 10 + digit;
}
*chipset = (struct cpuinfo_arm_chipset){
.vendor = cpuinfo_arm_chipset_vendor_unisoc,
.series = cpuinfo_arm_chipset_series_unisoc_ums,
.model = model,
};
return true;
}
/**
* Tries to match /lc\d{4}[a-z]?$/ signature for Leadcore LC chipsets.
* If match successful, extracts model information into \p chipset argument.
@@ -2508,6 +2573,16 @@ struct cpuinfo_arm_chipset cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_ha
return chipset;
}
/* Check Unisoc UMS signature */
if (match_ums(hardware, hardware_end, &chipset)) {
cpuinfo_log_debug(
"matched Unisoc UMS signature in /proc/cpuinfo Hardware string \"%.*s\"",
(int)hardware_length,
hardware);
return chipset;
}
#if CPUINFO_ARCH_ARM
/* Check Marvell PXA signature */
if (match_pxa(hardware, hardware_end, &chipset)) {
@@ -3726,6 +3801,7 @@ static const char* chipset_series_string[cpuinfo_arm_chipset_series_max] = {
[cpuinfo_arm_chipset_series_telechips_tcc] = "TCC",
[cpuinfo_arm_chipset_series_texas_instruments_omap] = "OMAP",
[cpuinfo_arm_chipset_series_unisoc_t] = "T",
[cpuinfo_arm_chipset_series_unisoc_ums] = "UMS",
[cpuinfo_arm_chipset_series_wondermedia_wm] = "WM",
};

View File

@@ -31,8 +31,8 @@ void cpuinfo_set_hwcap(uint32_t hwcap) {
mock_hwcap = hwcap;
}
static uint32_t mock_hwcap2 = 0;
void cpuinfo_set_hwcap2(uint32_t hwcap2) {
static uint64_t mock_hwcap2 = 0;
void cpuinfo_set_hwcap2(uint64_t hwcap2) {
mock_hwcap2 = hwcap2;
}
#endif
@@ -40,7 +40,7 @@ void cpuinfo_set_hwcap2(uint32_t hwcap2) {
#if CPUINFO_ARCH_ARM
typedef unsigned long (*getauxval_function_t)(unsigned long);
bool cpuinfo_arm_linux_hwcap_from_getauxval(uint32_t hwcap[restrict static 1], uint32_t hwcap2[restrict static 1]) {
bool cpuinfo_arm_linux_hwcap_from_getauxval(uint32_t hwcap[restrict static 1], uint64_t hwcap2[restrict static 1]) {
#if CPUINFO_MOCK
*hwcap = mock_hwcap;
*hwcap2 = mock_hwcap2;
@@ -83,13 +83,13 @@ cleanup:
}
#ifdef __ANDROID__
bool cpuinfo_arm_linux_hwcap_from_procfs(uint32_t hwcap[restrict static 1], uint32_t hwcap2[restrict static 1]) {
bool cpuinfo_arm_linux_hwcap_from_procfs(uint32_t hwcap[restrict static 1], uint64_t hwcap2[restrict static 1]) {
#if CPUINFO_MOCK
*hwcap = mock_hwcap;
*hwcap2 = mock_hwcap2;
return true;
#else
uint32_t hwcaps[2] = {0, 0};
uint64_t hwcaps[2] = {0, 0};
bool result = false;
int file = -1;
@@ -113,7 +113,7 @@ bool cpuinfo_arm_linux_hwcap_from_procfs(uint32_t hwcap[restrict static 1], uint
hwcaps[0] = (uint32_t)elf_auxv.a_un.a_val;
break;
case AT_HWCAP2:
hwcaps[1] = (uint32_t)elf_auxv.a_un.a_val;
hwcaps[1] = (uint64_t)elf_auxv.a_un.a_val;
break;
}
} else {
@@ -141,13 +141,13 @@ cleanup:
}
#endif /* __ANDROID__ */
#elif CPUINFO_ARCH_ARM64
void cpuinfo_arm_linux_hwcap_from_getauxval(uint32_t hwcap[restrict static 1], uint32_t hwcap2[restrict static 1]) {
void cpuinfo_arm_linux_hwcap_from_getauxval(uint32_t hwcap[restrict static 1], uint64_t hwcap2[restrict static 1]) {
#if CPUINFO_MOCK
*hwcap = mock_hwcap;
*hwcap2 = mock_hwcap2;
#else
*hwcap = (uint32_t)getauxval(AT_HWCAP);
*hwcap2 = (uint32_t)getauxval(AT_HWCAP2);
*hwcap2 = (uint64_t)getauxval(AT_HWCAP2);
return;
#endif
}

View File

@@ -247,7 +247,8 @@ void cpuinfo_arm_linux_init(void) {
#endif
#if CPUINFO_ARCH_ARM
uint32_t isa_features = 0, isa_features2 = 0;
uint32_t isa_features = 0;
uint64_t isa_features2 = 0;
#ifdef __ANDROID__
/*
* On Android before API 20, libc.so does not provide getauxval
@@ -299,7 +300,8 @@ void cpuinfo_arm_linux_init(void) {
&chipset,
&cpuinfo_isa);
#elif CPUINFO_ARCH_ARM64
uint32_t isa_features = 0, isa_features2 = 0;
uint32_t isa_features = 0;
uint64_t isa_features2 = 0;
/* getauxval is always available on ARM64 Android */
cpuinfo_arm_linux_hwcap_from_getauxval(&isa_features, &isa_features2);
cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
@@ -333,18 +335,52 @@ void cpuinfo_arm_linux_init(void) {
}
/* Propagate topology group IDs among siblings */
bool detected_core_siblings_list_node = false;
bool detected_cluster_cpus_list_node = false;
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
if (!bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
continue;
}
if (arm_linux_processors[i].flags & CPUINFO_LINUX_FLAG_PACKAGE_ID) {
if (!bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_PACKAGE_ID)) {
continue;
}
/* Use the cluster_cpus_list topology node if available. If not
* found, cache the result to avoid repeatedly attempting to
* read the non-existent paths.
* */
if (!detected_core_siblings_list_node && !detected_cluster_cpus_list_node) {
if (cpuinfo_linux_detect_cluster_cpus(
arm_linux_processors_count,
i,
(cpuinfo_siblings_callback)cluster_siblings_parser,
arm_linux_processors)) {
detected_cluster_cpus_list_node = true;
continue;
} else {
detected_core_siblings_list_node = true;
}
}
/* The cached result above will guarantee only one of the blocks
* below will execute, with a bias towards cluster_cpus_list.
**/
if (detected_core_siblings_list_node) {
cpuinfo_linux_detect_core_siblings(
arm_linux_processors_count,
i,
(cpuinfo_siblings_callback)cluster_siblings_parser,
arm_linux_processors);
}
if (detected_cluster_cpus_list_node) {
cpuinfo_linux_detect_cluster_cpus(
arm_linux_processors_count,
i,
(cpuinfo_siblings_callback)cluster_siblings_parser,
arm_linux_processors);
}
}
/* Propagate all cluster IDs */

View File

@@ -101,17 +101,35 @@ static enum cpuinfo_uarch decode_uarch(uint32_t cpu_family, uint32_t core_index,
return cpuinfo_uarch_unknown;
}
static void decode_package_name(char* package_name) {
/* Small bodge until cpuinfo merges PR #246 */
static int read_package_name_from_brand_string(char* package_name) {
size_t size;
if (sysctlbyname("machdep.cpu.brand_string", NULL, &size, NULL, 0) != 0) {
sysctlfail:
cpuinfo_log_warning("sysctlbyname(\"machdep.cpu.brand_string\") failed: %s", strerror(errno));
return false;
}
char* brand_string = alloca(size);
if (sysctlbyname("machdep.cpu.brand_string", brand_string, &size, NULL, 0) != 0)
goto sysctlfail;
cpuinfo_log_debug("machdep.cpu.brand_string: %s", brand_string);
strlcpy(package_name, brand_string, CPUINFO_PACKAGE_NAME_MAX);
return true;
}
static int decode_package_name_from_hw_machine(char* package_name) {
size_t size;
if (sysctlbyname("hw.machine", NULL, &size, NULL, 0) != 0) {
cpuinfo_log_warning("sysctlbyname(\"hw.machine\") failed: %s", strerror(errno));
return;
return false;
}
char* machine_name = alloca(size);
if (sysctlbyname("hw.machine", machine_name, &size, NULL, 0) != 0) {
cpuinfo_log_warning("sysctlbyname(\"hw.machine\") failed: %s", strerror(errno));
return;
return false;
}
cpuinfo_log_debug("hw.machine: %s", machine_name);
@@ -119,7 +137,7 @@ static void decode_package_name(char* package_name) {
uint32_t major = 0, minor = 0;
if (sscanf(machine_name, "%9[^,0123456789]%" SCNu32 ",%" SCNu32, name, &major, &minor) != 3) {
cpuinfo_log_warning("parsing \"hw.machine\" failed: %s", strerror(errno));
return;
return false;
}
uint32_t chip_model = 0;
@@ -224,7 +242,9 @@ static void decode_package_name(char* package_name) {
}
if (chip_model != 0) {
snprintf(package_name, CPUINFO_PACKAGE_NAME_MAX, "Apple A%" PRIu32 "%c", chip_model, suffix);
return true;
}
return false;
}
void cpuinfo_arm_mach_init(void) {
@@ -275,7 +295,8 @@ void cpuinfo_arm_mach_init(void) {
.core_start = i * cores_per_package,
.core_count = cores_per_package,
};
decode_package_name(packages[i].name);
if (!read_package_name_from_brand_string(packages[i].name))
decode_package_name_from_hw_machine(packages[i].name);
}
const uint32_t cpu_family = get_sys_info_by_name("hw.cpufamily");
@@ -399,6 +420,16 @@ void cpuinfo_arm_mach_init(void) {
cpuinfo_isa.i8mm = true;
}
const uint32_t has_feat_sme = get_sys_info_by_name("hw.optional.arm.FEAT_SME");
if (has_feat_sme != 0) {
cpuinfo_isa.sme = true;
}
const uint32_t has_feat_sme2 = get_sys_info_by_name("hw.optional.arm.FEAT_SME2");
if (has_feat_sme2 != 0) {
cpuinfo_isa.sme2 = true;
}
uint32_t num_clusters = 1;
for (uint32_t i = 0; i < mach_topology.cores; i++) {
cores[i] = (struct cpuinfo_core){

View File

@@ -34,6 +34,7 @@
#define CPUINFO_ARM_MIDR_KRYO_SILVER_820 UINT32_C(0x510F2110)
#define CPUINFO_ARM_MIDR_EXYNOS_M1_M2 UINT32_C(0x530F0010)
#define CPUINFO_ARM_MIDR_DENVER2 UINT32_C(0x4E0F0030)
#define CPUINFO_ARM_MIDR_AMPERE_ALTRA UINT32_C(0x413fd0c1)
inline static uint32_t midr_set_implementer(uint32_t midr, uint32_t implementer) {
return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) |
@@ -167,6 +168,11 @@ inline static bool midr_is_kryo_gold(uint32_t midr) {
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO_GOLD & uarch_mask);
}
inline static bool midr_is_ampere_altra(uint32_t midr) {
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_AMPERE_ALTRA & uarch_mask);
}
inline static uint32_t midr_score_core(uint32_t midr) {
const uint32_t core_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
switch (midr & core_mask) {

View File

@@ -24,8 +24,10 @@ static char* sysctl_str(const char* name) {
size_t value_size = 0;
if (sysctlbyname(name, NULL, &value_size, NULL, 0) != 0) {
cpuinfo_log_error("sysctlbyname(\"%s\") failed: %s", name, strerror(errno));
return NULL;
} else if (value_size <= 0) {
cpuinfo_log_error("sysctlbyname(\"%s\") returned invalid value size %zu", name, value_size);
return NULL;
}
value_size += 1;
char* value = calloc(value_size, 1);
@@ -52,29 +54,22 @@ struct cpuinfo_freebsd_topology cpuinfo_freebsd_detect_topology(void) {
if (!topology_spec) {
return topology;
}
const char* group_tag = "<group level=\"1\" cache-level=\"0\">";
char* p = strstr(topology_spec, group_tag);
while (p) {
const char* cpu_tag = "cpu count=\"";
char* q = strstr(p, cpu_tag);
if (q) {
p = q + strlen(cpu_tag);
topology.packages += atoi(p);
} else {
break;
}
}
if (topology.packages == 0) {
const char* group_tag = "<group level=\"1\"";
const char* group_tags[] = {"<group level=\"2\" cache-level=\"0\">", "<group level=\"1\" "};
for (size_t i = 0; i < sizeof(group_tags) / sizeof(group_tags[0]); i++) {
const char* group_tag = group_tags[i];
char* p = strstr(topology_spec, group_tag);
while (p) {
topology.packages += 1;
p++;
p = strstr(p, group_tag);
}
if (topology.packages > 0) {
break;
}
}
if (topology.packages == 0) {
cpuinfo_log_error("failed to parse topology_spec:%s", topology_spec);
cpuinfo_log_error("failed to parse topology_spec: %s", topology_spec);
free(topology_spec);
goto fail;
}
@@ -84,6 +79,7 @@ struct cpuinfo_freebsd_topology cpuinfo_freebsd_detect_topology(void) {
goto fail;
}
if (topology.cores < topology.packages) {
cpuinfo_log_error("invalid numbers of package and core: %d %d", topology.packages, topology.cores);
goto fail;
}
topology.threads_per_core = sysctl_int("kern.smp.threads_per_core");

View File

@@ -135,6 +135,10 @@ void cpuinfo_x86_freebsd_init(void) {
if (x86_processor.cache.l1i.size != 0 || x86_processor.cache.l1d.size != 0) {
/* Assume that threads on the same core share L1 */
threads_per_l1 = freebsd_topology.threads / freebsd_topology.cores;
if (threads_per_l1 == 0) {
cpuinfo_log_error("failed to detect threads_per_l1");
goto cleanup;
}
cpuinfo_log_warning(
"freebsd kernel did not report number of "
"threads sharing L1 cache; assume %" PRIu32,
@@ -154,6 +158,10 @@ void cpuinfo_x86_freebsd_init(void) {
* the same package share L2 */
threads_per_l2 = freebsd_topology.threads / freebsd_topology.packages;
}
if (threads_per_l2 == 0) {
cpuinfo_log_error("failed to detect threads_per_l1");
goto cleanup;
}
cpuinfo_log_warning(
"freebsd kernel did not report number of "
"threads sharing L2 cache; assume %" PRIu32,
@@ -170,6 +178,10 @@ void cpuinfo_x86_freebsd_init(void) {
* may be L4 cache as well)
*/
threads_per_l3 = freebsd_topology.threads / freebsd_topology.packages;
if (threads_per_l3 == 0) {
cpuinfo_log_error("failed to detect threads_per_l3");
goto cleanup;
}
cpuinfo_log_warning(
"freebsd kernel did not report number of "
"threads sharing L3 cache; assume %" PRIu32,
@@ -187,6 +199,10 @@ void cpuinfo_x86_freebsd_init(void) {
* shared L4 (like on IBM POWER8).
*/
threads_per_l4 = freebsd_topology.threads;
if (threads_per_l4 == 0) {
cpuinfo_log_error("failed to detect threads_per_l4");
goto cleanup;
}
cpuinfo_log_warning(
"freebsd kernel did not report number of "
"threads sharing L4 cache; assume %" PRIu32,
@@ -203,7 +219,7 @@ void cpuinfo_x86_freebsd_init(void) {
"%" PRIu32 " L1I caches",
l1_count * sizeof(struct cpuinfo_cache),
l1_count);
return;
goto cleanup;
}
for (uint32_t c = 0; c < l1_count; c++) {
l1i[c] = (struct cpuinfo_cache){
@@ -230,7 +246,7 @@ void cpuinfo_x86_freebsd_init(void) {
"%" PRIu32 " L1D caches",
l1_count * sizeof(struct cpuinfo_cache),
l1_count);
return;
goto cleanup;
}
for (uint32_t c = 0; c < l1_count; c++) {
l1d[c] = (struct cpuinfo_cache){
@@ -257,7 +273,7 @@ void cpuinfo_x86_freebsd_init(void) {
"%" PRIu32 " L2 caches",
l2_count * sizeof(struct cpuinfo_cache),
l2_count);
return;
goto cleanup;
}
for (uint32_t c = 0; c < l2_count; c++) {
l2[c] = (struct cpuinfo_cache){
@@ -284,7 +300,7 @@ void cpuinfo_x86_freebsd_init(void) {
"%" PRIu32 " L3 caches",
l3_count * sizeof(struct cpuinfo_cache),
l3_count);
return;
goto cleanup;
}
for (uint32_t c = 0; c < l3_count; c++) {
l3[c] = (struct cpuinfo_cache){
@@ -311,7 +327,7 @@ void cpuinfo_x86_freebsd_init(void) {
"%" PRIu32 " L4 caches",
l4_count * sizeof(struct cpuinfo_cache),
l4_count);
return;
goto cleanup;
}
for (uint32_t c = 0; c < l4_count; c++) {
l4[c] = (struct cpuinfo_cache){

View File

@@ -429,6 +429,11 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa(
*/
isa.avx512f = avx512_regs && !!(structured_feature_info0.ebx & UINT32_C(0x00010000));
/*
* AVX 10.1 instructions:
*/
isa.avx10_1 = avx512_regs && !!(structured_feature_info1.edx & UINT32_C(0x00080000));
/*
* AVX512PF instructions:
* - Intel: ebx[bit 26] in structured feature info (ecx = 0).

View File

@@ -387,6 +387,8 @@ enum cpuinfo_uarch cpuinfo_x86_decode_uarch(
return cpuinfo_uarch_zen4;
}
break;
case 0x1a:
return cpuinfo_uarch_zen5;
}
break;
case cpuinfo_vendor_hygon:

View File

@@ -1,4 +1,4 @@
Copyright (c) 2019-2022 Advanced Micro Devices, Inc. All rights reserved.
Copyright (c) 2019-2024 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -2,7 +2,7 @@
Easy to integrate memory allocation library for Direct3D 12.
**Documentation:** Browse online: [D3D12 Memory Allocator](https://gpuopen-librariesandsdks.github.io/D3D12MemoryAllocator/html/) (generated from Doxygen-style comments in [src/D3D12MemAlloc.h](src/D3D12MemAlloc.h))
**Documentation:** Browse online: [D3D12 Memory Allocator](https://gpuopen-librariesandsdks.github.io/D3D12MemoryAllocator/html/) (generated from Doxygen-style comments in [include/D3D12MemAlloc.h](include/D3D12MemAlloc.h))
**License:** MIT. See [LICENSE.txt](LICENSE.txt)
@@ -36,6 +36,7 @@ Additional features:
- Customization and integration with custom engines: Predefine appropriate macros to provide your own implementation of external facilities used by the library, like assert, mutex, and atomic.
- Support for resource aliasing (overlap).
- Custom memory pools: Create a pool with desired parameters (e.g. fixed or limited maximum size, custom `D3D12_HEAP_PROPERTIES` and `D3D12_HEAP_FLAGS`) and allocate memory out of it.
- Support for GPU Upload Heaps from preview Agility SDK (needs compilation with `D3D12MA_OPTIONS16_SUPPORTED` macro).
- Linear allocator: Create a pool with linear algorithm and use it for much faster allocations and deallocations in free-at-once, stack, double stack, or ring buffer fashion.
- Defragmentation: Let the library move data around to free some memory blocks and make your allocations better compacted.
- Statistics: Obtain brief or detailed statistics about the amount of memory used, unused, number of allocated heaps, number of allocations etc. - globally and per memory heap type. Current memory usage and budget as reported by the system can also be queried.
@@ -101,15 +102,18 @@ This software package uses third party software:
For more information see [NOTICES.txt](NOTICES.txt).
# Software using this library
- **[The Forge](https://github.com/ConfettiFX/The-Forge)** - cross-platform rendering framework. Apache License 2.0.
- **[Wicked Engine<img src="https://github.com/turanszkij/WickedEngine/blob/master/Content/logo_small.png" width="28px" align="center"/>](https://github.com/turanszkij/WickedEngine)** - 3D engine with modern graphics
[Some other projects on GitHub](https://github.com/search?q=D3D12MemAlloc.h&type=Code) and some game development studios that use DX12 in their games.
# See also
- **[Vcpkg](https://github.com/Microsoft/vcpkg)** dependency manager from Microsoft offers a port of this library that is easy to install.
- **[Vulkan Memory Allocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/)** - equivalent library for Vulkan. License: MIT.
- **[d3d12ma.c](https://github.com/milliewalky/d3d12ma.c)** - C bindings for this library. Author: Mateusz Maciejewski (Matt Walky). License: MIT.
- **[TerraFX.Interop.D3D12MemoryAllocator](https://github.com/terrafx/terrafx.interop.d3d12memoryallocator)** - interop bindings for this library for C#, as used by [TerraFX](https://github.com/terrafx/terrafx). License: MIT.
- **[Vulkan Memory Allocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator/)** - equivalent library for Vulkan. License: MIT.
# Software using this library
- **[Qt Project](https://github.com/qt)**
- **[Ghost of Tsushima: Director's Cut PC](https://www.youtube.com/watch?v=cPKBDbCYctc&t=698s)** - Information avaliable in 11:38 of credits
- **[The Forge](https://github.com/ConfettiFX/The-Forge)** - cross-platform rendering framework. Apache License 2.0.
- **[Wicked Engine<img src="https://github.com/turanszkij/WickedEngine/blob/master/Content/logo_small.png" width="28px" align="center"/>](https://github.com/turanszkij/WickedEngine)** - 3D engine with modern graphics
[Some other projects on GitHub](https://github.com/search?q=D3D12MemAlloc.h&type=Code) and some game development studios that use DX12 in their games.

View File

@@ -24,9 +24,9 @@
/** \mainpage D3D12 Memory Allocator
<b>Version 2.1.0-development</b> (2023-07-05)
<b>Version 2.1.0-development</b> (2024-07-05)
Copyright (c) 2019-2023 Advanced Micro Devices, Inc. All rights reserved. \n
Copyright (c) 2019-2024 Advanced Micro Devices, Inc. All rights reserved. \n
License: MIT
Documentation of all members: D3D12MemAlloc.h
@@ -160,9 +160,9 @@ class D3D12MA_API IUnknownImpl : public IUnknown
{
public:
virtual ~IUnknownImpl() = default;
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override;
ULONG STDMETHODCALLTYPE AddRef() override;
ULONG STDMETHODCALLTYPE Release() override;
protected:
virtual void ReleaseThis() { delete this; }
private:
@@ -265,18 +265,18 @@ enum ALLOCATION_FLAGS
*/
ALLOCATION_FLAG_CAN_ALIAS = 0x10,
/** Allocation strategy that chooses smallest possible free range for the allocation
/** %Allocation strategy that chooses smallest possible free range for the allocation
to minimize memory usage and fragmentation, possibly at the expense of allocation time.
*/
ALLOCATION_FLAG_STRATEGY_MIN_MEMORY = 0x00010000,
/** Allocation strategy that chooses first suitable free range for the allocation -
/** %Allocation strategy that chooses first suitable free range for the allocation -
not necessarily in terms of the smallest offset but the one that is easiest and fastest to find
to minimize allocation time, possibly at the expense of allocation quality.
*/
ALLOCATION_FLAG_STRATEGY_MIN_TIME = 0x00020000,
/** Allocation strategy that chooses always the lowest offset in available space.
/** %Allocation strategy that chooses always the lowest offset in available space.
This is not the most efficient strategy but achieves highly packed data.
Used internally by defragmentation, not recomended in typical usage.
*/
@@ -402,8 +402,9 @@ struct TotalStatistics
- 1 = `D3D12_HEAP_TYPE_UPLOAD`
- 2 = `D3D12_HEAP_TYPE_READBACK`
- 3 = `D3D12_HEAP_TYPE_CUSTOM`
- 4 = `D3D12_HEAP_TYPE_GPU_UPLOAD`
*/
DetailedStatistics HeapType[4];
DetailedStatistics HeapType[5];
/** \brief One element for each memory segment group located at the following indices:
- 0 = `DXGI_MEMORY_SEGMENT_GROUP_LOCAL`
@@ -413,9 +414,9 @@ struct TotalStatistics
- When `IsUMA() == FALSE` (discrete graphics card):
- `DXGI_MEMORY_SEGMENT_GROUP_LOCAL` (index 0) represents GPU memory
(resources allocated in `D3D12_HEAP_TYPE_DEFAULT` or `D3D12_MEMORY_POOL_L1`).
(resources allocated in `D3D12_HEAP_TYPE_DEFAULT`, `D3D12_HEAP_TYPE_GPU_UPLOAD` or `D3D12_MEMORY_POOL_L1`).
- `DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL` (index 1) represents system memory
(resources allocated in `D3D12_HEAP_TYPE_UPLOAD`, `D3D12_HEAP_TYPE_READBACK`, or `D3D12_MEMORY_POOL_L0`).
(resources allocated in `D3D12_HEAP_TYPE_UPLOAD`, `D3D12_HEAP_TYPE_READBACK`, or `D3D12_MEMORY_POOL_L0`).
- When `IsUMA() == TRUE` (integrated graphics chip):
- `DXGI_MEMORY_SEGMENT_GROUP_LOCAL` = (index 0) represents memory shared for all the resources.
- `DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL` = (index 1) is unused and always 0.
@@ -542,26 +543,6 @@ public:
*/
LPCWSTR GetName() const { return m_Name; }
/** \brief Returns `TRUE` if the memory of the allocation was filled with zeros when the allocation was created.
Returns `TRUE` only if the allocator is sure that the entire memory where the
allocation was created was filled with zeros at the moment the allocation was made.
Returns `FALSE` if the memory could potentially contain garbage data.
If it's a render-target or depth-stencil texture, it then needs proper
initialization with `ClearRenderTargetView`, `ClearDepthStencilView`, `DiscardResource`,
or a copy operation, as described on page
"ID3D12Device::CreatePlacedResource method - Notes on the required resource initialization" in Microsoft documentation.
Please note that rendering a fullscreen triangle or quad to the texture as
a render target is not a proper way of initialization!
See also articles:
- "Coming to DirectX 12: More control over memory allocation" on DirectX Developer Blog
- ["Initializing DX12 Textures After Allocation and Aliasing"](https://asawicki.info/news_1724_initializing_dx12_textures_after_allocation_and_aliasing).
*/
BOOL WasZeroInitialized() const { return m_PackedData.WasZeroInitialized(); }
protected:
void ReleaseThis() override;
@@ -620,29 +601,26 @@ private:
{
public:
PackedData() :
m_Type(0), m_ResourceDimension(0), m_ResourceFlags(0), m_TextureLayout(0), m_WasZeroInitialized(0) { }
m_Type(0), m_ResourceDimension(0), m_ResourceFlags(0), m_TextureLayout(0) { }
Type GetType() const { return (Type)m_Type; }
D3D12_RESOURCE_DIMENSION GetResourceDimension() const { return (D3D12_RESOURCE_DIMENSION)m_ResourceDimension; }
D3D12_RESOURCE_FLAGS GetResourceFlags() const { return (D3D12_RESOURCE_FLAGS)m_ResourceFlags; }
D3D12_TEXTURE_LAYOUT GetTextureLayout() const { return (D3D12_TEXTURE_LAYOUT)m_TextureLayout; }
BOOL WasZeroInitialized() const { return (BOOL)m_WasZeroInitialized; }
void SetType(Type type);
void SetResourceDimension(D3D12_RESOURCE_DIMENSION resourceDimension);
void SetResourceFlags(D3D12_RESOURCE_FLAGS resourceFlags);
void SetTextureLayout(D3D12_TEXTURE_LAYOUT textureLayout);
void SetWasZeroInitialized(BOOL wasZeroInitialized) { m_WasZeroInitialized = wasZeroInitialized ? 1 : 0; }
private:
UINT m_Type : 2; // enum Type
UINT m_ResourceDimension : 3; // enum D3D12_RESOURCE_DIMENSION
UINT m_ResourceFlags : 24; // flags D3D12_RESOURCE_FLAGS
UINT m_TextureLayout : 9; // enum D3D12_TEXTURE_LAYOUT
UINT m_WasZeroInitialized : 1; // BOOL
} m_PackedData;
Allocation(AllocatorPimpl* allocator, UINT64 size, UINT64 alignment, BOOL wasZeroInitialized);
Allocation(AllocatorPimpl* allocator, UINT64 size, UINT64 alignment);
// Nothing here, everything already done in Release.
virtual ~Allocation() = default;
@@ -1065,6 +1043,16 @@ enum ALLOCATOR_FLAGS
to create its heaps on smaller alignment not suitable for MSAA textures.
*/
ALLOCATOR_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED = 0x8,
/** \brief Disable optimization that prefers creating small buffers as committed to avoid 64 KB alignment.
By default, the library prefers creating small buffers <= 32 KB as committed,
because drivers tend to pack them better, while placed buffers require 64 KB alignment.
This, however, may decrease performance, as creating committed resources involves allocation of implicit heaps,
which may take longer than creating placed resources in existing heaps.
Passing this flag will disable this committed preference globally for the allocator.
It can also be disabled for a single allocation by using #ALLOCATION_FLAG_STRATEGY_MIN_TIME.
*/
ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED = 0x10,
};
/// \brief Parameters of created Allocator object. To be used with CreateAllocator().
@@ -1130,6 +1118,15 @@ public:
- "ID3D12Device::GetCustomHeapProperties method (d3d12.h)"
*/
BOOL IsCacheCoherentUMA() const;
/** \brief Returns true if GPU Upload Heaps are supported on the current system.
When true, you can use `D3D12_HEAP_TYPE_GPU_UPLOAD`.
This flag is fetched from `D3D12_FEATURE_D3D12_OPTIONS16::GPUUploadHeapSupported`.
`#define D3D12MA_OPTIONS16_SUPPORTED 1` is needed for the compilation of this library. Otherwise the flag is always false.
*/
BOOL IsGPUUploadHeapSupported() const;
/** \brief Returns total amount of memory of specific segment group, in bytes.
\param memorySegmentGroup use `DXGI_MEMORY_SEGMENT_GROUP_LOCAL` or DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL`.
@@ -1447,11 +1444,11 @@ enum VIRTUAL_ALLOCATION_FLAGS
*/
VIRTUAL_ALLOCATION_FLAG_UPPER_ADDRESS = ALLOCATION_FLAG_UPPER_ADDRESS,
/// Allocation strategy that tries to minimize memory usage.
/// %Allocation strategy that tries to minimize memory usage.
VIRTUAL_ALLOCATION_FLAG_STRATEGY_MIN_MEMORY = ALLOCATION_FLAG_STRATEGY_MIN_MEMORY,
/// Allocation strategy that tries to minimize allocation time.
/// %Allocation strategy that tries to minimize allocation time.
VIRTUAL_ALLOCATION_FLAG_STRATEGY_MIN_TIME = ALLOCATION_FLAG_STRATEGY_MIN_TIME,
/** \brief Allocation strategy that chooses always the lowest offset in available space.
/** %Allocation strategy that chooses always the lowest offset in available space.
This is not the most efficient strategy but achieves highly packed data.
*/
VIRTUAL_ALLOCATION_FLAG_STRATEGY_MIN_OFFSET = ALLOCATION_FLAG_STRATEGY_MIN_OFFSET,
@@ -1640,6 +1637,9 @@ ID3D12Device* device = (...)
D3D12MA::ALLOCATOR_DESC allocatorDesc = {};
allocatorDesc.pDevice = device;
allocatorDesc.pAdapter = adapter;
// These flags are optional but recommended.
allocatorDesc.Flags = D3D12MA::ALLOCATOR_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED |
D3D12MA::ALLOCATOR_FLAG_DEFAULT_POOLS_NOT_ZEROED;
D3D12MA::Allocator* allocator;
HRESULT hr = D3D12MA::CreateAllocator(&allocatorDesc, &allocator);
@@ -1864,6 +1864,9 @@ to obtain object D3D12MA::Pool. Example:
\code
POOL_DESC poolDesc = {};
poolDesc.HeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
// These flags are optional but recommended.
poolDesc.Flags = D3D12MA::POOL_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED;
poolDesc.HeapFlags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
Pool* pool;
HRESULT hr = allocator->CreatePool(&poolDesc, &pool);

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,27 @@
add_library(demanglegnu STATIC
src/alloca.c
src/cp-demangle.c
src/cplus-dem.c
src/d-demangle.c
src/dyn-string.c
src/getopt1.c
src/getopt.c
src/rust-demangle.c
src/safe-ctype.c
src/xexit.c
src/xmalloc.c
src/xmemdup.c
src/xstrdup.c
)
cmake_minimum_required(VERSION 3.6)
set(GNU_DEMANGLER_FLAGS -DHAVE_DECL_BASENAME=1 -DHAVE_LIMITS_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1)
project(demangler CXX)
target_include_directories(demanglegnu PUBLIC include)
target_compile_definitions(demanglegnu PUBLIC ${GNU_DEMANGLER_FLAGS})
add_subdirectory(src)
add_executable(demangler_fuzzer testsuite/demangler-fuzzer.c)
add_executable(demangler_test testsuite/test-demangle.c)
target_link_libraries(demangler_fuzzer demanglegnu)
target_link_libraries(demangler_test demanglegnu)
target_compile_definitions(demangler_fuzzer PUBLIC ${GNU_DEMANGLER_FLAGS})
target_compile_definitions(demangler_test PUBLIC ${GNU_DEMANGLER_FLAGS})

View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@@ -0,0 +1,482 @@
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the library GPL. It is
numbered 2 because it goes with version 2 of the ordinary GPL.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link a program with the library, you must provide
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
permission to copy, distribute and/or modify the library.
Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, so that any problems introduced by others will not reflect on
the original authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
analogous to running a utility program or application program. However, in
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
preserving your freedom as a user of such programs to change the free
libraries that are incorporated in them. (We have not seen how to achieve
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, while the latter only
works together with the library.
Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
GNU LIBRARY GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also compile or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
c) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
d) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the source code distributed need not include anything that is normally
distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Library General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

33
3rdparty/demangler/README vendored Normal file
View File

@@ -0,0 +1,33 @@
This code was taken from GCC 13.2.0 and specifically the libiberty library which
contains files licensed under the GPL and the LGPL.
Support for GCC 2.x-style symbols has been reintroduced by reversing the changes
made by the commit that removed it:
From: Jason Merrill <jason@redhat.com>
Date: Sun, 23 Dec 2018 00:06:34 +0000 (-0500)
Subject: Remove support for demangling GCC 2.x era mangling schemes.
X-Git-Tag: releases/gcc-9.1.0~2159
X-Git-Url: https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff_plain;h=6c8120c5ff130e03d32ff15a8f0d0e703592a2af
Remove support for demangling GCC 2.x era mangling schemes.
libiberty/
* cplus-dem.c: Remove cplus_mangle_opname, cplus_demangle_opname,
internal_cplus_demangle, and all subroutines.
(libiberty_demanglers): Remove entries for ancient GNU (pre-3.0),
Lucid, ARM, HP, and EDG demangling styles.
(cplus_demangle): Remove 'work' variable. Don't call
internal_cplus_demangle.
include/
* demangle.h: Remove support for ancient GNU (pre-3.0), Lucid,
ARM, HP, and EDG demangling styles.
From-SVN: r267363
In addition, the cplus_demangle_opname function has been modified to address a
memory safety issue:
/* CCC: Allocate the result on the heap to prevent buffer overruns. */
extern char *
cplus_demangle_opname (const char *opname, int options);

40
3rdparty/demangler/copy_demangler_files.sh vendored Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
set -e
# This script copies all the source files needed for the GNU demangler from a
# copy of GCC to the specified output directory.
if [ "$#" -ne 2 ]; then
echo "usage: $0 <gcc dir> <out dir>"
exit 1
fi
GCC_DIR=$1
OUT_DIR=$2
cp "$GCC_DIR/include/ansidecl.h" "$OUT_DIR/include/"
cp "$GCC_DIR/include/demangle.h" "$OUT_DIR/include/"
cp "$GCC_DIR/include/dyn-string.h" "$OUT_DIR/include/"
cp "$GCC_DIR/include/environ.h" "$OUT_DIR/include/"
cp "$GCC_DIR/include/getopt.h" "$OUT_DIR/include/"
cp "$GCC_DIR/include/libiberty.h" "$OUT_DIR/include/"
cp "$GCC_DIR/include/safe-ctype.h" "$OUT_DIR/include/"
cp "$GCC_DIR/libiberty/alloca.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/argv.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/cp-demangle.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/cp-demangle.h" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/cplus-dem.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/d-demangle.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/dyn-string.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/getopt.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/getopt1.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/rust-demangle.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/safe-ctype.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/xexit.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/xmalloc.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/xmemdup.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/xstrdup.c" "$OUT_DIR/src/"
cp "$GCC_DIR/libiberty/testsuite/demangle-expected" "$OUT_DIR/testsuite/"
cp "$GCC_DIR/libiberty/testsuite/demangler-fuzzer.c" "$OUT_DIR/testsuite/"
cp "$GCC_DIR/libiberty/testsuite/test-demangle.c" "$OUT_DIR/testsuite/"

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)common\vsprops\BaseProjectConfig.props" />
<Import Project="$(SolutionDir)common\vsprops\WinSDK.props" />
<PropertyGroup Label="Globals">
<ProjectGuid>{1E3D706C-1D95-4E1B-BDF2-CA3D0007DF7F}</ProjectGuid>
<ProjectGuid>{D31A6DD1-99CA-41D8-A230-1FAE913C8989}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
@@ -30,29 +30,36 @@
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<ClCompile Include="src\demangler.cpp" />
<ClCompile Include="src\demtools.cpp" />
<ClCompile Include="src\gparser.cpp" />
<ClCompile Include="src\igrams.cpp" />
<ClCompile Include="src\stgrammars\borlandll.cpp" />
<ClCompile Include="src\stgrammars\gccll.cpp" />
<ClCompile Include="src\stgrammars\msll.cpp" />
<ClInclude Include="include\ansidecl.h" />
<ClInclude Include="include\cp-demangle.h" />
<ClInclude Include="include\demangle.h" />
<ClInclude Include="include\dyn-string.h" />
<ClInclude Include="include\environ.h" />
<ClInclude Include="include\getopt.h" />
<ClInclude Include="include\libiberty.h" />
<ClInclude Include="include\safe-ctype.h" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\demangler\demangler.h" />
<ClInclude Include="include\demangler\demglobal.h" />
<ClInclude Include="include\demangler\demtools.h" />
<ClInclude Include="include\demangler\gparser.h" />
<ClInclude Include="include\demangler\igrams.h" />
<ClInclude Include="include\demangler\stgrammars\borlandll.h" />
<ClInclude Include="include\demangler\stgrammars\gccll.h" />
<ClInclude Include="include\demangler\stgrammars\msll.h" />
<ClCompile Include="src\alloca.c" />
<ClCompile Include="src\argv.c" />
<ClCompile Include="src\cp-demangle.c" />
<ClCompile Include="src\cplus-dem.c" />
<ClCompile Include="src\d-demangle.c" />
<ClCompile Include="src\dyn-string.c" />
<ClCompile Include="src\getopt.c" />
<ClCompile Include="src\getopt1.c" />
<ClCompile Include="src\rust-demangle.c" />
<ClCompile Include="src\safe-ctype.c" />
<ClCompile Include="src\xexit.c" />
<ClCompile Include="src\xmalloc.c" />
<ClCompile Include="src\xmemdup.c" />
<ClCompile Include="src\xstrdup.c" />
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>HAVE_DECL_BASENAME=1;HAVE_LIMITS_H;HAVE_STDLIB_H=1;HAVE_STRING_H=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<AdditionalIncludeDirectories>$(ProjectDir)include;$(ProjectDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@@ -1,22 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="src\demangler.cpp" />
<ClCompile Include="src\demtools.cpp" />
<ClCompile Include="src\gparser.cpp" />
<ClCompile Include="src\igrams.cpp" />
<ClCompile Include="src\stgrammars\borlandll.cpp" />
<ClCompile Include="src\stgrammars\gccll.cpp" />
<ClCompile Include="src\stgrammars\msll.cpp" />
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\demangler\demangler.h" />
<ClInclude Include="include\demangler\demglobal.h" />
<ClInclude Include="include\demangler\demtools.h" />
<ClInclude Include="include\demangler\gparser.h" />
<ClInclude Include="include\demangler\igrams.h" />
<ClInclude Include="include\demangler\stgrammars\borlandll.h" />
<ClInclude Include="include\demangler\stgrammars\gccll.h" />
<ClInclude Include="include\demangler\stgrammars\msll.h" />
<ClInclude Include="include\ansidecl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\cp-demangle.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\demangle.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\dyn-string.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\environ.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\getopt.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\libiberty.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\safe-ctype.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\alloca.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\argv.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\cp-demangle.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\cplus-dem.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\d-demangle.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\dyn-string.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\getopt.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\getopt1.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\rust-demangle.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\safe-ctype.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\xexit.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\xmalloc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\xmemdup.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\xstrdup.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

354
3rdparty/demangler/include/ansidecl.h vendored Normal file
View File

@@ -0,0 +1,354 @@
/* Compiler compatibility macros
Copyright (C) 1991-2023 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
/* For ease of writing code which uses GCC extensions but needs to be
portable to other compilers, we provide the GCC_VERSION macro that
simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various
wrappers around __attribute__. Also, __extension__ will be #defined
to nothing if it doesn't work. See below. */
#ifndef _ANSIDECL_H
#define _ANSIDECL_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* Every source file includes this file,
so they will all get the switch for lint. */
/* LINTLIBRARY */
/* Using MACRO(x,y) in cpp #if conditionals does not work with some
older preprocessors. Thus we can't define something like this:
#define HAVE_GCC_VERSION(MAJOR, MINOR) \
(__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
and then test "#if HAVE_GCC_VERSION(2,7)".
So instead we use the macro below and test it against specific values. */
/* This macro simplifies testing whether we are using gcc, and if it
is of a particular minimum version. (Both major & minor numbers are
significant.) This macro will evaluate to 0 if we are not using
gcc at all. */
#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#endif /* GCC_VERSION */
/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
it too, but it's not in C89. */
#undef inline
#if (!defined(__cplusplus) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__))
/* it's a keyword */
#else
# if GCC_VERSION >= 2007
# define inline __inline__ /* __inline__ prevents -pedantic warnings */
# else
# define inline /* nothing */
# endif
#endif
/* Define macros for some gcc attributes. This permits us to use the
macros freely, and know that they will come into play for the
version of gcc in which they are supported. */
#if (GCC_VERSION < 2007)
# define __attribute__(x)
#endif
/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
#ifndef ATTRIBUTE_MALLOC
# if (GCC_VERSION >= 2096)
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
# else
# define ATTRIBUTE_MALLOC
# endif /* GNUC >= 2.96 */
#endif /* ATTRIBUTE_MALLOC */
/* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For
g++ an attribute on a label must be followed by a semicolon. */
#ifndef ATTRIBUTE_UNUSED_LABEL
# ifndef __cplusplus
# if GCC_VERSION >= 2093
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
# else
# define ATTRIBUTE_UNUSED_LABEL
# endif
# else
# if GCC_VERSION >= 4005
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ;
# else
# define ATTRIBUTE_UNUSED_LABEL
# endif
# endif
#endif
/* Similarly to ARG_UNUSED below. Prior to GCC 3.4, the C++ frontend
couldn't parse attributes placed after the identifier name, and now
the entire compiler is built with C++. */
#ifndef ATTRIBUTE_UNUSED
#if GCC_VERSION >= 3004
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
#else
#define ATTRIBUTE_UNUSED
#endif
#endif /* ATTRIBUTE_UNUSED */
/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the
identifier name. */
#if ! defined(__cplusplus) || (GCC_VERSION >= 3004)
# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED
#else /* !__cplusplus || GNUC >= 3.4 */
# define ARG_UNUSED(NAME) NAME
#endif /* !__cplusplus || GNUC >= 3.4 */
#ifndef ATTRIBUTE_NORETURN
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
#endif /* ATTRIBUTE_NORETURN */
/* Attribute `nonnull' was valid as of gcc 3.3. */
#ifndef ATTRIBUTE_NONNULL
# if (GCC_VERSION >= 3003)
# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m)))
# else
# define ATTRIBUTE_NONNULL(m)
# endif /* GNUC >= 3.3 */
#endif /* ATTRIBUTE_NONNULL */
/* Attribute `returns_nonnull' was valid as of gcc 4.9. */
#ifndef ATTRIBUTE_RETURNS_NONNULL
# if (GCC_VERSION >= 4009)
# define ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__))
# else
# define ATTRIBUTE_RETURNS_NONNULL
# endif /* GNUC >= 4.9 */
#endif /* ATTRIBUTE_RETURNS_NONNULL */
/* Attribute `pure' was valid as of gcc 3.0. */
#ifndef ATTRIBUTE_PURE
# if (GCC_VERSION >= 3000)
# define ATTRIBUTE_PURE __attribute__ ((__pure__))
# else
# define ATTRIBUTE_PURE
# endif /* GNUC >= 3.0 */
#endif /* ATTRIBUTE_PURE */
/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL.
This was the case for the `printf' format attribute by itself
before GCC 3.3, but as of 3.3 we need to add the `nonnull'
attribute to retain this behavior. */
#ifndef ATTRIBUTE_PRINTF
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m)
#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
#endif /* ATTRIBUTE_PRINTF */
/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on
a function pointer. Format attributes were allowed on function
pointers as of gcc 3.1. */
#ifndef ATTRIBUTE_FPTR_PRINTF
# if (GCC_VERSION >= 3001)
# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n)
# else
# define ATTRIBUTE_FPTR_PRINTF(m, n)
# endif /* GNUC >= 3.1 */
# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2)
# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3)
# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4)
# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5)
# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6)
#endif /* ATTRIBUTE_FPTR_PRINTF */
/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A
NULL format specifier was allowed as of gcc 3.3. */
#ifndef ATTRIBUTE_NULL_PRINTF
# if (GCC_VERSION >= 3003)
# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
# else
# define ATTRIBUTE_NULL_PRINTF(m, n)
# endif /* GNUC >= 3.3 */
# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2)
# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3)
# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4)
# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5)
# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6)
#endif /* ATTRIBUTE_NULL_PRINTF */
/* Attribute `sentinel' was valid as of gcc 3.5. */
#ifndef ATTRIBUTE_SENTINEL
# if (GCC_VERSION >= 3005)
# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__))
# else
# define ATTRIBUTE_SENTINEL
# endif /* GNUC >= 3.5 */
#endif /* ATTRIBUTE_SENTINEL */
#ifndef ATTRIBUTE_ALIGNED_ALIGNOF
# if (GCC_VERSION >= 3000)
# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m))))
# else
# define ATTRIBUTE_ALIGNED_ALIGNOF(m)
# endif /* GNUC >= 3.0 */
#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */
/* Useful for structures whose layout must match some binary specification
regardless of the alignment and padding qualities of the compiler. */
#ifndef ATTRIBUTE_PACKED
# define ATTRIBUTE_PACKED __attribute__ ((packed))
#endif
/* Attribute `hot' and `cold' was valid as of gcc 4.3. */
#ifndef ATTRIBUTE_COLD
# if (GCC_VERSION >= 4003)
# define ATTRIBUTE_COLD __attribute__ ((__cold__))
# else
# define ATTRIBUTE_COLD
# endif /* GNUC >= 4.3 */
#endif /* ATTRIBUTE_COLD */
#ifndef ATTRIBUTE_HOT
# if (GCC_VERSION >= 4003)
# define ATTRIBUTE_HOT __attribute__ ((__hot__))
# else
# define ATTRIBUTE_HOT
# endif /* GNUC >= 4.3 */
#endif /* ATTRIBUTE_HOT */
/* Attribute 'no_sanitize_undefined' was valid as of gcc 4.9. */
#ifndef ATTRIBUTE_NO_SANITIZE_UNDEFINED
# if (GCC_VERSION >= 4009)
# define ATTRIBUTE_NO_SANITIZE_UNDEFINED __attribute__ ((no_sanitize_undefined))
# else
# define ATTRIBUTE_NO_SANITIZE_UNDEFINED
# endif /* GNUC >= 4.9 */
#endif /* ATTRIBUTE_NO_SANITIZE_UNDEFINED */
/* Attribute 'nonstring' was valid as of gcc 8. */
#ifndef ATTRIBUTE_NONSTRING
# if GCC_VERSION >= 8000
# define ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__))
# else
# define ATTRIBUTE_NONSTRING
# endif
#endif
/* Attribute `alloc_size' was valid as of gcc 4.3. */
#ifndef ATTRIBUTE_RESULT_SIZE_1
# if (GCC_VERSION >= 4003)
# define ATTRIBUTE_RESULT_SIZE_1 __attribute__ ((alloc_size (1)))
# else
# define ATTRIBUTE_RESULT_SIZE_1
#endif
#endif
#ifndef ATTRIBUTE_RESULT_SIZE_2
# if (GCC_VERSION >= 4003)
# define ATTRIBUTE_RESULT_SIZE_2 __attribute__ ((alloc_size (2)))
# else
# define ATTRIBUTE_RESULT_SIZE_2
#endif
#endif
#ifndef ATTRIBUTE_RESULT_SIZE_1_2
# if (GCC_VERSION >= 4003)
# define ATTRIBUTE_RESULT_SIZE_1_2 __attribute__ ((alloc_size (1, 2)))
# else
# define ATTRIBUTE_RESULT_SIZE_1_2
#endif
#endif
/* Attribute `warn_unused_result' was valid as of gcc 3.3. */
#ifndef ATTRIBUTE_WARN_UNUSED_RESULT
# if GCC_VERSION >= 3003
# define ATTRIBUTE_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__))
# else
# define ATTRIBUTE_WARN_UNUSED_RESULT
# endif
#endif
/* We use __extension__ in some places to suppress -pedantic warnings
about GCC extensions. This feature didn't work properly before
gcc 2.8. */
#if GCC_VERSION < 2008
#define __extension__
#endif
/* This is used to declare a const variable which should be visible
outside of the current compilation unit. Use it as
EXPORTED_CONST int i = 1;
This is because the semantics of const are different in C and C++.
"extern const" is permitted in C but it looks strange, and gcc
warns about it when -Wc++-compat is not used. */
#ifdef __cplusplus
#define EXPORTED_CONST extern const
#else
#define EXPORTED_CONST const
#endif
/* Be conservative and only use enum bitfields with C++ or GCC.
FIXME: provide a complete autoconf test for buggy enum bitfields. */
#ifdef __cplusplus
#define ENUM_BITFIELD(TYPE) enum TYPE
#elif (GCC_VERSION > 2000)
#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
#else
#define ENUM_BITFIELD(TYPE) unsigned int
#endif
#if defined(__cplusplus) && __cpp_constexpr >= 200704
#define CONSTEXPR constexpr
#else
#define CONSTEXPR
#endif
/* A macro to disable the copy constructor and assignment operator.
When building with C++11 and above, the methods are explicitly
deleted, causing a compile-time error if something tries to copy.
For C++03, this just declares the methods, causing a link-time
error if the methods end up called (assuming you don't
define them). For C++03, for best results, place the macro
under the private: access specifier, like this,
class name_lookup
{
private:
DISABLE_COPY_AND_ASSIGN (name_lookup);
};
so that most attempts at copy are caught at compile-time. */
#if defined(__cplusplus) && __cplusplus >= 201103
#define DISABLE_COPY_AND_ASSIGN(TYPE) \
TYPE (const TYPE&) = delete; \
void operator= (const TYPE &) = delete
#else
#define DISABLE_COPY_AND_ASSIGN(TYPE) \
TYPE (const TYPE&); \
void operator= (const TYPE &)
#endif /* __cplusplus >= 201103 */
#ifdef __cplusplus
}
#endif
#endif /* ansidecl.h */

201
3rdparty/demangler/include/cp-demangle.h vendored Normal file
View File

@@ -0,0 +1,201 @@
/* Internal demangler interface for g++ V3 ABI.
Copyright (C) 2003-2023 Free Software Foundation, Inc.
Written by Ian Lance Taylor <ian@wasabisystems.com>.
This file is part of the libiberty library, which is part of GCC.
This file is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combined
executable.)
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* This file provides some definitions shared by cp-demangle.c and
cp-demint.c. It should not be included by any other files. */
/* Information we keep for operators. */
struct demangle_operator_info
{
/* Mangled name. */
const char *code;
/* Real name. */
const char *name;
/* Length of real name. */
int len;
/* Number of arguments. */
int args;
};
/* How to print the value of a builtin type. */
enum d_builtin_type_print
{
/* Print as (type)val. */
D_PRINT_DEFAULT,
/* Print as integer. */
D_PRINT_INT,
/* Print as unsigned integer, with trailing "u". */
D_PRINT_UNSIGNED,
/* Print as long, with trailing "l". */
D_PRINT_LONG,
/* Print as unsigned long, with trailing "ul". */
D_PRINT_UNSIGNED_LONG,
/* Print as long long, with trailing "ll". */
D_PRINT_LONG_LONG,
/* Print as unsigned long long, with trailing "ull". */
D_PRINT_UNSIGNED_LONG_LONG,
/* Print as bool. */
D_PRINT_BOOL,
/* Print as float--put value in square brackets. */
D_PRINT_FLOAT,
/* Print in usual way, but here to detect void. */
D_PRINT_VOID
};
/* Information we keep for a builtin type. */
struct demangle_builtin_type_info
{
/* Type name. */
const char *name;
/* Length of type name. */
int len;
/* Type name when using Java. */
const char *java_name;
/* Length of java name. */
int java_len;
/* How to print a value of this type. */
enum d_builtin_type_print print;
};
/* The information structure we pass around. */
struct d_info
{
/* The string we are demangling. */
const char *s;
/* The end of the string we are demangling. */
const char *send;
/* The options passed to the demangler. */
int options;
/* The next character in the string to consider. */
const char *n;
/* The array of components. */
struct demangle_component *comps;
/* The index of the next available component. */
int next_comp;
/* The number of available component structures. */
int num_comps;
/* The array of substitutions. */
struct demangle_component **subs;
/* The index of the next substitution. */
int next_sub;
/* The number of available entries in the subs array. */
int num_subs;
/* The last name we saw, for constructors and destructors. */
struct demangle_component *last_name;
/* A running total of the length of large expansions from the
mangled name to the demangled name, such as standard
substitutions and builtin types. */
int expansion;
/* Non-zero if we are parsing an expression. */
int is_expression;
/* Non-zero if we are parsing the type operand of a conversion
operator, but not when in an expression. */
int is_conversion;
/* 1: using new unresolved-name grammar.
-1: using new unresolved-name grammar and saw an unresolved-name.
0: using old unresolved-name grammar. */
int unresolved_name_state;
/* If DMGL_NO_RECURSE_LIMIT is not active then this is set to
the current recursion level. */
unsigned int recursion_level;
};
/* To avoid running past the ending '\0', don't:
- call d_peek_next_char if d_peek_char returned '\0'
- call d_advance with an 'i' that is too large
- call d_check_char(di, '\0')
Everything else is safe. */
#define d_peek_char(di) (*((di)->n))
#ifndef CHECK_DEMANGLER
# define d_peek_next_char(di) ((di)->n[1])
# define d_advance(di, i) ((di)->n += (i))
#endif
#define d_check_char(di, c) (d_peek_char(di) == c ? ((di)->n++, 1) : 0)
#define d_next_char(di) (d_peek_char(di) == '\0' ? '\0' : *((di)->n++))
#define d_str(di) ((di)->n)
#ifdef CHECK_DEMANGLER
static inline char
d_peek_next_char (const struct d_info *di)
{
if (!di->n[0])
abort ();
return di->n[1];
}
static inline void
d_advance (struct d_info *di, int i)
{
if (i < 0)
abort ();
while (i--)
{
if (!di->n[0])
abort ();
di->n++;
}
}
#endif
/* Functions and arrays in cp-demangle.c which are referenced by
functions in cp-demint.c. */
#ifdef IN_GLIBCPP_V3
#define CP_STATIC_IF_GLIBCPP_V3 static
#else
#define CP_STATIC_IF_GLIBCPP_V3 extern
#endif
#ifndef IN_GLIBCPP_V3
extern const struct demangle_operator_info cplus_demangle_operators[];
#endif
#define D_BUILTIN_TYPE_COUNT (36)
CP_STATIC_IF_GLIBCPP_V3
const struct demangle_builtin_type_info
cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT];
CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_mangled_name (struct d_info *, int);
CP_STATIC_IF_GLIBCPP_V3
struct demangle_component *
cplus_demangle_type (struct d_info *);
extern void
cplus_demangle_init_info (const char *, int, size_t, struct d_info *);
/* cp-demangle.c needs to define this a little differently */
#undef CP_STATIC_IF_GLIBCPP_V3

Some files were not shown because too many files have changed in this diff Show More